Upstream merge for M31.

Merged from b1e276f8df257a7ad190419b349d0d86d104c8ae.

Conflicts:
	.gitignore
	libavcodec/cdxl.c
	libavcodec/h264.c
	libavcodec/h264_parser.c
	libavcodec/ituh263dec.c
	libavcodec/mpeg12.c
	libavcodec/vp3.c
	libavcodec/x86/dsputil_mmx.c
	libavcodec/x86/dsputil_x86.h
diff --git a/.gitignore b/.gitignore
index 191d154..298bea9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -67,6 +67,7 @@
 /tools/fourcc2pixfmt
 /tools/ffescape
 /tools/ffeval
+/tools/ffhash
 /tools/graph2dot
 /tools/ismindex
 /tools/pktdumper
@@ -74,6 +75,7 @@
 /tools/qt-faststart
 /tools/trasher
 /tools/seek_print
+/tools/zmqsend
 
 # Chromium stuff.
 /chromium/binaries/Chrome
@@ -82,4 +84,4 @@
 *.target.mk
 /*.targets
 /*.vcxproj*
-/*.xml
+/*.xml
\ No newline at end of file
diff --git a/Changelog b/Changelog
index f71e0d8..4a6c60c 100644
--- a/Changelog
+++ b/Changelog
@@ -1,7 +1,24 @@
 Entries are sorted chronologically from oldest to youngest within each release,
 releases are sorted from youngest to oldest.
 
-version <next>:
+version <next>
+
+- aecho filter
+- perspective filter ported from libmpcodecs
+- ffprobe -show_programs option
+- compand filter
+- RTMP seek support
+- when transcoding with ffmpeg (i.e. not streamcopying), -ss is now accurate
+  even when used as an input option. Previous behavior can be restored with
+  the -noaccurate_seek option.
+- ffmpeg -t option can now be used for inputs, to limit the duration of
+  data read from an input file
+- incomplete Voxware MetaSound decoder
+- read EXIF metadata from JPEG
+
+
+version 2.0:
+
 - curves filter
 - reference-counting for AVFrame and AVPacket data
 - ffmpeg now fails when input options are used for output file
@@ -33,6 +50,43 @@
 - timeline editing with filters
 - vidstabdetect and vidstabtransform filters for video stabilization using
   the vid.stab library
+- astats filter
+- trim and atrim filters
+- ffmpeg -t and -ss (output-only) options are now sample-accurate when
+  transcoding audio
+- Matroska muxer can now put the index at the beginning of the file.
+- extractplanes filter
+- avectorscope filter
+- ADPCM DTK decoder
+- ADP demuxer
+- RSD demuxer
+- RedSpark demuxer
+- ADPCM IMA Radical decoder
+- zmq filters
+- DCT denoiser filter (dctdnoiz)
+- Wavelet denoiser filter ported from libmpcodecs as owdenoise (formerly "ow")
+- Apple Intermediate Codec decoder
+- Escape 130 video decoder
+- FTP protocol support
+- V4L2 output device
+- 3D LUT filter (lut3d)
+- SMPTE 302M audio encoder
+- support for slice multithreading in libavfilter
+- Hald CLUT support (generation and filtering)
+- VC-1 interlaced B-frame support
+- support for WavPack muxing (raw and in Matroska)
+- XVideo output device
+- vignette filter
+- True Audio (TTA) encoder
+- Go2Webinar decoder
+- mcdeint filter ported from libmpcodecs
+- sab filter ported from libmpcodecs
+- ffprobe -show_chapters option
+- WavPack encoding through libwavpack
+- rotate filter
+- spp filter ported from libmpcodecs
+- libgme support
+- psnr filter
 
 
 version 1.2:
@@ -669,7 +723,7 @@
 - MXF demuxer
 - VC-1/WMV3/WMV9 video decoder
 - MacIntel support
-- AVISynth support
+- AviSynth support
 - VMware video decoder
 - VP5 video decoder
 - VP6 video decoder
diff --git a/LICENSE b/LICENSE
index 8760753..575824e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -35,10 +35,15 @@
     - vf_hqdn3d.c
     - vf_hue.c
     - vf_kerndeint.c
+    - vf_mcdeint.c
     - vf_mp.c
     - vf_noise.c
+    - vf_owdenoise.c
+    - vf_perspective.c
     - vf_pp.c
+    - vf_sab.c
     - vf_smartblur.c
+    - vf_spp.c
     - vf_stereo3d.c
     - vf_super2xsai.c
     - vf_tinterlace.c
@@ -70,6 +75,7 @@
 --------------------
 
 The following libraries are under GPL:
+    - frei0r
     - libcdio
     - libutvideo
     - libvidstab
diff --git a/MAINTAINERS b/MAINTAINERS
index 3b3cdc5..8b00d1f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7,8 +7,8 @@
 Please try to keep entries where you are the maintainer up to date!
 
 Names in () mean that the maintainer currently has no time to maintain the code.
-A CC after the name means that the maintainer prefers to be CC-ed on patches
-and related discussions.
+A (CC <address>) after the name means that the maintainer prefers to be CC-ed on
+patches and related discussions.
 
 
 Project Leader
@@ -46,7 +46,7 @@
 documentation                           Mike Melanson
 website                                 Robert Swain, Lou Logan
 build system (configure,Makefiles)      Diego Biurrun, Mans Rullgard
-project server                          Árpád Gereöffy, Michael Niedermayer, Reimar Döffinger
+project server                          Árpád Gereöffy, Michael Niedermayer, Reimar Döffinger, Alexander Strasser
 mailinglists                            Michael Niedermayer, Baptiste Coudurier, Lou Logan
 presets                                 Robert Swain
 metadata subsystem                      Aurelien Jacobs
@@ -62,12 +62,20 @@
   libavutil/common.h                    Michael Niedermayer
 
 Other:
-  intfloat*                             Michael Niedermayer
-  rational.c, rational.h                Michael Niedermayer
-  mathematics.c, mathematics.h          Michael Niedermayer
-  integer.c, integer.h                  Michael Niedermayer
+  bprint                                Nicolas George
   bswap.h
+  des                                   Reimar Doeffinger
+  float_dsp                             Loren Merritt
+  hash                                  Reimar Doeffinger
+  intfloat*                             Michael Niedermayer
+  integer.c, integer.h                  Michael Niedermayer
+  lzo                                   Reimar Doeffinger
+  mathematics.c, mathematics.h          Michael Niedermayer
   opencl.c, opencl.h                    Wei Gao
+  rational.c, rational.h                Michael Niedermayer
+  rc4                                   Reimar Doeffinger
+  ripemd.c, ripemd.h                    James Almer
+  timecode                              Clément Bœsch
 
 
 libavcodec
@@ -112,6 +120,8 @@
     libpostproc/*                       Michael Niedermayer
   table generation:
     tableprint.c, tableprint.h          Reimar Doeffinger
+  fixed point FFT:
+    fft*                                Zeljko Lukac
 
 Codecs:
   4xm.c                                 Michael Niedermayer
@@ -130,8 +140,8 @@
   binkaudio.c                           Peter Ross
   bmp.c                                 Mans Rullgard, Kostya Shishkov
   cavs*                                 Stefan Gehrer
-  celp_filters.*                        Vitor Sessak
   cdxl.c                                Paul B Mahol
+  celp_filters.*                        Vitor Sessak
   cinepak.c                             Roberto Togni
   cljr                                  Alex Beregszaszi
   cllc.c                                Derek Buitenhuis
@@ -142,9 +152,10 @@
   dca.c                                 Kostya Shishkov, Benjamin Larsson
   dnxhd*                                Baptiste Coudurier
   dpcm.c                                Mike Melanson
-  dxa.c                                 Kostya Shishkov
   dv.c                                  Roman Shaposhnik
+  dxa.c                                 Kostya Shishkov
   eacmv*, eaidct*, eat*                 Peter Ross
+  exif.c, exif.h                        Thilo Borgmann
   ffv1.c                                Michael Niedermayer
   ffwavesynth.c                         Nicolas George
   flac*                                 Justin Ruggles
@@ -153,9 +164,9 @@
   g722.c                                Martin Storsjo
   g726.c                                Roman Shaposhnik
   gifdec.c                              Baptiste Coudurier
-  h264*                                 Loren Merritt, Michael Niedermayer
   h261*                                 Michael Niedermayer
   h263*                                 Michael Niedermayer
+  h264*                                 Loren Merritt, Michael Niedermayer
   huffyuv.c                             Michael Niedermayer
   idcinvideo.c                          Mike Melanson
   imc*                                  Benjamin Larsson
@@ -170,8 +181,8 @@
   kmvc.c                                Kostya Shishkov
   lcl*.c                                Roberto Togni, Reimar Doeffinger
   libcelt_dec.c                         Nicolas George
-  libgsm.c                              Michel Bardiaux
   libdirac*                             David Conrad
+  libgsm.c                              Michel Bardiaux
   libopenjpeg.c                         Jaikrishnan Menon
   libopenjpegenc.c                      Michael Bradshaw
   libschroedinger*                      David Conrad
@@ -179,8 +190,8 @@
   libtheoraenc.c                        David Conrad
   libutvideo*                           Derek Buitenhuis
   libvorbis.c                           David Conrad
-  libxavs.c                             Stefan Gehrer
   libx264.c                             Mans Rullgard, Jason Garrett-Glaser
+  libxavs.c                             Stefan Gehrer
   loco.c                                Kostya Shishkov
   lzo.h, lzo.c                          Reimar Doeffinger
   mdec.c                                Michael Niedermayer
@@ -217,6 +228,7 @@
   s3tc*                                 Ivo van Poorten
   smacker.c                             Kostya Shishkov
   smc.c                                 Mike Melanson
+  smvjpegdec.c                          Ash Hughes
   snow.c                                Michael Niedermayer, Loren Merritt
   sonic.c                               Alex Beregszaszi
   srt*                                  Aurelien Jacobs
@@ -230,6 +242,7 @@
   truespeech.c                          Kostya Shishkov
   tscc.c                                Kostya Shishkov
   tta.c                                 Alex Beregszaszi, Jaikrishnan Menon
+  ttaenc.c                              Paul B Mahol
   txd.c                                 Ivo van Poorten
   ulti*                                 Kostya Shishkov
   v410*.c                               Derek Buitenhuis
@@ -240,8 +253,8 @@
   vda_h264_dec.c                        Xidorn Quan
   vima.c                                Paul B Mahol
   vmnc.c                                Kostya Shishkov
-  vorbis_enc.c                          Oded Shimon
   vorbis_dec.c                          Denes Balatoni, David Conrad
+  vorbis_enc.c                          Oded Shimon
   vp3*                                  Mike Melanson
   vp5                                   Aurelien Jacobs
   vp6                                   Aurelien Jacobs
@@ -275,11 +288,11 @@
     libavdevice/avdevice.h
 
 
+  dshow.c                               Roger Pack
   iec61883.c                            Georg Lippitsch
   libdc1394.c                           Roman Shaposhnik
   v4l2.c                                Luca Abeni
   vfwcap.c                              Ramiro Polla
-  dshow.c                               Roger Pack
 
 libavfilter
 ===========
@@ -289,9 +302,13 @@
 
 Filters:
   af_amerge.c                           Nicolas George
+  af_aresample.c                        Michael Niedermayer
   af_astreamsync.c                      Nicolas George
   af_atempo.c                           Pavel Koshevoy
   af_pan.c                              Nicolas George
+  vf_delogo.c                           Jean Delvare (CC <khali@linux-fr.org>)
+  vf_drawbox.c/drawgrid                 Andrey Utkin
+  vf_scale.c                            Michael Niedermayer
   vf_yadif.c                            Michael Niedermayer
 
 Sources:
@@ -311,13 +328,14 @@
   4xm.c                                 Mike Melanson
   adtsenc.c                             Robert Swain
   afc.c                                 Paul B Mahol
-  aiff.c                                Baptiste Coudurier
+  aiffdec.c                             Baptiste Coudurier, Matthieu Bouron
+  aiffenc.c                             Baptiste Coudurier, Matthieu Bouron
   ape.c                                 Kostya Shishkov
   ass*                                  Aurelien Jacobs
   astdec.c                              Paul B Mahol
   astenc.c                              James Almer
   avi*                                  Michael Niedermayer
-  avisynth.c                            AvxSynth Team
+  avisynth.c                            AvxSynth Team (avxsynth.testing at gmail dot com)
   avr.c                                 Paul B Mahol
   bink.c                                Peter Ross
   brstm.c                               Paul B Mahol
@@ -339,8 +357,8 @@
   idcin.c                               Mike Melanson
   idroqdec.c                            Mike Melanson
   iff.c                                 Jaikrishnan Menon
-  ipmovie.c                             Mike Melanson
   img2*.c                               Michael Niedermayer
+  ipmovie.c                             Mike Melanson
   ircam*                                Paul B Mahol
   iss.c                                 Stefan Gehrer
   jacosub*                              Clément Bœsch
@@ -354,11 +372,11 @@
   matroskadec.c                         Aurelien Jacobs
   matroskaenc.c                         David Conrad
   metadata*                             Aurelien Jacobs
-  microdvd*                             Aurelien Jacobs
   mgsts.c                               Paul B Mahol
+  microdvd*                             Aurelien Jacobs
   mm.c                                  Peter Ross
   mov.c                                 Michael Niedermayer, Baptiste Coudurier
-  movenc.c                              Michael Niedermayer, Baptiste Coudurier
+  movenc.c                              Baptiste Coudurier, Matthieu Bouron
   mpc.c                                 Kostya Shishkov
   mpeg.c                                Michael Niedermayer
   mpegenc.c                             Michael Niedermayer
@@ -403,6 +421,7 @@
   voc.c                                 Aurelien Jacobs
   wav.c                                 Michael Niedermayer
   wc3movie.c                            Mike Melanson
+  webvtt*                               Matthew J Heaney
   westwood.c                            Mike Melanson
   wtv.c                                 Peter Ross
   wv.c                                  Kostya Shishkov
@@ -410,6 +429,7 @@
 
 Protocols:
   bluray.c                              Petri Hintukainen
+  ftp.c                                 Lukasz Marek
   http.c                                Ronald S. Bultje
   mms*.c                                Ronald S. Bultje
   udp.c                                 Luca Abeni
@@ -435,7 +455,7 @@
 Alpha                                   Mans Rullgard, Falk Hueffner
 ARM                                     Mans Rullgard
 AVR32                                   Mans Rullgard
-MIPS                                    Mans Rullgard
+MIPS                                    Mans Rullgard, Nedeljko Babic
 Mac OS X / PowerPC                      Romain Dolbeau, Guillaume Poirier
 Amiga / PowerPC                         Colin Ward
 Linux / PowerPC                         Luca Barbato
@@ -449,9 +469,8 @@
 Releases
 ========
 
+2.0                                     Michael Niedermayer
 1.2                                     Michael Niedermayer
-1.1                                     Michael Niedermayer
-1.0                                     Michael Niedermayer
 
 If you want to maintain an older release, please contact us
 
@@ -461,6 +480,7 @@
 
 Anssi Hannula                 1A92 FF42 2DD9 8D2E 8AF7 65A9 4278 C520 513D F3CB
 Anton Khirnov                 6D0C 6625 56F8 65D1 E5F5 814B B50A 1241 C067 07AB
+Ash Hughes                    694D 43D2 D180 C7C7 6421 ABD3 A641 D0B7 623D 6029
 Attila Kinali                 11F0 F9A6 A1D2 11F6 C745 D10C 6520 BCDD F2DF E765
 Baptiste Coudurier            8D77 134D 20CC 9220 201F C5DB 0AC9 325C 5C1A BAAA
 Ben Littler                   3EE3 3723 E560 3214 A8CD 4DEB 2CDB FCE7 768C 8D2C
@@ -468,8 +488,10 @@
 Bœsch Clément                 52D0 3A82 D445 F194 DB8B 2B16 87EE 2CB8 F4B8 FCF9
 Daniel Verkamp                78A6 07ED 782C 653E C628 B8B9 F0EB 8DD8 2F0E 21C7
 Diego Biurrun                 8227 1E31 B6D9 4994 7427 E220 9CAE D6CC 4757 FCC5
+FFmpeg release signing key    FCF9 86EA 15E6 E293 A564 4F10 B432 2F04 D676 58D8
 Gwenole Beauchesne            2E63 B3A6 3E44 37E2 017D 2704 53C7 6266 B153 99C4
 Jaikrishnan Menon             61A1 F09F 01C9 2D45 78E1 C862 25DC 8831 AF70 D368
+Jean Delvare                  7CA6 9F44 60F1 BDC4 1FD2 C858 A552 6B9B B3CD 4E6A
 Justin Ruggles                3136 ECC0 C10D 6C04 5F43 CA29 FCBE CD2A 3787 1EBF
 Loren Merritt                 ABD9 08F4 C920 3F65 D8BE 35D7 1540 DAA7 060F 56DE
 Lou Logan                     7D68 DC73 CBEF EABB 671A B6CF 621C 2E28 82F8 DC3A
diff --git a/Makefile b/Makefile
index 7addffb..46d4d52 100644
--- a/Makefile
+++ b/Makefile
@@ -28,7 +28,6 @@
 BASENAMES   = ffmpeg ffplay ffprobe ffserver
 ALLPROGS    = $(BASENAMES:%=%$(PROGSSUF)$(EXESUF))
 ALLPROGS_G  = $(BASENAMES:%=%$(PROGSSUF)_g$(EXESUF))
-ALLMANPAGES = $(BASENAMES:%=%.1)
 
 FFLIBS-$(CONFIG_AVDEVICE) += avdevice
 FFLIBS-$(CONFIG_AVFILTER) += avfilter
@@ -44,7 +43,7 @@
 DATA_FILES := $(wildcard $(SRC_PATH)/presets/*.ffpreset) $(SRC_PATH)/doc/ffprobe.xsd
 EXAMPLES_FILES := $(wildcard $(SRC_PATH)/doc/examples/*.c) $(SRC_PATH)/doc/examples/Makefile $(SRC_PATH)/doc/examples/README
 
-SKIPHEADERS = cmdutils_common_opts.h
+SKIPHEADERS = cmdutils_common_opts.h compat/w32pthreads.h
 
 include $(SRC_PATH)/common.mak
 
diff --git a/RELEASE b/RELEASE
index 3d529fb..cd5ac03 100644
--- a/RELEASE
+++ b/RELEASE
@@ -1 +1 @@
-1.1.git
+2.0
diff --git a/cmdutils.c b/cmdutils.c
index b9985d6..b1d831d 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -111,6 +111,21 @@
     fflush(report_file);
 }
 
+static void (*program_exit)(int ret);
+
+void register_exit(void (*cb)(int ret))
+{
+    program_exit = cb;
+}
+
+void exit_program(int ret)
+{
+    if (program_exit)
+        program_exit(ret);
+
+    exit(ret);
+}
+
 double parse_number_or_die(const char *context, const char *numstr, int type,
                            double min, double max)
 {
@@ -128,7 +143,7 @@
     else
         return d;
     av_log(NULL, AV_LOG_FATAL, error, context, numstr, min, max);
-    exit(1);
+    exit_program(1);
     return 0;
 }
 
@@ -139,7 +154,7 @@
     if (av_parse_time(&us, timestr, is_duration) < 0) {
         av_log(NULL, AV_LOG_FATAL, "Invalid %s specification for %s: %s\n",
                is_duration ? "duration" : "date", context, timestr);
-        exit(1);
+        exit_program(1);
     }
     return us;
 }
@@ -198,7 +213,10 @@
     return po;
 }
 
-#if HAVE_COMMANDLINETOARGVW
+/* _WIN32 means using the windows libc - cygwin doesn't define that
+ * by default. HAVE_COMMANDLINETOARGVW is true on cygwin, while
+ * it doesn't provide the actual command line via GetCommandLineW(). */
+#if HAVE_COMMANDLINETOARGVW && defined(_WIN32)
 #include <windows.h>
 #include <shellapi.h>
 /* Will be leaked on exit */
@@ -304,7 +322,7 @@
         }
     }
     if (po->flags & OPT_EXIT)
-        exit(0);
+        exit_program(0);
 
     return 0;
 }
@@ -364,7 +382,7 @@
             opt++;
 
             if ((ret = parse_option(optctx, opt, argv[optindex], options)) < 0)
-                exit(1);
+                exit_program(1);
             optindex += ret;
         } else {
             if (parse_arg_function)
@@ -637,7 +655,7 @@
     octx->nb_groups = nb_groups;
     octx->groups    = av_mallocz(sizeof(*octx->groups) * octx->nb_groups);
     if (!octx->groups)
-        exit(1);
+        exit_program(1);
 
     for (i = 0; i < octx->nb_groups; i++)
         octx->groups[i].group_def = &groups[i];
@@ -817,7 +835,7 @@
                "Possible levels are numbers or:\n", arg);
         for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
             av_log(NULL, AV_LOG_FATAL, "\"%s\"\n", log_levels[i].name);
-        exit(1);
+        exit_program(1);
     }
     av_log_set_level(level);
     return 0;
@@ -910,7 +928,6 @@
            tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
            tm->tm_hour, tm->tm_min, tm->tm_sec,
            filename.str);
-    av_log_set_level(FFMAX(av_log_get_level(), AV_LOG_VERBOSE));
     av_bprint_finalize(&filename, NULL);
     return 0;
 }
@@ -928,7 +945,7 @@
     max = strtol(arg, &tail, 10);
     if (*tail) {
         av_log(NULL, AV_LOG_FATAL, "Invalid max_alloc \"%s\".\n", arg);
-        exit(1);
+        exit_program(1);
     }
     av_max_alloc(max);
     return 0;
@@ -1214,7 +1231,8 @@
     printf("%s %s [%s]:\n", encoder ? "Encoder" : "Decoder", c->name,
            c->long_name ? c->long_name : "");
 
-    if (c->type == AVMEDIA_TYPE_VIDEO) {
+    if (c->type == AVMEDIA_TYPE_VIDEO ||
+        c->type == AVMEDIA_TYPE_AUDIO) {
         printf("    Threading capabilities: ");
         switch (c->capabilities & (CODEC_CAP_FRAME_THREADS |
                                    CODEC_CAP_SLICE_THREADS)) {
@@ -1295,7 +1313,7 @@
         nb_codecs++;
     if (!(codecs = av_calloc(nb_codecs, sizeof(*codecs)))) {
         av_log(NULL, AV_LOG_ERROR, "Out of memory\n");
-        exit(1);
+        exit_program(1);
     }
     desc = NULL;
     while ((desc = avcodec_descriptor_next(desc)))
@@ -1454,6 +1472,8 @@
     const AVFilterPad *pad;
 
     printf("Filters:\n"
+           "  T. = Timeline support\n"
+           "  .S = Slice threading\n"
            "  A = Audio input/output\n"
            "  V = Video input/output\n"
            "  N = Dynamic number and/or type of input/output\n"
@@ -1477,7 +1497,10 @@
                                   ( i && (filter->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS))) ? 'N' : '|';
         }
         *descr_cur = 0;
-        printf("%-16s %-10s %s\n", filter->name, descr, filter->description);
+        printf(" %c%c %-16s %-10s %s\n",
+               filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE ? 'T' : '.',
+               filter->flags & AVFILTER_FLAG_SLICE_THREADS    ? 'S' : '.',
+               filter->name, descr, filter->description);
     }
 #endif
     return 0;
@@ -1504,11 +1527,11 @@
     while ((pix_desc = av_pix_fmt_desc_next(pix_desc))) {
         enum AVPixelFormat pix_fmt = av_pix_fmt_desc_get_id(pix_desc);
         printf("%c%c%c%c%c %-16s       %d            %2d\n",
-               sws_isSupportedInput (pix_fmt)      ? 'I' : '.',
-               sws_isSupportedOutput(pix_fmt)      ? 'O' : '.',
-               pix_desc->flags & PIX_FMT_HWACCEL   ? 'H' : '.',
-               pix_desc->flags & PIX_FMT_PAL       ? 'P' : '.',
-               pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
+               sws_isSupportedInput (pix_fmt)              ? 'I' : '.',
+               sws_isSupportedOutput(pix_fmt)              ? 'O' : '.',
+               pix_desc->flags & AV_PIX_FMT_FLAG_HWACCEL   ? 'H' : '.',
+               pix_desc->flags & AV_PIX_FMT_FLAG_PAL       ? 'P' : '.',
+               pix_desc->flags & AV_PIX_FMT_FLAG_BITSTREAM ? 'B' : '.',
                pix_desc->name,
                pix_desc->nb_components,
                av_get_bits_per_pixel(pix_desc));
@@ -1658,6 +1681,10 @@
     printf("Filter %s\n", f->name);
     if (f->description)
         printf("  %s\n", f->description);
+
+    if (f->flags & AVFILTER_FLAG_SLICE_THREADS)
+        printf("    slice threading supported\n");
+
     printf("    Inputs:\n");
     count = avfilter_pad_count(f->inputs);
     for (i = 0; i < count; i++) {
@@ -1915,13 +1942,13 @@
 {
     if (new_size >= INT_MAX / elem_size) {
         av_log(NULL, AV_LOG_ERROR, "Array too big.\n");
-        exit(1);
+        exit_program(1);
     }
     if (*size < new_size) {
         uint8_t *tmp = av_realloc(array, new_size*elem_size);
         if (!tmp) {
             av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
-            exit(1);
+            exit_program(1);
         }
         memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
         *size = new_size;
diff --git a/cmdutils.h b/cmdutils.h
index 8a5dada..3af4476 100644
--- a/cmdutils.h
+++ b/cmdutils.h
@@ -55,6 +55,16 @@
 extern AVDictionary *format_opts, *codec_opts, *resample_opts;
 
 /**
+ * Register a program-specific cleanup routine.
+ */
+void register_exit(void (*cb)(int ret));
+
+/**
+ * Wraps exit with a program-specific cleanup routine.
+ */
+void exit_program(int ret);
+
+/**
  * Initialize the cmdutils option system, in particular
  * allocate the *_opts contexts.
  */
diff --git a/compat/aix/math.h b/compat/aix/math.h
new file mode 100644
index 0000000..65a89c4
--- /dev/null
+++ b/compat/aix/math.h
@@ -0,0 +1,31 @@
+/*
+ * Work around the class() function in AIX math.h clashing with
+ * identifiers named "class".
+ *
+ * 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
+ */
+
+#ifndef FFMPEG_COMPAT_AIX_MATH_H
+#define FFMPEG_COMPAT_AIX_MATH_H
+
+#define class class_in_math_h_causes_problems
+
+#include_next <math.h>
+
+#undef class
+
+#endif /* FFMPEG_COMPAT_AIX_MATH_H */
diff --git a/compat/avisynth/avisynth_c_25.h b/compat/avisynth/avisynth_c_25.h
new file mode 100644
index 0000000..9288761
--- /dev/null
+++ b/compat/avisynth/avisynth_c_25.h
@@ -0,0 +1,68 @@
+//  Copyright (c) 2011 FFmpegSource Project
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+
+/* these are defines/functions that are used and were changed in the switch to 2.6
+ * and are needed to maintain full compatility with 2.5 */
+
+enum {
+  AVS_CS_YV12_25 = 1<<3 | AVS_CS_YUV | AVS_CS_PLANAR,  // y-v-u, planar
+  AVS_CS_I420_25 = 1<<4 | AVS_CS_YUV | AVS_CS_PLANAR,  // y-u-v, planar
+};
+
+AVSC_INLINE int avs_get_height_p_25(const AVS_VideoFrame * p, int plane) {
+    switch (plane)
+    {
+        case AVS_PLANAR_U: case AVS_PLANAR_V:
+            if (p->pitchUV)
+                return p->height>>1;
+            return 0;
+    }
+    return p->height;}
+
+AVSC_INLINE int avs_get_row_size_p_25(const AVS_VideoFrame * p, int plane) {
+    int r;
+    switch (plane)
+    {
+    case AVS_PLANAR_U: case AVS_PLANAR_V:
+        if (p->pitchUV)
+            return p->row_size>>1;
+        else
+            return 0;
+    case AVS_PLANAR_U_ALIGNED: case AVS_PLANAR_V_ALIGNED:
+        if (p->pitchUV)
+        {
+            r = ((p->row_size+AVS_FRAME_ALIGN-1)&(~(AVS_FRAME_ALIGN-1)) )>>1; // Aligned rowsize
+            if (r < p->pitchUV)
+                return r;
+            return p->row_size>>1;
+        }
+        else
+            return 0;
+    case AVS_PLANAR_Y_ALIGNED:
+        r = (p->row_size+AVS_FRAME_ALIGN-1)&(~(AVS_FRAME_ALIGN-1)); // Aligned rowsize
+        if (r <= p->pitch)
+            return r;
+        return p->row_size;
+    }
+    return p->row_size;
+}
+
+AVSC_INLINE int avs_is_yv12_25(const AVS_VideoInfo * p)
+    { return ((p->pixel_type & AVS_CS_YV12_25) == AVS_CS_YV12_25)||((p->pixel_type & AVS_CS_I420_25) == AVS_CS_I420_25); }
diff --git a/libavcodec/os2threads.h b/compat/os2threads.h
similarity index 100%
rename from libavcodec/os2threads.h
rename to compat/os2threads.h
diff --git a/compat/tms470/math.h b/compat/tms470/math.h
index 1104d74..6234cc5 100644
--- a/compat/tms470/math.h
+++ b/compat/tms470/math.h
@@ -1,3 +1,24 @@
+/*
+ * 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
+ */
+
+#ifndef FFMPEG_COMPAT_TMS470_MATH_H
+#define FFMPEG_COMPAT_TMS470_MATH_H
+
 #include_next <math.h>
 
 #undef INFINITY
@@ -5,3 +26,5 @@
 
 #define INFINITY (*(const float*)((const unsigned []){ 0x7f800000 }))
 #define NAN      (*(const float*)((const unsigned []){ 0x7fc00000 }))
+
+#endif /* FFMPEG_COMPAT_TMS470_MATH_H */
diff --git a/libavcodec/w32pthreads.h b/compat/w32pthreads.h
similarity index 90%
rename from libavcodec/w32pthreads.h
rename to compat/w32pthreads.h
index 29185c7..4b6924f 100644
--- a/libavcodec/w32pthreads.h
+++ b/compat/w32pthreads.h
@@ -4,20 +4,20 @@
  * Authors: Steven Walters <kemuri9@gmail.com>
  *          Pegasys Inc. <http://www.pegasys-inc.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
  */
 
@@ -26,8 +26,8 @@
  * w32threads to pthreads wrapper
  */
 
-#ifndef AVCODEC_W32PTHREADS_H
-#define AVCODEC_W32PTHREADS_H
+#ifndef FFMPEG_COMPAT_W32PTHREADS_H
+#define FFMPEG_COMPAT_W32PTHREADS_H
 
 /* Build up a pthread-like API using underlying Windows API. Have only static
  * methods so as to not conflict with a potentially linked in pthread-win32
@@ -130,7 +130,7 @@
 static void pthread_cond_init(pthread_cond_t *cond, const void *unused_attr)
 {
     win32_cond_t *win32_cond = NULL;
-    if (cond_init) {
+    if (_WIN32_WINNT >= 0x0600 || cond_init) {
         cond_init(cond);
         return;
     }
@@ -155,7 +155,7 @@
 {
     win32_cond_t *win32_cond = cond->ptr;
     /* native condition variables do not destroy */
-    if (cond_init)
+    if (_WIN32_WINNT >= 0x0600 || cond_init)
         return;
 
     /* non native condition variables */
@@ -172,7 +172,7 @@
     win32_cond_t *win32_cond = cond->ptr;
     int have_waiter;
 
-    if (cond_broadcast) {
+    if (_WIN32_WINNT >= 0x0600 || cond_broadcast) {
         cond_broadcast(cond);
         return;
     }
@@ -202,7 +202,7 @@
 {
     win32_cond_t *win32_cond = cond->ptr;
     int last_waiter;
-    if (cond_wait) {
+    if (_WIN32_WINNT >= 0x0600 || cond_wait) {
         cond_wait(cond, mutex, INFINITE);
         return 0;
     }
@@ -234,7 +234,7 @@
 {
     win32_cond_t *win32_cond = cond->ptr;
     int have_waiter;
-    if (cond_signal) {
+    if (_WIN32_WINNT >= 0x0600 || cond_signal) {
         cond_signal(cond);
         return;
     }
@@ -257,6 +257,7 @@
 
 static void w32thread_init(void)
 {
+#if _WIN32_WINNT < 0x0600
     HANDLE kernel_dll = GetModuleHandle(TEXT("kernel32.dll"));
     /* if one is available, then they should all be available */
     cond_init      =
@@ -267,6 +268,13 @@
         (void*)GetProcAddress(kernel_dll, "WakeConditionVariable");
     cond_wait      =
         (void*)GetProcAddress(kernel_dll, "SleepConditionVariableCS");
+#else
+    cond_init      = InitializeConditionVariable;
+    cond_broadcast = WakeAllConditionVariable;
+    cond_signal    = WakeConditionVariable;
+    cond_wait      = SleepConditionVariableCS;
+#endif
+
 }
 
-#endif /* AVCODEC_W32PTHREADS_H */
+#endif /* FFMPEG_COMPAT_W32PTHREADS_H */
diff --git a/configure b/configure
index 648db2f..ad9e03d 100755
--- a/configure
+++ b/configure
@@ -102,6 +102,8 @@
   --enable-gray            enable full grayscale support (slower color)
   --disable-swscale-alpha  disable alpha channel support in swscale
   --disable-all            disable building components, libraries and programs
+  --enable-incompatible-libav-abi enable incompatible Libav fork ABI [no]
+  --enable-incompatible-fork-abi  enable incompatible Libav fork ABI (deprecated) [no]
 
 Program options:
   --disable-programs       do not build command line programs
@@ -141,10 +143,10 @@
   --disable-fft            disable FFT code
 
 Hardware accelerators:
-  --enable-dxva2           enable DXVA2 code
-  --enable-vaapi           enable VAAPI code
+  --disable-dxva2          disable DXVA2 code [autodetect]
+  --disable-vaapi          disable VAAPI code [autodetect]
   --enable-vda             enable VDA code
-  --enable-vdpau           enable VDPAU code
+  --disable-vdpau          disable VDPAU code [autodetect]
 
 Individual component options:
   --disable-everything     disable all components listed below
@@ -184,12 +186,12 @@
   --disable-filters        disable all filters
 
 External library support:
-  --enable-avisynth        enable reading of AVISynth script files [no]
-  --enable-bzlib           enable bzlib [autodetect]
+  --enable-avisynth        enable reading of AviSynth script files [no]
+  --disable-bzlib          disable bzlib [autodetect]
   --enable-fontconfig      enable fontconfig
   --enable-frei0r          enable frei0r video filtering
   --enable-gnutls          enable gnutls [no]
-  --enable-iconv           enable iconv [autodetect]
+  --disable-iconv          disable iconv [autodetect]
   --enable-libaacplus      enable AAC+ encoding via libaacplus [no]
   --enable-libass          enable libass subtitles rendering [no]
   --enable-libbluray       enable BluRay reading using libbluray [no]
@@ -199,9 +201,10 @@
   --enable-libdc1394       enable IIDC-1394 grabbing using libdc1394
                            and libraw1394 [no]
   --enable-libfaac         enable AAC encoding via libfaac [no]
-  --enable-libfdk-aac      enable AAC encoding via libfdk-aac [no]
+  --enable-libfdk-aac      enable AAC de/encoding via libfdk-aac [no]
   --enable-libflite        enable flite (voice synthesis) support via libflite [no]
   --enable-libfreetype     enable libfreetype [no]
+  --enable-libgme          enable Game Music Emu via libgme [no]
   --enable-libgsm          enable GSM de/encoding via libgsm [no]
   --enable-libiec61883     enable iec61883 via libiec61883 [no]
   --enable-libilbc         enable iLBC de/encoding via libilbc [no]
@@ -232,15 +235,17 @@
   --enable-libvorbis       enable Vorbis en/decoding via libvorbis,
                            native implementation exists [no]
   --enable-libvpx          enable VP8 and VP9 de/encoding via libvpx [no]
+  --enable-libwavpack      enable wavpack encoding via libwavpack [no]
   --enable-libx264         enable H.264 encoding via x264 [no]
   --enable-libxavs         enable AVS encoding via xavs [no]
   --enable-libxvid         enable Xvid encoding via xvidcore,
                            native MPEG-4/Xvid encoder exists [no]
+  --enable-libzmq          enable message passing via libzmq [no]
   --enable-openal          enable OpenAL 1.1 capture support [no]
   --enable-opencl          enable OpenCL code
   --enable-openssl         enable openssl [no]
   --enable-x11grab         enable X11 grabbing [no]
-  --enable-zlib            enable zlib [autodetect]
+  --disable-zlib           disable zlib [autodetect]
 
 Advanced options (experts only):
   --cross-prefix=PREFIX    use PREFIX for compilation tools [$cross_prefix]
@@ -250,6 +255,7 @@
   --target-os=OS           compiler targets OS [$target_os]
   --target-exec=CMD        command to run executables on target
   --target-path=DIR        path to view of build directory on target
+  --target-samples=DIR     path to samples directory on target
   --toolchain=NAME         set tool defaults according to NAME
   --nm=NM                  use nm tool NM [$nm_default]
   --ar=AR                  use archive tool AR [$ar_default]
@@ -475,21 +481,21 @@
 }
 
 pushvar(){
-    for var in $*; do
-        eval level=\${${var}_level:=0}
-        eval ${var}_${level}="\$$var"
-        eval ${var}_level=$(($level+1))
+    for pvar in $*; do
+        eval level=\${${pvar}_level:=0}
+        eval ${pvar}_${level}="\$$pvar"
+        eval ${pvar}_level=$(($level+1))
     done
 }
 
 popvar(){
-    for var in $*; do
-        eval level=\${${var}_level:-0}
+    for pvar in $*; do
+        eval level=\${${pvar}_level:-0}
         test $level = 0 && continue
         eval level=$(($level-1))
-        eval $var="\${${var}_${level}}"
-        eval ${var}_level=$level
-        eval unset ${var}_${level}
+        eval $pvar="\${${pvar}_${level}}"
+        eval ${pvar}_level=$level
+        eval unset ${pvar}_${level}
     done
 }
 
@@ -540,8 +546,13 @@
 }
 
 enable_deep_weak(){
-    do_enable_deep $*
-    enable_weak $*
+    for var; do
+        disabled $var && continue
+        pushvar var
+        do_enable_deep $var
+        popvar var
+        enable_weak $var
+    done
 }
 
 enabled(){
@@ -1008,10 +1019,10 @@
 static void sighandler(int sig){
     raise(SIGTERM);
 }
-int func(void){
+int foo(void){
     $code
 }
-int (*func_ptr)(void) = func;
+int (*func_ptr)(void) = foo;
 int main(void){
     signal(SIGILL, sighandler);
     signal(SIGFPE, sighandler);
@@ -1159,6 +1170,7 @@
     libfdk_aac
     libflite
     libfreetype
+    libgme
     libgsm
     libiec61883
     libilbc
@@ -1187,9 +1199,11 @@
     libvo_amrwbenc
     libvorbis
     libvpx
+    libwavpack
     libx264
     libxavs
     libxvid
+    libzmq
     openal
     opencl
     openssl
@@ -1247,6 +1261,7 @@
     gpl
     gray
     hardcoded_tables
+    incompatible_libav_abi
     incompatible_fork_abi
     lsp
     lzo
@@ -1353,6 +1368,7 @@
 HAVE_LIST_PUB='
     bigendian
     fast_unaligned
+    incompatible_libav_abi
     incompatible_fork_abi
 '
 
@@ -1408,9 +1424,9 @@
     attribute_packed
     cdio_paranoia_h
     cdio_paranoia_paranoia_h
+    CL_cl_h
     clock_gettime
     closesocket
-    cmov
     CommandLineToArgvW
     cpunop
     CryptGenRandom
@@ -1445,9 +1461,11 @@
     glob
     gnu_as
     gsm_h
+    i686
     ibm_asm
     inet_aton
     io_h
+    inline_asm_labels
     isatty
     jack_port_get_latency_range
     kbhit
@@ -1479,9 +1497,11 @@
     pod2man
     poll_h
     posix_memalign
+    pragma_deprecated
     pthread_cancel
     rdtsc
     rsync_contimeout
+    sarestart
     sched_getaffinity
     sdl
     SetConsoleTextAttribute
@@ -1502,6 +1522,7 @@
     struct_sockaddr_in6
     struct_sockaddr_sa_len
     struct_sockaddr_storage
+    struct_stat_st_mtim_tv_nsec
     struct_v4l2_frmivalenum_discrete
     symver_asm_label
     symver_gnu_asm
@@ -1514,6 +1535,7 @@
     sys_select_h
     sys_soundcard_h
     sys_time_h
+    sys_un_h
     sys_videoio_h
     termios_h
     texi2html
@@ -1534,6 +1556,7 @@
     ac3dsp
     audio_frame_queue
     dsputil
+    exif
     frame_thread_encoder
     gcrypt
     golomb
@@ -1552,6 +1575,8 @@
     mpegvideoenc
     nettle
     rangecoder
+    riffdec
+    riffenc
     rtpdec
     rtpenc_chain
     sinewin
@@ -1619,6 +1644,7 @@
     target_exec
     target_os
     target_path
+    target_samples
     toolchain
     valgrind
     yasmexe
@@ -1653,7 +1679,7 @@
 
 vis_deps="sparc"
 
-x86_64_suggest="cmov fast_cmov"
+x86_64_suggest="fast_cmov i686"
 
 amd3dnow_deps="mmx"
 amd3dnowext_deps="amd3dnow"
@@ -1710,11 +1736,12 @@
 ac3_decoder_select="mdct ac3dsp ac3_parser dsputil"
 ac3_encoder_select="mdct ac3dsp dsputil"
 ac3_fixed_encoder_select="mdct ac3dsp dsputil"
+aic_decoder_select="dsputil golomb"
 alac_encoder_select="lpc"
 als_decoder_select="dsputil"
 amrnb_decoder_select="lsp"
 amrwb_decoder_select="lsp"
-amv_decoder_select="dsputil hpeldsp"
+amv_decoder_select="dsputil hpeldsp exif"
 amv_encoder_select="aandcttables"
 ape_decoder_select="dsputil"
 asv1_decoder_select="dsputil"
@@ -1723,6 +1750,7 @@
 asv2_encoder_select="dsputil"
 atrac1_decoder_select="mdct sinewin"
 atrac3_decoder_select="mdct"
+avrn_decoder_select="exif"
 bink_decoder_select="dsputil hpeldsp"
 binkaudio_dct_decoder_select="mdct rdft dct sinewin"
 binkaudio_rdft_decoder_select="mdct rdft sinewin"
@@ -1738,27 +1766,29 @@
 dnxhd_encoder_select="aandcttables dsputil mpegvideoenc"
 dvvideo_decoder_select="dsputil"
 dvvideo_encoder_select="dsputil"
-dxa_decoder_select="zlib"
+dxa_decoder_deps="zlib"
 eac3_decoder_select="ac3_decoder"
 eac3_encoder_select="ac3_encoder"
 eamad_decoder_select="aandcttables dsputil mpegvideo"
 eatgq_decoder_select="aandcttables"
 eatqi_decoder_select="aandcttables error_resilience mpegvideo"
-exr_decoder_select="zlib"
+exr_decoder_deps="zlib"
 ffv1_decoder_select="dsputil golomb rangecoder"
 ffv1_encoder_select="dsputil rangecoder"
 ffvhuff_decoder_select="dsputil"
 ffvhuff_encoder_select="dsputil huffman"
 flac_decoder_select="golomb"
 flac_encoder_select="dsputil golomb lpc"
-flashsv_decoder_select="zlib"
-flashsv_encoder_select="zlib"
-flashsv2_encoder_select="zlib"
-flashsv2_decoder_select="zlib"
+flashsv_decoder_deps="zlib"
+flashsv_encoder_deps="zlib"
+flashsv2_encoder_deps="zlib"
+flashsv2_decoder_deps="zlib"
 flv_decoder_select="h263_decoder"
 flv_encoder_select="h263_encoder"
 fourxm_decoder_select="dsputil"
 fraps_decoder_select="dsputil huffman"
+g2m_decoder_deps="zlib"
+g2m_decoder_select="dsputil"
 g729_decoder_select="dsputil"
 h261_decoder_select="error_resilience mpegvideo"
 h261_encoder_select="aandcttables mpegvideoenc"
@@ -1774,16 +1804,17 @@
 imc_decoder_select="dsputil fft mdct sinewin"
 indeo3_decoder_select="hpeldsp"
 interplay_video_decoder_select="hpeldsp"
-jpegls_decoder_select="dsputil golomb hpeldsp"
+jpegls_decoder_select="dsputil golomb hpeldsp exif"
 jpegls_encoder_select="golomb"
 jv_decoder_select="dsputil"
 lagarith_decoder_select="dsputil"
 ljpeg_encoder_select="aandcttables mpegvideoenc"
 loco_decoder_select="golomb"
 mdec_decoder_select="dsputil error_resilience mpegvideo"
+metasound_decoder_select="lsp mdct sinewin"
 mimic_decoder_select="dsputil hpeldsp"
-mjpeg_decoder_select="dsputil hpeldsp"
-mjpegb_decoder_select="dsputil hpeldsp"
+mjpeg_decoder_select="dsputil hpeldsp exif"
+mjpegb_decoder_select="dsputil hpeldsp exif"
 mjpeg_encoder_select="aandcttables dsputil mpegvideoenc"
 mlp_decoder_select="dsputil mlp_parser"
 motionpixels_decoder_select="dsputil"
@@ -1813,12 +1844,13 @@
 msmpeg4v3_decoder_select="h263_decoder"
 msmpeg4v3_encoder_select="h263_encoder"
 mss2_decoder_select="error_resilience vc1_decoder"
-mxpeg_decoder_select="dsputil hpeldsp"
+mxpeg_decoder_select="dsputil hpeldsp exif"
 nellymoser_decoder_select="mdct sinewin"
 nellymoser_encoder_select="audio_frame_queue mdct sinewin"
 nuv_decoder_select="dsputil lzo"
-png_decoder_select="zlib"
-png_encoder_select="dsputil zlib"
+png_decoder_deps="zlib"
+png_encoder_deps="zlib"
+png_encoder_select="dsputil"
 prores_decoder_select="dsputil"
 prores_encoder_select="dsputil"
 qcelp_decoder_select="lsp"
@@ -1839,7 +1871,7 @@
 sonic_decoder_select="golomb"
 sonic_encoder_select="golomb"
 sonic_ls_encoder_select="golomb"
-sp5x_decoder_select="dsputil hpeldsp"
+sp5x_decoder_select="dsputil hpeldsp exif"
 svq1_decoder_select="hpeldsp"
 svq1_encoder_select="aandcttables dsputil hpeldsp mpegvideoenc"
 svq3_decoder_select="golomb h264chroma h264dsp h264pred h264qpel hpeldsp mpegvideo videodsp"
@@ -1848,11 +1880,11 @@
 theora_decoder_select="vp3_decoder"
 tiff_decoder_suggest="zlib"
 tiff_encoder_suggest="zlib"
-thp_decoder_select="dsputil hpeldsp"
+thp_decoder_select="dsputil hpeldsp exif"
 truehd_decoder_select="mlp_parser"
 truemotion2_decoder_select="dsputil"
 truespeech_decoder_select="dsputil"
-tscc_decoder_select="zlib"
+tscc_decoder_deps="zlib"
 twinvq_decoder_select="mdct lsp sinewin"
 utvideo_decoder_select="dsputil"
 utvideo_encoder_select="dsputil huffman"
@@ -1867,6 +1899,7 @@
 vp6a_decoder_select="vp6_decoder"
 vp6f_decoder_select="vp6_decoder"
 vp8_decoder_select="h264pred videodsp"
+webp_decoder_select="vp8_decoder"
 wmapro_decoder_select="mdct sinewin"
 wmav1_decoder_select="mdct sinewin"
 wmav1_encoder_select="mdct sinewin"
@@ -1879,11 +1912,11 @@
 wmv2_encoder_select="h263_encoder"
 wmv3_decoder_select="vc1_decoder"
 wmv3image_decoder_select="wmv3_decoder"
-zerocodec_decoder_select="zlib"
-zlib_decoder_select="zlib"
-zlib_encoder_select="zlib"
-zmbv_decoder_select="zlib"
-zmbv_encoder_select="zlib"
+zerocodec_decoder_deps="zlib"
+zlib_decoder_deps="zlib"
+zlib_encoder_deps="zlib"
+zmbv_decoder_deps="zlib"
+zmbv_encoder_deps="zlib"
 
 # hardware accelerators
 crystalhd_deps="libcrystalhd_libcrystalhd_if_h"
@@ -1957,8 +1990,10 @@
 libcelt_decoder_deps="libcelt"
 libfaac_encoder_deps="libfaac"
 libfaac_encoder_select="audio_frame_queue"
+libfdk_aac_decoder_deps="libfdk_aac"
 libfdk_aac_encoder_deps="libfdk_aac"
 libfdk_aac_encoder_select="audio_frame_queue"
+libgme_demuxer_deps="libgme"
 libgsm_decoder_deps="libgsm"
 libgsm_encoder_deps="libgsm"
 libgsm_ms_decoder_deps="libgsm"
@@ -1998,6 +2033,7 @@
 libvpx_vp8_encoder_deps="libvpx"
 libvpx_vp9_decoder_deps="libvpx"
 libvpx_vp9_encoder_deps="libvpx"
+libwavpack_encoder_deps="libwavpack"
 libx264_encoder_deps="libx264"
 libx264rgb_encoder_deps="libx264"
 libxavs_encoder_deps="libxavs"
@@ -2007,27 +2043,41 @@
 
 # demuxers / muxers
 ac3_demuxer_select="ac3_parser"
+asf_demuxer_select="riffdec"
+asf_muxer_select="riffenc"
 asf_stream_muxer_select="asf_muxer"
+avi_demuxer_select="riffdec"
+avi_muxer_select="riffenc"
 avisynth_demuxer_deps="avisynth"
+avisynth_demuxer_select="riffdec"
+caf_demuxer_select="riffdec"
 dirac_demuxer_select="dirac_parser"
 dts_demuxer_select="dca_parser"
 dtshd_demuxer_select="dca_parser"
+dxa_demuxer_select="riffdec"
 eac3_demuxer_select="ac3_parser"
 f4v_muxer_select="mov_muxer"
 flac_demuxer_select="flac_parser"
+hls_muxer_select="mpegts_muxer"
 ipod_muxer_select="mov_muxer"
 ismv_muxer_select="mov_muxer"
 libnut_demuxer_deps="libnut"
 libnut_muxer_deps="libnut"
 matroska_audio_muxer_select="matroska_muxer"
+matroska_demuxer_select="riffdec"
 matroska_demuxer_suggest="bzlib lzo zlib"
+matroska_muxer_select="riffenc"
+mmf_muxer_select="riffenc"
+mov_demuxer_select="riffdec"
 mov_demuxer_suggest="zlib"
-mov_muxer_select="rtpenc_chain"
+mov_muxer_select="riffenc rtpenc_chain"
 mp3_demuxer_select="mpegaudio_parser"
 mp4_muxer_select="mov_muxer"
 mpegts_muxer_select="adts_muxer latm_muxer"
 mpegtsraw_demuxer_select="mpegts_demuxer"
 mxf_d10_muxer_select="mxf_muxer"
+nut_muxer_select="riffenc"
+nuv_demuxer_select="riffdec"
 ogg_demuxer_select="golomb"
 psp_muxer_select="mov_muxer"
 rtp_demuxer_select="sdp_demuxer"
@@ -2043,8 +2093,14 @@
 tg2_muxer_select="mov_muxer"
 tgp_muxer_select="mov_muxer"
 vobsub_demuxer_select="mpegps_demuxer"
-w64_demuxer_deps="wav_demuxer"
-w64_muxer_deps="wav_muxer"
+w64_demuxer_select="wav_demuxer"
+w64_muxer_select="wav_muxer"
+wav_demuxer_select="riffdec"
+wav_muxer_select="riffenc"
+webm_muxer_select="riffenc"
+wtv_demuxer_select="riffdec"
+xmv_demuxer_select="riffdec"
+xwma_demuxer_select="riffdec"
 
 # indevs / outdevs
 alsa_indev_deps="alsa_asoundlib_h snd_pcm_htimestamp"
@@ -2053,7 +2109,8 @@
 caca_outdev_deps="libcaca"
 dshow_indev_deps="IBaseFilter"
 dshow_indev_extralibs="-lpsapi -lole32 -lstrmiids -luuid"
-dv1394_indev_deps="dv1394 dv_demuxer"
+dv1394_indev_deps="dv1394"
+dv1394_indev_select="dv_demuxer"
 fbdev_indev_deps="linux_fb_h"
 iec61883_indev_deps="libiec61883"
 jack_indev_deps="jack_jack_h sem_timedwait"
@@ -2070,8 +2127,11 @@
 sndio_outdev_deps="sndio_h"
 v4l_indev_deps="linux_videodev_h"
 v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h"
+v4l2_outdev_deps_any="linux_videodev2_h sys_videoio_h"
 vfwcap_indev_deps="capCreateCaptureWindow vfwcap_defines"
 vfwcap_indev_extralibs="-lavicap32"
+xv_outdev_deps="X11_extensions_Xvlib_h XvGetPortAttribute"
+xv_outdev_extralibs="-lXv -lX11 -lXext"
 x11grab_indev_deps="x11grab"
 
 # protocols
@@ -2081,6 +2141,7 @@
 ffrtmpcrypt_protocol_select="tcp_protocol"
 ffrtmphttp_protocol_deps="!librtmp_protocol"
 ffrtmphttp_protocol_select="http_protocol"
+ftp_protocol_select="tcp_protocol"
 gopher_protocol_select="network"
 httpproxy_protocol_select="tcp_protocol"
 http_protocol_select="tcp_protocol"
@@ -2108,6 +2169,8 @@
 tls_protocol_deps_any="openssl gnutls"
 tls_protocol_select="tcp_protocol"
 udp_protocol_select="network"
+unix_protocol_deps="sys_un_h"
+unix_protocol_select="network"
 
 # filters
 aconvert_filter_deps="swresample"
@@ -2116,10 +2179,12 @@
 ass_filter_deps="libass"
 asyncts_filter_deps="avresample"
 atempo_filter_deps="avcodec rdft"
+azmq_filter_deps="libzmq"
 blackframe_filter_deps="gpl"
 boxblur_filter_deps="gpl"
 colormatrix_filter_deps="gpl"
 cropdetect_filter_deps="gpl"
+dctdnoiz_filter_deps="avcodec fft"
 delogo_filter_deps="gpl"
 deshake_filter_deps="avcodec"
 deshake_filter_select="dsputil"
@@ -2136,20 +2201,25 @@
 hue_filter_deps="gpl"
 interlace_filter_deps="gpl"
 kerndeint_filter_deps="gpl"
+mcdeint_filter_deps="avcodec gpl"
 movie_filter_deps="avcodec avformat"
 mp_filter_deps="gpl avcodec swscale inline_asm"
 mpdecimate_filter_deps="gpl avcodec"
 mptestsrc_filter_deps="gpl"
 negate_filter_deps="lut_filter"
 noise_filter_deps="gpl"
+perspective_filter_deps="gpl"
 resample_filter_deps="avresample"
 ocv_filter_deps="libopencv"
+owdenoise_filter_deps="gpl"
 pan_filter_deps="swresample"
 pp_filter_deps="gpl postproc"
 removelogo_filter_deps="avcodec avformat swscale"
+sab_filter_deps="gpl swscale"
 scale_filter_deps="swscale"
 smartblur_filter_deps="gpl swscale"
 showspectrum_filter_deps="avcodec rdft"
+spp_filter_deps="gpl avcodec fft"
 stereo3d_filter_deps="gpl"
 subtitles_filter_deps="avformat avcodec libass"
 super2xsai_filter_deps="gpl"
@@ -2160,6 +2230,7 @@
 pixfmts_super2xsai_test_deps="super2xsai_filter"
 tinterlace_merge_test_deps="tinterlace_filter"
 tinterlace_pad_test_deps="tinterlace_filter"
+zmq_filter_deps="libzmq"
 
 # libraries
 avcodec_deps="avutil"
@@ -2172,12 +2243,14 @@
 
 # programs
 ffmpeg_deps="avcodec avfilter avformat swscale swresample"
-ffmpeg_select="format_filter aformat_filter
-               setpts_filter null_filter anull_filter"
+ffmpeg_select="aformat_filter anull_filter atrim_filter format_filter
+               null_filter
+               setpts_filter trim_filter"
 ffplay_deps="avcodec avformat swscale swresample sdl"
 ffplay_select="rdft crop_filter"
 ffprobe_deps="avcodec avformat"
-ffserver_deps="avformat ffm_muxer fork rtp_protocol rtsp_demuxer"
+ffserver_deps="avformat fork sarestart"
+ffserver_select="ffm_muxer rtp_protocol rtsp_demuxer"
 ffserver_extralibs='$ldl'
 
 # documentation
@@ -2240,12 +2313,11 @@
 enable static
 enable swscale_alpha
 
-# By default, enable only those hwaccels that have no external dependencies.
-enable dxva2 vdpau
+# Enable hwaccels by default.
+enable dxva2 vaapi vdpau
 
 # build settings
 SHFLAGS='-shared -Wl,-soname,$$(@F)'
-FFSERVERLDFLAGS=-Wl,-E
 LIBPREF="lib"
 LIBSUF=".a"
 FULLNAME='$(NAME)$(BUILDSUF)'
@@ -2487,6 +2559,8 @@
 
 sysinclude_default="${sysroot}/usr/include"
 
+test -n "$valgrind" && toolchain="valgrind-memcheck"
+
 case "$toolchain" in
     clang-asan)
         cc_default="clang"
@@ -2498,6 +2572,24 @@
         add_cflags  -fsanitize=thread -pie
         add_ldflags -fsanitize=thread -pie
     ;;
+    gcc-asan)
+        cc_default="gcc"
+        add_cflags  -fsanitize=address
+        add_ldflags -fsanitize=address
+    ;;
+    gcc-tsan)
+        cc_default="gcc"
+        add_cflags  -fsanitize=thread -pie -fPIC
+        add_ldflags -fsanitize=thread -pie -fPIC
+    ;;
+    valgrind-massif)
+        target_exec_default=${valgrind:-"valgrind"}
+        target_exec_args="--tool=massif --alloc-fn=av_malloc --alloc-fn=av_mallocz --alloc-fn=av_calloc --alloc-fn=av_fast_padded_malloc --alloc-fn=av_fast_malloc --alloc-fn=av_realloc_f --alloc-fn=av_fast_realloc --alloc-fn=av_realloc"
+    ;;
+    valgrind-memcheck)
+        target_exec_default=${valgrind:-"valgrind"}
+        target_exec_args="--error-exitcode=1 --malloc-fill=0x2a --track-origins=yes --leak-check=full --gen-suppressions=all --suppressions=$source_path/tests/fate-valgrind.supp"
+    ;;
     msvc)
         cc_default="c99wrap cl"
         ld_default="c99wrap link"
@@ -2505,6 +2597,13 @@
         ar_default="lib"
         target_os_default="win32"
     ;;
+    icl)
+        cc_default="c99wrap -noconv icl"
+        ld_default="c99wrap xilink"
+        nm_default="dumpbin -symbols"
+        ar_default="xilib"
+        target_os_default="win32"
+    ;;
     gcov)
         add_cflags  -fprofile-arcs -ftest-coverage
         add_ldflags -fprofile-arcs -ftest-coverage
@@ -2514,7 +2613,7 @@
     ;;
 esac
 
-set_default arch cc cxx pkg_config strip sysinclude target_os yasmexe
+set_default arch cc cxx pkg_config strip sysinclude target_exec target_os yasmexe
 enabled cross_compile || host_cc_default=$cc
 set_default host_cc
 
@@ -2600,21 +2699,23 @@
    done
 }
 
-msvc_flags(){
+msvc_common_flags(){
     for flag; do
         case $flag in
-            -fomit-frame-pointer) echo -Oy ;;
-            -g)                   echo -Z7 ;;
-            -Wall)                echo -W4 -wd4244 -wd4127 -wd4018 -wd4389 \
-                                       -wd4146 -wd4057 -wd4204 -wd4706 -wd4305 \
-                                       -wd4152 -wd4324 -we4013 -wd4100 -wd4214 \
-                                       -wd4554 \
-                                       -wd4996 -wd4273 ;;
+            # In addition to specifying certain flags under the compiler
+            # specific filters, they must be specified here as well or else the
+            # generic catch all at the bottom will print the original flag.
+            -Wall)                ;;
             -std=c99)             ;;
+            # Common flags
+            -fomit-frame-pointer) ;;
+            -g)                   echo -Z7 ;;
             -fno-math-errno)      ;;
             -fno-common)          ;;
             -fno-signed-zeros)    ;;
             -fPIC)                ;;
+            -mthumb)              ;;
+            -march=*)             ;;
             -lz)                  echo zlib.lib ;;
             -lavifil32)           echo vfw32.lib ;;
             -lavicap32)           echo vfw32.lib user32.lib ;;
@@ -2624,6 +2725,31 @@
     done
 }
 
+msvc_flags(){
+    msvc_common_flags "$@"
+    for flag; do
+        case $flag in
+            -Wall)                echo -W4 -wd4244 -wd4127 -wd4018 -wd4389     \
+                                       -wd4146 -wd4057 -wd4204 -wd4706 -wd4305 \
+                                       -wd4152 -wd4324 -we4013 -wd4100 -wd4214 \
+                                       -wd4554 \
+                                       -wd4996 -wd4273 ;;
+        esac
+    done
+}
+
+icl_flags(){
+    msvc_common_flags "$@"
+    for flag; do
+        case $flag in
+            # Despite what Intel's documentation says -Wall, which is supported
+            # on Windows, does enable remarks so disable them here.
+            -Wall)                echo $flag -Qdiag-disable:remark ;;
+            -std=c99)             echo -Qstd=c99 ;;
+        esac
+    done
+}
+
 pgi_flags(){
     for flag; do
         case $flag in
@@ -2654,12 +2780,12 @@
                     core2)              echo -xarch=ssse3 -xchip=core2   ;;
                     corei7)           echo -xarch=sse4_2 -xchip=nehalem  ;;
                     corei7-avx)       echo -xarch=avx -xchip=sandybridge ;;
-                    amdfam10|barcelona)       echo -xtarget=barcelona    ;;
-                    bdver*)                   echo -xarch=avx            ;;
-                    athlon-4|athlon-[mx]p)    echo -xarch=ssea           ;;
+                    amdfam10|barcelona)        echo -xtarget=barcelona   ;;
+                    bdver*)                    echo -xarch=avx           ;;
+                    athlon-4|athlon-[mx]p)     echo -xarch=ssea          ;;
                     k8|opteron|athlon64|athlon-fx)
-                                              echo -xarch=sse2a          ;;
-                    athlon*)                  echo -xarch=pentium_proa   ;;
+                                               echo -xarch=sse2a         ;;
+                    athlon*)                   echo -xarch=pentium_proa  ;;
                 esac
                 ;;
             -std=c99)             echo -xc99              ;;
@@ -2819,7 +2945,8 @@
         _DEPFLAGS='$(CPPFLAGS) $(CFLAGS) -showIncludes -Zs'
         _cflags_speed="-O2"
         _cflags_size="-O1"
-        # Nonstandard output options, to avoid msys path conversion issues, relies on wrapper to remap it
+        # Nonstandard output options, to avoid msys path conversion issues.
+        # Relies on wrapper to remap it.
         if $_cc 2>&1 | grep -q Linker; then
             _ld_o='-out $@'
         else
@@ -2836,6 +2963,34 @@
             append _cflags -Dsnprintf=_snprintf
         fi
         disable stripping
+    elif $_cc 2>&1 | grep -q Intel; then
+        _type=icl
+        _ident=$($cc 2>&1 | head -n1)
+        _depflags='-QMMD -QMF$(@:.o=.d) -QMT$@'
+        # Not only is O3 broken on 13.x+ but it is slower on all previous
+        # versions (tested) as well.
+        _cflags_speed="-O2"
+        _cflags_size="-O1 -Oi" # -O1 without -Oi miscompiles stuff
+        # Nonstandard output options, to avoid msys path conversion issues.
+        # Relies on wrapper to remap it.
+        if $_cc 2>&1 | grep -q Linker; then
+            _ld_o='-out $@'
+        else
+            _ld_o='-Fe$@'
+        fi
+        _cc_o='-Fo $@'
+        _cc_e='-P'
+        _flags_filter=icl_flags
+        _ld_lib='lib%.a'
+        _ld_path='-libpath:'
+        # -Qdiag-error to make icl error when seeing certain unknown arguments
+        _flags='-nologo -Qdiag-error:4044,10157'
+        # -Qvec- -Qsimd- to prevent miscompilation, -GS for consistency
+        # with MSVC which enables it by default.
+        _cflags='-D_USE_MATH_DEFINES -FIstdlib.h -Dstrtoll=_strtoi64 -Qms0 -Qvec- -Qsimd- -GS'
+        if [ $pfx = hostcc ]; then
+            append _cflags -Dsnprintf=_snprintf
+        fi
     fi
 
     eval ${pfx}_type=\$_type
@@ -2910,6 +3065,9 @@
 elif $ar 2>&1 | grep -q 'Texas Instruments'; then
     arflags="rq"
     ar_o='$@'
+elif $ar 2>&1 | grep -q 'Usage: ar.*-X.*any'; then
+    arflags='-Xany -r -c'
+    ar_o='$@'
 else
     arflags="rc"
     ar_o='$@'
@@ -2933,7 +3091,8 @@
 fi
 
 if test "$cpu" = host; then
-    enabled cross_compile && die "--cpu=host makes no sense when cross-compiling."
+    enabled cross_compile &&
+        die "--cpu=host makes no sense when cross-compiling."
 
     case "$cc_type" in
         gcc|llvm_gcc)
@@ -2949,7 +3108,8 @@
         ;;
     esac
 
-    test "${cpu:-host}" = host && die "--cpu=host not supported with compiler $cc"
+    test "${cpu:-host}" = host &&
+        die "--cpu=host not supported with compiler $cc"
 fi
 
 # Deal with common $arch aliases
@@ -2957,7 +3117,7 @@
     aarch64|arm64)
         arch="aarch64"
     ;;
-    arm*|iPad*)
+    arm*|iPad*|iPhone*)
         arch="arm"
     ;;
     mips*|IP*)
@@ -3181,21 +3341,21 @@
             cpuflags="-march=$cpu"
             disable mmx
         ;;
-        # targets that do NOT support conditional mov (cmov)
+        # targets that do NOT support nopl and conditional mov (cmov)
         pentium-mmx|k6|k6-[23]|winchip-c6|winchip2|c3)
             cpuflags="-march=$cpu"
-            disable cmov
+            disable i686
         ;;
-        # targets that do support conditional mov (cmov)
+        # targets that do support nopl and conditional mov (cmov)
         i686|pentiumpro|pentium[23]|pentium-m|athlon|athlon-tbird|athlon-4|athlon-[mx]p|athlon64*|k8*|opteron*|athlon-fx|core2|corei7*|amdfam10|barcelona|atom|bdver*)
             cpuflags="-march=$cpu"
-            enable cmov
+            enable i686
             enable fast_cmov
         ;;
         # targets that do support conditional mov but on which it's slow
         pentium4|pentium4m|prescott|nocona)
             cpuflags="-march=$cpu"
-            enable cmov
+            enable i686
             disable fast_cmov
         ;;
     esac
@@ -3275,17 +3435,21 @@
 esac
 
 enable $subarch
-enabled spic && enable pic
+enabled spic && enable_weak pic
 
 # OS specific
 case $target_os in
+    aix)
+        SHFLAGS=-shared
+        add_cppflags '-I\$(SRC_PATH)/compat/aix'
+        enabled shared && add_ldflags -Wl,-brtl
+        ;;
     haiku)
         prefix_default="/boot/common"
         network_extralibs="-lnetwork"
         host_libs=
         ;;
     sunos)
-        FFSERVERLDFLAGS=""
         SHFLAGS='-shared -Wl,-h,$$(@F)'
         enabled x86 && SHFLAGS="-mimpure-text $SHFLAGS"
         network_extralibs="-lsocket -lnsl"
@@ -3295,7 +3459,9 @@
         # the Solaris assembler.  As our libraries contain their own
         # guards for processor-specific code, instead suppress
         # generation of the HWCAPS ELF section on Solaris x86 only.
-        enabled_all suncc x86 && echo "hwcap_1 = OVERRIDE;" > mapfile && add_ldflags -Wl,-M,mapfile
+        enabled_all suncc x86 &&
+            echo "hwcap_1 = OVERRIDE;" > mapfile &&
+            add_ldflags -Wl,-M,mapfile
         nm_default='nm -P -g'
         ;;
     netbsd)
@@ -3331,7 +3497,6 @@
         SLIBSUF=".dylib"
         SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME).$(LIBVERSION)$(SLIBSUF)'
         SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME).$(LIBMAJOR)$(SLIBSUF)'
-        FFSERVERLDFLAGS=-Wl,-bind_at_load
         objformat="macho"
         enabled x86_64 && objformat="macho64"
         enabled_any pic shared ||
@@ -3349,6 +3514,8 @@
         elif enabled arm; then
             LIBTARGET=arm-wince
         fi
+        check_ldflags -Wl,--nxcompat
+        check_ldflags -Wl,--dynamicbase
         shlibdir_default="$bindir_default"
         SLIBPREF=""
         SLIBSUF=".dll"
@@ -3377,8 +3544,7 @@
             # Link to the import library instead of the normal static library
             # for shared libs.
             LD_LIB='%.lib'
-            # Cannot build shared and static libraries at the same time with
-            # MSVC.
+            # Cannot build shared and static libs at the same time with MSVC.
             disable static
         fi
         shlibdir_default="$bindir_default"
@@ -3430,7 +3596,6 @@
         add_cppflags -D_GNU_SOURCE
         add_ldflags -Zomf -Zbin-files -Zargs-wild -Zmap
         SHFLAGS='$(SUBDIR)$(NAME).def -Zdll -Zomf'
-        FFSERVERLDFLAGS=""
         LIBSUF="_s.a"
         SLIBPREF=""
         SLIBSUF=".dll"
@@ -3471,7 +3636,6 @@
         ;;
     osf1)
         add_cppflags -D_OSF_SOURCE -D_POSIX_PII -D_REENTRANT
-        FFSERVERLDFLAGS=
         ;;
     minix)
         ;;
@@ -3518,6 +3682,8 @@
             __MINGW64_VERSION_MAJOR < 3"; then
         add_compat msvcrt/snprintf.o
         add_cflags "-include $source_path/compat/msvcrt/snprintf.h"
+    else
+        add_cppflags -D__USE_MINGW_ANSI_STDIO=1
     fi
 elif check_func_headers stdlib.h _get_doserrno; then
     libc_type=msvcrt
@@ -3525,8 +3691,18 @@
     add_compat msvcrt/snprintf.o snprintf=avpriv_snprintf   \
                                  _snprintf=avpriv_snprintf  \
                                  vsnprintf=avpriv_vsnprintf
+    # The MSVC 2010 headers (Win 7.0 SDK) set _WIN32_WINNT to
+    # 0x601 by default unless something else is set by the user.
+    # This can easily lead to us detecting functions only present
+    # in such new versions and producing binaries requiring windows 7.0.
+    # Therefore explicitly set the default to XP unless the user has
+    # set something else on the command line.
+    check_cpp_condition stdlib.h "defined(_WIN32_WINNT)" || add_cppflags -D_WIN32_WINNT=0x0502
 elif check_cpp_condition stddef.h "defined __KLIBC__"; then
     libc_type=klibc
+elif check_cpp_condition sys/cdefs.h "defined __BIONIC__"; then
+    libc_type=bionic
+    add_compat strtod.o strtod=avpriv_strtod
 fi
 
 test -n "$libc_type" && enable $libc_type
@@ -3551,7 +3727,7 @@
 
 echo "config:$arch:$subarch:$cpu:$target_os:$(esc $cc_ident):$(esc $FFMPEG_CONFIGURATION)" >config.fate
 
-check_cpp_condition stdlib.h "defined(__PIC__) || defined(__pic__) || defined(PIC)" && enable pic
+check_cpp_condition stdlib.h "defined(__PIC__) || defined(__pic__) || defined(PIC)" && enable_weak pic
 
 set_default $PATHS_LIST
 set_default nm
@@ -3567,6 +3743,10 @@
     exit 1;
 fi
 
+# backward compatibility layer for incompatible_libav/fork_abi
+enabled incompatible_fork_abi  && enable incompatible_libav_abi
+enabled incompatible_libav_abi && enable incompatible_fork_abi
+
 die_license_disabled() {
     enabled $1 || { enabled $2 && die "$2 is $1 and --enable-$1 is not specified."; }
 }
@@ -3575,6 +3755,7 @@
     enabled $1 || { enabled $2 && die "$2 is incompatible with the gpl and --enable-$1 is not specified."; }
 }
 
+die_license_disabled gpl frei0r
 die_license_disabled gpl libcdio
 die_license_disabled gpl libutvideo
 die_license_disabled gpl libvidstab
@@ -3597,14 +3778,21 @@
 
 disabled optimizations || check_cflags -fomit-frame-pointer
 
-enable_pic() {
+enable_weak_pic() {
+    disabled pic && return
     enable pic
     add_cppflags -DPIC
-    add_cflags   -fPIC
+    case "$target_os" in
+    mingw*|cygwin*)
+        ;;
+    *)
+        add_cflags -fPIC
+        ;;
+    esac
     add_asflags  -fPIC
 }
 
-enabled pic && enable_pic
+enabled pic && enable_weak_pic
 
 check_cc <<EOF || die "Symbol mangling check failed."
 int ff_extern;
@@ -3623,6 +3811,10 @@
 EOF
 done
 
+check_cc <<EOF && enable pragma_deprecated
+void foo(void) { _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") }
+EOF
+
 check_cc <<EOF && enable attribute_packed
 struct { int x; } __attribute__((packed)) x;
 EOF
@@ -3636,6 +3828,8 @@
 EOF
 od -t x1 $TMPO | grep -q '42 *49 *47 *45' && enable bigendian
 
+check_inline_asm inline_asm_labels '"1:\n"'
+
 if enabled alpha; then
 
     check_cflags -mieee
@@ -3676,7 +3870,7 @@
     check_inline_asm asm_mod_q '"add r0, %Q0, %R0" :: "r"((long long)0)'
     check_inline_asm asm_mod_y '"vmul.i32 d0, d0, %y0" :: "x"(0)'
 
-    enabled_all armv6t2 shared !pic && enable_pic
+    [ $target_os != win32 ] && enabled_all armv6t2 shared !pic && enable_weak_pic
 
 elif enabled mips; then
 
@@ -3709,7 +3903,9 @@
 
     # AltiVec flags: The FSF version of GCC differs from the Apple version
     if enabled altivec; then
-        nogas=warn
+        if ! enabled_any pic ppc64; then
+            nogas=warn
+        fi
         check_cflags -maltivec -mabi=altivec &&
         { check_header altivec.h && inc_altivec_h="#include <altivec.h>" ; } ||
         check_cflags -faltivec
@@ -3779,9 +3975,9 @@
 
         check_yasm "pextrd [eax], xmm0, 1" && enable yasm ||
             die "yasm not found, use --disable-yasm for a crippled build"
-        check_yasm "vextractf128 xmm0, ymm0, 0"      || disable avx_external
+        check_yasm "vextractf128 xmm0, ymm0, 0"      || disable avx_external avresample
         check_yasm "vfmaddps ymm0, ymm1, ymm2, ymm3" || disable fma4_external
-        check_yasm "CPU amdnop" && enable cpunop
+        check_yasm "CPU amdnop" && enabled i686 && enable cpunop
     fi
 
     case "$cpu" in
@@ -3854,6 +4050,7 @@
 check_func  clock_gettime || { check_func clock_gettime -lrt && add_extralibs -lrt; }
 check_func  fcntl
 check_func  fork
+check_func_headers stdlib.h getenv
 check_func  gethrtime
 check_func  getopt
 check_func  getrusage
@@ -3869,12 +4066,14 @@
 check_func  ${malloc_prefix}posix_memalign      && enable posix_memalign
 check_func_headers malloc.h _aligned_malloc     && enable aligned_malloc
 check_func  setrlimit
+check_struct "sys/stat.h" "struct stat" st_mtim.tv_nsec -D_BSD_SOURCE
 check_func  strerror_r
 check_func  sched_getaffinity
 check_builtin sync_val_compare_and_swap "" "int *ptr; int oldval, newval; __sync_val_compare_and_swap(ptr, oldval, newval)"
 check_builtin machine_rw_barrier mbarrier.h "__machine_rw_barrier()"
 check_builtin atomic_cas_ptr atomic.h "void **ptr; void *oldval, *newval; atomic_cas_ptr(ptr, oldval, newval)"
 check_builtin MemoryBarrier windows.h "MemoryBarrier()"
+check_builtin sarestart signal.h "SA_RESTART"
 check_func  sysconf
 check_func  sysctl
 check_func  usleep
@@ -3893,7 +4092,9 @@
 check_func_headers windows.h Sleep
 check_func_headers windows.h VirtualAlloc
 check_func_headers glob.h glob
+check_func_headers "X11/Xlib.h X11/extensions/Xvlib.h" XvGetPortAttribute -lXv -lX11 -lXext
 
+check_header cl/cl.h
 check_header direct.h
 check_header dlfcn.h
 check_header dxva.h
@@ -3907,6 +4108,7 @@
 check_header sys/resource.h
 check_header sys/select.h
 check_header sys/time.h
+check_header sys/un.h
 check_header termios.h
 check_header unistd.h
 check_header vdpau/vdpau.h
@@ -3955,12 +4157,11 @@
 fi
 
 enabled sync_val_compare_and_swap && enable atomics_gcc
-enabled machine_rw_barrier && enabled atomic_cas_ptr && enable atomics_suncc
+enabled_all atomic_cas_ptr machine_rw_barrier && enable atomics_suncc
 enabled MemoryBarrier && enable atomics_win32
 
 check_lib math.h sin -lm && LIBM="-lm"
 disabled crystalhd || check_lib libcrystalhd/libcrystalhd_if.h DtsCrystalHDVersion -lcrystalhd || disable crystalhd
-enabled vaapi && require vaapi va/va.h vaInitialize -lva
 
 atan2f_args=2
 ldexpf_args=2
@@ -3971,81 +4172,91 @@
 done
 
 # these are off by default, so fail if requested and not available
-enabled avisynth   && { { check_lib2 "windows.h" LoadLibrary; } ||
-                        { check_lib2 "dlfcn.h" dlopen -ldl; } ||
-                        die "ERROR: LoadLibrary/dlopen not found for avisynth"; }
-enabled fontconfig && require_pkg_config fontconfig "fontconfig/fontconfig.h" FcInit
-enabled frei0r     && { check_header frei0r.h || die "ERROR: frei0r.h header not found"; }
-enabled gnutls     && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init
-enabled libiec61883 && require libiec61883 libiec61883/iec61883.h iec61883_cmp_connect -lraw1394 -lavc1394 -lrom1394 -liec61883
-enabled libaacplus && require  "libaacplus >= 2.0.0" aacplus.h aacplusEncOpen -laacplus
-enabled libass     && require_pkg_config libass ass/ass.h ass_library_init
-enabled libbluray  && require libbluray libbluray/bluray.h bd_open -lbluray
-enabled libcelt    && require libcelt celt/celt.h celt_decode -lcelt0 &&
-                      { check_lib celt/celt.h celt_decoder_create_custom -lcelt0 ||
-                        die "ERROR: libcelt must be installed and version must be >= 0.11.0."; }
-enabled libcaca    && require_pkg_config caca caca.h caca_create_canvas
-enabled libfaac    && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac
-enabled libfdk_aac && require  libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac
+enabled avisynth          && { { check_lib2 "windows.h" LoadLibrary; } ||
+                               { check_lib2 "dlfcn.h" dlopen -ldl; } ||
+                               die "ERROR: LoadLibrary/dlopen not found for avisynth"; }
+enabled fontconfig        && require_pkg_config fontconfig "fontconfig/fontconfig.h" FcInit
+enabled frei0r            && { check_header frei0r.h || die "ERROR: frei0r.h header not found"; }
+enabled gnutls            && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init
+enabled libiec61883       && require libiec61883 libiec61883/iec61883.h iec61883_cmp_connect -lraw1394 -lavc1394 -lrom1394 -liec61883
+enabled libaacplus        && require "libaacplus >= 2.0.0" aacplus.h aacplusEncOpen -laacplus
+enabled libass            && require_pkg_config libass ass/ass.h ass_library_init
+enabled libbluray         && require libbluray libbluray/bluray.h bd_open -lbluray
+enabled libcelt           && require libcelt celt/celt.h celt_decode -lcelt0 &&
+                             { check_lib celt/celt.h celt_decoder_create_custom -lcelt0 ||
+                               die "ERROR: libcelt must be installed and version must be >= 0.11.0."; }
+enabled libcaca           && require_pkg_config caca caca.h caca_create_canvas
+enabled libfaac           && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac
+enabled libfdk_aac        && require libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac
 flite_libs="-lflite_cmu_time_awb -lflite_cmu_us_awb -lflite_cmu_us_kal -lflite_cmu_us_kal16 -lflite_cmu_us_rms -lflite_cmu_us_slt -lflite_usenglish -lflite_cmulex -lflite"
-enabled libflite   && require2 libflite "flite/flite.h" flite_init $flite_libs
-enabled libfreetype && require_pkg_config freetype2 "ft2build.h freetype/freetype.h" FT_Init_FreeType
-enabled libgsm     && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do
-                            check_lib "${gsm_hdr}" gsm_create -lgsm && break;
-                        done || die "ERROR: libgsm not found"; }
-enabled libilbc    && require  libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc
-enabled libmodplug && require  libmodplug libmodplug/modplug.h ModPlug_Load -lmodplug
-enabled libmp3lame && require  "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame
-enabled libnut     && require  libnut libnut.h nut_demuxer_init -lnut
-enabled libopencore_amrnb  && require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb
-enabled libopencore_amrwb  && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb
-enabled libopencv  && require_pkg_config opencv opencv/cxcore.h cvCreateImageHeader
-enabled libopenjpeg && { check_lib openjpeg-1.5/openjpeg.h opj_version -lopenjpeg ||
-                         check_lib openjpeg.h opj_version -lopenjpeg ||
-                         die "ERROR: libopenjpeg not found"; }
-enabled libopus    && require_pkg_config opus opus_multistream.h opus_multistream_decoder_create
-enabled libpulse && require_pkg_config libpulse-simple pulse/simple.h pa_simple_new
-enabled libquvi    && require_pkg_config libquvi quvi/quvi.h quvi_init
-enabled librtmp    && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket
-enabled libschroedinger && require_pkg_config schroedinger-1.0 schroedinger/schro.h schro_init
-enabled libshine   && require_pkg_config shine shine/layer3.h shine_encode_frame
-enabled libsoxr    && require  libsoxr soxr.h soxr_create -lsoxr
-enabled libspeex   && require  libspeex speex/speex.h speex_decoder_init -lspeex
-enabled libstagefright_h264  && require_cpp libstagefright_h264 "binder/ProcessState.h media/stagefright/MetaData.h
+enabled libflite          && require2 libflite "flite/flite.h" flite_init $flite_libs
+enabled libfreetype       && require_pkg_config freetype2 "ft2build.h freetype/freetype.h" FT_Init_FreeType
+enabled libgme            && require  libgme gme/gme.h gme_new_emu -lgme -lstdc++
+enabled libgsm            && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do
+                                   check_lib "${gsm_hdr}" gsm_create -lgsm && break;
+                               done || die "ERROR: libgsm not found"; }
+enabled libilbc           && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc
+enabled libmodplug        && require libmodplug libmodplug/modplug.h ModPlug_Load -lmodplug
+enabled libmp3lame        && require "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame
+enabled libnut            && require libnut libnut.h nut_demuxer_init -lnut
+enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb
+enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb
+enabled libopencv         && require_pkg_config opencv opencv/cxcore.h cvCreateImageHeader
+enabled libopenjpeg       && { check_lib openjpeg-1.5/openjpeg.h opj_version -lopenjpeg ||
+                               check_lib openjpeg.h opj_version -lopenjpeg ||
+                               die "ERROR: libopenjpeg not found"; }
+enabled libopus           && require_pkg_config opus opus_multistream.h opus_multistream_decoder_create
+enabled libpulse          && require_pkg_config libpulse-simple pulse/simple.h pa_simple_new
+enabled libquvi           && require_pkg_config libquvi quvi/quvi.h quvi_init
+enabled librtmp           && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket
+enabled libschroedinger   && require_pkg_config schroedinger-1.0 schroedinger/schro.h schro_init
+enabled libshine          && require_pkg_config shine shine/layer3.h shine_encode_buffer
+enabled libsoxr           && require libsoxr soxr.h soxr_create -lsoxr
+enabled libspeex          && require libspeex speex/speex.h speex_decoder_init -lspeex
+enabled libstagefright_h264 && require_cpp libstagefright_h264 "binder/ProcessState.h media/stagefright/MetaData.h
     media/stagefright/MediaBufferGroup.h media/stagefright/MediaDebug.h media/stagefright/MediaDefs.h
     media/stagefright/OMXClient.h media/stagefright/OMXCodec.h" android::OMXClient -lstagefright -lmedia -lutils -lbinder -lgnustl_static
-enabled libtheora  && require  libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg
-enabled libtwolame && require  libtwolame twolame.h twolame_init -ltwolame &&
-                      { check_lib twolame.h twolame_encode_buffer_float32_interleaved -ltwolame ||
-                        die "ERROR: libtwolame must be installed and version must be >= 0.3.10"; }
-enabled libutvideo    && require_cpp utvideo "stdint.h stdlib.h utvideo/utvideo.h utvideo/Codec.h" 'CCodec*' -lutvideo -lstdc++
-enabled libv4l2    && require_pkg_config libv4l2 libv4l2.h v4l2_ioctl
-enabled libvidstab && require_pkg_config vidstab vid.stab/libvidstab.h vsMotionDetectInit
-enabled libvo_aacenc && require libvo_aacenc vo-aacenc/voAAC.h voGetAACEncAPI -lvo-aacenc
-enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc
-enabled libvorbis  && require  libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg
-enabled libvpx     && {
+enabled libtheora         && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg
+enabled libtwolame        && require libtwolame twolame.h twolame_init -ltwolame &&
+                             { check_lib twolame.h twolame_encode_buffer_float32_interleaved -ltwolame ||
+                               die "ERROR: libtwolame must be installed and version must be >= 0.3.10"; }
+enabled libutvideo        && require_cpp utvideo "stdint.h stdlib.h utvideo/utvideo.h utvideo/Codec.h" 'CCodec*' -lutvideo -lstdc++
+enabled libv4l2           && require_pkg_config libv4l2 libv4l2.h v4l2_ioctl
+enabled libvidstab        && require_pkg_config vidstab vid.stab/libvidstab.h vsMotionDetectInit
+enabled libvo_aacenc      && require libvo_aacenc vo-aacenc/voAAC.h voGetAACEncAPI -lvo-aacenc
+enabled libvo_amrwbenc    && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc
+enabled libvorbis         && require libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg
+enabled libvpx            && {
     enabled libvpx_vp8_decoder && { check_lib2 "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_dec_init_ver -lvpx ||
-                                die "ERROR: libvpx decoder version must be >=0.9.1"; }
+                                    die "ERROR: libvpx decoder version must be >=0.9.1"; }
     enabled libvpx_vp8_encoder && { check_lib2 "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_enc_init_ver VP8E_SET_MAX_INTRA_BITRATE_PCT" -lvpx ||
-                                die "ERROR: libvpx encoder version must be >=0.9.7"; }
-    enabled libvpx_vp9_decoder && { check_lib2 "vpx/vpx_decoder.h vpx/vp8dx.h" "vpx_codec_vp9_dx" -lvpx || disable libvpx_vp9_decoder;  }
+                                    die "ERROR: libvpx encoder version must be >=0.9.7"; }
+    enabled libvpx_vp9_decoder && { check_lib2 "vpx/vpx_decoder.h vpx/vp8dx.h" "vpx_codec_vp9_dx" -lvpx || disable libvpx_vp9_decoder; }
     enabled libvpx_vp9_encoder && { check_lib2 "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_vp9_cx" -lvpx || disable libvpx_vp9_encoder; } }
-enabled libx264    && require  libx264 x264.h x264_encoder_encode -lx264 &&
-                      { check_cpp_condition x264.h "X264_BUILD >= 118" ||
-                        die "ERROR: libx264 must be installed and version must be >= 0.118."; }
-enabled libxavs    && require  libxavs xavs.h xavs_encoder_encode -lxavs
-enabled libxvid    && require  libxvid xvid.h xvid_global -lxvidcore
-enabled openal     && { { for al_libs in "${OPENAL_LIBS}" "-lopenal" "-lOpenAL32"; do
-                        check_lib 'AL/al.h' alGetError "${al_libs}" && break; done } ||
-                        die "ERROR: openal not found"; } &&
-                      { check_cpp_condition "AL/al.h" "defined(AL_VERSION_1_1)" ||
-                        die "ERROR: openal must be installed and version must be 1.1 or compatible"; }
-enabled opencl     && require2 opencl CL/cl.h clEnqueueNDRangeKernel -lOpenCL
-enabled openssl    && { check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto ||
-                        check_lib openssl/ssl.h SSL_library_init -lssl32 -leay32 ||
-                        check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 ||
-                        die "ERROR: openssl not found"; }
+enabled libwavpack        && require libwavpack wavpack/wavpack.h WavpackOpenFileOutput  -lwavpack
+enabled libx264           && require libx264 x264.h x264_encoder_encode -lx264 &&
+                             { check_cpp_condition x264.h "X264_BUILD >= 118" ||
+                               die "ERROR: libx264 must be installed and version must be >= 0.118."; }
+enabled libxavs           && require libxavs xavs.h xavs_encoder_encode -lxavs
+enabled libxvid           && require libxvid xvid.h xvid_global -lxvidcore
+enabled libzmq            && require_pkg_config libzmq zmq.h zmq_ctx_new
+enabled openal            && { { for al_libs in "${OPENAL_LIBS}" "-lopenal" "-lOpenAL32"; do
+                               check_lib 'AL/al.h' alGetError "${al_libs}" && break; done } ||
+                               die "ERROR: openal not found"; } &&
+                             { check_cpp_condition "AL/al.h" "defined(AL_VERSION_1_1)" ||
+                               die "ERROR: openal must be installed and version must be 1.1 or compatible"; }
+enabled opencl            && { check_lib2 OpenCL/cl.h clEnqueueNDRangeKernel -Wl,-framework,OpenCL ||
+                               check_lib2 CL/cl.h clEnqueueNDRangeKernel -lOpenCL ||
+                               die "ERROR: opencl not found"; } &&
+                             { enabled_any w32threads os2threads &&
+                               die "opencl currently needs --enable-pthreads or --disable-w32threads"; } &&
+                             { check_cpp_condition "OpenCL/cl.h" "defined(CL_VERSION_1_2)" ||
+                               check_cpp_condition "CL/cl.h" "defined(CL_VERSION_1_2)" ||
+                               die "ERROR: opencl must be installed and version must be 1.2 or compatible"; }
+enabled openssl           && { check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto ||
+                               check_lib openssl/ssl.h SSL_library_init -lssl32 -leay32 ||
+                               check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 ||
+                               die "ERROR: openssl not found"; }
 
 if enabled gnutls; then
     { check_lib nettle/bignum.h nettle_mpz_get_str_256 -lnettle -lhogweed -lgmp && enable nettle; } ||
@@ -4118,7 +4329,8 @@
 fi
 check_header soundcard.h
 
-enabled_any alsa_indev alsa_outdev && check_lib2 alsa/asoundlib.h snd_pcm_htimestamp -lasound
+enabled_any alsa_indev alsa_outdev &&
+    check_lib2 alsa/asoundlib.h snd_pcm_htimestamp -lasound
 
 enabled jack_indev && check_lib2 jack/jack.h jack_client_open -ljack && check_func sem_timedwait &&
     check_func jack_port_get_latency_range -ljack
@@ -4126,7 +4338,9 @@
 enabled_any sndio_indev sndio_outdev && check_lib2 sndio.h sio_open -lsndio
 
 if enabled libcdio; then
-    check_lib2 "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio || check_lib2 "cdio/paranoia/cdda.h cdio/paranoia/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio
+    check_lib2 "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio ||
+    check_lib2 "cdio/paranoia/cdda.h cdio/paranoia/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio ||
+    die "ERROR: libcdio-paranoia not found"
 fi
 
 enabled x11grab                                           &&
@@ -4134,12 +4348,9 @@
 require Xext X11/extensions/XShm.h XShmCreateImage -lXext &&
 require Xfixes X11/extensions/Xfixes.h XFixesGetCursorImage -lXfixes
 
-if ! disabled vaapi; then
-    check_lib va/va.h vaInitialize -lva && {
-        check_cpp_condition va/va_version.h "VA_CHECK_VERSION(0,32,0)" ||
-        warn "Please upgrade to VA-API >= 0.32 if you would like full VA-API support.";
-    } || disable vaapi
-fi
+enabled vaapi &&
+    check_lib va/va.h vaInitialize -lva ||
+    disable vaapi
 
 enabled vdpau &&
     check_cpp_condition vdpau/vdpau.h "defined VDP_DECODER_PROFILE_MPEG4_PART2_ASP" ||
@@ -4149,7 +4360,6 @@
 disabled iconv || check_func_headers iconv.h iconv || check_lib2 iconv.h iconv -liconv || disable iconv
 
 enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel"
-test -n "$valgrind" && target_exec="$valgrind --error-exitcode=1 --malloc-fill=0x2a --track-origins=yes --leak-check=full --gen-suppressions=all --suppressions=$source_path/tests/fate-valgrind.supp"
 
 # add some useful compiler flags if supported
 check_cflags -Wdeclaration-after-statement
@@ -4286,8 +4496,17 @@
     add_cflags -pds=824 -pds=837
 elif enabled pathscale; then
     add_cflags -fstrict-overflow -OPT:wrap_around_unsafe_opt=OFF
-elif enabled msvc; then
+elif enabled_any msvc icl; then
     enabled x86_32 && disable aligned_stack
+    enabled_all x86_32 debug && add_cflags -Oy-
+    enabled debug && add_ldflags -debug
+    if enabled icl; then
+        # basically -fstrict-aliasing that does not work (correctly) on icl 13.x
+        check_cpp_condition "windows.h" "__ICL < 1300" && add_cflags -Qansi-alias
+        # icl will pass the inline asm tests but inline asm is currently
+        # not supported (build will fail)
+        disable inline_asm
+    fi
 fi
 
 case $target_os in
@@ -4371,7 +4590,7 @@
     echo "SSSE3 enabled             ${ssse3-no}"
     echo "AVX enabled               ${avx-no}"
     echo "FMA4 enabled              ${fma4-no}"
-    echo "CMOV enabled              ${cmov-no}"
+    echo "i686 features enabled     ${i686-no}"
     echo "CMOV is fast              ${fast_cmov-no}"
     echo "EBX available             ${ebx_available-no}"
     echo "EBP available             ${ebp_available-no}"
@@ -4411,7 +4630,6 @@
 echo "safe bitstream reader     ${safe_bitstream_reader-no}"
 echo "SDL support               ${sdl-no}"
 echo "opencl enabled            ${opencl-no}"
-echo "libshine enabled          ${libshine-no}"
 echo "texi2html enabled         ${texi2html-no}"
 echo "perl enabled              ${perl-no}"
 echo "pod2man enabled           ${pod2man-no}"
@@ -4503,7 +4721,6 @@
 LD_PATH=$LD_PATH
 DLLTOOL=$dlltool
 LDFLAGS=$LDFLAGS
-LDFLAGS-ffserver=$FFSERVERLDFLAGS
 SHFLAGS=$(echo $($ldflags_filter $SHFLAGS))
 YASMFLAGS=$YASMFLAGS
 BUILDSUF=$build_suffix
@@ -4538,8 +4755,9 @@
 HOSTCC_C=$HOSTCC_C
 HOSTCC_O=$HOSTCC_O
 HOSTLD_O=$HOSTLD_O
-TARGET_EXEC=$target_exec
+TARGET_EXEC=$target_exec $target_exec_args
 TARGET_PATH=$target_path
+TARGET_SAMPLES=${target_samples:-\$(SAMPLES)}
 LIBS-ffplay=$sdl_libs
 CFLAGS-ffplay=$sdl_cflags
 ZLIB=$($ldflags_filter -lz)
@@ -4602,6 +4820,9 @@
     printf '' >$TMPASM
 fi
 
+enabled getenv || echo "#define getenv(x) NULL" >> $TMPH
+
+
 mkdir -p doc
 echo "@c auto-generated by configure" > doc/config.texi
 
@@ -4684,27 +4905,27 @@
 EOF
 }
 
-libavfilter_pc_deps="libavutil${build_suffix} = $LIBAVUTIL_VERSION"
-enabled libavfilter_deps_avcodec    && prepend libavfilter_pc_deps "libavcodec${build_suffix} = $LIBAVCODEC_VERSION,"
-enabled libavfilter_deps_avformat   && prepend libavfilter_pc_deps "libavformat${build_suffix} = $LIBAVFORMAT_VERSION,"
-enabled libavfilter_deps_avresample && prepend libavfilter_pc_deps "libavresample${build_suffix} = $LIBAVRESAMPLE_VERSION,"
-enabled libavfilter_deps_swscale    && prepend libavfilter_pc_deps "libswscale${build_suffix} = $LIBSWSCALE_VERSION,"
-enabled libavfilter_deps_swresample && prepend libavfilter_pc_deps "libswresample${build_suffix} = $LIBSWRESAMPLE_VERSION,"
-enabled libavfilter_deps_postproc   && prepend libavfilter_pc_deps "libpostproc${build_suffix} = $LIBPOSTPROC_VERSION,"
-libavfilter_pc_deps=${libavfilter_pc_deps%, }
+lavfi_libs="libavutil${build_suffix} = $LIBAVUTIL_VERSION"
+enabled libavfilter_deps_avcodec    && prepend lavfi_libs "libavcodec${build_suffix} = $LIBAVCODEC_VERSION,"
+enabled libavfilter_deps_avformat   && prepend lavfi_libs "libavformat${build_suffix} = $LIBAVFORMAT_VERSION,"
+enabled libavfilter_deps_avresample && prepend lavfi_libs "libavresample${build_suffix} = $LIBAVRESAMPLE_VERSION,"
+enabled libavfilter_deps_swscale    && prepend lavfi_libs "libswscale${build_suffix} = $LIBSWSCALE_VERSION,"
+enabled libavfilter_deps_swresample && prepend lavfi_libs "libswresample${build_suffix} = $LIBSWRESAMPLE_VERSION,"
+enabled libavfilter_deps_postproc   && prepend lavfi_libs "libpostproc${build_suffix} = $LIBPOSTPROC_VERSION,"
+lavfi_libs=${lavfi_libs%, }
 
-libavdevice_pc_deps="libavformat${build_suffix} = $LIBAVFORMAT_VERSION"
-enabled lavfi_indev && prepend libavdevice_pc_deps "libavfilter${build_suffix} = $LIBAVFILTER_VERSION,"
+lavd_libs="libavformat${build_suffix} = $LIBAVFORMAT_VERSION"
+enabled lavfi_indev && prepend lavd_libs "libavfilter${build_suffix} = $LIBAVFILTER_VERSION,"
 
-pkgconfig_generate libavutil "FFmpeg utility library" "$LIBAVUTIL_VERSION" "$LIBM"
-pkgconfig_generate libavcodec "FFmpeg codec library" "$LIBAVCODEC_VERSION" "$extralibs" "libavutil${build_suffix} = $LIBAVUTIL_VERSION"
-pkgconfig_generate libavformat "FFmpeg container format library" "$LIBAVFORMAT_VERSION" "$extralibs" "libavcodec${build_suffix} = $LIBAVCODEC_VERSION"
-pkgconfig_generate libavdevice "FFmpeg device handling library" "$LIBAVDEVICE_VERSION" "$extralibs" "$libavdevice_pc_deps"
-pkgconfig_generate libavfilter "FFmpeg audio/video filtering library" "$LIBAVFILTER_VERSION" "$extralibs" "$libavfilter_pc_deps"
-pkgconfig_generate libpostproc "FFmpeg postprocessing library" "$LIBPOSTPROC_VERSION" "" "libavutil${build_suffix} = $LIBAVUTIL_VERSION"
-pkgconfig_generate libavresample "Libav audio resampling library" "$LIBAVRESAMPLE_VERSION" "$extralibs" "libavutil${build_suffix} = $LIBAVUTIL_VERSION"
-pkgconfig_generate libswscale "FFmpeg image rescaling library" "$LIBSWSCALE_VERSION" "$LIBM" "libavutil${build_suffix} = $LIBAVUTIL_VERSION"
-pkgconfig_generate libswresample "FFmpeg audio resampling library" "$LIBSWRESAMPLE_VERSION" "$LIBM" "libavutil${build_suffix} = $LIBAVUTIL_VERSION"
+pkgconfig_generate libavutil     "FFmpeg utility library"               "$LIBAVUTIL_VERSION"     "$LIBM"
+pkgconfig_generate libavcodec    "FFmpeg codec library"                 "$LIBAVCODEC_VERSION"    "$extralibs" "libavutil${build_suffix} = $LIBAVUTIL_VERSION"
+pkgconfig_generate libavformat   "FFmpeg container format library"      "$LIBAVFORMAT_VERSION"   "$extralibs" "libavcodec${build_suffix} = $LIBAVCODEC_VERSION"
+pkgconfig_generate libavdevice   "FFmpeg device handling library"       "$LIBAVDEVICE_VERSION"   "$extralibs" "$lavd_libs"
+pkgconfig_generate libavfilter   "FFmpeg audio/video filtering library" "$LIBAVFILTER_VERSION"   "$extralibs" "$lavfi_libs"
+pkgconfig_generate libpostproc   "FFmpeg postprocessing library"        "$LIBPOSTPROC_VERSION"   ""           "libavutil${build_suffix} = $LIBAVUTIL_VERSION"
+pkgconfig_generate libavresample "Libav audio resampling library"       "$LIBAVRESAMPLE_VERSION" "$extralibs" "libavutil${build_suffix} = $LIBAVUTIL_VERSION"
+pkgconfig_generate libswscale    "FFmpeg image rescaling library"       "$LIBSWSCALE_VERSION"    "$LIBM"      "libavutil${build_suffix} = $LIBAVUTIL_VERSION"
+pkgconfig_generate libswresample "FFmpeg audio resampling library"      "$LIBSWRESAMPLE_VERSION" "$LIBM"      "libavutil${build_suffix} = $LIBAVUTIL_VERSION"
 
 fix_ffmpeg_remote(){
     git_remote_from=$1
diff --git a/doc/APIchanges b/doc/APIchanges
index cd7c4ca..1ea2bd6 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,6 +15,87 @@
 
 API changes, most recent first:
 
+2013-08-xx - xxxxxxx - lsws 2.5.100 -
+  Add a sws_dither AVOption, allowing to set the dither algorithm used
+
+2013-08-xx - xxxxxxx - lavc 55.27.100 - vdpau.h
+  Add a render2 alternative to the render callback function.
+
+2013-08-xx - xxxxxxx - lavc 55.26.100 - vdpau.h
+  Add allocation function for AVVDPAUContext, allowing
+  to extend it in the future without breaking ABI/API.
+
+2013-08-xx - xxxxxxx - lavc 55.16.0 - avcodec.h
+  Extend AVPacket API with av_packet_unref, av_packet_ref,
+  av_packet_move_ref, av_packet_copy_props, av_packet_free_side_data.
+
+2013-08-xx - xxxxxxx - lavc 55.13.0 - avcodec.h
+  Deprecate the bitstream-related members from struct AVVDPAUContext.
+  The bistream buffers no longer need to be explicitly freed.
+
+2013-08-xx - xxxxxxx - lavc 55.12.0 - avcodec.h
+  Deprecate the CODEC_CAP_HWACCEL_VDPAU codec capability. Use CODEC_CAP_HWACCEL
+  and select the AV_PIX_FMT_VDPAU format with get_format() instead.
+
+2013-08-xx - xxxxxxx - lavu 52.14.0 - pixfmt.h
+  Deprecate AV_PIX_FMT_VDPAU_*. Use AV_PIX_FMT_VDPAU instead.
+
+2013-08-xx - xxxxxxx - lavc 55.11.0 - avcodec.h
+  Add output_picture_number to AVCodecParserContext.
+
+2013-07-XX - xxxxxxx - XXXXXXXXXXXXXX - avcodec.h
+  Add avcodec_chroma_pos_to_enum()
+  Add avcodec_enum_to_chroma_pos()
+
+2013-07-03 - xxxxxxx - lavfi 3.78.100 - avfilter.h
+  Deprecate avfilter_graph_parse() in favor of the equivalent
+  avfilter_graph_parse_ptr().
+
+2013-06-xx - xxxxxxx - lavc 55.10.0 - avcodec.h
+  Add MPEG-2 AAC profiles
+
+2013-06-xx - xxxxxxx - lavf 55.10.100 - avformat.h
+  Add AV_DISPOSITION_* flags to indicate text track kind.
+
+2013-06-xx - xxxxxxx - lavu 52.36.100
+  Add AVRIPEMD:
+   av_ripemd_alloc()
+   av_ripemd_init()
+   av_ripemd_update()
+   av_ripemd_final()
+
+2013-06-05 - fc962d4 - lavu 52.13.0 - mem.h
+  Add av_realloc_array and av_reallocp_array
+
+2013-05-30 - 682b227 - lavu 52.35.100
+  Add AVSHA512:
+   av_sha512_alloc()
+   av_sha512_init()
+   av_sha512_update()
+   av_sha512_final()
+
+2013-05-24 - xxxxxxx - lavfi 3.70.100 - avfilter.h
+  Add support for slice multithreading to lavfi. Filters supporting threading
+  are marked with AVFILTER_FLAG_SLICE_THREADS.
+  New fields AVFilterContext.thread_type, AVFilterGraph.thread_type and
+  AVFilterGraph.nb_threads (accessible directly or through AVOptions) may be
+  used to configure multithreading.
+
+2013-05-24 - xxxxxxx - lavu 52.34.100 - cpu.h
+  Add av_cpu_count() function for getting the number of logical CPUs.
+
+2013-05-24 - xxxxxxx - lavc 55.12.100 - avcodec.h
+  Add picture_structure to AVCodecParserContext.
+
+2013-05-17 - xxxxxxx - lavu 52.33.100 - opt.h
+  Add AV_OPT_TYPE_COLOR value to AVOptionType enum.
+
+2013-05-13 - xxxxxxx - lavu 52.31.100 - mem.h
+  Add av_dynarray2_add().
+
+2013-05-12 - xxxxxxx - lavfi 3.65.100
+  Add AVFILTER_FLAG_SUPPORT_TIMELINE* filter flags.
+
 2013-04-19 - xxxxxxx - lavc 55.4.100
   Add AV_CODEC_PROP_TEXT_SUB property for text based subtitles codec.
 
@@ -167,46 +248,52 @@
 2012-03-26 - a67d9cf - lavfi 2.66.100
   Add avfilter_fill_frame_from_{audio_,}buffer_ref() functions.
 
+2013-05-xx - xxxxxxx - lavu 52.11.0 - pixdesc.h
+  Replace PIX_FMT_* flags with AV_PIX_FMT_FLAG_*.
+
+2013-04-xx - xxxxxxx - lavc 55.4.0 - avcodec.h
+  Add field_order to AVCodecParserContext.
+
 2013-03-xx - xxxxxxx - lavc 55.2.0 - avcodec.h
   Add CODEC_FLAG_UNALIGNED to allow decoders to produce unaligned output.
 
-2013-xx-xx - lavfi 3.8.0
-  Move all content from avfiltergraph.h to avfilter.h. Deprecate
-  avfilterhraph.h, user applications should include just avfilter.h
-  Add avfilter_graph_alloc_filter(), deprecate avfilter_open() and
-  avfilter_graph_add_filter().
-  Add AVFilterContext.graph pointing to the AVFilterGraph that contains the
-  filter.
-  Add avfilter_init_str(), deprecate avfilter_init_filter().
-  Add avfilter_init_dict().
-  Add AVFilter.flags field and AVFILTER_FLAG_DYNAMIC_{INPUTS,OUTPUTS} flags.
-  Add avfilter_pad_count() for counting filter inputs/outputs.
-  Add avfilter_next(), deprecate av_filter_next().
-  Deprecate avfilter_uninit().
+2013-04-11 - lavfi 3.8.0
+  38f0c07 - Move all content from avfiltergraph.h to avfilter.h. Deprecate
+            avfilterhraph.h, user applications should include just avfilter.h
+  bc1a985 - Add avfilter_graph_alloc_filter(), deprecate avfilter_open() and
+            avfilter_graph_add_filter().
+  1113672 - Add AVFilterContext.graph pointing to the AVFilterGraph that contains the
+            filter.
+  48a5ada - Add avfilter_init_str(), deprecate avfilter_init_filter().
+  1ba95a9 - Add avfilter_init_dict().
+  7cdd737 - Add AVFilter.flags field and AVFILTER_FLAG_DYNAMIC_{INPUTS,OUTPUTS} flags.
+  7e8fe4b - Add avfilter_pad_count() for counting filter inputs/outputs.
+  fa2a34c - Add avfilter_next(), deprecate av_filter_next().
+            Deprecate avfilter_uninit().
 
-2013-xx-xx - lavfi 3.7.0 - avfilter.h
-  Add AVFilter.priv_class for exporting filter options through the AVOptions API
-  in the similar way private options work in lavc and lavf.
-  Add avfilter_get_class().
+2013-04-09 - lavfi 3.7.0 - avfilter.h
+  b439c99 - Add AVFilter.priv_class for exporting filter options through the
+            AVOptions API in the similar way private options work in lavc and lavf.
+  8114c10 - Add avfilter_get_class().
   Switch all filters to use AVOptions.
 
-2013-xx-xx - lavu 52.9.0 - pixdesc.h
+2013-03-19 - 2c328a9 - lavu 52.9.0 - pixdesc.h
   Add av_pix_fmt_count_planes() function for counting planes in a pixel format.
 
-2013-xx-xx - lavfi 3.6.0
+2013-03-16 - 42c7c61 - lavfi 3.6.0
   Add AVFilterGraph.nb_filters, deprecate AVFilterGraph.filter_count.
 
-2013-03-xx - Reference counted buffers - lavu 52.8.0, lavc 55.0.0, lavf 55.0.0,
+2013-03-08 - Reference counted buffers - lavu 52.8.0, lavc 55.0.0, lavf 55.0.0,
 lavd 54.0.0, lavfi 3.5.0
-  xxxxxxx, xxxxxxx - add a new API for reference counted buffers and buffer
+  8e401db, 1cec062 - add a new API for reference counted buffers and buffer
                      pools (new header libavutil/buffer.h).
-  xxxxxxx - add AVPacket.buf to allow reference counting for the AVPacket data.
+  1afddbe - add AVPacket.buf to allow reference counting for the AVPacket data.
             Add av_packet_from_data() function for constructing packets from
             av_malloc()ed data.
-  xxxxxxx - move AVFrame from lavc to lavu (new header libavutil/frame.h), add
+  7ecc2d4 - move AVFrame from lavc to lavu (new header libavutil/frame.h), add
             AVFrame.buf/extended_buf to allow reference counting for the AVFrame
             data. Add new API for working with reference-counted AVFrames.
-  xxxxxxx - add the refcounted_frames field to AVCodecContext to make audio and
+  759001c - add the refcounted_frames field to AVCodecContext to make audio and
             video decoders return reference-counted frames. Add get_buffer2()
             callback to AVCodecContext which allocates reference-counted frames.
             Add avcodec_default_get_buffer2() as the default get_buffer2()
@@ -224,30 +311,30 @@
                 * qscale_table, qstride, qscale_type, mbskip_table, motion_val,
                   mb_type, dct_coeff, ref_index -- mpegvideo-specific tables,
                   which are not exported anymore.
-  xxxxxxx - switch libavfilter to use AVFrame instead of AVFilterBufferRef. Add
+  7e35037 - switch libavfilter to use AVFrame instead of AVFilterBufferRef. Add
             av_buffersrc_add_frame(), deprecate av_buffersrc_buffer().
             Add av_buffersink_get_frame() and av_buffersink_get_samples(),
             deprecate av_buffersink_read() and av_buffersink_read_samples().
             Deprecate AVFilterBufferRef and all functions for working with it.
 
-2013-xx-xx - xxxxxxx - lavu 52.8.0 - avstring.h
+2013-03-17 - 12c5c1d - lavu 52.8.0 - avstring.h
   Add av_isdigit, av_isgraph, av_isspace, av_isxdigit.
 
-2013-xx-xx - xxxxxxx - lavfi 3.4.0 - avfiltergraph.h
+2013-02-23 - 9f12235 - lavfi 3.4.0 - avfiltergraph.h
   Add resample_lavr_opts to AVFilterGraph for setting libavresample options
   for auto-inserted resample filters.
 
-2013-xx-xx - xxxxxxx - lavu 52.7.0 - dict.h
+2013-01-25 - 38c1466 - lavu 52.7.0 - dict.h
   Add av_dict_parse_string() to set multiple key/value pairs at once from a
   string.
 
-2013-01-xx - xxxxxxx - lavu 52.6.0 - avstring.h
+2013-01-25 - b85a5e8 - lavu 52.6.0 - avstring.h
   Add av_strnstr()
 
-2013-01-xx - xxxxxxx - lavu 52.5.0 - hmac.h
+2013-01-15 - 8ee288d - lavu 52.5.0 - hmac.h
   Add AVHMAC.
 
-2013-01-13 - xxxxxxx - lavc 54.87.100 / 54.36.0 - vdpau.h
+2013-01-13 - 44e065d - lavc 54.87.100 / 54.36.0 - vdpau.h
   Add AVVDPAUContext struct for VDPAU hardware-accelerated decoding.
 
 2013-01-12 - dae382b / 169fb94 - lavu 52.14.100 / 52.4.0 - pixdesc.h
diff --git a/doc/Doxyfile b/doc/Doxyfile
index faaa462..6488aad 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -33,7 +33,7 @@
 
 PROJECT_NUMBER         =
 
-# With the PROJECT_LOGO tag one can specify an logo or icon that is included
+# With the PROJECT_LOGO tag one can specify a logo or icon that is included
 # in the documentation. The maximum height of the logo should not exceed 55
 # pixels and the maximum width should not exceed 200 pixels. Doxygen will
 # copy the logo to the output directory.
@@ -277,7 +277,7 @@
 # be useful for C code in case the coding convention dictates that all compound
 # types are typedef'ed and only the typedef is referenced, never the tag name.
 
-TYPEDEF_HIDES_STRUCT   = NO
+TYPEDEF_HIDES_STRUCT   = YES
 
 # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
 # determine which symbols to keep in memory and which to flush to disk.
@@ -409,7 +409,7 @@
 # alphabetically by member name. If set to NO the members will appear in
 # declaration order.
 
-SORT_MEMBER_DOCS       = YES
+SORT_MEMBER_DOCS       = NO
 
 # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
 # brief documentation of file, namespace and class members alphabetically
diff --git a/doc/Makefile b/doc/Makefile
index 9189c7b..cd24b8c 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -14,7 +14,9 @@
 COMPONENTS-$(CONFIG_AVDEVICE)   += ffmpeg-devices
 COMPONENTS-$(CONFIG_AVFILTER)   += ffmpeg-filters
 
-MANPAGES    = $(PROGS-yes:%=doc/%.1)    $(PROGS-yes:%=doc/%-all.1)    $(COMPONENTS-yes:%=doc/%.1)    $(LIBRARIES-yes:%=doc/%.3)
+MANPAGES1   = $(PROGS-yes:%=doc/%.1)    $(PROGS-yes:%=doc/%-all.1)    $(COMPONENTS-yes:%=doc/%.1)
+MANPAGES3   = $(LIBRARIES-yes:%=doc/%.3)
+MANPAGES    = $(MANPAGES1) $(MANPAGES3)
 PODPAGES    = $(PROGS-yes:%=doc/%.pod)  $(PROGS-yes:%=doc/%-all.pod)  $(COMPONENTS-yes:%=doc/%.pod)  $(LIBRARIES-yes:%=doc/%.pod)
 HTMLPAGES   = $(PROGS-yes:%=doc/%.html) $(PROGS-yes:%=doc/%-all.html) $(COMPONENTS-yes:%=doc/%.html) $(LIBRARIES-yes:%=doc/%.html) \
               doc/developer.html                                        \
@@ -93,13 +95,16 @@
 
 install-man: $(MANPAGES)
 	$(Q)mkdir -p "$(MANDIR)/man1"
-	$(INSTALL) -m 644 $(MANPAGES) "$(MANDIR)/man1"
+	$(INSTALL) -m 644 $(MANPAGES1) "$(MANDIR)/man1"
+	$(Q)mkdir -p "$(MANDIR)/man3"
+	$(INSTALL) -m 644 $(MANPAGES3) "$(MANDIR)/man3"
 endif
 
 uninstall: uninstall-man
 
 uninstall-man:
-	$(RM) $(addprefix "$(MANDIR)/man1/",$(ALLMANPAGES))
+	$(RM) $(addprefix "$(MANDIR)/man1/",$(MANPAGES1))
+	$(RM) $(addprefix "$(MANDIR)/man3/",$(MANPAGES3))
 
 clean:: docclean
 
diff --git a/doc/RELEASE_NOTES b/doc/RELEASE_NOTES
index 2faf40d..28a1c05 100644
--- a/doc/RELEASE_NOTES
+++ b/doc/RELEASE_NOTES
@@ -1,7 +1,7 @@
 Release Notes
 =============
 
-* 1.2 "Magic"  March, 2013
+* 2.0 "Nameless"  July, 2013
 
 
 General notes
diff --git a/doc/all-components.texi b/doc/all-components.texi
deleted file mode 100644
index 177cf10..0000000
--- a/doc/all-components.texi
+++ /dev/null
@@ -1,31 +0,0 @@
-@include config.texi
-
-@ifset config-avutil
-@include utils.texi
-@end ifset
-
-@ifset config-avcodec
-@include codecs.texi
-@include bitstream_filters.texi
-@end ifset
-
-@ifset config-avformat
-@include formats.texi
-@include protocols.texi
-@end ifset
-
-@ifset config-avdevice
-@include devices.texi
-@end ifset
-
-@ifset config-swresample
-@include resampler.texi
-@end ifset
-
-@ifset config-swscale
-@include scaler.texi
-@end ifset
-
-@ifset config-avfilter
-@include filters.texi
-@end ifset
diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi
index 2ee00c1..315fe33 100644
--- a/doc/bitstream_filters.texi
+++ b/doc/bitstream_filters.texi
@@ -17,9 +17,46 @@
 
 @section aac_adtstoasc
 
+Convert MPEG-2/4 AAC ADTS to MPEG-4 Audio Specific Configuration
+bitstream filter.
+
+This filter creates an MPEG-4 AudioSpecificConfig from an MPEG-2/4
+ADTS header and removes the ADTS header.
+
+This is required for example when copying an AAC stream from a raw
+ADTS AAC container to a FLV or a MOV/MP4 file.
+
 @section chomp
 
-@section dump_extradata
+Remove zero padding at the end of a packet.
+
+@section dump_extra
+
+Add extradata to the beginning of the filtered packets.
+
+The additional argument specifies which packets should be filtered.
+It accepts the values:
+@table @samp
+@item a
+add extradata to all key packets, but only if @var{local_header} is
+set in the @option{flags2} codec context field
+
+@item k
+add extradata to all key packets
+
+@item e
+add extradata to all packets
+@end table
+
+If not specified it is assumed @samp{k}.
+
+For example the following @command{ffmpeg} command forces a global
+header (thus disabling individual packet headers) in the H.264 packets
+generated by the @code{libx264} encoder, but corrects them by adding
+the header stored in extradata to the key packets:
+@example
+ffmpeg -i INPUT -map 0 -flags:v +global_header -c:v libx264 -bsf:v dump_extra out.ts
+@end example
 
 @section h264_mp4toannexb
 
@@ -86,6 +123,6 @@
 
 @section noise
 
-@section remove_extradata
+@section remove_extra
 
 @c man end BITSTREAM FILTERS
diff --git a/doc/codecs.texi b/doc/codecs.texi
index 2adadc0..6ff2a65 100644
--- a/doc/codecs.texi
+++ b/doc/codecs.texi
@@ -1,3 +1,4 @@
+@anchor{codec-options}
 @chapter Codec Options
 @c man begin CODEC OPTIONS
 
@@ -259,7 +260,10 @@
 @item unofficial
 allow unofficial extensions
 @item experimental
-allow non standardized experimental things
+allow non standardized experimental things, experimental
+(unfinished/work in progress/not well tested) decoders and encoders.
+Note: experimental decoders can pose a security risk, do not use this for
+decoding untrusted input.
 @end table
 
 @item b_qoffset @var{float} (@emph{encoding,video})
diff --git a/doc/decoders.texi b/doc/decoders.texi
index 2d812a27..aa82add 100644
--- a/doc/decoders.texi
+++ b/doc/decoders.texi
@@ -60,6 +60,78 @@
 use is purely internal and the format of the data it accepts is not publicly
 documented.
 
+@section libcelt
+
+libcelt decoder wrapper.
+
+libcelt allows libavcodec to decode the Xiph CELT ultra-low delay audio codec.
+Requires the presence of the libcelt headers and library during configuration.
+You need to explicitly configure the build with @code{--enable-libcelt}.
+
+@section libgsm
+
+libgsm decoder wrapper.
+
+libgsm allows libavcodec to decode the GSM full rate audio codec. Requires
+the presence of the libgsm headers and library during configuration. You need
+to explicitly configure the build with @code{--enable-libgsm}.
+
+This decoder supports both the ordinary GSM and the Microsoft variant.
+
+@section libilbc
+
+libilbc decoder wrapper.
+
+libilbc allows libavcodec to decode the Internet Low Bitrate Codec (iLBC)
+audio codec. Requires the presence of the libilbc headers and library during
+configuration. You need to explicitly configure the build with
+@code{--enable-libilbc}.
+
+@subsection Options
+
+The following option is supported by the libilbc wrapper.
+
+@table @option
+@item enhance
+
+Enable the enhancement of the decoded audio when set to 1. The default
+value is 0 (disabled).
+
+@end table
+
+@section libopencore-amrnb
+
+libopencore-amrnb decoder wrapper.
+
+libopencore-amrnb allows libavcodec to decode the Adaptive Multi-Rate
+Narrowband audio codec. Using it requires the presence of the
+libopencore-amrnb headers and library during configuration. You need to
+explicitly configure the build with @code{--enable-libopencore-amrnb}.
+
+An FFmpeg native decoder for AMR-NB exists, so users can decode AMR-NB
+without this library.
+
+@section libopencore-amrwb
+
+libopencore-amrwb decoder wrapper.
+
+libopencore-amrwb allows libavcodec to decode the Adaptive Multi-Rate
+Wideband audio codec. Using it requires the presence of the
+libopencore-amrwb headers and library during configuration. You need to
+explicitly configure the build with @code{--enable-libopencore-amrwb}.
+
+An FFmpeg native decoder for AMR-WB exists, so users can decode AMR-WB
+without this library.
+
+@section libopus
+
+libopus decoder wrapper.
+
+libopus allows libavcodec to decode the Opus Interactive Audio Codec.
+Requires the presence of the libopus headers and library during
+configuration. You need to explicitly configure the build with
+@code{--enable-libopus}.
+
 @c man end AUDIO DECODERS
 
 @chapter Subtitles Decoders
diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index c75e1ab..437d1ca 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -1,7 +1,7 @@
 @chapter Demuxers
 @c man begin DEMUXERS
 
-Demuxers are configured elements in FFmpeg which allow to read the
+Demuxers are configured elements in FFmpeg that can read the
 multimedia streams from a particular type of file.
 
 When you configure your FFmpeg build, all the supported demuxers
@@ -103,6 +103,19 @@
 
 @end table
 
+@section libgme
+
+The Game Music Emu library is a collection of video game music file emulators.
+
+See @url{http://code.google.com/p/game-music-emu/} for more information.
+
+Some files have multiple tracks. The demuxer will pick the first track by
+default. The @option{track_index} option can be used to select a different
+track. Track indexes start at 0. The demuxer exports the number of tracks as
+@var{tracks} meta data entry.
+
+For very large files, the @option{max_size} option may have to be adjusted.
+
 @section libquvi
 
 Play media from Internet services using the quvi project.
@@ -210,6 +223,10 @@
 Set the index interval range to check when looking for the first image
 file in the sequence, starting from @var{start_number}. Default value
 is 5.
+@item ts_from_file
+If set to 1, will set frame timestamp to modification time of image file. Note
+that monotonity of timestamps is not provided: images go in the same order as
+without this option. Default value is 0.
 @item video_size
 Set the video size of the images to read. If not specified the video
 size is guessed from the first image file in the sequence.
@@ -240,6 +257,19 @@
 @end example
 @end itemize
 
+@section mpegts
+
+MPEG-2 transport stream demuxer.
+
+@table @option
+
+@item fix_teletext_pts
+Overrides teletext packet PTS and DTS values with the timestamps calculated
+from the PCR of the first program which the teletext stream is part of and is
+not discarded. Default value is 1, set this option to 0 if you want your
+teletext packet PTS and DTS values untouched.
+@end table
+
 @section rawvideo
 
 Raw video demuxer.
diff --git a/doc/developer.texi b/doc/developer.texi
index d5580d1..b9951a4 100644
--- a/doc/developer.texi
+++ b/doc/developer.texi
@@ -11,29 +11,23 @@
 
 @chapter Developers Guide
 
-@section API
-@itemize @bullet
-@item libavcodec is the library containing the codecs (both encoding and
-decoding). Look at @file{doc/examples/decoding_encoding.c} to see how to use
-it.
+@section Notes for external developers
 
-@item libavformat is the library containing the file format handling (mux and
-demux code for several formats). Look at @file{ffplay.c} to use it in a
-player. See @file{doc/examples/muxing.c} to use it to generate audio or video
-streams.
+This document is mostly useful for internal FFmpeg developers.
+External developers who need to use the API in their application should
+refer to the API doxygen documentation in the public headers, and
+check the examples in @file{doc/examples} and in the source code to
+see how the public API is employed.
 
-@end itemize
+You can use the FFmpeg libraries in your commercial program, but you
+are encouraged to @emph{publish any patch you make}. In this case the
+best way to proceed is to send your patches to the ffmpeg-devel
+mailing list following the guidelines illustrated in the remainder of
+this document.
 
-@section Integrating libavcodec or libavformat in your program
-
-You can integrate all the source code of the libraries to link them
-statically to avoid any version problem. All you need is to provide a
-'config.mak' and a 'config.h' in the parent directory. See the defines
-generated by ./configure to understand what is needed.
-
-You can use libavcodec or libavformat in your commercial program, but
-@emph{any patch you make must be published}. The best way to proceed is
-to send your patches to the FFmpeg mailing list.
+For more detailed legal information about the use of FFmpeg in
+external programs read the @file{LICENSE} file in the source tree and
+consult @url{http://ffmpeg.org/legal.html}.
 
 @section Contributing
 
@@ -57,13 +51,16 @@
 @subsection Code formatting conventions
 
 There are the following guidelines regarding the indentation in files:
+
 @itemize @bullet
 @item
 Indent size is 4.
+
 @item
 The TAB character is forbidden outside of Makefiles as is any
 form of trailing whitespace. Commits containing either will be
 rejected by the git repository.
+
 @item
 You should try to limit your code lines to 80 characters; however, do so if
 and only if this improves readability.
@@ -117,13 +114,17 @@
 
 FFmpeg is programmed in the ISO C90 language with a few additional
 features from ISO C99, namely:
+
 @itemize @bullet
 @item
 the @samp{inline} keyword;
+
 @item
 @samp{//} comments;
+
 @item
 designated struct initializers (@samp{struct s x = @{ .i = 17 @};})
+
 @item
 compound literals (@samp{x = (struct s) @{ 17, 23 @};})
 @end itemize
@@ -135,13 +136,17 @@
 All code must compile with recent versions of GCC and a number of other
 currently supported compilers. To ensure compatibility, please do not use
 additional C99 features or GCC extensions. Especially watch out for:
+
 @itemize @bullet
 @item
 mixing statements and declarations;
+
 @item
 @samp{long long} (use @samp{int64_t} instead);
+
 @item
 @samp{__attribute__} not protected by @samp{#ifdef __GNUC__} or similar;
+
 @item
 GCC statement expressions (@samp{(x = (@{ int y = 4; y; @})}).
 @end itemize
@@ -153,20 +158,25 @@
 for example structs and enums; they should always be in the CamelCase
 
 There are the following conventions for naming variables and functions:
+
 @itemize @bullet
 @item
 For local variables no prefix is required.
+
 @item
 For file-scope variables and functions declared as @code{static}, no prefix
 is required.
+
 @item
 For variables and functions visible outside of file scope, but only used
 internally by a library, an @code{ff_} prefix should be used,
 e.g. @samp{ff_w64_demuxer}.
+
 @item
 For variables and functions visible outside of file scope, used internally
 across multiple libraries, use @code{avpriv_} as prefix, for example,
 @samp{avpriv_aac_parse_header}.
+
 @item
 Each library has its own prefix for public symbols, in addition to the
 commonly used @code{av_} (@code{avformat_} for libavformat,
@@ -186,10 +196,12 @@
 symbols. If in doubt, just avoid names starting with @code{_} altogether.
 
 @subsection Miscellaneous conventions
+
 @itemize @bullet
 @item
 fprintf and printf are forbidden in libavformat and libavcodec,
 please use av_log() instead.
+
 @item
 Casts should be used only when necessary. Unneeded parentheses
 should also be avoided if they don't make the code easier to understand.
@@ -232,131 +244,149 @@
 
 @enumerate
 @item
-   Contributions should be licensed under the
-   @uref{http://www.gnu.org/licenses/lgpl-2.1.html, LGPL 2.1},
-   including an "or any later version" clause, or, if you prefer
-   a gift-style license, the
-   @uref{http://www.isc.org/software/license/, ISC} or
-   @uref{http://mit-license.org/, MIT} license.
-   @uref{http://www.gnu.org/licenses/gpl-2.0.html, GPL 2} including
-   an "or any later version" clause is also acceptable, but LGPL is
-   preferred.
-@item
-   You must not commit code which breaks FFmpeg! (Meaning unfinished but
-   enabled code which breaks compilation or compiles but does not work or
-   breaks the regression tests)
-   You can commit unfinished stuff (for testing etc), but it must be disabled
-   (#ifdef etc) by default so it does not interfere with other developers'
-   work.
-@item
-   The commit message should have a short first line in the form of
-   a @samp{topic: short description} as a header, separated by a newline
-   from the body consisting of an explanation of why the change is necessary.
-   If the commit fixes a known bug on the bug tracker, the commit message
-   should include its bug ID. Referring to the issue on the bug tracker does
-   not exempt you from writing an excerpt of the bug in the commit message.
-@item
-   You do not have to over-test things. If it works for you, and you think it
-   should work for others, then commit. If your code has problems
-   (portability, triggers compiler bugs, unusual environment etc) they will be
-   reported and eventually fixed.
-@item
-   Do not commit unrelated changes together, split them into self-contained
-   pieces. Also do not forget that if part B depends on part A, but A does not
-   depend on B, then A can and should be committed first and separate from B.
-   Keeping changes well split into self-contained parts makes reviewing and
-   understanding them on the commit log mailing list easier. This also helps
-   in case of debugging later on.
-   Also if you have doubts about splitting or not splitting, do not hesitate to
-   ask/discuss it on the developer mailing list.
-@item
-   Do not change behavior of the programs (renaming options etc) or public
-   API or ABI without first discussing it on the ffmpeg-devel mailing list.
-   Do not remove functionality from the code. Just improve!
+Contributions should be licensed under the
+@uref{http://www.gnu.org/licenses/lgpl-2.1.html, LGPL 2.1},
+including an "or any later version" clause, or, if you prefer
+a gift-style license, the
+@uref{http://www.isc.org/software/license/, ISC} or
+@uref{http://mit-license.org/, MIT} license.
+@uref{http://www.gnu.org/licenses/gpl-2.0.html, GPL 2} including
+an "or any later version" clause is also acceptable, but LGPL is
+preferred.
 
-   Note: Redundant code can be removed.
 @item
-   Do not commit changes to the build system (Makefiles, configure script)
-   which change behavior, defaults etc, without asking first. The same
-   applies to compiler warning fixes, trivial looking fixes and to code
-   maintained by other developers. We usually have a reason for doing things
-   the way we do. Send your changes as patches to the ffmpeg-devel mailing
-   list, and if the code maintainers say OK, you may commit. This does not
-   apply to files you wrote and/or maintain.
-@item
-   We refuse source indentation and other cosmetic changes if they are mixed
-   with functional changes, such commits will be rejected and removed. Every
-   developer has his own indentation style, you should not change it. Of course
-   if you (re)write something, you can use your own style, even though we would
-   prefer if the indentation throughout FFmpeg was consistent (Many projects
-   force a given indentation style - we do not.). If you really need to make
-   indentation changes (try to avoid this), separate them strictly from real
-   changes.
+You must not commit code which breaks FFmpeg! (Meaning unfinished but
+enabled code which breaks compilation or compiles but does not work or
+breaks the regression tests)
+You can commit unfinished stuff (for testing etc), but it must be disabled
+(#ifdef etc) by default so it does not interfere with other developers'
+work.
 
-   NOTE: If you had to put if()@{ .. @} over a large (> 5 lines) chunk of code,
-   then either do NOT change the indentation of the inner part within (do not
-   move it to the right)! or do so in a separate commit
 @item
-   Always fill out the commit log message. Describe in a few lines what you
-   changed and why. You can refer to mailing list postings if you fix a
-   particular bug. Comments such as "fixed!" or "Changed it." are unacceptable.
-   Recommended format:
-   area changed: Short 1 line description
+The commit message should have a short first line in the form of
+a @samp{topic: short description} as a header, separated by a newline
+from the body consisting of an explanation of why the change is necessary.
+If the commit fixes a known bug on the bug tracker, the commit message
+should include its bug ID. Referring to the issue on the bug tracker does
+not exempt you from writing an excerpt of the bug in the commit message.
 
-   details describing what and why and giving references.
 @item
-   Make sure the author of the commit is set correctly. (see git commit --author)
-   If you apply a patch, send an
-   answer to ffmpeg-devel (or wherever you got the patch from) saying that
-   you applied the patch.
+You do not have to over-test things. If it works for you, and you think it
+should work for others, then commit. If your code has problems
+(portability, triggers compiler bugs, unusual environment etc) they will be
+reported and eventually fixed.
+
 @item
-   When applying patches that have been discussed (at length) on the mailing
-   list, reference the thread in the log message.
+Do not commit unrelated changes together, split them into self-contained
+pieces. Also do not forget that if part B depends on part A, but A does not
+depend on B, then A can and should be committed first and separate from B.
+Keeping changes well split into self-contained parts makes reviewing and
+understanding them on the commit log mailing list easier. This also helps
+in case of debugging later on.
+Also if you have doubts about splitting or not splitting, do not hesitate to
+ask/discuss it on the developer mailing list.
+
 @item
-    Do NOT commit to code actively maintained by others without permission.
-    Send a patch to ffmpeg-devel instead. If no one answers within a reasonable
-    timeframe (12h for build failures and security fixes, 3 days small changes,
-    1 week for big patches) then commit your patch if you think it is OK.
-    Also note, the maintainer can simply ask for more time to review!
+Do not change behavior of the programs (renaming options etc) or public
+API or ABI without first discussing it on the ffmpeg-devel mailing list.
+Do not remove functionality from the code. Just improve!
+
+Note: Redundant code can be removed.
+
 @item
-    Subscribe to the ffmpeg-cvslog mailing list. The diffs of all commits
-    are sent there and reviewed by all the other developers. Bugs and possible
-    improvements or general questions regarding commits are discussed there. We
-    expect you to react if problems with your code are uncovered.
+Do not commit changes to the build system (Makefiles, configure script)
+which change behavior, defaults etc, without asking first. The same
+applies to compiler warning fixes, trivial looking fixes and to code
+maintained by other developers. We usually have a reason for doing things
+the way we do. Send your changes as patches to the ffmpeg-devel mailing
+list, and if the code maintainers say OK, you may commit. This does not
+apply to files you wrote and/or maintain.
+
 @item
-    Update the documentation if you change behavior or add features. If you are
-    unsure how best to do this, send a patch to ffmpeg-devel, the documentation
-    maintainer(s) will review and commit your stuff.
+We refuse source indentation and other cosmetic changes if they are mixed
+with functional changes, such commits will be rejected and removed. Every
+developer has his own indentation style, you should not change it. Of course
+if you (re)write something, you can use your own style, even though we would
+prefer if the indentation throughout FFmpeg was consistent (Many projects
+force a given indentation style - we do not.). If you really need to make
+indentation changes (try to avoid this), separate them strictly from real
+changes.
+
+NOTE: If you had to put if()@{ .. @} over a large (> 5 lines) chunk of code,
+then either do NOT change the indentation of the inner part within (do not
+move it to the right)! or do so in a separate commit
+
 @item
-    Try to keep important discussions and requests (also) on the public
-    developer mailing list, so that all developers can benefit from them.
+Always fill out the commit log message. Describe in a few lines what you
+changed and why. You can refer to mailing list postings if you fix a
+particular bug. Comments such as "fixed!" or "Changed it." are unacceptable.
+Recommended format:
+area changed: Short 1 line description
+
+details describing what and why and giving references.
+
 @item
-    Never write to unallocated memory, never write over the end of arrays,
-    always check values read from some untrusted source before using them
-    as array index or other risky things.
+Make sure the author of the commit is set correctly. (see git commit --author)
+If you apply a patch, send an
+answer to ffmpeg-devel (or wherever you got the patch from) saying that
+you applied the patch.
+
 @item
-    Remember to check if you need to bump versions for the specific libav*
-    parts (libavutil, libavcodec, libavformat) you are changing. You need
-    to change the version integer.
-    Incrementing the first component means no backward compatibility to
-    previous versions (e.g. removal of a function from the public API).
-    Incrementing the second component means backward compatible change
-    (e.g. addition of a function to the public API or extension of an
-    existing data structure).
-    Incrementing the third component means a noteworthy binary compatible
-    change (e.g. encoder bug fix that matters for the decoder). The third
-    component always starts at 100 to distinguish FFmpeg from Libav.
+When applying patches that have been discussed (at length) on the mailing
+list, reference the thread in the log message.
+
 @item
-    Compiler warnings indicate potential bugs or code with bad style. If a type of
-    warning always points to correct and clean code, that warning should
-    be disabled, not the code changed.
-    Thus the remaining warnings can either be bugs or correct code.
-    If it is a bug, the bug has to be fixed. If it is not, the code should
-    be changed to not generate a warning unless that causes a slowdown
-    or obfuscates the code.
+Do NOT commit to code actively maintained by others without permission.
+Send a patch to ffmpeg-devel instead. If no one answers within a reasonable
+timeframe (12h for build failures and security fixes, 3 days small changes,
+1 week for big patches) then commit your patch if you think it is OK.
+Also note, the maintainer can simply ask for more time to review!
+
 @item
-    If you add a new file, give it a proper license header. Do not copy and
-    paste it from a random place, use an existing file as template.
+Subscribe to the ffmpeg-cvslog mailing list. The diffs of all commits
+are sent there and reviewed by all the other developers. Bugs and possible
+improvements or general questions regarding commits are discussed there. We
+expect you to react if problems with your code are uncovered.
+
+@item
+Update the documentation if you change behavior or add features. If you are
+unsure how best to do this, send a patch to ffmpeg-devel, the documentation
+maintainer(s) will review and commit your stuff.
+
+@item
+Try to keep important discussions and requests (also) on the public
+developer mailing list, so that all developers can benefit from them.
+
+@item
+Never write to unallocated memory, never write over the end of arrays,
+always check values read from some untrusted source before using them
+as array index or other risky things.
+
+@item
+Remember to check if you need to bump versions for the specific libav*
+parts (libavutil, libavcodec, libavformat) you are changing. You need
+to change the version integer.
+Incrementing the first component means no backward compatibility to
+previous versions (e.g. removal of a function from the public API).
+Incrementing the second component means backward compatible change
+(e.g. addition of a function to the public API or extension of an
+existing data structure).
+Incrementing the third component means a noteworthy binary compatible
+change (e.g. encoder bug fix that matters for the decoder). The third
+component always starts at 100 to distinguish FFmpeg from Libav.
+
+@item
+Compiler warnings indicate potential bugs or code with bad style. If a type of
+warning always points to correct and clean code, that warning should
+be disabled, not the code changed.
+Thus the remaining warnings can either be bugs or correct code.
+If it is a bug, the bug has to be fixed. If it is not, the code should
+be changed to not generate a warning unless that causes a slowdown
+or obfuscates the code.
+
+@item
+If you add a new file, give it a proper license header. Do not copy and
+paste it from a random place, use an existing file as template.
 @end enumerate
 
 We think our rules are not too hard. If you have comments, contact us.
@@ -411,40 +441,51 @@
 
 @enumerate
 @item
-    Did you use av_cold for codec initialization and close functions?
+Did you use av_cold for codec initialization and close functions?
+
 @item
-    Did you add a long_name under NULL_IF_CONFIG_SMALL to the AVCodec or
-    AVInputFormat/AVOutputFormat struct?
+Did you add a long_name under NULL_IF_CONFIG_SMALL to the AVCodec or
+AVInputFormat/AVOutputFormat struct?
+
 @item
-    Did you bump the minor version number (and reset the micro version
-    number) in @file{libavcodec/version.h} or @file{libavformat/version.h}?
+Did you bump the minor version number (and reset the micro version
+number) in @file{libavcodec/version.h} or @file{libavformat/version.h}?
+
 @item
-    Did you register it in @file{allcodecs.c} or @file{allformats.c}?
+Did you register it in @file{allcodecs.c} or @file{allformats.c}?
+
 @item
-    Did you add the AVCodecID to @file{avcodec.h}?
-    When adding new codec IDs, also add an entry to the codec descriptor
-    list in @file{libavcodec/codec_desc.c}.
+Did you add the AVCodecID to @file{avcodec.h}?
+When adding new codec IDs, also add an entry to the codec descriptor
+list in @file{libavcodec/codec_desc.c}.
+
 @item
-    If it has a FourCC, did you add it to @file{libavformat/riff.c},
-    even if it is only a decoder?
+If it has a FourCC, did you add it to @file{libavformat/riff.c},
+even if it is only a decoder?
+
 @item
-    Did you add a rule to compile the appropriate files in the Makefile?
-    Remember to do this even if you're just adding a format to a file that is
-    already being compiled by some other rule, like a raw demuxer.
+Did you add a rule to compile the appropriate files in the Makefile?
+Remember to do this even if you're just adding a format to a file that is
+already being compiled by some other rule, like a raw demuxer.
+
 @item
-    Did you add an entry to the table of supported formats or codecs in
-    @file{doc/general.texi}?
+Did you add an entry to the table of supported formats or codecs in
+@file{doc/general.texi}?
+
 @item
-    Did you add an entry in the Changelog?
+Did you add an entry in the Changelog?
+
 @item
-    If it depends on a parser or a library, did you add that dependency in
-    configure?
+If it depends on a parser or a library, did you add that dependency in
+configure?
+
 @item
-    Did you @code{git add} the appropriate files before committing?
+Did you @code{git add} the appropriate files before committing?
+
 @item
-    Did you make sure it compiles standalone, i.e. with
-    @code{configure --disable-everything --enable-decoder=foo}
-    (or @code{--enable-demuxer} or whatever your component is)?
+Did you make sure it compiles standalone, i.e. with
+@code{configure --disable-everything --enable-decoder=foo}
+(or @code{--enable-demuxer} or whatever your component is)?
 @end enumerate
 
 
@@ -452,82 +493,109 @@
 
 @enumerate
 @item
-    Does @code{make fate} pass with the patch applied?
+Does @code{make fate} pass with the patch applied?
+
 @item
-    Was the patch generated with git format-patch or send-email?
+Was the patch generated with git format-patch or send-email?
+
 @item
-    Did you sign off your patch? (git commit -s)
-    See @url{http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob_plain;f=Documentation/SubmittingPatches} for the meaning
-    of sign off.
+Did you sign off your patch? (git commit -s)
+See @url{http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob_plain;f=Documentation/SubmittingPatches} for the meaning
+of sign off.
+
 @item
-    Did you provide a clear git commit log message?
+Did you provide a clear git commit log message?
+
 @item
-    Is the patch against latest FFmpeg git master branch?
+Is the patch against latest FFmpeg git master branch?
+
 @item
-    Are you subscribed to ffmpeg-devel?
-    (the list is subscribers only due to spam)
+Are you subscribed to ffmpeg-devel?
+(the list is subscribers only due to spam)
+
 @item
-    Have you checked that the changes are minimal, so that the same cannot be
-    achieved with a smaller patch and/or simpler final code?
+Have you checked that the changes are minimal, so that the same cannot be
+achieved with a smaller patch and/or simpler final code?
+
 @item
-    If the change is to speed critical code, did you benchmark it?
+If the change is to speed critical code, did you benchmark it?
+
 @item
-    If you did any benchmarks, did you provide them in the mail?
+If you did any benchmarks, did you provide them in the mail?
+
 @item
-    Have you checked that the patch does not introduce buffer overflows or
-    other security issues?
+Have you checked that the patch does not introduce buffer overflows or
+other security issues?
+
 @item
-    Did you test your decoder or demuxer against damaged data? If no, see
-    tools/trasher, the noise bitstream filter, and
-    @uref{http://caca.zoy.org/wiki/zzuf, zzuf}. Your decoder or demuxer
-    should not crash, end in a (near) infinite loop, or allocate ridiculous
-    amounts of memory when fed damaged data.
+Did you test your decoder or demuxer against damaged data? If no, see
+tools/trasher, the noise bitstream filter, and
+@uref{http://caca.zoy.org/wiki/zzuf, zzuf}. Your decoder or demuxer
+should not crash, end in a (near) infinite loop, or allocate ridiculous
+amounts of memory when fed damaged data.
+
 @item
-    Does the patch not mix functional and cosmetic changes?
+Does the patch not mix functional and cosmetic changes?
+
 @item
-    Did you add tabs or trailing whitespace to the code? Both are forbidden.
+Did you add tabs or trailing whitespace to the code? Both are forbidden.
+
 @item
-    Is the patch attached to the email you send?
+Is the patch attached to the email you send?
+
 @item
-    Is the mime type of the patch correct? It should be text/x-diff or
-    text/x-patch or at least text/plain and not application/octet-stream.
+Is the mime type of the patch correct? It should be text/x-diff or
+text/x-patch or at least text/plain and not application/octet-stream.
+
 @item
-    If the patch fixes a bug, did you provide a verbose analysis of the bug?
+If the patch fixes a bug, did you provide a verbose analysis of the bug?
+
 @item
-    If the patch fixes a bug, did you provide enough information, including
-    a sample, so the bug can be reproduced and the fix can be verified?
-    Note please do not attach samples >100k to mails but rather provide a
-    URL, you can upload to ftp://upload.ffmpeg.org
+If the patch fixes a bug, did you provide enough information, including
+a sample, so the bug can be reproduced and the fix can be verified?
+Note please do not attach samples >100k to mails but rather provide a
+URL, you can upload to ftp://upload.ffmpeg.org
+
 @item
-    Did you provide a verbose summary about what the patch does change?
+Did you provide a verbose summary about what the patch does change?
+
 @item
-    Did you provide a verbose explanation why it changes things like it does?
+Did you provide a verbose explanation why it changes things like it does?
+
 @item
-    Did you provide a verbose summary of the user visible advantages and
-    disadvantages if the patch is applied?
+Did you provide a verbose summary of the user visible advantages and
+disadvantages if the patch is applied?
+
 @item
-    Did you provide an example so we can verify the new feature added by the
-    patch easily?
+Did you provide an example so we can verify the new feature added by the
+patch easily?
+
 @item
-    If you added a new file, did you insert a license header? It should be
-    taken from FFmpeg, not randomly copied and pasted from somewhere else.
+If you added a new file, did you insert a license header? It should be
+taken from FFmpeg, not randomly copied and pasted from somewhere else.
+
 @item
-    You should maintain alphabetical order in alphabetically ordered lists as
-    long as doing so does not break API/ABI compatibility.
+You should maintain alphabetical order in alphabetically ordered lists as
+long as doing so does not break API/ABI compatibility.
+
 @item
-    Lines with similar content should be aligned vertically when doing so
-    improves readability.
+Lines with similar content should be aligned vertically when doing so
+improves readability.
+
 @item
-    Consider to add a regression test for your code.
+Consider to add a regression test for your code.
+
 @item
-    If you added YASM code please check that things still work with --disable-yasm
+If you added YASM code please check that things still work with --disable-yasm
+
 @item
-    Make sure you check the return values of function and return appropriate
-    error codes. Especially memory allocation functions like @code{av_malloc()}
-    are notoriously left unchecked, which is a serious problem.
+Make sure you check the return values of function and return appropriate
+error codes. Especially memory allocation functions like @code{av_malloc()}
+are notoriously left unchecked, which is a serious problem.
+
 @item
-    Test your code with valgrind and or Address Sanitizer to ensure it's free
-    of leaks, out of array accesses, etc.
+Test your code with valgrind and or Address Sanitizer to ensure it's free
+of leaks, out of array accesses, etc.
 @end enumerate
 
 @section Patch review process
@@ -590,12 +658,15 @@
 @item
     Configure to compile with instrumentation enabled:
     @code{configure --toolchain=gcov}.
+
 @item
     Run your test case, either manually or via FATE. This can be either
     the full FATE regression suite, or any arbitrary invocation of any
     front-end tool provided by FFmpeg, in any combination.
+
 @item
     Run @code{make lcov} to generate coverage data in HTML format.
+
 @item
     View @code{lcov/index.html} in your preferred HTML viewer.
 @end enumerate
@@ -604,6 +675,19 @@
 measurements. You will need to rerun @code{make lcov} after running a
 new test.
 
+@subsection Using Valgrind
+
+The configure script provides a shortcut for using valgrind to spot bugs
+related to memory handling. Just add the option
+@code{--toolchain=valgrind-memcheck} or @code{--toolchain=valgrind-massif}
+to your configure line, and reasonable defaults will be set for running
+FATE under the supervision of either the @strong{memcheck} or the
+@strong{massif} tool of the valgrind suite.
+
+In case you need finer control over how valgrind is invoked, use the
+@code{--target-exec='valgrind <your_custom_valgrind_options>} option in
+your configure line instead.
+
 @anchor{Release process}
 @section Release process
 
@@ -617,12 +701,13 @@
 
 @enumerate
 @item
-    @strong{Major releases} always include the latest and greatest
-    features and functionality.
+@strong{Major releases} always include the latest and greatest
+features and functionality.
+
 @item
-    @strong{Point releases} are cut from @strong{release} branches,
-    which are named @code{release/X}, with @code{X} being the release
-    version number.
+@strong{Point releases} are cut from @strong{release} branches,
+which are named @code{release/X}, with @code{X} being the release
+version number.
 @end enumerate
 
 Note that we promise to our users that shared libraries from any FFmpeg
@@ -643,15 +728,18 @@
 
 @enumerate
 @item
-    Fixes a security issue, preferably identified by a @strong{CVE
-    number} issued by @url{http://cve.mitre.org/}.
+Fixes a security issue, preferably identified by a @strong{CVE
+number} issued by @url{http://cve.mitre.org/}.
+
 @item
-    Fixes a documented bug in @url{https://ffmpeg.org/trac/ffmpeg}.
+Fixes a documented bug in @url{https://trac.ffmpeg.org}.
+
 @item
-    Improves the included documentation.
+Improves the included documentation.
+
 @item
-    Retains both source code and binary compatibility with previous
-    point releases of the same release branch.
+Retains both source code and binary compatibility with previous
+point releases of the same release branch.
 @end enumerate
 
 The order for checking the rules is (1 OR 2 OR 3) AND 4.
@@ -663,33 +751,42 @@
 
 @enumerate
 @item
-    Ensure that the @file{RELEASE} file contains the version number for
-    the upcoming release.
+Ensure that the @file{RELEASE} file contains the version number for
+the upcoming release.
+
 @item
-    Add the release at @url{https://ffmpeg.org/trac/ffmpeg/admin/ticket/versions}.
+Add the release at @url{https://trac.ffmpeg.org/admin/ticket/versions}.
+
 @item
-    Announce the intent to do a release to the mailing list.
+Announce the intent to do a release to the mailing list.
+
 @item
-    Make sure all relevant security fixes have been backported. See
-    @url{https://ffmpeg.org/security.html}.
+Make sure all relevant security fixes have been backported. See
+@url{https://ffmpeg.org/security.html}.
+
 @item
-    Ensure that the FATE regression suite still passes in the release
-    branch on at least @strong{i386} and @strong{amd64}
-    (cf. @ref{Regression tests}).
+Ensure that the FATE regression suite still passes in the release
+branch on at least @strong{i386} and @strong{amd64}
+(cf. @ref{Regression tests}).
+
 @item
-    Prepare the release tarballs in @code{bz2} and @code{gz} formats, and
-    supplementing files that contain @code{gpg} signatures
+Prepare the release tarballs in @code{bz2} and @code{gz} formats, and
+supplementing files that contain @code{gpg} signatures
+
 @item
-    Publish the tarballs at @url{http://ffmpeg.org/releases}. Create and
-    push an annotated tag in the form @code{nX}, with @code{X}
-    containing the version number.
+Publish the tarballs at @url{http://ffmpeg.org/releases}. Create and
+push an annotated tag in the form @code{nX}, with @code{X}
+containing the version number.
+
 @item
-    Propose and send a patch to the @strong{ffmpeg-devel} mailing list
-    with a news entry for the website.
+Propose and send a patch to the @strong{ffmpeg-devel} mailing list
+with a news entry for the website.
+
 @item
-    Publish the news entry.
+Publish the news entry.
+
 @item
-    Send announcement to the mailing list.
+Send announcement to the mailing list.
 @end enumerate
 
 @bye
diff --git a/doc/encoders.texi b/doc/encoders.texi
index ab88b6c..585eae6 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -412,6 +412,296 @@
 
 @end table
 
+@section libmp3lame
+
+LAME (Lame Ain't an MP3 Encoder) MP3 encoder wrapper.
+
+Requires the presence of the libmp3lame headers and library during
+configuration. You need to explicitly configure the build with
+@code{--enable-libmp3lame}.
+
+@subsection Option Mapping
+
+The following options are supported by the libmp3lame wrapper,
+the LAME-equivalent options follow the FFmpeg ones.
+
+@multitable @columnfractions .2 .2
+@item FFmpeg            @tab LAME
+@item b                 @tab b
+Set bitrate expressed in bits/s, LAME @code{bitrate} is expressed in
+kilobits/s.
+@item q                 @tab V
+Set quality setting for VBR.
+@item compression_level @tab q
+Set algorithm quality. Valid arguments are integers in the 0-9 range.
+@item reservoir         @tab N.A.
+Enable use of bit reservoir. LAME has this enabled by default.
+@item joint_stereo      @tab -m j
+Enable the encoder to use (on a frame by frame basis) either L/R
+stereo or mid/side stereo.
+@end multitable
+
+@section libopencore-amrnb
+
+OpenCORE Adaptive Multi-Rate Narrowband encoder.
+
+Requires the presence of the libopencore-amrnb headers and library during
+configuration. You need to explicitly configure the build with
+@code{--enable-libopencore-amrnb --enable-version3}.
+
+This is a mono-only encoder. Officially it only supports 8000Hz sample rate,
+but you can override it by setting @option{strict} to @samp{unofficial} or
+lower.
+
+@subsection Options
+
+@table @option
+
+@item b
+Set bitrate in bits per second. Only the following bitrates are supported,
+otherwise libavcodec will round to the nearest valid bitrate.
+
+@table @option
+@item 4750
+@item 5150
+@item 5900
+@item 6700
+@item 7400
+@item 7950
+@item 10200
+@item 12200
+@end table
+
+@item dtx
+Allow discontinuous transmission (generate comfort noise) when set to 1. The
+default value is 0 (disabled).
+
+@end table
+
+@section libtwolame
+
+TwoLAME MP2 encoder wrapper.
+
+Requires the presence of the libtwolame headers and library during
+configuration. You need to explicitly configure the build with
+@code{--enable-libtwolame}.
+
+@subsection Options Mapping
+
+The following options are supported by the libtwolame wrapper. The
+TwoLAME-equivalent options follow the FFmpeg ones and are in
+parentheses.
+
+@table @option
+@item b
+(b) Set bitrate in bits/s. Note that FFmpeg @code{b} option is
+expressed in bits/s, twolame @code{b} in kilobits/s. The default
+value is 128k.
+
+@item q
+(V) Set quality for experimental VBR support. Maximum value range is
+from -50 to 50, useful range is from -10 to 10.
+
+@item mode
+(mode) Set MPEG mode. Possible values:
+
+@table @samp
+@item auto
+Choose mode automatically based on the input. This is the default.
+@item stereo
+Stereo
+@item joint_stereo
+Joint stereo
+@item dual_channel
+Dual channel
+@item mono
+Mono
+@end table
+
+@item psymodel
+(psyc-mode) Set psychoacoustic model to use in encoding. The argument
+must be an integer between -1 and 4, inclusive. The higher the value,
+the better the quality. The default value is 3.
+
+@item energy_levels
+(energy) Enable energy levels extensions when set to 1. The default
+value is 0 (disabled).
+
+@item error_protection
+(protect) Enable CRC error protection when set to 1. The default value
+is 0 (disabled).
+
+@item copyright
+(copyright) Set MPEG audio copyright flag when set to 1. The default
+value is 0 (disabled).
+
+@item original
+(original) Set MPEG audio original flag when set to 1. The default
+value is 0 (disabled).
+
+@end table
+
+@section libvo-aacenc
+
+VisualOn AAC encoder.
+
+Requires the presence of the libvo-aacenc headers and library during
+configuration. You need to explicitly configure the build with
+@code{--enable-libvo-aacenc --enable-version3}.
+
+@subsection Options
+
+The VisualOn AAC encoder only support encoding AAC-LC and up to 2
+channels. It is also CBR-only. It is considered to be worse than the
+native experimental FFmpeg AAC encoder.
+
+@table @option
+
+@item b
+Bitrate.
+
+@end table
+
+@section libvo-amrwbenc
+
+VisualOn Adaptive Multi-Rate Wideband encoder.
+
+Requires the presence of the libvo-amrwbenc headers and library during
+configuration. You need to explicitly configure the build with
+@code{--enable-libvo-amrwbenc --enable-version3}.
+
+This is a mono-only encoder. Officially it only supports 16000Hz sample
+rate, but you can override it by setting @option{strict} to
+@samp{unofficial} or lower.
+
+@subsection Options
+
+@table @option
+
+@item b
+Set bitrate in bits/s. Only the following bitrates are supported, otherwise
+libavcodec will round to the nearest valid bitrate.
+
+@table @samp
+@item 6600
+@item 8850
+@item 12650
+@item 14250
+@item 15850
+@item 18250
+@item 19850
+@item 23050
+@item 23850
+@end table
+
+@item dtx
+Allow discontinuous transmission (generate comfort noise) when set to 1. The
+default value is 0 (disabled).
+
+@end table
+
+@section libopus
+
+libopus Opus Interactive Audio Codec encoder wrapper.
+
+Requires the presence of the libopus headers and library during
+configuration. You need to explicitly configure the build with
+@code{--enable-libopus}.
+
+@subsection Option Mapping
+
+Most libopus options are modeled after the @command{opusenc} utility from
+opus-tools. The following is an option mapping chart describing options
+supported by the libopus wrapper, and their @command{opusenc}-equivalent
+in parentheses.
+
+@table @option
+
+@item b (@emph{bitrate})
+Set the bit rate in bits/s.  FFmpeg's @option{b} option is
+expressed in bits/s, while @command{opusenc}'s @option{bitrate} in
+kilobits/s.
+
+@item vbr (@emph{vbr}, @emph{hard-cbr}, and @emph{cvbr})
+Set VBR mode. The FFmpeg @option{vbr} option has the following
+valid arguments, with the their @command{opusenc} equivalent options
+in parentheses:
+
+@table @samp
+@item off (@emph{hard-cbr})
+Use constant bit rate encoding.
+
+@item on (@emph{vbr})
+Use variable bit rate encoding (the default).
+
+@item constrained (@emph{cvbr})
+Use constrained variable bit rate encoding.
+@end table
+
+@item compression_level (@emph{comp})
+Set encoding algorithm complexity. Valid options are integers in
+the 0-10 range. 0 gives the fastest encodes but lower quality, while 10
+gives the highest quality but slowest encoding. The default is 10.
+
+@item frame_duration (@emph{framesize})
+Set maximum frame size, or duration of a frame in milliseconds. The
+argument must be exactly the following: 2.5, 5, 10, 20, 40, 60. Smaller
+frame sizes achieve lower latency but less quality at a given bitrate.
+Sizes greater than 20ms are only interesting at fairly low bitrates.
+The default of FFmpeg is 10ms, but is 20ms in @command{opusenc}.
+
+@item packet_loss (@emph{expect-loss})
+Set expected packet loss percentage. The default is 0.
+
+@item application (N.A.)
+Set intended application type. Valid options are listed below:
+
+@table @samp
+@item voip
+Favor improved speech intelligibility.
+@item audio
+Favor faithfulness to the input (the default).
+@item lowdelay
+Restrict to only the lowest delay modes.
+@end table
+
+@item cutoff (N.A.)
+Set cutoff bandwidth in Hz. The argument must be exactly one of the
+following: 4000, 6000, 8000, 12000, or 20000, corresponding to
+narrowband, mediumband, wideband, super wideband, and fullband
+respectively. The default is 0 (cutoff disabled).
+
+@end table
+
+@section libwavpack
+
+A wrapper providing WavPack encoding through libwavpack.
+
+Only lossless mode using 32-bit integer samples is supported currently.
+The @option{compression_level} option can be used to control speed vs.
+compression tradeoff, with the values mapped to libwavpack as follows:
+
+@table @option
+
+@item 0
+Fast mode - corresponding to the wavpack @option{-f} option.
+
+@item 1
+Normal (default) settings.
+
+@item 2
+High quality - corresponding to the wavpack @option{-h} option.
+
+@item 3
+Very high quality - corresponding to the wavpack @option{-hh} option.
+
+@item 4-8
+Same as 3, but with extra processing enabled - corresponding to the wavpack
+@option{-x} option. I.e. 4 is the same as @option{-x2} and 8 is the same as
+@option{-x6}.
+
+@end table
+
 @c man end AUDIO ENCODERS
 
 @chapter Video Encoders
@@ -581,180 +871,324 @@
 
 @section libx264
 
-x264 H.264/MPEG-4 AVC encoder wrapper
+x264 H.264/MPEG-4 AVC encoder wrapper.
 
-Requires the presence of the libx264 headers and library during
-configuration. You need to explicitly configure the build with
+This encoder requires the presence of the libx264 headers and library
+during configuration. You need to explicitly configure the build with
 @code{--enable-libx264}.
 
-x264 supports an impressive number of features, including 8x8 and 4x4 adaptive
-spatial transform, adaptive B-frame placement, CAVLC/CABAC entropy coding,
-interlacing (MBAFF), lossless mode, psy optimizations for detail retention
-(adaptive quantization, psy-RD, psy-trellis).
+libx264 supports an impressive number of features, including 8x8 and
+4x4 adaptive spatial transform, adaptive B-frame placement, CAVLC/CABAC
+entropy coding, interlacing (MBAFF), lossless mode, psy optimizations
+for detail retention (adaptive quantization, psy-RD, psy-trellis).
 
-The FFmpeg wrapper provides a mapping for most of them using global options
-that match those of the encoders and provides private options for the unique
-encoder options. Additionally an expert override is provided to directly pass
-a list of key=value tuples as accepted by x264_param_parse.
+Many libx264 encoder options are mapped to FFmpeg global codec
+options, while unique encoder options are provided through private
+options. Additionally the @option{x264opts} and @option{x264-params}
+private options allows to pass a list of key=value tuples as accepted
+by the libx264 @code{x264_param_parse} function.
 
-@subsection Option Mapping
+The x264 project website is at
+@url{http://www.videolan.org/developers/x264.html}.
 
-The following options are supported by the x264 wrapper, the x264-equivalent
-options follow the FFmpeg ones.
+@subsection Options
 
-@multitable @columnfractions .2 .2
-@item b                 @tab bitrate
-FFmpeg @code{b} option is expressed in bits/s, x264 @code{bitrate} in kilobits/s.
-@item bf                @tab bframes
-Maximum number of B-frames.
-@item g                 @tab keyint
-Maximum GOP size.
-@item qmin              @tab qpmin
-@item qmax              @tab qpmax
-@item qdiff             @tab qpstep
-@item qblur             @tab qblur
-@item qcomp             @tab qcomp
-@item refs              @tab ref
-@item sc_threshold      @tab scenecut
-@item trellis           @tab trellis
-@item nr                @tab nr
-Noise reduction.
-@item me_range          @tab merange
-@item me_method         @tab me
-@item subq              @tab subme
-@item b_strategy        @tab b-adapt
-@item keyint_min        @tab keyint-min
-@item coder             @tab cabac
-Set coder to @code{ac} to use CABAC.
-@item cmp               @tab chroma-me
-Set to @code{chroma} to use chroma motion estimation.
-@item threads           @tab threads
-@item thread_type       @tab sliced_threads
-Set to @code{slice} to use sliced threading instead of frame threading.
-@item flags -cgop       @tab open-gop
-Set @code{-cgop} to use recovery points to close GOPs.
-@item rc_init_occupancy @tab vbv-init
-Initial buffer occupancy.
-@end multitable
+The following options are supported by the libx264 wrapper. The
+@command{x264}-equivalent options or values are listed in parentheses
+for easy migration.
 
-@subsection Private Options
+To reduce the duplication of documentation, only the private options
+and some others requiring special attention are documented here. For
+the documentation of the undocumented generic options, see
+@ref{codec-options,,the Codec Options chapter}.
+
+To get a more accurate and extensive documentation of the libx264
+options, invoke the command @command{x264 --full-help} or consult
+the libx264 documentation.
+
 @table @option
-@item -preset @var{string}
-Set the encoding preset (cf. x264 --fullhelp).
-@item -tune @var{string}
-Tune the encoding params (cf. x264 --fullhelp).
-@item -profile @var{string}
-Set profile restrictions (cf. x264 --fullhelp).
-@item -fastfirstpass @var{integer}
-Use fast settings when encoding first pass.
-@item -crf @var{float}
-Select the quality for constant quality mode.
-@item -crf_max @var{float}
-In CRF mode, prevents VBV from lowering quality beyond this point.
-@item -qp @var{integer}
-Constant quantization parameter rate control method.
-@item -aq-mode @var{integer}
-AQ method
+@item b (@emph{bitrate})
+Set bitrate in bits/s. Note that FFmpeg's @option{b} option is
+expressed in bits/s, while @command{x264}'s @option{bitrate} is in
+kilobits/s.
 
-Possible values:
+@item bf (@emph{bframes})
+
+@item g (@emph{keyint})
+
+@item qmax (@emph{qpmax})
+
+@item qmin (@emph{qpmin})
+
+@item qdiff (@emph{qpstep})
+
+@item qblur (@emph{qblur})
+
+@item qcomp (@emph{qcomp})
+
+@item refs (@emph{ref})
+
+@item sc_threshold (@emph{scenecut})
+
+@item trellis (@emph{trellis})
+
+@item nr  (@emph{nr})
+
+@item me_range (@emph{merange})
+
+@item me_method (@emph{me})
+Set motion estimation method. Possible values in the decreasing order
+of speed:
+
 @table @samp
-@item none
+@item dia (@emph{dia})
+@item epzs (@emph{dia})
+Diamond search with radius 1 (fastest). @samp{epzs} is an alias for
+@samp{dia}.
+@item hex (@emph{hex})
+Hexagonal search with radius 2.
+@item umh (@emph{umh})
+Uneven multi-hexagon search.
+@item esa (@emph{esa})
+Exhaustive search.
+@item tesa (@emph{tesa})
+Hadamard exhaustive search (slowest).
+@end table
 
-@item variance
+@item subq (@emph{subme})
+
+@item b_strategy (@emph{b-adapt})
+
+@item keyint_min (@emph{min-keyint})
+
+@item coder
+Set entropy encoder. Possible values:
+
+@table @samp
+@item ac
+Enable CABAC.
+
+@item vlc
+Enable CAVLC and disable CABAC. It generates the same effect as
+@command{x264}'s @option{--no-cabac} option.
+@end table
+
+@item cmp
+Set full pixel motion estimation comparation algorithm. Possible values:
+
+@table @samp
+@item chroma
+Enable chroma in motion estimation.
+
+@item sad
+Ignore chroma in motion estimation. It generates the same effect as
+@command{x264}'s @option{--no-chroma-me} option.
+@end table
+
+@item threads (@emph{threads})
+
+@item thread_type
+Set multithreading technique. Possible values:
+
+@table @samp
+@item slice
+Slice-based multithreading. It generates the same effect as
+@command{x264}'s @option{--sliced-threads} option.
+@item frame
+Frame-based multithreading.
+@end table
+
+@item flags
+Set encoding flags. It can be used to disable closed GOP and enable
+open GOP by setting it to @code{-cgop}. The result is similar to
+the behavior of @command{x264}'s @option{--open-gop} option.
+
+@item rc_init_occupancy (@emph{vbv-init})
+
+@item preset (@emph{preset})
+Set the encoding preset.
+
+@item tune (@emph{tune})
+Set tuning of the encoding params.
+
+@item profile (@emph{profile})
+Set profile restrictions.
+
+@item fastfirstpass
+Enable fast settings when encoding first pass, when set to 1. When set
+to 0, it has the same effect of @command{x264}'s
+@option{--slow-firstpass} option.
+
+@item crf (@emph{crf})
+Set the quality for constant quality mode.
+
+@item crf_max (@emph{crf-max})
+In CRF mode, prevents VBV from lowering quality beyond this point.
+
+@item qp (@emph{qp})
+Set constant quantization rate control method parameter.
+
+@item aq-mode (@emph{aq-mode})
+Set AQ method. Possible values:
+
+@table @samp
+@item none (@emph{0})
+Disabled.
+
+@item variance (@emph{1})
 Variance AQ (complexity mask).
-@item autovariance
+
+@item autovariance (@emph{2})
 Auto-variance AQ (experimental).
 @end table
-@item -aq-strength @var{float}
-AQ strength, reduces blocking and blurring in flat and textured areas.
-@item -psy @var{integer}
-Use psychovisual optimizations.
-@item -psy-rd @var{string}
-Strength of psychovisual optimization, in <psy-rd>:<psy-trellis> format.
-@item -rc-lookahead @var{integer}
-Number of frames to look ahead for frametype and ratecontrol.
-@item -weightb @var{integer}
-Weighted prediction for B-frames.
-@item -weightp @var{integer}
-Weighted prediction analysis method.
 
-Possible values:
+@item aq-strength (@emph{aq-strength})
+Set AQ strength, reduce blocking and blurring in flat and textured areas.
+
+@item psy
+Use psychovisual optimizations when set to 1. When set to 0, it has the
+same effect as @command{x264}'s @option{--no-psy} option.
+
+@item psy-rd  (@emph{psy-rd})
+Set strength of psychovisual optimization, in
+@var{psy-rd}:@var{psy-trellis} format.
+
+@item rc-lookahead (@emph{rc-lookahead})
+Set number of frames to look ahead for frametype and ratecontrol.
+
+@item weightb
+Enable weighted prediction for B-frames when set to 1. When set to 0,
+it has the same effect as @command{x264}'s @option{--no-weightb} option.
+
+@item weightp (@emph{weightp})
+Set weighted prediction method for P-frames. Possible values:
+
 @table @samp
-@item none
-
-@item simple
-
-@item smart
-
+@item none (@emph{0})
+Disabled
+@item simple (@emph{1})
+Enable only weighted refs
+@item smart (@emph{2})
+Enable both weighted refs and duplicates
 @end table
-@item -ssim @var{integer}
-Calculate and print SSIM stats.
-@item -intra-refresh @var{integer}
-Use Periodic Intra Refresh instead of IDR frames.
-@item -b-bias @var{integer}
-Influences how often B-frames are used.
-@item -b-pyramid @var{integer}
-Keep some B-frames as references.
 
-Possible values:
+@item ssim (@emph{ssim})
+Enable calculation and printing SSIM stats after the encoding.
+
+@item intra-refresh (@emph{intra-refresh})
+Enable the use of Periodic Intra Refresh instead of IDR frames when set
+to 1.
+
+@item bluray-compat (@emph{bluray-compat})
+Configure the encoder to be compatible with the bluray standard.
+It is a shorthand for setting "bluray-compat=1 force-cfr=1".
+
+@item b-bias (@emph{b-bias})
+Set the influence on how often B-frames are used.
+
+@item b-pyramid (@emph{b-pyramid})
+Set method for keeping of some B-frames as references. Possible values:
+
 @table @samp
-@item none
-
-@item strict
+@item none (@emph{none})
+Disabled.
+@item strict (@emph{strict})
 Strictly hierarchical pyramid.
-@item normal
+@item normal (@emph{normal})
 Non-strict (not Blu-ray compatible).
 @end table
-@item -mixed-refs @var{integer}
-One reference per partition, as opposed to one reference per macroblock.
-@item -8x8dct @var{integer}
-High profile 8x8 transform.
-@item -fast-pskip @var{integer}
-@item -aud @var{integer}
-Use access unit delimiters.
-@item -mbtree @var{integer}
-Use macroblock tree ratecontrol.
-@item -deblock @var{string}
-Loop filter parameters, in <alpha:beta> form.
-@item -cplxblur @var{float}
-Reduce fluctuations in QP (before curve compression).
-@item -partitions @var{string}
-A comma-separated list of partitions to consider, possible values: p8x8, p4x4, b8x8, i8x8, i4x4, none, all.
-@item -direct-pred @var{integer}
-Direct MV prediction mode
 
-Possible values:
+@item mixed-refs
+Enable the use of one reference per partition, as opposed to one
+reference per macroblock when set to 1. When set to 0, it has the
+same effect as @command{x264}'s @option{--no-mixed-refs} option.
+
+@item 8x8dct
+Enable adaptive spatial transform (high profile 8x8 transform)
+when set to 1. When set to 0, it has the same effect as
+@command{x264}'s @option{--no-8x8dct} option.
+
+@item fast-pskip
+Enable early SKIP detection on P-frames when set to 1. When set
+to 0, it has the same effect as @command{x264}'s
+@option{--no-fast-pskip} option.
+
+@item aud (@emph{aud})
+Enable use of access unit delimiters when set to 1.
+
+@item mbtree
+Enable use macroblock tree ratecontrol when set to 1. When set
+to 0, it has the same effect as @command{x264}'s
+@option{--no-mbtree} option.
+
+@item deblock (@emph{deblock})
+Set loop filter parameters, in @var{alpha}:@var{beta} form.
+
+@item cplxblur (@emph{cplxblur})
+Set fluctuations reduction in QP (before curve compression).
+
+@item partitions (@emph{partitions})
+Set partitions to consider as a comma-separated list of. Possible
+values in the list:
+
 @table @samp
-@item none
-
-@item spatial
-
-@item temporal
-
-@item auto
-
-@end table
-@item -slice-max-size @var{integer}
-Limit the size of each slice in bytes.
-@item -stats @var{string}
-Filename for 2 pass stats.
-@item -nal-hrd @var{integer}
-Signal HRD information (requires vbv-bufsize; cbr not allowed in .mp4).
-
-Possible values:
-@table @samp
-@item none
-
-@item vbr
-
-@item cbr
-
+@item p8x8
+8x8 P-frame partition.
+@item p4x4
+4x4 P-frame partition.
+@item b8x8
+4x4 B-frame partition.
+@item i8x8
+8x8 I-frame partition.
+@item i4x4
+4x4 I-frame partition.
+(Enabling @samp{p4x4} requires @samp{p8x8} to be enabled. Enabling
+@samp{i8x8} requires adaptive spatial transform (@option{8x8dct}
+option) to be enabled.)
+@item none (@emph{none})
+Do not consider any partitions.
+@item all (@emph{all})
+Consider every partition.
 @end table
 
-@item x264opts @var{options}
-Allow to set any x264 option, see @code{x264 --fullhelp} for a list.
+@item direct-pred (@emph{direct})
+Set direct MV prediction mode. Possible values:
 
-@var{options} is a list of @var{key}=@var{value} couples separated by
+@table @samp
+@item none (@emph{none})
+Disable MV prediction.
+@item spatial (@emph{spatial})
+Enable spatial predicting.
+@item temporal (@emph{temporal})
+Enable temporal predicting.
+@item auto (@emph{auto})
+Automatically decided.
+@end table
+
+@item slice-max-size (@emph{slice-max-size})
+Set the limit of the size of each slice in bytes. If not specified
+but RTP payload size (@option{ps}) is specified, that is used.
+
+@item stats (@emph{stats})
+Set the file name for multi-pass stats.
+
+@item nal-hrd (@emph{nal-hrd})
+Set signal HRD information (requires @option{vbv-bufsize} to be set).
+Possible values:
+
+@table @samp
+@item none (@emph{none})
+Disable HRD information signaling.
+@item vbr (@emph{vbr})
+Variable bit rate.
+@item cbr (@emph{cbr})
+Constant bit rate (not allowed in MP4 container).
+@end table
+
+@item x264opts (N.A.)
+Set any x264 option, see @command{x264 --fullhelp} for a list.
+
+Argument is a list of @var{key}=@var{value} couples separated by
 ":". In @var{filter} and @var{psy-rd} options that use ":" as a separator
 themselves, use "," instead. They accept it as well since long ago but this
 is kept undocumented for some reason.
@@ -764,18 +1198,199 @@
 ffmpeg -i foo.mpg -vcodec libx264 -x264opts keyint=123:min-keyint=20 -an out.mkv
 @end example
 
-For more information about libx264 and the supported options see:
-@url{http://www.videolan.org/developers/x264.html}
+@item x264-params (N.A.)
+Override the x264 configuration using a :-separated list of key=value
+parameters.
 
-@item -x264-params @var{string}
-Override the x264 configuration using a :-separated list of key=value parameters.
+This option is functionally the same as the @option{x264opts}, but is
+duplicated for compability with the Libav fork.
+
+For example to specify libx264 encoding options with @command{ffmpeg}:
 @example
--x264-params level=30:bframes=0:weightp=0:cabac=0:ref=1:vbv-maxrate=768:vbv-bufsize=2000:analyse=all:me=umh:no-fast-pskip=1:subq=6:8x8dct=0:trellis=0
+ffmpeg -i INPUT -c:v libx264 -x264-params level=30:bframes=0:weightp=0:\
+cabac=0:ref=1:vbv-maxrate=768:vbv-bufsize=2000:analyse=all:me=umh:\
+no-fast-pskip=1:subq=6:8x8dct=0:trellis=0 OUTPUT
 @end example
 @end table
 
-Encoding avpresets for common usages are provided so they can be used with the
-general presets system (e.g. passing the @code{-pre} option).
+Encoding ffpresets for common usages are provided so they can be used with the
+general presets system (e.g. passing the @option{pre} option).
+
+@section libxvid
+
+Xvid MPEG-4 Part 2 encoder wrapper.
+
+This encoder requires the presence of the libxvidcore headers and library
+during configuration. You need to explicitly configure the build with
+@code{--enable-libxvid --enable-gpl}.
+
+The native @code{mpeg4} encoder supports the MPEG-4 Part 2 format, so
+users can encode to this format without this library.
+
+@subsection Options
+
+The following options are supported by the libxvid wrapper. Some of
+the following options are listed but are not documented, and
+correspond to shared codec options. See @ref{codec-options,,the Codec
+Options chapter} for their documentation. The other shared options
+which are not listed have no effect for the libxvid encoder.
+
+@table @option
+@item b
+
+@item g
+
+@item qmin
+
+@item qmax
+
+@item mpeg_quant
+
+@item threads
+
+@item bf
+
+@item b_qfactor
+
+@item b_qoffset
+
+@item flags
+Set specific encoding flags. Possible values:
+
+@table @samp
+
+@item mv4
+Use four motion vector by macroblock.
+
+@item aic
+Enable high quality AC prediction.
+
+@item gray
+Only encode grayscale.
+
+@item gmc
+Enable the use of global motion compensation (GMC).
+
+@item qpel
+Enable quarter-pixel motion compensation.
+
+@item cgop
+Enable closed GOP.
+
+@item global_header
+Place global headers in extradata instead of every keyframe.
+
+@end table
+
+@item trellis
+
+@item me_method
+Set motion estimation method. Possible values in decreasing order of
+speed and increasing order of quality:
+
+@table @samp
+@item zero
+Use no motion estimation (default).
+
+@item phods
+@item x1
+@item log
+Enable advanced diamond zonal search for 16x16 blocks and half-pixel
+refinement for 16x16 blocks. @samp{x1} and @samp{log} are aliases for
+@samp{phods}.
+
+@item epzs
+Enable all of the things described above, plus advanced diamond zonal
+search for 8x8 blocks, half-pixel refinement for 8x8 blocks, and motion
+estimation on chroma planes.
+
+@item full
+Enable all of the things described above, plus extended 16x16 and 8x8
+blocks search.
+@end table
+
+@item mbd
+Set macroblock decision algorithm. Possible values in the increasing
+order of quality:
+
+@table @samp
+@item simple
+Use macroblock comparing function algorithm (default).
+
+@item bits
+Enable rate distortion-based half pixel and quarter pixel refinement for
+16x16 blocks.
+
+@item rd
+Enable all of the things described above, plus rate distortion-based
+half pixel and quarter pixel refinement for 8x8 blocks, and rate
+distortion-based search using square pattern.
+@end table
+
+@item lumi_aq
+Enable lumi masking adaptive quantization when set to 1. Default is 0
+(disabled).
+
+@item variance_aq
+Enable variance adaptive quantization when set to 1. Default is 0
+(disabled).
+
+When combined with @option{lumi_aq}, the resulting quality will not
+be better than any of the two specified individually. In other
+words, the resulting quality will be the worse one of the two
+effects.
+
+@item ssim
+Set structural similarity (SSIM) displaying method. Possible values:
+
+@table @samp
+@item off
+Disable displaying of SSIM information.
+
+@item avg
+Output average SSIM at the end of encoding to stdout. The format of
+showing the average SSIM is:
+
+@example
+Average SSIM: %f
+@end example
+
+For users who are not familiar with C, %f means a float number, or
+a decimal (e.g. 0.939232).
+
+@item frame
+Output both per-frame SSIM data during encoding and average SSIM at
+the end of encoding to stdout. The format of per-frame information
+is:
+
+@example
+       SSIM: avg: %1.3f min: %1.3f max: %1.3f
+@end example
+
+For users who are not familiar with C, %1.3f means a float number
+rounded to 3 digits after the dot (e.g. 0.932).
+
+@end table
+
+@item ssim_acc
+Set SSIM accuracy. Valid options are integers within the range of
+0-4, while 0 gives the most accurate result and 4 computes the
+fastest.
+
+@end table
+
+@section png
+
+PNG image encoder.
+
+@subsection Private options
+
+@table @option
+@item dpi @var{integer}
+Set physical density of pixels, in dots per inch, unset by default
+@item dpm @var{integer}
+Set physical density of pixels, in dots per meter, unset by default
+@end table
 
 @section ProRes
 
@@ -794,6 +1409,7 @@
 @item lt
 @item standard
 @item hq
+@item 4444
 @end table
 
 @item quant_mat @var{integer}
@@ -823,6 +1439,11 @@
 A custom vendor ID like @var{apl0} would claim the stream was produced by
 the Apple encoder.
 
+@item alpha_bits @var{integer}
+Specify number of bits for alpha component.
+Possible values are @var{0}, @var{8} and @var{16}.
+Use @var{0} to disable alpha plane coding.
+
 @end table
 
 @subsection Speed considerations
diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index c849daa..3a84de8 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -7,7 +7,7 @@
                 libswscale                         \
                 libavutil                          \
 
-CFLAGS += -Wall -O2 -g
+CFLAGS += -Wall -g
 CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)
 LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
 
diff --git a/doc/examples/demuxing.c b/doc/examples/demuxing.c
index 8a1b69b..e459cf0 100644
--- a/doc/examples/demuxing.c
+++ b/doc/examples/demuxing.c
@@ -47,10 +47,6 @@
 static int      video_dst_linesize[4];
 static int video_dst_bufsize;
 
-static uint8_t **audio_dst_data = NULL;
-static int       audio_dst_linesize;
-static int audio_dst_bufsize;
-
 static int video_stream_idx = -1, audio_stream_idx = -1;
 static AVFrame *frame = NULL;
 static AVPacket pkt;
@@ -60,6 +56,7 @@
 static int decode_packet(int *got_frame, int cached)
 {
     int ret = 0;
+    int decoded = pkt.size;
 
     if (pkt.stream_index == video_stream_idx) {
         /* decode video frame */
@@ -91,37 +88,32 @@
             fprintf(stderr, "Error decoding audio frame\n");
             return ret;
         }
+        /* Some audio decoders decode only part of the packet, and have to be
+         * called again with the remainder of the packet data.
+         * Sample: fate-suite/lossless-audio/luckynight-partial.shn
+         * Also, some decoders might over-read the packet. */
+        decoded = FFMIN(ret, pkt.size);
 
         if (*got_frame) {
+            size_t unpadded_linesize = frame->nb_samples * av_get_bytes_per_sample(frame->format);
             printf("audio_frame%s n:%d nb_samples:%d pts:%s\n",
                    cached ? "(cached)" : "",
                    audio_frame_count++, frame->nb_samples,
                    av_ts2timestr(frame->pts, &audio_dec_ctx->time_base));
 
-            ret = av_samples_alloc(audio_dst_data, &audio_dst_linesize, av_frame_get_channels(frame),
-                                   frame->nb_samples, frame->format, 1);
-            if (ret < 0) {
-                fprintf(stderr, "Could not allocate audio buffer\n");
-                return AVERROR(ENOMEM);
-            }
-
-            /* TODO: extend return code of the av_samples_* functions so that this call is not needed */
-            audio_dst_bufsize =
-                av_samples_get_buffer_size(NULL, av_frame_get_channels(frame),
-                                           frame->nb_samples, frame->format, 1);
-
-            /* copy audio data to destination buffer:
-             * this is required since rawaudio expects non aligned data */
-            av_samples_copy(audio_dst_data, frame->data, 0, 0,
-                            frame->nb_samples, av_frame_get_channels(frame), frame->format);
-
-            /* write to rawaudio file */
-            fwrite(audio_dst_data[0], 1, audio_dst_bufsize, audio_dst_file);
-            av_freep(&audio_dst_data[0]);
+            /* Write the raw audio data samples of the first plane. This works
+             * fine for packed formats (e.g. AV_SAMPLE_FMT_S16). However,
+             * most audio decoders output planar audio, which uses a separate
+             * plane of audio samples for each channel (e.g. AV_SAMPLE_FMT_S16P).
+             * In other words, this code will write only the first audio channel
+             * in these cases.
+             * You should use libswresample or libavfilter to convert the frame
+             * to packed data. */
+            fwrite(frame->extended_data[0], 1, unpadded_linesize, audio_dst_file);
         }
     }
 
-    return ret;
+    return decoded;
 }
 
 static int open_codec_context(int *stream_idx,
@@ -244,8 +236,6 @@
     }
 
     if (open_codec_context(&audio_stream_idx, fmt_ctx, AVMEDIA_TYPE_AUDIO) >= 0) {
-        int nb_planes;
-
         audio_stream = fmt_ctx->streams[audio_stream_idx];
         audio_dec_ctx = audio_stream->codec;
         audio_dst_file = fopen(audio_dst_filename, "wb");
@@ -254,15 +244,6 @@
             ret = 1;
             goto end;
         }
-
-        nb_planes = av_sample_fmt_is_planar(audio_dec_ctx->sample_fmt) ?
-            audio_dec_ctx->channels : 1;
-        audio_dst_data = av_mallocz(sizeof(uint8_t *) * nb_planes);
-        if (!audio_dst_data) {
-            fprintf(stderr, "Could not allocate audio data buffers\n");
-            ret = AVERROR(ENOMEM);
-            goto end;
-        }
     }
 
     /* dump input information to stderr */
@@ -293,8 +274,15 @@
 
     /* read frames from the file */
     while (av_read_frame(fmt_ctx, &pkt) >= 0) {
-        decode_packet(&got_frame, 0);
-        av_free_packet(&pkt);
+        AVPacket orig_pkt = pkt;
+        do {
+            ret = decode_packet(&got_frame, 0);
+            if (ret < 0)
+                break;
+            pkt.data += ret;
+            pkt.size -= ret;
+        } while (pkt.size > 0);
+        av_free_packet(&orig_pkt);
     }
 
     /* flush cached frames */
@@ -314,13 +302,25 @@
     }
 
     if (audio_stream) {
+        enum AVSampleFormat sfmt = audio_dec_ctx->sample_fmt;
+        int n_channels = audio_dec_ctx->channels;
         const char *fmt;
 
-        if ((ret = get_format_from_sample_fmt(&fmt, audio_dec_ctx->sample_fmt)) < 0)
+        if (av_sample_fmt_is_planar(sfmt)) {
+            const char *packed = av_get_sample_fmt_name(sfmt);
+            printf("Warning: the sample format the decoder produced is planar "
+                   "(%s). This example will output the first channel only.\n",
+                   packed ? packed : "?");
+            sfmt = av_get_packed_sample_fmt(sfmt);
+            n_channels = 1;
+        }
+
+        if ((ret = get_format_from_sample_fmt(&fmt, sfmt)) < 0)
             goto end;
+
         printf("Play the output audio file with the command:\n"
                "ffplay -f %s -ac %d -ar %d %s\n",
-               fmt, audio_dec_ctx->channels, audio_dec_ctx->sample_rate,
+               fmt, n_channels, audio_dec_ctx->sample_rate,
                audio_dst_filename);
     }
 
@@ -336,7 +336,6 @@
         fclose(audio_dst_file);
     av_free(frame);
     av_free(video_dst_data[0]);
-    av_free(audio_dst_data);
 
     return ret < 0;
 }
diff --git a/doc/examples/filtering_audio.c b/doc/examples/filtering_audio.c
index b6b05a2..35dd4e7 100644
--- a/doc/examples/filtering_audio.c
+++ b/doc/examples/filtering_audio.c
@@ -38,8 +38,8 @@
 #include <libavfilter/buffersrc.h>
 #include <libavutil/opt.h>
 
-const char *filter_descr = "aresample=8000,aformat=sample_fmts=s16:channel_layouts=mono";
-const char *player       = "ffplay -f s16le -ar 8000 -ac 1 -";
+static const char *filter_descr = "aresample=8000,aformat=sample_fmts=s16:channel_layouts=mono";
+static const char *player       = "ffplay -f s16le -ar 8000 -ac 1 -";
 
 static AVFormatContext *fmt_ctx;
 static AVCodecContext *dec_ctx;
@@ -90,9 +90,9 @@
     AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
     AVFilterInOut *outputs = avfilter_inout_alloc();
     AVFilterInOut *inputs  = avfilter_inout_alloc();
-    const enum AVSampleFormat out_sample_fmts[] = { AV_SAMPLE_FMT_S16, -1 };
-    const int64_t out_channel_layouts[] = { AV_CH_LAYOUT_MONO, -1 };
-    const int out_sample_rates[] = { 8000, -1 };
+    static const enum AVSampleFormat out_sample_fmts[] = { AV_SAMPLE_FMT_S16, -1 };
+    static const int64_t out_channel_layouts[] = { AV_CH_LAYOUT_MONO, -1 };
+    static const int out_sample_rates[] = { 8000, -1 };
     const AVFilterLink *outlink;
     AVRational time_base = fmt_ctx->streams[audio_stream_index]->time_base;
 
@@ -152,7 +152,7 @@
     inputs->pad_idx    = 0;
     inputs->next       = NULL;
 
-    if ((ret = avfilter_graph_parse(filter_graph, filters_descr,
+    if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
                                     &inputs, &outputs, NULL)) < 0)
         return ret;
 
diff --git a/doc/examples/filtering_video.c b/doc/examples/filtering_video.c
index daa3966..d3c33df 100644
--- a/doc/examples/filtering_video.c
+++ b/doc/examples/filtering_video.c
@@ -129,7 +129,7 @@
     inputs->pad_idx    = 0;
     inputs->next       = NULL;
 
-    if ((ret = avfilter_graph_parse(filter_graph, filters_descr,
+    if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
                                     &inputs, &outputs, NULL)) < 0)
         return ret;
 
diff --git a/doc/examples/muxing.c b/doc/examples/muxing.c
index 7305cc6..a8f979f 100644
--- a/doc/examples/muxing.c
+++ b/doc/examples/muxing.c
@@ -34,9 +34,11 @@
 #include <string.h>
 #include <math.h>
 
+#include <libavutil/opt.h>
 #include <libavutil/mathematics.h>
 #include <libavformat/avformat.h>
 #include <libswscale/swscale.h>
+#include <libswresample/swresample.h>
 
 /* 5 seconds stream duration */
 #define STREAM_DURATION   200.0
@@ -46,13 +48,6 @@
 
 static int sws_flags = SWS_BICUBIC;
 
-/**************************************************************/
-/* audio output */
-
-static float t, tincr, tincr2;
-static int16_t *samples;
-static int audio_input_frame_size;
-
 /* Add an output stream. */
 static AVStream *add_stream(AVFormatContext *oc, AVCodec **codec,
                             enum AVCodecID codec_id)
@@ -78,8 +73,7 @@
 
     switch ((*codec)->type) {
     case AVMEDIA_TYPE_AUDIO:
-        st->id = 1;
-        c->sample_fmt  = AV_SAMPLE_FMT_S16;
+        c->sample_fmt  = AV_SAMPLE_FMT_FLTP;
         c->bit_rate    = 64000;
         c->sample_rate = 44100;
         c->channels    = 2;
@@ -127,8 +121,17 @@
 /* audio output */
 
 static float t, tincr, tincr2;
-static int16_t *samples;
-static int audio_input_frame_size;
+
+static uint8_t **src_samples_data;
+static int       src_samples_linesize;
+static int       src_nb_samples;
+
+static int max_dst_nb_samples;
+uint8_t **dst_samples_data;
+int       dst_samples_linesize;
+int       dst_samples_size;
+
+struct SwrContext *swr_ctx = NULL;
 
 static void open_audio(AVFormatContext *oc, AVCodec *codec, AVStream *st)
 {
@@ -150,17 +153,51 @@
     /* increment frequency by 110 Hz per second */
     tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
 
-    if (c->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)
-        audio_input_frame_size = 10000;
-    else
-        audio_input_frame_size = c->frame_size;
-    samples = av_malloc(audio_input_frame_size *
-                        av_get_bytes_per_sample(c->sample_fmt) *
-                        c->channels);
-    if (!samples) {
-        fprintf(stderr, "Could not allocate audio samples buffer\n");
+    src_nb_samples = c->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE ?
+        10000 : c->frame_size;
+
+    ret = av_samples_alloc_array_and_samples(&src_samples_data, &src_samples_linesize, c->channels,
+                                             src_nb_samples, c->sample_fmt, 0);
+    if (ret < 0) {
+        fprintf(stderr, "Could not allocate source samples\n");
         exit(1);
     }
+
+    /* create resampler context */
+    if (c->sample_fmt != AV_SAMPLE_FMT_S16) {
+        swr_ctx = swr_alloc();
+        if (!swr_ctx) {
+            fprintf(stderr, "Could not allocate resampler context\n");
+            exit(1);
+        }
+
+        /* set options */
+        av_opt_set_int       (swr_ctx, "in_channel_count",   c->channels,       0);
+        av_opt_set_int       (swr_ctx, "in_sample_rate",     c->sample_rate,    0);
+        av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt",      AV_SAMPLE_FMT_S16, 0);
+        av_opt_set_int       (swr_ctx, "out_channel_count",  c->channels,       0);
+        av_opt_set_int       (swr_ctx, "out_sample_rate",    c->sample_rate,    0);
+        av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt",     c->sample_fmt,     0);
+
+        /* initialize the resampling context */
+        if ((ret = swr_init(swr_ctx)) < 0) {
+            fprintf(stderr, "Failed to initialize the resampling context\n");
+            exit(1);
+        }
+    }
+
+    /* compute the number of converted samples: buffering is avoided
+     * ensuring that the output buffer will contain at least all the
+     * converted input samples */
+    max_dst_nb_samples = src_nb_samples;
+    ret = av_samples_alloc_array_and_samples(&dst_samples_data, &dst_samples_linesize, c->channels,
+                                             max_dst_nb_samples, c->sample_fmt, 0);
+    if (ret < 0) {
+        fprintf(stderr, "Could not allocate destination samples\n");
+        exit(1);
+    }
+    dst_samples_size = av_samples_get_buffer_size(NULL, c->channels, max_dst_nb_samples,
+                                                  c->sample_fmt, 0);
 }
 
 /* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
@@ -185,18 +222,45 @@
     AVCodecContext *c;
     AVPacket pkt = { 0 }; // data and size must be 0;
     AVFrame *frame = avcodec_alloc_frame();
-    int got_packet, ret;
+    int got_packet, ret, dst_nb_samples;
 
     av_init_packet(&pkt);
     c = st->codec;
 
-    get_audio_frame(samples, audio_input_frame_size, c->channels);
-    frame->nb_samples = audio_input_frame_size;
+    get_audio_frame((int16_t *)src_samples_data[0], src_nb_samples, c->channels);
+
+    /* convert samples from native format to destination codec format, using the resampler */
+    if (swr_ctx) {
+        /* compute destination number of samples */
+        dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, c->sample_rate) + src_nb_samples,
+                                        c->sample_rate, c->sample_rate, AV_ROUND_UP);
+        if (dst_nb_samples > max_dst_nb_samples) {
+            av_free(dst_samples_data[0]);
+            ret = av_samples_alloc(dst_samples_data, &dst_samples_linesize, c->channels,
+                                   dst_nb_samples, c->sample_fmt, 0);
+            if (ret < 0)
+                exit(1);
+            max_dst_nb_samples = dst_nb_samples;
+            dst_samples_size = av_samples_get_buffer_size(NULL, c->channels, dst_nb_samples,
+                                                          c->sample_fmt, 0);
+        }
+
+        /* convert to destination format */
+        ret = swr_convert(swr_ctx,
+                          dst_samples_data, dst_nb_samples,
+                          (const uint8_t **)src_samples_data, src_nb_samples);
+        if (ret < 0) {
+            fprintf(stderr, "Error while converting\n");
+            exit(1);
+        }
+    } else {
+        dst_samples_data[0] = src_samples_data[0];
+        dst_nb_samples = src_nb_samples;
+    }
+
+    frame->nb_samples = dst_nb_samples;
     avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
-                             (uint8_t *)samples,
-                             audio_input_frame_size *
-                             av_get_bytes_per_sample(c->sample_fmt) *
-                             c->channels, 1);
+                             dst_samples_data[0], dst_samples_size, 0);
 
     ret = avcodec_encode_audio2(c, &pkt, frame, &got_packet);
     if (ret < 0) {
@@ -222,8 +286,8 @@
 static void close_audio(AVFormatContext *oc, AVStream *st)
 {
     avcodec_close(st->codec);
-
-    av_free(samples);
+    av_free(src_samples_data[0]);
+    av_free(dst_samples_data[0]);
 }
 
 /**************************************************************/
@@ -388,7 +452,7 @@
     AVFormatContext *oc;
     AVStream *audio_st, *video_st;
     AVCodec *audio_codec, *video_codec;
-    double audio_pts, video_pts;
+    double audio_time, video_time;
     int ret;
 
     /* Initialize libavcodec, and register all codecs and formats. */
@@ -461,23 +525,15 @@
         frame->pts = 0;
     for (;;) {
         /* Compute current audio and video time. */
-        if (audio_st)
-            audio_pts = (double)audio_st->pts.val * audio_st->time_base.num / audio_st->time_base.den;
-        else
-            audio_pts = 0.0;
+        audio_time = audio_st ? audio_st->pts.val * av_q2d(audio_st->time_base) : 0.0;
+        video_time = video_st ? video_st->pts.val * av_q2d(video_st->time_base) : 0.0;
 
-        if (video_st)
-            video_pts = (double)video_st->pts.val * video_st->time_base.num /
-                        video_st->time_base.den;
-        else
-            video_pts = 0.0;
-
-        if ((!audio_st || audio_pts >= STREAM_DURATION) &&
-            (!video_st || video_pts >= STREAM_DURATION))
+        if ((!audio_st || audio_time >= STREAM_DURATION) &&
+            (!video_st || video_time >= STREAM_DURATION))
             break;
 
         /* write interleaved audio and video frames */
-        if (!video_st || (video_st && audio_st && audio_pts < video_pts)) {
+        if (!video_st || (video_st && audio_st && audio_time < video_time)) {
             write_audio_frame(oc, audio_st);
         } else {
             write_video_frame(oc, video_st);
diff --git a/doc/faq.texi b/doc/faq.texi
index 4b0b09c..a0ae537 100644
--- a/doc/faq.texi
+++ b/doc/faq.texi
@@ -234,8 +234,8 @@
   ffmpeg -i input.avs
 @end example
 
-For ANY other help on Avisynth, please visit the
-@uref{http://www.avisynth.org/, Avisynth homepage}.
+For ANY other help on AviSynth, please visit the
+@uref{http://www.avisynth.org/, AviSynth homepage}.
 
 @section How can I join video files?
 
diff --git a/doc/fate.texi b/doc/fate.texi
index 28eadfd..4e5cbd7 100644
--- a/doc/fate.texi
+++ b/doc/fate.texi
@@ -131,7 +131,12 @@
 running your SSH client manually and killing it after you accepted the key.
 The FATE server's fingerprint is:
 
-  b1:31:c8:79:3f:04:1d:f8:f2:23:26:5a:fd:55:fa:92
+@table @option
+@item RSA
+   d3:f1:83:97:a4:75:2b:a6:fb:d6:e8:aa:81:93:97:51
+@item ECDSA
+   76:9f:68:32:04:1e:d5:d4:ec:47:3f:dc:fc:18:17:86
+@end table
 
   If you have problems connecting to the FATE server, it may help to try out
 the @command{ssh} command with one or more @option{-v} options. You should
@@ -148,20 +153,20 @@
 
 @table @option
 @item fate-rsync
-    Download/synchronize sample files to the configured samples directory.
+Download/synchronize sample files to the configured samples directory.
 
 @item fate-list
-    Will list all fate/regression test targets.
+Will list all fate/regression test targets.
 
 @item fate
-    Run the FATE test suite (requires the fate-suite dataset).
+Run the FATE test suite (requires the fate-suite dataset).
 @end table
 
 @section Makefile variables
 
 @table @option
 @item V
-    Verbosity level, can be set to 0, 1 or 2.
+Verbosity level, can be set to 0, 1 or 2.
     @itemize
         @item 0: show just the test arguments
         @item 1: show just the command used in the test
@@ -169,22 +174,26 @@
     @end itemize
 
 @item SAMPLES
-    Specify or override the path to the FATE samples at make time, it has a
-    meaning only while running the regression tests.
+Specify or override the path to the FATE samples at make time, it has a
+meaning only while running the regression tests.
 
 @item THREADS
-    Specify how many threads to use while running regression tests, it is
-    quite useful to detect thread-related regressions.
+Specify how many threads to use while running regression tests, it is
+quite useful to detect thread-related regressions.
+
 @item THREAD_TYPE
-    Specify which threading strategy test, either @var{slice} or @var{frame},
-    by default @var{slice+frame}
+Specify which threading strategy test, either @var{slice} or @var{frame},
+by default @var{slice+frame}
+
 @item CPUFLAGS
-    Specify CPU flags.
+Specify CPU flags.
+
 @item TARGET_EXEC
-    Specify or override the wrapper used to run the tests.
-    The @var{TARGET_EXEC} option provides a way to run FATE wrapped in
-    @command{valgrind}, @command{qemu-user} or @command{wine} or on remote targets
-    through @command{ssh}.
+Specify or override the wrapper used to run the tests.
+The @var{TARGET_EXEC} option provides a way to run FATE wrapped in
+@command{valgrind}, @command{qemu-user} or @command{wine} or on remote targets
+through @command{ssh}.
+
 @item GEN
 Set to @var{1} to generate the missing or mismatched references.
 @end table
diff --git a/doc/fate_config.sh.template b/doc/fate_config.sh.template
index f7bd625..1487c1d 100644
--- a/doc/fate_config.sh.template
+++ b/doc/fate_config.sh.template
@@ -4,16 +4,20 @@
 workdir=                                 # directory in which to do all the work
 #fate_recv="ssh -T fate@fate.ffmpeg.org" # command to submit report
 comment=                                 # optional description
+build_only=     # set to "yes" for a compile-only instance that skips tests
 
 # the following are optional and map to configure options
 arch=
 cpu=
 cross_prefix=
+as=
 cc=
+ld=
 target_os=
 sysroot=
 target_exec=
 target_path=
+target_samples=
 extra_cflags=
 extra_ldflags=
 extra_libs=
diff --git a/doc/ffmpeg-resampler.texi b/doc/ffmpeg-resampler.texi
index da3d033..69767a2 100644
--- a/doc/ffmpeg-resampler.texi
+++ b/doc/ffmpeg-resampler.texi
@@ -12,7 +12,7 @@
 @chapter Description
 @c man begin DESCRIPTION
 
-The FFmpeg resampler provides an high-level interface to the
+The FFmpeg resampler provides a high-level interface to the
 libswresample library audio resampling utilities. In particular it
 allows to perform audio resampling, audio channel layout rematrixing,
 and convert audio format and packing layout.
diff --git a/doc/ffmpeg-scaler.texi b/doc/ffmpeg-scaler.texi
index 47b81a4..1eb8cd6 100644
--- a/doc/ffmpeg-scaler.texi
+++ b/doc/ffmpeg-scaler.texi
@@ -12,7 +12,7 @@
 @chapter Description
 @c man begin DESCRIPTION
 
-The FFmpeg rescaler provides an high-level interface to the libswscale
+The FFmpeg rescaler provides a high-level interface to the libswscale
 library image conversion utilities. In particular it allows to perform
 image rescaling and pixel format conversion.
 
diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index 94f48fd..c03f9a5 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -272,9 +272,15 @@
 
 @item -ss @var{position} (@emph{input/output})
 When used as an input option (before @code{-i}), seeks in this input file to
-@var{position}. When used as an output option (before an output filename),
-decodes but discards input until the timestamps reach @var{position}. This is
-slower, but more accurate.
+@var{position}. Note the in most formats it is not possible to seek exactly, so
+@command{ffmpeg} will seek to the closest seek point before @var{position}.
+When transcoding and @option{-accurate_seek} is enabled (the default), this
+extra segment between the seek point and @var{position} will be decoded and
+discarded. When doing stream copy or when @option{-noaccurate_seek} is used, it
+will be preserved.
+
+When used as an output option (before an output filename), decodes but discards
+input until the timestamps reach @var{position}.
 
 @var{position} may be either in seconds or in @code{hh:mm:ss[.xxx]} form.
 
@@ -532,10 +538,6 @@
 end frame numbers, last one is quantizer to use if positive, or quality
 factor if negative.
 
-@item -deinterlace
-Deinterlace pictures.
-This option is deprecated since the deinterlacing is very low quality.
-Use the yadif filter with @code{-filter:v yadif}.
 @item -ilme
 Force interlacing support in encoder (MPEG-2 and MPEG-4 only).
 Use this option if your input file is interlaced and you want
@@ -875,13 +877,12 @@
 When dumping packets, also dump the payload.
 @item -re (@emph{input})
 Read input at native frame rate. Mainly used to simulate a grab device.
+or live input stream (e.g. when reading from a file). Should not be used
+with actual grab devices or live input streams (where it can cause packet
+loss).
 By default @command{ffmpeg} attempts to read the input(s) as fast as possible.
 This option will slow down the reading of the input(s) to the native frame rate
-of the input(s). It is useful for real-time output (e.g. live streaming). If
-your input(s) is coming from some other live streaming source (through HTTP or
-UDP for example) the server might already be in real-time, thus the option will
-likely not be required. On the other hand, this is meaningful if your input(s)
-is a file you are trying to push in real-time.
+of the input(s). It is useful for real-time output (e.g. live streaming).
 @item -loop_input
 Loop over the input stream. Currently it works only for image
 streams. This option is used for automatic FFserver testing.
@@ -1064,6 +1065,20 @@
 its argument is the name of the file from which a complex filtergraph
 description is to be read.
 
+@item -accurate_seek (@emph{input})
+This option enables or disables accurate seeking in input files with the
+@option{-ss} option. It is enabled by default, so seeking is accurate when
+transcoding. Use @option{-noaccurate_seek} to disable it, which may be useful
+e.g. when copying some streams and transcoding the others.
+
+@item -override_ffserver (@emph{global})
+Overrides the input specifications from ffserver. Using this option you can
+map any input stream to ffserver and control many aspects of the encoding from
+ffmpeg. Without this option ffmpeg will transmit to ffserver what is requested by
+ffserver.
+The option is intended for cases where features are needed that cannot be
+specified to ffserver but can be to ffmpeg.
+
 @end table
 
 As a special exception, you can use a bitmap subtitle stream as input: it
@@ -1121,7 +1136,7 @@
 
 @itemize
 @item
-For streaming at very low bitrate application, use a low frame rate
+For streaming at very low bitrates, use a low frame rate
 and a small GOP size. This is especially true for RealVideo where
 the Linux player does not seem to be very fast, so it can miss
 frames. An example is:
@@ -1366,8 +1381,31 @@
 @end itemize
 @c man end EXAMPLES
 
+@include config.texi
 @ifset config-all
-@include all-components.texi
+@ifset config-avutil
+@include utils.texi
+@end ifset
+@ifset config-avcodec
+@include codecs.texi
+@include bitstream_filters.texi
+@end ifset
+@ifset config-avformat
+@include formats.texi
+@include protocols.texi
+@end ifset
+@ifset config-avdevice
+@include devices.texi
+@end ifset
+@ifset config-swresample
+@include resampler.texi
+@end ifset
+@ifset config-swscale
+@include scaler.texi
+@end ifset
+@ifset config-avfilter
+@include filters.texi
+@end ifset
 @end ifset
 
 @chapter See Also
diff --git a/doc/ffplay.texi b/doc/ffplay.texi
index 21a6e6c..943cbb9 100644
--- a/doc/ffplay.texi
+++ b/doc/ffplay.texi
@@ -201,8 +201,31 @@
 
 @c man end
 
+@include config.texi
 @ifset config-all
-@include all-components.texi
+@ifset config-avutil
+@include utils.texi
+@end ifset
+@ifset config-avcodec
+@include codecs.texi
+@include bitstream_filters.texi
+@end ifset
+@ifset config-avformat
+@include formats.texi
+@include protocols.texi
+@end ifset
+@ifset config-avdevice
+@include devices.texi
+@end ifset
+@ifset config-swresample
+@include resampler.texi
+@end ifset
+@ifset config-swscale
+@include scaler.texi
+@end ifset
+@ifset config-avfilter
+@include filters.texi
+@end ifset
 @end ifset
 
 @chapter See Also
diff --git a/doc/ffprobe.texi b/doc/ffprobe.texi
index aacee3a..daeb8cb 100644
--- a/doc/ffprobe.texi
+++ b/doc/ffprobe.texi
@@ -44,7 +44,8 @@
 name. See the output of @option{sections}.
 
 Metadata tags stored in the container or in the streams are recognized
-and printed in the corresponding "FORMAT" or "STREAM" section.
+and printed in the corresponding "FORMAT", "STREAM" or "PROGRAM_STREAM"
+section.
 
 @c man end
 
@@ -112,7 +113,7 @@
 @end example
 
 @item -show_data
-Show payload data, as an hexadecimal and ASCII dump. Coupled with
+Show payload data, as a hexadecimal and ASCII dump. Coupled with
 @option{-show_packets}, it will dump the packets' data. Coupled with
 @option{-show_streams}, it will dump the codec extradata.
 
@@ -209,6 +210,18 @@
 Each media stream information is printed within a dedicated section
 with name "STREAM".
 
+@item -show_programs
+Show information about programs and their streams contained in the input
+multimedia stream.
+
+Each media stream information is printed within a dedicated section
+with name "PROGRAM_STREAM".
+
+@item -show_chapters
+Show information about chapters stored in the format.
+
+Each chapter is printed within a dedicated section with name "CHAPTER".
+
 @item -count_frames
 Count the number of frames per stream and report it in the
 corresponding stream section.
@@ -274,8 +287,8 @@
 [/SECTION]
 @end example
 
-Metadata tags are printed as a line in the corresponding FORMAT or
-STREAM section, and are prefixed by the string "TAG:".
+Metadata tags are printed as a line in the corresponding FORMAT, STREAM or
+PROGRAM_STREAM section, and are prefixed by the string "TAG:".
 
 A description of the accepted options follows.
 
@@ -487,8 +500,31 @@
 @end itemize
 @c man end TIMECODE
 
+@include config.texi
 @ifset config-all
-@include all-components.texi
+@ifset config-avutil
+@include utils.texi
+@end ifset
+@ifset config-avcodec
+@include codecs.texi
+@include bitstream_filters.texi
+@end ifset
+@ifset config-avformat
+@include formats.texi
+@include protocols.texi
+@end ifset
+@ifset config-avdevice
+@include devices.texi
+@end ifset
+@ifset config-swresample
+@include resampler.texi
+@end ifset
+@ifset config-swscale
+@include scaler.texi
+@end ifset
+@ifset config-avfilter
+@include filters.texi
+@end ifset
 @end ifset
 
 @chapter See Also
diff --git a/doc/ffprobe.xsd b/doc/ffprobe.xsd
index eab97fb..8a1e102 100644
--- a/doc/ffprobe.xsd
+++ b/doc/ffprobe.xsd
@@ -11,6 +11,8 @@
             <xsd:element name="packets"  type="ffprobe:packetsType" minOccurs="0" maxOccurs="1" />
             <xsd:element name="frames"   type="ffprobe:framesType"  minOccurs="0" maxOccurs="1" />
             <xsd:element name="streams"  type="ffprobe:streamsType" minOccurs="0" maxOccurs="1" />
+            <xsd:element name="programs" type="ffprobe:programsType" minOccurs="0" maxOccurs="1" />
+            <xsd:element name="chapters" type="ffprobe:chaptersType" minOccurs="0" maxOccurs="1" />
             <xsd:element name="format"   type="ffprobe:formatType"  minOccurs="0" maxOccurs="1" />
             <xsd:element name="error"    type="ffprobe:errorType"   minOccurs="0" maxOccurs="1" />
             <xsd:element name="program_version"  type="ffprobe:programVersionType"  minOccurs="0" maxOccurs="1" />
@@ -86,6 +88,12 @@
         </xsd:sequence>
     </xsd:complexType>
 
+    <xsd:complexType name="programsType">
+        <xsd:sequence>
+            <xsd:element name="program" type="ffprobe:programType" minOccurs="0" maxOccurs="unbounded"/>
+        </xsd:sequence>
+    </xsd:complexType>
+
     <xsd:complexType name="streamDispositionType">
       <xsd:attribute name="default"          type="xsd:int" use="required" />
       <xsd:attribute name="dub"              type="xsd:int" use="required" />
@@ -102,8 +110,8 @@
 
     <xsd:complexType name="streamType">
       <xsd:sequence>
-        <xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/>
         <xsd:element name="disposition" type="ffprobe:streamDispositionType" minOccurs="0" maxOccurs="1"/>
+        <xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/>
       </xsd:sequence>
 
       <xsd:attribute name="index"            type="xsd:int" use="required"/>
@@ -146,6 +154,23 @@
       <xsd:attribute name="nb_read_packets"  type="xsd:int"/>
     </xsd:complexType>
 
+    <xsd:complexType name="programType">
+      <xsd:sequence>
+        <xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="streams" type="ffprobe:streamsType" minOccurs="0" maxOccurs="1"/>
+      </xsd:sequence>
+
+      <xsd:attribute name="program_id"           type="xsd:int"    use="required"/>
+      <xsd:attribute name="program_num"          type="xsd:int"    use="required"/>
+      <xsd:attribute name="nb_streams"           type="xsd:int"    use="required"/>
+      <xsd:attribute name="start_time"           type="xsd:float"/>
+      <xsd:attribute name="start_pts"            type="xsd:long"/>
+      <xsd:attribute name="end_time"             type="xsd:float"/>
+      <xsd:attribute name="end_pts"              type="xsd:long"/>
+      <xsd:attribute name="pmt_pid"              type="xsd:int"    use="required"/>
+      <xsd:attribute name="pcr_pid"              type="xsd:int"    use="required"/>
+    </xsd:complexType>
+
     <xsd:complexType name="formatType">
       <xsd:sequence>
         <xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/>
@@ -181,6 +206,25 @@
       <xsd:attribute name="configuration"    type="xsd:string" use="required"/>
     </xsd:complexType>
 
+    <xsd:complexType name="chaptersType">
+      <xsd:sequence>
+        <xsd:element name="chapter" type="ffprobe:chapterType" minOccurs="0" maxOccurs="unbounded"/>
+      </xsd:sequence>
+    </xsd:complexType>
+
+    <xsd:complexType name="chapterType">
+      <xsd:sequence>
+        <xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/>
+      </xsd:sequence>
+
+      <xsd:attribute name="id"         type="xsd:int" use="required"/>
+      <xsd:attribute name="time_base"  type="xsd:string" use="required"/>
+      <xsd:attribute name="start"      type="xsd:int" use="required"/>
+      <xsd:attribute name="start_time" type="xsd:float"/>
+      <xsd:attribute name="end"        type="xsd:int" use="required"/>
+      <xsd:attribute name="end_time"   type="xsd:float" use="required"/>
+    </xsd:complexType>
+
     <xsd:complexType name="libraryVersionType">
       <xsd:attribute name="name"        type="xsd:string" use="required"/>
       <xsd:attribute name="major"       type="xsd:int"    use="required"/>
diff --git a/doc/ffserver.texi b/doc/ffserver.texi
index 8844941..bfc2e60 100644
--- a/doc/ffserver.texi
+++ b/doc/ffserver.texi
@@ -246,8 +246,31 @@
 @end table
 @c man end
 
+@include config.texi
 @ifset config-all
-@include all-components.texi
+@ifset config-avutil
+@include utils.texi
+@end ifset
+@ifset config-avcodec
+@include codecs.texi
+@include bitstream_filters.texi
+@end ifset
+@ifset config-avformat
+@include formats.texi
+@include protocols.texi
+@end ifset
+@ifset config-avdevice
+@include devices.texi
+@end ifset
+@ifset config-swresample
+@include resampler.texi
+@end ifset
+@ifset config-swscale
+@include scaler.texi
+@end ifset
+@ifset config-avfilter
+@include filters.texi
+@end ifset
 @end ifset
 
 @chapter See Also
diff --git a/doc/filter_design.txt b/doc/filter_design.txt
index c303c3c..fca24a9 100644
--- a/doc/filter_design.txt
+++ b/doc/filter_design.txt
@@ -166,7 +166,7 @@
       WRITE permission.
 
     * Filters that read their input to produce a new frame on output (like
-      scale) need the READ permission on input and and must request a buffer
+      scale) need the READ permission on input and must request a buffer
       with the WRITE permission.
 
     * Filters that intend to keep a reference after the filtering process
diff --git a/doc/filters.texi b/doc/filters.texi
index 8971276..5d9a2df 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -293,11 +293,11 @@
 Like any other filtering option, the @option{enable} option follows the same
 rules.
 
-For example, to enable a denoiser filter (@ref{hqdn3d}) from 10 seconds to 3
+For example, to enable a blur filter (@ref{smartblur}) from 10 seconds to 3
 minutes, and a @ref{curves} filter starting at 3 seconds:
 @example
-hqdn3d = enable='between(t,10,3*60)',
-curves = enable='gte(t,3)' : preset=cross_process
+smartblur = enable='between(t,10,3*60)',
+curves    = enable='gte(t,3)' : preset=cross_process
 @end example
 
 @c man end FILTERGRAPH DESCRIPTION
@@ -347,281 +347,65 @@
 @end example
 @end itemize
 
-@section allpass
+@section aecho
 
-Apply a two-pole all-pass filter with central frequency (in Hz)
-@var{frequency}, and filter-width @var{width}.
-An all-pass filter changes the audio's frequency to phase relationship
-without changing its frequency to amplitude relationship.
+Apply echoing to the input audio.
 
-The filter accepts the following options:
+Echoes are reflected sound and can occur naturally amongst mountains
+(and sometimes large buildings) when talking or shouting; digital echo
+effects emulate this behaviour and are often used to help fill out the
+sound of a single instrument or vocal. The time difference between the
+original signal and the reflection is the @code{delay}, and the
+loudness of the reflected signal is the @code{decay}.
+Multiple echoes can have different delays and decays.
+
+A description of the accepted parameters follows.
 
 @table @option
-@item frequency, f
-Set frequency in Hz.
+@item in_gain
+Set input gain of reflected signal. Default is @code{0.6}.
 
-@item width_type
-Set method to specify band-width of filter.
-@table @option
-@item h
-Hz
-@item q
-Q-Factor
-@item o
-octave
-@item s
-slope
+@item out_gain
+Set output gain of reflected signal. Default is @code{0.3}.
+
+@item delays
+Set list of time intervals in milliseconds between original signal and reflections
+separated by '|'. Allowed range for each @code{delay} is @code{(0 - 90000.0]}.
+Default is @code{1000}.
+
+@item decays
+Set list of loudnesses of reflected signals separated by '|'.
+Allowed range for each @code{decay} is @code{(0 - 1.0]}.
+Default is @code{0.5}.
 @end table
 
-@item width, w
-Specify the band-width of a filter in width_type units.
-@end table
+@subsection Examples
 
-@section highpass
+@itemize
+@item
+Make it sound as if there are twice as many instruments as are actually playing:
+@example
+aecho=0.8:0.88:60:0.4
+@end example
 
-Apply a high-pass filter with 3dB point frequency.
-The filter can be either single-pole, or double-pole (the default).
-The filter roll off at 6dB per pole per octave (20dB per pole per decade).
+@item
+If delay is very short, then it sound like a (metallic) robot playing music:
+@example
+aecho=0.8:0.88:6:0.4
+@end example
 
-The filter accepts the following options:
+@item
+A longer delay will sound like an open air concert in the mountains:
+@example
+aecho=0.8:0.9:1000:0.3
+@end example
 
-@table @option
-@item frequency, f
-Set frequency in Hz. Default is 3000.
-
-@item poles, p
-Set number of poles. Default is 2.
-
-@item width_type
-Set method to specify band-width of filter.
-@table @option
-@item h
-Hz
-@item q
-Q-Factor
-@item o
-octave
-@item s
-slope
-@end table
-
-@item width, w
-Specify the band-width of a filter in width_type units.
-Applies only to double-pole filter.
-The default is 0.707q and gives a Butterworth response.
-@end table
-
-@section lowpass
-
-Apply a low-pass filter with 3dB point frequency.
-The filter can be either single-pole or double-pole (the default).
-The filter roll off at 6dB per pole per octave (20dB per pole per decade).
-
-The filter accepts the following options:
-
-@table @option
-@item frequency, f
-Set frequency in Hz. Default is 500.
-
-@item poles, p
-Set number of poles. Default is 2.
-
-@item width_type
-Set method to specify band-width of filter.
-@table @option
-@item h
-Hz
-@item q
-Q-Factor
-@item o
-octave
-@item s
-slope
-@end table
-
-@item width, w
-Specify the band-width of a filter in width_type units.
-Applies only to double-pole filter.
-The default is 0.707q and gives a Butterworth response.
-@end table
-
-@section bass
-
-Boost or cut the bass (lower) frequencies of the audio using a two-pole
-shelving filter with a response similar to that of a standard
-hi-fi's tone-controls. This is also known as shelving equalisation (EQ).
-
-The filter accepts the following options:
-
-@table @option
-@item gain, g
-Give the gain at 0 Hz. Its useful range is about -20
-(for a large cut) to +20 (for a large boost).
-Beware of clipping when using a positive gain.
-
-@item frequency, f
-Set the filter's central frequency and so can be used
-to extend or reduce the frequency range to be boosted or cut.
-The default value is @code{100} Hz.
-
-@item width_type
-Set method to specify band-width of filter.
-@table @option
-@item h
-Hz
-@item q
-Q-Factor
-@item o
-octave
-@item s
-slope
-@end table
-
-@item width, w
-Determine how steep is the filter's shelf transition.
-@end table
-
-@section treble
-
-Boost or cut treble (upper) frequencies of the audio using a two-pole
-shelving filter with a response similar to that of a standard
-hi-fi's tone-controls. This is also known as shelving equalisation (EQ).
-
-The filter accepts the following options:
-
-@table @option
-@item gain, g
-Give the gain at whichever is the lower of ~22 kHz and the
-Nyquist frequency. Its useful range is about -20 (for a large cut)
-to +20 (for a large boost). Beware of clipping when using a positive gain.
-
-@item frequency, f
-Set the filter's central frequency and so can be used
-to extend or reduce the frequency range to be boosted or cut.
-The default value is @code{3000} Hz.
-
-@item width_type
-Set method to specify band-width of filter.
-@table @option
-@item h
-Hz
-@item q
-Q-Factor
-@item o
-octave
-@item s
-slope
-@end table
-
-@item width, w
-Determine how steep is the filter's shelf transition.
-@end table
-
-@section bandpass
-
-Apply a two-pole Butterworth band-pass filter with central
-frequency @var{frequency}, and (3dB-point) band-width width.
-The @var{csg} option selects a constant skirt gain (peak gain = Q)
-instead of the default: constant 0dB peak gain.
-The filter roll off at 6dB per octave (20dB per decade).
-
-The filter accepts the following options:
-
-@table @option
-@item frequency, f
-Set the filter's central frequency. Default is @code{3000}.
-
-@item csg
-Constant skirt gain if set to 1. Defaults to 0.
-
-@item width_type
-Set method to specify band-width of filter.
-@table @option
-@item h
-Hz
-@item q
-Q-Factor
-@item o
-octave
-@item s
-slope
-@end table
-
-@item width, w
-Specify the band-width of a filter in width_type units.
-@end table
-
-@section bandreject
-
-Apply a two-pole Butterworth band-reject filter with central
-frequency @var{frequency}, and (3dB-point) band-width @var{width}.
-The filter roll off at 6dB per octave (20dB per decade).
-
-The filter accepts the following options:
-
-@table @option
-@item frequency, f
-Set the filter's central frequency. Default is @code{3000}.
-
-@item width_type
-Set method to specify band-width of filter.
-@table @option
-@item h
-Hz
-@item q
-Q-Factor
-@item o
-octave
-@item s
-slope
-@end table
-
-@item width, w
-Specify the band-width of a filter in width_type units.
-@end table
-
-@section biquad
-
-Apply a biquad IIR filter with the given coefficients.
-Where @var{b0}, @var{b1}, @var{b2} and @var{a0}, @var{a1}, @var{a2}
-are the numerator and denominator coefficients respectively.
-
-@section equalizer
-
-Apply a two-pole peaking equalisation (EQ) filter. With this
-filter, the signal-level at and around a selected frequency can
-be increased or decreased, whilst (unlike bandpass and bandreject
-filters) that at all other frequencies is unchanged.
-
-In order to produce complex equalisation curves, this filter can
-be given several times, each with a different central frequency.
-
-The filter accepts the following options:
-
-@table @option
-@item frequency, f
-Set the filter's central frequency in Hz.
-
-@item width_type
-Set method to specify band-width of filter.
-@table @option
-@item h
-Hz
-@item q
-Q-Factor
-@item o
-octave
-@item s
-slope
-@end table
-
-@item width, w
-Specify the band-width of a filter in width_type units.
-
-@item gain, g
-Set the required gain or attenuation in dB.
-Beware of clipping when using a positive gain.
-@end table
+@item
+Same as above but with one more mountain:
+@example
+aecho=0.8:0.9:1000|1800:0.3|0.25
+@end example
+@end itemize
 
 @section afade
 
@@ -707,7 +491,7 @@
 @item
 Fade out last 25 seconds of a 900 seconds audio:
 @example
-afade=t=out:ss=875:d=25
+afade=t=out:st=875:d=25
 @end example
 @end itemize
 
@@ -738,6 +522,36 @@
 aformat=sample_fmts=u8|s16:channel_layouts=stereo
 @end example
 
+@section allpass
+
+Apply a two-pole all-pass filter with central frequency (in Hz)
+@var{frequency}, and filter-width @var{width}.
+An all-pass filter changes the audio's frequency to phase relationship
+without changing its frequency to amplitude relationship.
+
+The filter accepts the following options:
+
+@table @option
+@item frequency, f
+Set frequency in Hz.
+
+@item width_type
+Set method to specify band-width of filter.
+@table @option
+@item h
+Hz
+@item q
+Q-Factor
+@item o
+octave
+@item s
+slope
+@end table
+
+@item width, w
+Specify the band-width of a filter in width_type units.
+@end table
+
 @section amerge
 
 Merge two or more audio streams into a single multi-channel stream.
@@ -990,6 +804,51 @@
 A list of Adler-32 checksums for each data plane.
 @end table
 
+@section astats
+
+Display time domain statistical information about the audio channels.
+Statistics are calculated and displayed for each audio channel and,
+where applicable, an overall figure is also given.
+
+The filter accepts the following option:
+@table @option
+@item length
+Short window length in seconds, used for peak and trough RMS measurement.
+Default is @code{0.05} (50 miliseconds). Allowed range is @code{[0.1 - 10]}.
+@end table
+
+A description of each shown parameter follows:
+
+@table @option
+@item DC offset
+Mean amplitude displacement from zero.
+
+@item Min level
+Minimal sample level.
+
+@item Max level
+Maximal sample level.
+
+@item Peak level dB
+@item RMS level dB
+Standard peak and RMS level measured in dBFS.
+
+@item RMS peak dB
+@item RMS trough dB
+Peak and trough values for RMS level measured over a short window.
+
+@item Crest factor
+Standard ratio of peak to RMS level (note: not in dB).
+
+@item Flat factor
+Flatness (i.e. consecutive samples with the same value) of the signal at its peak levels
+(i.e. either @var{Min level} or @var{Max level}).
+
+@item Peak count
+Number of occasions (not the number of samples) that the signal attained either
+@var{Min level} or @var{Max level}.
+@end table
+
 @section astreamsync
 
 Forward two audio streams and control the order the buffers are forwarded.
@@ -1026,6 +885,39 @@
 [a2] [b2] amerge
 @end example
 
+@section asyncts
+
+Synchronize audio data with timestamps by squeezing/stretching it and/or
+dropping samples/adding silence when needed.
+
+This filter is not built by default, please use @ref{aresample} to do squeezing/stretching.
+
+The filter accepts the following named parameters:
+@table @option
+
+@item compensate
+Enable stretching/squeezing the data to make it match the timestamps. Disabled
+by default. When disabled, time gaps are covered with silence.
+
+@item min_delta
+Minimum difference between timestamps and audio data (in seconds) to trigger
+adding/dropping samples. Default value is 0.1. If you get non-perfect sync with
+this filter, try setting this parameter to 0.
+
+@item max_comp
+Maximum compensation in samples per second. Relevant only with compensate=1.
+Default value 500.
+
+@item first_pts
+Assume the first pts should be this value. The time base is 1 / sample rate.
+This allows for padding/trimming at the start of stream. By default, no
+assumption is made about the first frame's expected pts, so no padding or
+trimming is done. For example, this could be set to 0 to pad the beginning with
+silence if an audio stream starts after the video stream or to trim any samples
+with a negative pts due to encoder delay.
+
+@end table
+
 @section atempo
 
 Adjust audio tempo.
@@ -1050,6 +942,317 @@
 @end example
 @end itemize
 
+@section atrim
+
+Trim the input so that the output contains one continuous subpart of the input.
+
+This filter accepts the following options:
+@table @option
+@item start
+Specify time of the start of the kept section, i.e. the audio sample
+with the timestamp @var{start} will be the first sample in the output.
+
+@item end
+Specify time of the first audio sample that will be dropped, i.e. the
+audio sample immediately preceding the one with the timestamp @var{end} will be
+the last sample in the output.
+
+@item start_pts
+Same as @var{start}, except this option sets the start timestamp in samples
+instead of seconds.
+
+@item end_pts
+Same as @var{end}, except this option sets the end timestamp in samples instead
+of seconds.
+
+@item duration
+Specify maximum duration of the output.
+
+@item start_sample
+Number of the first sample that should be passed to output.
+
+@item end_sample
+Number of the first sample that should be dropped.
+@end table
+
+@option{start}, @option{end}, @option{duration} are expressed as time
+duration specifications, check the "Time duration" section in the
+ffmpeg-utils manual.
+
+Note that the first two sets of the start/end options and the @option{duration}
+option look at the frame timestamp, while the _sample options simply count the
+samples that pass through the filter. So start/end_pts and start/end_sample will
+give different results when the timestamps are wrong, inexact or do not start at
+zero. Also note that this filter does not modify the timestamps. If you wish
+that the output timestamps start at zero, insert the asetpts filter after the
+atrim filter.
+
+If multiple start or end options are set, this filter tries to be greedy and
+keep all samples that match at least one of the specified constraints. To keep
+only the part that matches all the constraints at once, chain multiple atrim
+filters.
+
+The defaults are such that all the input is kept. So it is possible to set e.g.
+just the end values to keep everything before the specified time.
+
+Examples:
+@itemize
+@item
+drop everything except the second minute of input
+@example
+ffmpeg -i INPUT -af atrim=60:120
+@end example
+
+@item
+keep only the first 1000 samples
+@example
+ffmpeg -i INPUT -af atrim=end_sample=1000
+@end example
+
+@end itemize
+
+@section bandpass
+
+Apply a two-pole Butterworth band-pass filter with central
+frequency @var{frequency}, and (3dB-point) band-width width.
+The @var{csg} option selects a constant skirt gain (peak gain = Q)
+instead of the default: constant 0dB peak gain.
+The filter roll off at 6dB per octave (20dB per decade).
+
+The filter accepts the following options:
+
+@table @option
+@item frequency, f
+Set the filter's central frequency. Default is @code{3000}.
+
+@item csg
+Constant skirt gain if set to 1. Defaults to 0.
+
+@item width_type
+Set method to specify band-width of filter.
+@table @option
+@item h
+Hz
+@item q
+Q-Factor
+@item o
+octave
+@item s
+slope
+@end table
+
+@item width, w
+Specify the band-width of a filter in width_type units.
+@end table
+
+@section bandreject
+
+Apply a two-pole Butterworth band-reject filter with central
+frequency @var{frequency}, and (3dB-point) band-width @var{width}.
+The filter roll off at 6dB per octave (20dB per decade).
+
+The filter accepts the following options:
+
+@table @option
+@item frequency, f
+Set the filter's central frequency. Default is @code{3000}.
+
+@item width_type
+Set method to specify band-width of filter.
+@table @option
+@item h
+Hz
+@item q
+Q-Factor
+@item o
+octave
+@item s
+slope
+@end table
+
+@item width, w
+Specify the band-width of a filter in width_type units.
+@end table
+
+@section bass
+
+Boost or cut the bass (lower) frequencies of the audio using a two-pole
+shelving filter with a response similar to that of a standard
+hi-fi's tone-controls. This is also known as shelving equalisation (EQ).
+
+The filter accepts the following options:
+
+@table @option
+@item gain, g
+Give the gain at 0 Hz. Its useful range is about -20
+(for a large cut) to +20 (for a large boost).
+Beware of clipping when using a positive gain.
+
+@item frequency, f
+Set the filter's central frequency and so can be used
+to extend or reduce the frequency range to be boosted or cut.
+The default value is @code{100} Hz.
+
+@item width_type
+Set method to specify band-width of filter.
+@table @option
+@item h
+Hz
+@item q
+Q-Factor
+@item o
+octave
+@item s
+slope
+@end table
+
+@item width, w
+Determine how steep is the filter's shelf transition.
+@end table
+
+@section biquad
+
+Apply a biquad IIR filter with the given coefficients.
+Where @var{b0}, @var{b1}, @var{b2} and @var{a0}, @var{a1}, @var{a2}
+are the numerator and denominator coefficients respectively.
+
+@section channelmap
+
+Remap input channels to new locations.
+
+This filter accepts the following named parameters:
+@table @option
+@item channel_layout
+Channel layout of the output stream.
+
+@item map
+Map channels from input to output. The argument is a '|'-separated list of
+mappings, each in the @code{@var{in_channel}-@var{out_channel}} or
+@var{in_channel} form. @var{in_channel} can be either the name of the input
+channel (e.g. FL for front left) or its index in the input channel layout.
+@var{out_channel} is the name of the output channel or its index in the output
+channel layout. If @var{out_channel} is not given then it is implicitly an
+index, starting with zero and increasing by one for each mapping.
+@end table
+
+If no mapping is present, the filter will implicitly map input channels to
+output channels preserving index.
+
+For example, assuming a 5.1+downmix input MOV file
+@example
+ffmpeg -i in.mov -filter 'channelmap=map=DL-FL|DR-FR' out.wav
+@end example
+will create an output WAV file tagged as stereo from the downmix channels of
+the input.
+
+To fix a 5.1 WAV improperly encoded in AAC's native channel order
+@example
+ffmpeg -i in.wav -filter 'channelmap=1|2|0|5|3|4:channel_layout=5.1' out.wav
+@end example
+
+@section channelsplit
+
+Split each channel in input audio stream into a separate output stream.
+
+This filter accepts the following named parameters:
+@table @option
+@item channel_layout
+Channel layout of the input stream. Default is "stereo".
+@end table
+
+For example, assuming a stereo input MP3 file
+@example
+ffmpeg -i in.mp3 -filter_complex channelsplit out.mkv
+@end example
+will create an output Matroska file with two audio streams, one containing only
+the left channel and the other the right channel.
+
+To split a 5.1 WAV file into per-channel files
+@example
+ffmpeg -i in.wav -filter_complex
+'channelsplit=channel_layout=5.1[FL][FR][FC][LFE][SL][SR]'
+-map '[FL]' front_left.wav -map '[FR]' front_right.wav -map '[FC]'
+front_center.wav -map '[LFE]' lfe.wav -map '[SL]' side_left.wav -map '[SR]'
+side_right.wav
+@end example
+
+@section compand
+
+Compress or expand audio dynamic range.
+
+A description of the accepted options follows.
+
+@table @option
+@item attacks
+@item decays
+Set list of times in seconds for each channel over which the instantaneous
+level of the input signal is averaged to determine its volume.
+@option{attacks} refers to increase of volume and @option{decays} refers
+to decrease of volume.
+For most situations, the attack time (response to the audio getting louder)
+should be shorter than the decay time because the human ear is more sensitive
+to sudden loud audio than sudden soft audio.
+Typical value for attack is @code{0.3} seconds and for decay @code{0.8}
+seconds.
+
+@item points
+Set list of points for transfer function, specified in dB relative to maximum
+possible signal amplitude.
+Each key points list need to be defined using the following syntax:
+@code{x0/y0 x1/y1 x2/y2 ...}.
+
+The input values must be in strictly increasing order but the transfer
+function does not have to be monotonically rising.
+The point @code{0/0} is assumed but may be overridden (by @code{0/out-dBn}).
+Typical values for the transfer function are @code{-70/-70 -60/-20}.
+
+@item soft-knee
+Set amount for which the points at where adjacent line segments on the
+transfer function meet will be rounded. Defaults is @code{0.01}.
+
+@item gain
+Set additional gain in dB to be applied at all points on the transfer function
+and allows easy adjustment of the overall gain.
+Default is @code{0}.
+
+@item volume
+Set initial volume in dB to be assumed for each channel when filtering starts.
+This permits the user to supply a nominal level initially, so that,
+for example, a very large gain is not applied to initial signal levels before
+the companding has begun to operate. A typical value for audio which is
+initially quiet is -90 dB. Default is @code{0}.
+
+@item delay
+Set delay in seconds. Default is @code{0}. The input audio
+is analysed immediately, but audio is delayed before being fed to the
+volume adjuster. Specifying a delay approximately equal to the attack/decay
+times allows the filter to effectively operate in predictive rather than
+reactive mode.
+@end table
+
+@subsection Examples
+@itemize
+@item
+Make music with both quiet and loud passages suitable for listening
+in a noisy environment:
+@example
+compand=.3 .3:1 1:-90/-60 -60/-40 -40/-30 -20/-20:6:0:-90:0.2
+@end example
+
+@item
+Noise-gate for when the noise is at a lower level than the signal:
+@example
+compand=.1 .1:.2 .2:-900/-900 -50.1/-900 -50/-50:.01:0:-90:.1
+@end example
+
+@item
+Here is another noise-gate, this time for when the noise is at a higher level
+than the signal (making it, in some ways, similar to squelch):
+@example
+compand=.1 .1:.1 .1:-45.1/-45.1 -45/-900 0/-900:.01:45:-90:.1
+@end example
+@end itemize
+
 @section earwax
 
 Make audio easier to listen to on headphones.
@@ -1061,6 +1264,149 @@
 
 Ported from SoX.
 
+@section equalizer
+
+Apply a two-pole peaking equalisation (EQ) filter. With this
+filter, the signal-level at and around a selected frequency can
+be increased or decreased, whilst (unlike bandpass and bandreject
+filters) that at all other frequencies is unchanged.
+
+In order to produce complex equalisation curves, this filter can
+be given several times, each with a different central frequency.
+
+The filter accepts the following options:
+
+@table @option
+@item frequency, f
+Set the filter's central frequency in Hz.
+
+@item width_type
+Set method to specify band-width of filter.
+@table @option
+@item h
+Hz
+@item q
+Q-Factor
+@item o
+octave
+@item s
+slope
+@end table
+
+@item width, w
+Specify the band-width of a filter in width_type units.
+
+@item gain, g
+Set the required gain or attenuation in dB.
+Beware of clipping when using a positive gain.
+@end table
+
+@section highpass
+
+Apply a high-pass filter with 3dB point frequency.
+The filter can be either single-pole, or double-pole (the default).
+The filter roll off at 6dB per pole per octave (20dB per pole per decade).
+
+The filter accepts the following options:
+
+@table @option
+@item frequency, f
+Set frequency in Hz. Default is 3000.
+
+@item poles, p
+Set number of poles. Default is 2.
+
+@item width_type
+Set method to specify band-width of filter.
+@table @option
+@item h
+Hz
+@item q
+Q-Factor
+@item o
+octave
+@item s
+slope
+@end table
+
+@item width, w
+Specify the band-width of a filter in width_type units.
+Applies only to double-pole filter.
+The default is 0.707q and gives a Butterworth response.
+@end table
+
+@section join
+
+Join multiple input streams into one multi-channel stream.
+
+The filter accepts the following named parameters:
+@table @option
+
+@item inputs
+Number of input streams. Defaults to 2.
+
+@item channel_layout
+Desired output channel layout. Defaults to stereo.
+
+@item map
+Map channels from inputs to output. The argument is a '|'-separated list of
+mappings, each in the @code{@var{input_idx}.@var{in_channel}-@var{out_channel}}
+form. @var{input_idx} is the 0-based index of the input stream. @var{in_channel}
+can be either the name of the input channel (e.g. FL for front left) or its
+index in the specified input stream. @var{out_channel} is the name of the output
+channel.
+@end table
+
+The filter will attempt to guess the mappings when those are not specified
+explicitly. It does so by first trying to find an unused matching input channel
+and if that fails it picks the first unused input channel.
+
+E.g. to join 3 inputs (with properly set channel layouts)
+@example
+ffmpeg -i INPUT1 -i INPUT2 -i INPUT3 -filter_complex join=inputs=3 OUTPUT
+@end example
+
+To build a 5.1 output from 6 single-channel streams:
+@example
+ffmpeg -i fl -i fr -i fc -i sl -i sr -i lfe -filter_complex
+'join=inputs=6:channel_layout=5.1:map=0.0-FL|1.0-FR|2.0-FC|3.0-SL|4.0-SR|5.0-LFE'
+out
+@end example
+
+@section lowpass
+
+Apply a low-pass filter with 3dB point frequency.
+The filter can be either single-pole or double-pole (the default).
+The filter roll off at 6dB per pole per octave (20dB per pole per decade).
+
+The filter accepts the following options:
+
+@table @option
+@item frequency, f
+Set frequency in Hz. Default is 500.
+
+@item poles, p
+Set number of poles. Default is 2.
+
+@item width_type
+Set method to specify band-width of filter.
+@table @option
+@item h
+Hz
+@item q
+Q-Factor
+@item o
+octave
+@item s
+slope
+@end table
+
+@item width, w
+Specify the band-width of a filter in width_type units.
+Applies only to double-pole filter.
+The default is 0.707q and gives a Butterworth response.
+@end table
+
 @section pan
 
 Mix channels with specific gain levels. The filter accepts the output
@@ -1151,6 +1497,11 @@
 pan="stereo: c0=FR : c1=FR"
 @end example
 
+@section resample
+
+Convert the audio sample format, sample rate and channel layout. This filter is
+not meant to be used directly.
+
 @section silencedetect
 
 Detect silence in an audio stream.
@@ -1189,137 +1540,42 @@
 @end example
 @end itemize
 
-@section asyncts
-Synchronize audio data with timestamps by squeezing/stretching it and/or
-dropping samples/adding silence when needed.
+@section treble
 
-This filter is not built by default, please use @ref{aresample} to do squeezing/stretching.
+Boost or cut treble (upper) frequencies of the audio using a two-pole
+shelving filter with a response similar to that of a standard
+hi-fi's tone-controls. This is also known as shelving equalisation (EQ).
 
-The filter accepts the following named parameters:
+The filter accepts the following options:
+
 @table @option
+@item gain, g
+Give the gain at whichever is the lower of ~22 kHz and the
+Nyquist frequency. Its useful range is about -20 (for a large cut)
+to +20 (for a large boost). Beware of clipping when using a positive gain.
 
-@item compensate
-Enable stretching/squeezing the data to make it match the timestamps. Disabled
-by default. When disabled, time gaps are covered with silence.
+@item frequency, f
+Set the filter's central frequency and so can be used
+to extend or reduce the frequency range to be boosted or cut.
+The default value is @code{3000} Hz.
 
-@item min_delta
-Minimum difference between timestamps and audio data (in seconds) to trigger
-adding/dropping samples. Default value is 0.1. If you get non-perfect sync with
-this filter, try setting this parameter to 0.
-
-@item max_comp
-Maximum compensation in samples per second. Relevant only with compensate=1.
-Default value 500.
-
-@item first_pts
-Assume the first pts should be this value. The time base is 1 / sample rate.
-This allows for padding/trimming at the start of stream. By default, no
-assumption is made about the first frame's expected pts, so no padding or
-trimming is done. For example, this could be set to 0 to pad the beginning with
-silence if an audio stream starts after the video stream or to trim any samples
-with a negative pts due to encoder delay.
-
+@item width_type
+Set method to specify band-width of filter.
+@table @option
+@item h
+Hz
+@item q
+Q-Factor
+@item o
+octave
+@item s
+slope
 @end table
 
-@section channelsplit
-Split each channel in input audio stream into a separate output stream.
-
-This filter accepts the following named parameters:
-@table @option
-@item channel_layout
-Channel layout of the input stream. Default is "stereo".
+@item width, w
+Determine how steep is the filter's shelf transition.
 @end table
 
-For example, assuming a stereo input MP3 file
-@example
-ffmpeg -i in.mp3 -filter_complex channelsplit out.mkv
-@end example
-will create an output Matroska file with two audio streams, one containing only
-the left channel and the other the right channel.
-
-To split a 5.1 WAV file into per-channel files
-@example
-ffmpeg -i in.wav -filter_complex
-'channelsplit=channel_layout=5.1[FL][FR][FC][LFE][SL][SR]'
--map '[FL]' front_left.wav -map '[FR]' front_right.wav -map '[FC]'
-front_center.wav -map '[LFE]' lfe.wav -map '[SL]' side_left.wav -map '[SR]'
-side_right.wav
-@end example
-
-@section channelmap
-Remap input channels to new locations.
-
-This filter accepts the following named parameters:
-@table @option
-@item channel_layout
-Channel layout of the output stream.
-
-@item map
-Map channels from input to output. The argument is a '|'-separated list of
-mappings, each in the @code{@var{in_channel}-@var{out_channel}} or
-@var{in_channel} form. @var{in_channel} can be either the name of the input
-channel (e.g. FL for front left) or its index in the input channel layout.
-@var{out_channel} is the name of the output channel or its index in the output
-channel layout. If @var{out_channel} is not given then it is implicitly an
-index, starting with zero and increasing by one for each mapping.
-@end table
-
-If no mapping is present, the filter will implicitly map input channels to
-output channels preserving index.
-
-For example, assuming a 5.1+downmix input MOV file
-@example
-ffmpeg -i in.mov -filter 'channelmap=map=DL-FL|DR-FR' out.wav
-@end example
-will create an output WAV file tagged as stereo from the downmix channels of
-the input.
-
-To fix a 5.1 WAV improperly encoded in AAC's native channel order
-@example
-ffmpeg -i in.wav -filter 'channelmap=1|2|0|5|3|4:channel_layout=5.1' out.wav
-@end example
-
-@section join
-Join multiple input streams into one multi-channel stream.
-
-The filter accepts the following named parameters:
-@table @option
-
-@item inputs
-Number of input streams. Defaults to 2.
-
-@item channel_layout
-Desired output channel layout. Defaults to stereo.
-
-@item map
-Map channels from inputs to output. The argument is a '|'-separated list of
-mappings, each in the @code{@var{input_idx}.@var{in_channel}-@var{out_channel}}
-form. @var{input_idx} is the 0-based index of the input stream. @var{in_channel}
-can be either the name of the input channel (e.g. FL for front left) or its
-index in the specified input stream. @var{out_channel} is the name of the output
-channel.
-@end table
-
-The filter will attempt to guess the mappings when those are not specified
-explicitly. It does so by first trying to find an unused matching input channel
-and if that fails it picks the first unused input channel.
-
-E.g. to join 3 inputs (with properly set channel layouts)
-@example
-ffmpeg -i INPUT1 -i INPUT2 -i INPUT3 -filter_complex join=inputs=3 OUTPUT
-@end example
-
-To build a 5.1 output from 6 single-channel streams:
-@example
-ffmpeg -i fl -i fr -i fc -i sl -i sr -i lfe -filter_complex
-'join=inputs=6:channel_layout=5.1:map=0.0-FL|1.0-FR|2.0-FC|3.0-SL|4.0-SR|5.0-LFE'
-out
-@end example
-
-@section resample
-Convert the audio sample format, sample rate and channel layout. This filter is
-not meant to be used directly.
-
 @section volume
 
 Adjust the input audio volume.
@@ -1388,7 +1644,7 @@
 the volume will be printed in the log when the input stream end is reached.
 
 In particular it will show the mean volume (root mean square), maximum
-volume (on a per-sample basis), and the beginning of an histogram of the
+volume (on a per-sample basis), and the beginning of a histogram of the
 registered volume values (from the maximum value to a cumulated 1/1000 of
 the samples).
 
@@ -1619,31 +1875,6 @@
 @end example
 @end itemize
 
-@section abuffer
-Buffer audio frames, and make them available to the filter chain.
-
-This source is not intended to be part of user-supplied graph descriptions but
-for insertion by calling programs through the interface defined in
-@file{libavfilter/buffersrc.h}.
-
-It accepts the following named parameters:
-@table @option
-
-@item time_base
-Timebase which will be used for timestamps of submitted frames. It must be
-either a floating-point number or in @var{numerator}/@var{denominator} form.
-
-@item sample_rate
-Audio sample rate.
-
-@item sample_fmt
-Name of the sample format, as returned by @code{av_get_sample_fmt_name()}.
-
-@item channel_layout
-Channel layout of the audio data, in the form that can be accepted by
-@code{av_get_channel_layout()}.
-@end table
-
 All the parameters need to be explicitly defined.
 
 @section flite
@@ -1727,7 +1958,7 @@
 Enable a periodic beep every second with frequency @var{beep_factor} times
 the carrier frequency. Default is 0, meaning the beep is disabled.
 
-@item sample_rate, s
+@item sample_rate, r
 Specify the sample rate, default is 44100.
 
 @item duration, d
@@ -1835,6 +2066,13 @@
 The parameters describing the bounding box are printed on the filter
 log.
 
+The filter accepts the following option:
+
+@table @option
+@item min_val
+Set the minimal luminance value. Default is @code{16}.
+@end table
+
 @section blackdetect
 
 Detect video intervals that are (almost) completely black. Can be
@@ -2004,6 +2242,13 @@
 @item BOTTOM, B
 Value of pixel component at current location for second video frame (bottom layer).
 @end table
+
+@item shortest
+Force termination when the shortest input terminates. Default is @code{0}.
+@item repeatlast
+Continue applying the last bottom frame after the end of the stream. A value of
+@code{0} disable the filter after the last frame of the bottom layer is reached.
+Default is @code{1}.
 @end table
 
 @subsection Examples
@@ -2059,13 +2304,16 @@
 
 The expressions can contain the following constants:
 @table @option
-@item w, h
+@item w
+@item h
 the input width and height in pixels
 
-@item cw, ch
+@item cw
+@item ch
 the input chroma image width and height in pixels
 
-@item hsub, vsub
+@item hsub
+@item vsub
 horizontal and vertical chroma subsample values. For example for the
 pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
 @end table
@@ -2200,6 +2448,11 @@
 @example
 colorchannelmixer=.3:.4:.3:0:.3:.4:.3:0:.3:.4:.3
 @end example
+@item
+Simulate sepia tones:
+@example
+colorchannelmixer=.393:.769:.189:0:.349:.686:.168:0:.272:.534:.131
+@end example
 @end itemize
 
 @section colormatrix
@@ -2277,20 +2530,25 @@
 expressions containing the following constants:
 
 @table @option
-@item x, y
+@item x
+@item y
 the computed values for @var{x} and @var{y}. They are evaluated for
 each new frame.
 
-@item in_w, in_h
+@item in_w
+@item in_h
 the input width and height
 
-@item iw, ih
+@item iw
+@item ih
 same as @var{in_w} and @var{in_h}
 
-@item out_w, out_h
+@item out_w
+@item out_h
 the output (cropped) width and height
 
-@item ow, oh
+@item ow
+@item oh
 same as @var{out_w} and @var{out_h}
 
 @item a
@@ -2302,7 +2560,8 @@
 @item dar
 input display aspect ratio, it is the same as (@var{iw} / @var{ih}) * @var{sar}
 
-@item hsub, vsub
+@item hsub
+@item vsub
 horizontal and vertical chroma subsample values. For example for the
 pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
 
@@ -2556,6 +2815,59 @@
 @end example
 @end itemize
 
+@section dctdnoiz
+
+Denoise frames using 2D DCT (frequency domain filtering).
+
+This filter is not designed for real time and can be extremely slow.
+
+The filter accepts the following options:
+
+@table @option
+@item sigma, s
+Set the noise sigma constant.
+
+This @var{sigma} defines a hard threshold of @code{3 * sigma}; every DCT
+coefficient (absolute value) below this threshold with be dropped.
+
+If you need a more advanced filtering, see @option{expr}.
+
+Default is @code{0}.
+
+@item overlap
+Set number overlapping pixels for each block. Each block is of size
+@code{16x16}. Since the filter can be slow, you may want to reduce this value,
+at the cost of a less effective filter and the risk of various artefacts.
+
+If the overlapping value doesn't allow to process the whole input width or
+height, a warning will be displayed and according borders won't be denoised.
+
+Default value is @code{15}.
+
+@item expr, e
+Set the coefficient factor expression.
+
+For each coefficient of a DCT block, this expression will be evaluated as a
+multiplier value for the coefficient.
+
+If this is option is set, the @option{sigma} option will be ignored.
+
+The absolute value of the coefficient can be accessed through the @var{c}
+variable.
+@end table
+
+@subsection Examples
+
+Apply a denoise with a @option{sigma} of @code{4.5}:
+@example
+dctdnoiz=4.5
+@end example
+
+The same operation can be achieved using the expression system:
+@example
+dctdnoiz=e='gte(c, 4.5*3)'
+@end example
+
 @anchor{decimate}
 @section decimate
 
@@ -2605,11 +2917,13 @@
 This filter accepts the following options:
 @table @option
 
-@item x, y
+@item x
+@item y
 Specify the top left corner coordinates of the logo. They must be
 specified.
 
-@item w, h
+@item w
+@item h
 Specify the width and height of the logo to clear. They must be
 specified.
 
@@ -2619,8 +2933,13 @@
 
 @item show
 When set to 1, a green rectangle is drawn on the screen to simplify
-finding the right @var{x}, @var{y}, @var{w}, @var{h} parameters, and
-@var{band} is set to 4. The default value is 0.
+finding the right @var{x}, @var{y}, @var{w}, and @var{h} parameters.
+The default value is 0.
+
+The rectangle is drawn on the outermost pixels which will be (partly)
+replaced with interpolated values. The values of the next pixels
+immediately outside this rectangle in each direction will be used to
+compute the interpolated pixel values inside the rectangle.
 
 @end table
 
@@ -2723,12 +3042,13 @@
 This filter accepts the following options:
 
 @table @option
-@item x, y
-Specify the top left corner coordinates of the box. Default to 0.
+@item x
+@item y
+The expressions which specify the top left corner coordinates of the box. Default to 0.
 
 @item width, w
 @item height, h
-Specify the width and height of the box, if 0 they are interpreted as
+The expressions which specify the width and height of the box, if 0 they are interpreted as
 the input width and height. Default to 0.
 
 @item color, c
@@ -2738,7 +3058,44 @@
 video with inverted luma.
 
 @item thickness, t
-Set the thickness of the box edge. Default value is @code{4}.
+The expression which sets the thickness of the box edge. Default value is @code{3}.
+
+See below for the list of accepted constants.
+@end table
+
+The parameters for @var{x}, @var{y}, @var{w} and @var{h} and @var{t} are expressions containing the
+following constants:
+
+@table @option
+@item dar
+The input display aspect ratio, it is the same as (@var{w} / @var{h}) * @var{sar}.
+
+@item hsub
+@item vsub
+horizontal and vertical chroma subsample values. For example for the
+pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
+
+@item in_h, ih
+@item in_w, iw
+The input width and height.
+
+@item sar
+The input sample aspect ratio.
+
+@item x
+@item y
+The x and y offset coordinates where the box is drawn.
+
+@item w
+@item h
+The width and height of the drawn box.
+
+@item t
+The thickness of the drawn box.
+
+These constants allow the @var{x}, @var{y}, @var{w}, @var{h} and @var{t} expressions to refer to
+each other, so you may for example specify @code{y=x/dar} or @code{h=w/dar}.
+
 @end table
 
 @subsection Examples
@@ -2766,6 +3123,94 @@
 @example
 drawbox=x=10:y=10:w=100:h=100:color=pink@@0.5:t=max
 @end example
+
+@item
+Draw a 2-pixel red 2.40:1 mask:
+@example
+drawbox=x=-t:y=0.5*(ih-iw/2.4)-t:w=iw+t*2:h=iw/2.4+t*2:t=2:c=red
+@end example
+@end itemize
+
+@section drawgrid
+
+Draw a grid on the input image.
+
+This filter accepts the following options:
+
+@table @option
+@item x
+@item y
+The expressions which specify the coordinates of some point of grid intersection (meant to configure offset). Both default to 0.
+
+@item width, w
+@item height, h
+The expressions which specify the width and height of the grid cell, if 0 they are interpreted as the
+input width and height, respectively, minus @code{thickness}, so image gets
+framed. Default to 0.
+
+@item color, c
+Specify the color of the grid, it can be the name of a color
+(case insensitive match) or a 0xRRGGBB[AA] sequence. If the special
+value @code{invert} is used, the grid color is the same as the
+video with inverted luma.
+Note that you can append opacity value (in range of 0.0 - 1.0)
+to color name after @@ sign.
+
+@item thickness, t
+The expression which sets the thickness of the grid line. Default value is @code{1}.
+
+See below for the list of accepted constants.
+@end table
+
+The parameters for @var{x}, @var{y}, @var{w} and @var{h} and @var{t} are expressions containing the
+following constants:
+
+@table @option
+@item dar
+The input display aspect ratio, it is the same as (@var{w} / @var{h}) * @var{sar}.
+
+@item hsub
+@item vsub
+horizontal and vertical chroma subsample values. For example for the
+pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
+
+@item in_h, ih
+@item in_w, iw
+The input grid cell width and height.
+
+@item sar
+The input sample aspect ratio.
+
+@item x
+@item y
+The x and y coordinates of some point of grid intersection (meant to configure offset).
+
+@item w
+@item h
+The width and height of the drawn cell.
+
+@item t
+The thickness of the drawn cell.
+
+These constants allow the @var{x}, @var{y}, @var{w}, @var{h} and @var{t} expressions to refer to
+each other, so you may for example specify @code{y=x/dar} or @code{h=w/dar}.
+
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Draw a grid with cell 100x100 pixels, thickness 2 pixels, with color red and an opacity of 50%:
+@example
+drawgrid=width=100:height=100:thickness=2:color=red@@0.5
+@end example
+
+@item
+Draw a white 3x3 grid with an opacity of 50%:
+@example
+drawgrid=w=iw/3:h=ih/3:t=2:c=white@@0.5
+@end example
 @end itemize
 
 @anchor{drawtext}
@@ -2848,7 +3293,6 @@
 @item monochrome
 @item linear_design
 @item no_autohint
-@item end table
 @end table
 
 Default value is "render".
@@ -2862,11 +3306,16 @@
 form (e.g. "0xff00ff"), possibly followed by an alpha specifier.
 The default value of @var{shadowcolor} is "black".
 
-@item shadowx, shadowy
+@item shadowx
+@item shadowy
 The x and y offsets for the text shadow position with respect to the
 position of the text. They can be either positive or negative
 values. Default value for both is "0".
 
+@item start_number
+The starting frame number for the n/frame_num variable. The default value
+is "0".
+
 @item tabsize
 The size in number of spaces to use for rendering the tab.
 Default value is 4.
@@ -2898,7 +3347,8 @@
 If set to 1, the @var{textfile} will be reloaded before each frame.
 Be sure to update it atomically, or it may be read partially, or even fail.
 
-@item x, y
+@item x
+@item y
 The expressions which specify the offsets where text will be drawn
 within the video frame. They are relative to the top/left border of the
 output image.
@@ -2915,7 +3365,8 @@
 @item dar
 input display aspect ratio, it is the same as (@var{w} / @var{h}) * @var{sar}
 
-@item hsub, vsub
+@item hsub
+@item vsub
 horizontal and vertical chroma subsample values. For example for the
 pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
 
@@ -2968,7 +3419,8 @@
 @item text_w, tw
 the width of the rendered text
 
-@item x, y
+@item x
+@item y
 the x and y offset coordinates where the text is drawn.
 
 These parameters allow the @var{x} and @var{y} expressions to refer
@@ -3027,6 +3479,9 @@
 The time at which the filter is running, expressed in the local time zone.
 It can accept an argument: a strftime() format string.
 
+@item metadata
+Frame metadata. It must take one argument specifying metadata key.
+
 @item n, frame_num
 The frame number, starting from 0.
 
@@ -3123,7 +3578,8 @@
 The filter accepts the following options:
 
 @table @option
-@item low, high
+@item low
+@item high
 Set low and high threshold values used by the Canny thresholding
 algorithm.
 
@@ -3143,6 +3599,44 @@
 edgedetect=low=0.1:high=0.4
 @end example
 
+@section extractplanes
+
+Extract color channel components from input video stream into
+separate grayscale video streams.
+
+The filter accepts the following option:
+
+@table @option
+@item planes
+Set plane(s) to extract.
+
+Available values for planes are:
+@table @samp
+@item y
+@item u
+@item v
+@item a
+@item r
+@item g
+@item b
+@end table
+
+Choosing planes not available in the input will result in an error.
+That means you cannot select @code{r}, @code{g}, @code{b} planes
+with @code{y}, @code{u}, @code{v} planes at same time.
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Extract luma, u and v color channel component from input video frame
+into 3 grayscale outputs:
+@example
+ffmpeg -i video.avi -filter_complex 'extractplanes=y+u+v[y][u][v]' -map '[y]' y.avi -map '[u]' u.avi -map '[v]' v.avi
+@end example
+@end itemize
+
 @section fade
 
 Apply fade-in/out effect to input video.
@@ -3292,7 +3786,7 @@
 
 @item mode
 Set the matching mode or strategy to use. @option{pc} mode is the safest in the
-sense that it wont risk creating jerkiness due to duplicate frames when
+sense that it won't risk creating jerkiness due to duplicate frames when
 possible, but if there are bad edits or blended fields it will end up
 outputting combed frames when a good match might actually exist. On the other
 hand, @option{pcn_ub} mode is the most risky in terms of creating jerkiness,
@@ -3665,6 +4159,14 @@
 @end table
 The default is @code{near}.
 
+@item start_time
+Assume the first PTS should be the given value, in seconds. This allows for
+padding/trimming at the start of stream. By default, no assumption is made
+about the first frame's expected PTS, so no padding or trimming is done.
+For example, this could be set to 0 to pad the beginning with duplicates of
+the first frame if a video stream starts after the audio stream or to trim any
+frames with a negative PTS.
+
 @end table
 
 Alternatively, the options can be specified as a flat string:
@@ -3672,6 +4174,22 @@
 
 See also the @ref{setpts} filter.
 
+@subsection Examples
+
+@itemize
+@item
+A typical usage in order to set the fps to 25:
+@example
+fps=fps=25
+@end example
+
+@item
+Sets the fps to 24, using abbreviation and rounding method to round to nearest:
+@example
+fps=fps=film:round=near
+@end example
+@end itemize
+
 @section framestep
 
 Select one frame every N-th frame.
@@ -3751,26 +4269,33 @@
 The filter accepts the following options:
 
 @table @option
-@item lum_expr
-the luminance expression
-@item cb_expr
-the chrominance blue expression
-@item cr_expr
-the chrominance red expression
-@item alpha_expr
-the alpha expression
-@item r
-the red expression
-@item g
-the green expression
-@item b
-the blue expression
+@item lum_expr, lum
+Set the luminance expression.
+@item cb_expr, cb
+Set the chrominance blue expression.
+@item cr_expr, cr
+Set the chrominance red expression.
+@item alpha_expr, a
+Set the alpha expression.
+@item red_expr, r
+Set the red expression.
+@item green_expr, g
+Set the green expression.
+@item blue_expr, b
+Set the blue expression.
 @end table
 
+The colorspace is selected according to the specified options. If one
+of the @option{lum_expr}, @option{cb_expr}, or @option{cr_expr}
+options is specified, the filter will automatically select a YCbCr
+colorspace. If one of the @option{red_expr}, @option{green_expr}, or
+@option{blue_expr} options is specified, it will select an RGB
+colorspace.
+
 If one of the chrominance expression is not defined, it falls back on the other
 one. If no alpha expression is specified it will evaluate to opaque value.
-If none of chrominance expressions are
-specified, they will evaluate the luminance expression.
+If none of chrominance expressions are specified, they will evaluate
+to the luminance expression.
 
 The expressions can use the following variables and functions:
 
@@ -3806,15 +4331,21 @@
 
 @item cb(x, y)
 Return the value of the pixel at location (@var{x},@var{y}) of the
-blue-difference chroma plane. Returns 0 if there is no such plane.
+blue-difference chroma plane. Return 0 if there is no such plane.
 
 @item cr(x, y)
 Return the value of the pixel at location (@var{x},@var{y}) of the
-red-difference chroma plane. Returns 0 if there is no such plane.
+red-difference chroma plane. Return 0 if there is no such plane.
+
+@item r(x, y)
+@item g(x, y)
+@item b(x, y)
+Return the value of the pixel at location (@var{x},@var{y}) of the
+red/green/blue component. Return 0 if there is no such component.
 
 @item alpha(x, y)
 Return the value of the pixel at location (@var{x},@var{y}) of the alpha
-plane. Returns 0 if there is no such plane.
+plane. Return 0 if there is no such plane.
 @end table
 
 For functions, if @var{x} and @var{y} are outside the area, the value will be
@@ -3847,6 +4378,12 @@
 @example
 format=gray,geq=lum_expr='(p(X,Y)+(256-p(X-4,Y-4)))/2'
 @end example
+
+@item
+Modify RGB components depending on pixel position:
+@example
+geq=r='X/W*r(X,Y)':g='(1-X/W)*g(X,Y)':b='(H-Y)/H*b(X,Y)'
+@end example
 @end itemize
 
 @section gradfun
@@ -3899,6 +4436,79 @@
 
 @end itemize
 
+@anchor{haldclut}
+@section haldclut
+
+Apply a Hald CLUT to a video stream.
+
+First input is the video stream to process, and second one is the Hald CLUT.
+The Hald CLUT input can be a simple picture or a complete video stream.
+
+The filter accepts the following options:
+
+@table @option
+@item shortest
+Force termination when the shortest input terminates. Default is @code{0}.
+@item repeatlast
+Continue applying the last CLUT after the end of the stream. A value of
+@code{0} disable the filter after the last frame of the CLUT is reached.
+Default is @code{1}.
+@end table
+
+@code{haldclut} also has the same interpolation options as @ref{lut3d} (both
+filters share the same internals).
+
+More information about the Hald CLUT can be found on Eskil Steenberg's website
+(Hald CLUT author) at @url{http://www.quelsolaar.com/technology/clut.html}.
+
+@subsection Workflow examples
+
+@subsubsection Hald CLUT video stream
+
+Generate an identity Hald CLUT stream altered with various effects:
+@example
+ffmpeg -f lavfi -i @ref{haldclutsrc}=8 -vf "hue=H=2*PI*t:s=sin(2*PI*t)+1, curves=cross_process" -t 10 -c:v ffv1 clut.nut
+@end example
+
+Note: make sure you use a lossless codec.
+
+Then use it with @code{haldclut} to apply it on some random stream:
+@example
+ffmpeg -f lavfi -i mandelbrot -i clut.nut -filter_complex '[0][1] haldclut' -t 20 mandelclut.mkv
+@end example
+
+The Hald CLUT will be applied to the 10 first seconds (duration of
+@file{clut.nut}), then the latest picture of that CLUT stream will be applied
+to the remaining frames of the @code{mandelbrot} stream.
+
+@subsubsection Hald CLUT with preview
+
+A Hald CLUT is supposed to be a squared image of @code{Level*Level*Level} by
+@code{Level*Level*Level} pixels. For a given Hald CLUT, FFmpeg will select the
+biggest possible square starting at the top left of the picture. The remaining
+padding pixels (bottom or right) will be ignored. This area can be used to add
+a preview of the Hald CLUT.
+
+Typically, the following generated Hald CLUT will be supported by the
+@code{haldclut} filter:
+
+@example
+ffmpeg -f lavfi -i @ref{haldclutsrc}=8 -vf "
+   pad=iw+320 [padded_clut];
+   smptebars=s=320x256, split [a][b];
+   [padded_clut][a] overlay=W-320:h, curves=color_negative [main];
+   [main][b] overlay=W-320" -frames:v 1 clut.png
+@end example
+
+It contains the original and a preview of the effect of the CLUT: SMPTE color
+bars are displayed on the right-top, and below the same color bars processed by
+the color changes.
+
+Then, the effect of this Hald CLUT can be visualized with:
+@example
+ffplay input.mkv -vf "movie=clut.png, [in] haldclut"
+@end example
+
 @section hflip
 
 Flip the input video horizontally.
@@ -4042,6 +4652,10 @@
 or blacks.
 @end table
 Default is @code{parade}.
+
+@item levels_mode
+Set mode for @code{levels}. Can be either @code{linear}, or @code{logarithmic}.
+Default is @code{linear}.
 @end table
 
 @subsection Examples
@@ -4101,12 +4715,16 @@
 @item H
 Specify the hue angle as a number of radians. It accepts an
 expression, and defaults to "0".
+
+@item b
+Specify the brightness in the [-10,10] range. It accepts an expression and
+defaults to "0".
 @end table
 
 @option{h} and @option{H} are mutually exclusive, and can't be
 specified at the same time.
 
-The @option{h}, @option{H} and @option{s} option values are
+The @option{b}, @option{h}, @option{H} and @option{s} option values are
 expressions containing the following constants:
 
 @table @option
@@ -4176,10 +4794,11 @@
 
 This filter supports the following commands:
 @table @option
+@item b
 @item s
 @item h
 @item H
-Modify the hue and/or the saturation of the input video.
+Modify the hue and/or the saturation and/or brightness of the input video.
 The command accepts the same syntax of the corresponding option.
 
 If the specified expression is not valid, it is kept at its current
@@ -4216,7 +4835,7 @@
 
 @table @option
 @item luma_mode, l
-@item chroma_mode, s
+@item chroma_mode, c
 @item alpha_mode, a
 Available values for @var{luma_mode}, @var{chroma_mode} and
 @var{alpha_mode} are:
@@ -4321,6 +4940,43 @@
 @end example
 @end itemize
 
+@anchor{lut3d}
+@section lut3d
+
+Apply a 3D LUT to an input video.
+
+The filter accepts the following options:
+
+@table @option
+@item file
+Set the 3D LUT file name.
+
+Currently supported formats:
+@table @samp
+@item 3dl
+AfterEffects
+@item cube
+Iridas
+@item dat
+DaVinci
+@item m3d
+Pandora
+@end table
+@item interp
+Select interpolation mode.
+
+Available values are:
+
+@table @samp
+@item nearest
+Use values from the nearest defined point.
+@item trilinear
+Interpolate values using the 8 points defining a cube.
+@item tetrahedral
+Interpolate values using a tetrahedron.
+@end table
+@end table
+
 @section lut, lutrgb, lutyuv
 
 Compute a look-up table for binding each pixel component input value
@@ -4369,7 +5025,8 @@
 The expressions can contain the following constants and functions:
 
 @table @option
-@item w, h
+@item w
+@item h
 the input width and height
 
 @item val
@@ -4462,11 +5119,55 @@
 @end example
 @end itemize
 
+@section mcdeint
+
+Apply motion-compensation deinterlacing.
+
+It needs one field per frame as input and must thus be used together
+with yadif=1/3 or equivalent.
+
+This filter accepts the following options:
+@table @option
+@item mode
+Set the deinterlacing mode.
+
+It accepts one of the following values:
+@table @samp
+@item fast
+@item medium
+@item slow
+use iterative motion estimation
+@item extra_slow
+like @samp{slow}, but use multiple reference frames.
+@end table
+Default value is @samp{fast}.
+
+@item parity
+Set the picture field parity assumed for the input video. It must be
+one of the following values:
+
+@table @samp
+@item 0, tff
+assume top field first
+@item 1, bff
+assume bottom field first
+@end table
+
+Default value is @samp{bff}.
+
+@item qp
+Set per-block quantization parameter (QP) used by the internal
+encoder.
+
+Higher values should result in a smoother motion vector field but less
+optimal individual vectors. Default value is 1.
+@end table
+
 @section mp
 
 Apply an MPlayer filter to the input video.
 
-This filter provides a wrapper around most of the filters of
+This filter provides a wrapper around some of the filters of
 MPlayer/MEncoder.
 
 This wrapper is considered experimental. Some of the wrapped filters
@@ -4474,7 +5175,7 @@
 be implemented natively into FFmpeg. Thus you should avoid
 depending on them when writing portable scripts.
 
-The filters accepts the parameters:
+The filter accepts the parameters:
 @var{filter_name}[:=]@var{filter_params}
 
 @var{filter_name} is the name of a supported MPlayer filter,
@@ -4489,17 +5190,11 @@
 @item fil
 @item fspp
 @item ilpack
-@item mcdeint
-@item ow
-@item perspective
 @item phase
 @item pp7
 @item pullup
 @item qp
-@item sab
 @item softpulldown
-@item spp
-@item tinterlace
 @item uspp
 @end table
 
@@ -4631,8 +5326,6 @@
 averaged temporal noise (smoother)
 @item p
 mix random noise with a (semi)regular pattern
-@item q
-higher quality (slightly better looking, slightly slower)
 @item t
 temporal noise (noise pattern changes between frames)
 @item u
@@ -4818,7 +5511,7 @@
 @item repeatlast
 If set to 1, force the filter to draw the last overlay frame over the
 main input until the end of the stream. A value of 0 disables this
-behavior, which is enabled by default.
+behavior. Default value is 1.
 @end table
 
 The @option{x}, and @option{y} expressions can contain the following
@@ -4859,7 +5552,7 @@
 when @option{eval} is set to @samp{init}.
 
 Be aware that frames are taken from each input video in timestamp
-order, hence, if their initial timestamps differ, it is a a good idea
+order, hence, if their initial timestamps differ, it is a good idea
 to pass the two inputs through a @var{setpts=PTS-STARTPTS} filter to
 have them begin in the same zero timestamp, as it does the example for
 the @var{movie} filter.
@@ -4960,6 +5653,32 @@
 
 @end itemize
 
+@section owdenoise
+
+Apply Overcomplete Wavelet denoiser.
+
+The filter accepts the following options:
+
+@table @option
+@item depth
+Set depth.
+
+Larger depth values will denoise lower frequency components more, but
+slow down filtering.
+
+Must be an int in the range 8-16, default is @code{8}.
+
+@item luma_strength, ls
+Set luma strength.
+
+Must be a double value in the range 0-1000, default is @code{1.0}.
+
+@item chroma_strength, cs
+Set chroma strength.
+
+Must be a double value in the range 0-1000, default is @code{1.0}.
+@end table
+
 @section pad
 
 Add paddings to the input image, and place the original input at the
@@ -5001,20 +5720,25 @@
 options are expressions containing the following constants:
 
 @table @option
-@item in_w, in_h
+@item in_w
+@item in_h
 the input video width and height
 
-@item iw, ih
+@item iw
+@item ih
 same as @var{in_w} and @var{in_h}
 
-@item out_w, out_h
+@item out_w
+@item out_h
 the output width and height, that is the size of the padded area as
 specified by the @var{width} and @var{height} expressions
 
-@item ow, oh
+@item ow
+@item oh
 same as @var{out_w} and @var{out_h}
 
-@item x, y
+@item x
+@item y
 x and y offsets as specified by the @var{x} and @var{y}
 expressions, or NAN if not yet specified
 
@@ -5027,7 +5751,8 @@
 @item dar
 input display aspect ratio, it is the same as (@var{iw} / @var{ih}) * @var{sar}
 
-@item hsub, vsub
+@item hsub
+@item vsub
 horizontal and vertical chroma subsample values. For example for the
 pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
 @end table
@@ -5091,6 +5816,44 @@
 @end example
 @end itemize
 
+@section perspective
+
+Correct perspective of video not recorded perpendicular to the screen.
+
+A description of the accepted parameters follows.
+
+@table @option
+@item x0
+@item y0
+@item x1
+@item y1
+@item x2
+@item y2
+@item x3
+@item y3
+Set coordinates expression for top left, top right, bottom left and bottom right corners.
+Default values are @code{0:0:W:0:0:H:W:H} with which perspective will remain unchanged.
+
+The expressions can use the following variables:
+
+@table @option
+@item W
+@item H
+the width and height of video frame.
+@end table
+
+@item interpolation
+Set interpolation for perspective correction.
+
+It accepts the following values:
+@table @samp
+@item linear
+@item cubic
+@end table
+
+Default value is @samp{linear}.
+@end table
+
 @section pixdesctest
 
 Pixel format descriptor test filter, mainly useful for internal
@@ -5278,13 +6041,81 @@
 @end example
 @end itemize
 
+@section psnr
+
+Obtain the average, maximum and minimum PSNR (Peak Signal to Noise
+Ratio) between two input videos.
+
+This filter takes in input two input videos, the first input is
+considered the "main" source and is passed unchanged to the
+output. The second input is used as a "reference" video for computing
+the PSNR.
+
+Both video inputs must have the same resolution and pixel format for
+this filter to work correctly. Also it assumes that both inputs
+have the same number of frames, which are compared one by one.
+
+The obtained average PSNR is printed through the logging system.
+
+The filter stores the accumulated MSE (mean squared error) of each
+frame, and at the end of the processing it is averaged across all frames
+equally, and the following formula is applied to obtain the PSNR:
+
+@example
+PSNR = 10*log10(MAX^2/MSE)
+@end example
+
+Where MAX is the average of the maximum values of each component of the
+image.
+
+The description of the accepted parameters follows.
+
+@table @option
+@item stats_file, f
+If specified the filter will use the named file to save the PSNR of
+each individual frame.
+@end table
+
+The file printed if @var{stats_file} is selected, contains a sequence of
+key/value pairs of the form @var{key}:@var{value} for each compared
+couple of frames.
+
+A description of each shown parameter follows:
+
+@table @option
+@item n
+sequential number of the input frame, starting from 1
+
+@item mse_avg
+Mean Square Error pixel-by-pixel average difference of the compared
+frames, averaged over all the image components.
+
+@item mse_y, mse_u, mse_v, mse_r, mse_g, mse_g, mse_a
+Mean Square Error pixel-by-pixel average difference of the compared
+frames for the component specified by the suffix.
+
+@item psnr_y, psnr_u, psnr_v, psnr_r, psnr_g, psnr_b, psnr_a
+Peak Signal to Noise ratio of the compared frames for the component
+specified by the suffix.
+@end table
+
+For example:
+@example
+movie=ref_movie.mpg, setpts=PTS-STARTPTS [main];
+[main][ref] psnr="stats_file=stats.log" [out]
+@end example
+
+On this example the input file being processed is compared with the
+reference file @file{ref_movie.mpg}. The PSNR of each individual frame
+is stored in @file{stats.log}.
+
 @section removelogo
 
 Suppress a TV station logo, using an image file to determine which
 pixels comprise the logo. It works by filling in the pixels that
 comprise the logo with neighboring pixels.
 
-The filters accept the following options:
+The filter accepts the following options:
 
 @table @option
 @item filename, f
@@ -5308,139 +6139,166 @@
 the image and will destroy more information than necessary, and extra
 pixels will slow things down on a large logo.
 
-@anchor{vidstabtransform}
-@section vidstabtransform
+@section rotate
 
-Video stabilization/deshaking: pass 2 of 2,
-see @ref{vidstabdetect} for pass 1.
+Rotate video by an arbitrary angle expressed in radians.
 
-Read a file with transform information for each frame and
-apply/compensate them. Together with the @ref{vidstabdetect}
-filter this can be used to deshake videos. See also
-@url{http://public.hronopik.de/vid.stab}. It is important to also use
-the unsharp filter, see below.
+The filter accepts the following options:
 
-To enable compilation of this filter you need to configure FFmpeg with
-@code{--enable-libvidstab}.
+A description of the optional parameters follows.
+@table @option
+@item angle, a
+Set an expression for the angle by which to rotate the input video
+clockwise, expressed as a number of radians. A negative value will
+result in a counter-clockwise rotation. By default it is set to "0".
 
-This filter accepts the following options:
+This expression is evaluated for each frame.
+
+@item out_w, ow
+Set the output width expression, default value is "iw".
+This expression is evaluated just once during configuration.
+
+@item out_h, oh
+Set the output height expression, default value is "ih".
+This expression is evaluated just once during configuration.
+
+@item bilinear
+Enable bilinear interpolation if set to 1, a value of 0 disables
+it. Default value is 1.
+
+@item fillcolor, c
+Set the color used to fill the output area not covered by the rotated
+image. If the special value "none" is selected then no background is
+printed (useful for example if the background is never shown). Default
+value is "black".
+@end table
+
+The expressions for the angle and the output size can contain the
+following constants and functions:
 
 @table @option
+@item n
+sequential number of the input frame, starting from 0. It is always NAN
+before the first frame is filtered.
 
-@item input
-path to the file used to read the transforms (default: @file{transforms.trf})
+@item t
+time in seconds of the input frame, it is set to 0 when the filter is
+configured. It is always NAN before the first frame is filtered.
 
-@item smoothing
-number of frames (value*2 + 1) used for lowpass filtering the camera movements
-(default: 10). For example a number of 10 means that 21 frames are used
-(10 in the past and 10 in the future) to smoothen the motion in the
-video. A larger values leads to a smoother video, but limits the
-acceleration of the camera (pan/tilt movements).
+@item hsub
+@item vsub
+horizontal and vertical chroma subsample values. For example for the
+pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
 
-@item maxshift
-maximal number of pixels to translate frames (default: -1 no limit)
+@item in_w, iw
+@item in_h, ih
+the input video width and heigth
 
-@item maxangle
-maximal angle in radians (degree*PI/180) to rotate frames (default: -1
-no limit)
+@item out_w, ow
+@item out_h, oh
+the output width and heigth, that is the size of the padded area as
+specified by the @var{width} and @var{height} expressions
 
-@item crop
-How to deal with borders that may be visible due to movement
-compensation. Available values are:
+@item rotw(a)
+@item roth(a)
+the minimal width/height required for completely containing the input
+video rotated by @var{a} radians.
 
-@table @samp
-@item keep
-keep image information from previous frame (default)
-@item black
-fill the border black
-@end table
-
-@item invert
-@table @samp
-@item 0
- keep transforms normal (default)
-@item 1
- invert transforms
-@end table
-
-
-@item relative
-consider transforms as
-@table @samp
-@item 0
- absolute
-@item 1
- relative to previous frame (default)
-@end table
-
-
-@item zoom
-percentage to zoom (default: 0)
-@table @samp
-@item >0
-  zoom in
-@item <0
-  zoom out
-@end table
-
-@item optzoom
-if 1 then optimal zoom value is determined (default).
-Optimal zoom means no (or only little) border should be visible.
-Note that the value given at zoom is added to the one calculated
-here.
-
-@item interpol
-type of interpolation
-
-Available values are:
-@table @samp
-@item no
-no interpolation
-@item linear
-linear only horizontal
-@item bilinear
-linear in both directions (default)
-@item bicubic
-cubic in both directions (slow)
-@end table
-
-@item tripod
-virtual tripod mode means that the video is stabilized such that the
-camera stays stationary. Use also @code{tripod} option of
-@ref{vidstabdetect}.
-@table @samp
-@item 0
-off (default)
-@item 1
-virtual tripod mode: equivalent to @code{relative=0:smoothing=0}
-@end table
-
+These are only available when computing the @option{out_w} and
+@option{out_h} expressions.
 @end table
 
 @subsection Examples
 
 @itemize
 @item
-typical call with default default values:
- (note the unsharp filter which is always recommended)
+Rotate the input by PI/6 radians clockwise:
 @example
-ffmpeg -i inp.mpeg -vf vidstabtransform,unsharp=5:5:0.8:3:3:0.4 inp_stabilized.mpeg
+rotate=PI/6
 @end example
 
 @item
-zoom in a bit more and load transform data from a given file
+Rotate the input by PI/6 radians counter-clockwise:
 @example
-vidstabtransform=zoom=5:input="mytransforms.trf"
+rotate=-PI/6
 @end example
 
 @item
-smoothen the video even more
+Apply a constant rotation with period T, starting from an angle of PI/3:
 @example
-vidstabtransform=smoothing=30
+rotate=PI/3+2*PI*t/T
 @end example
 
+@item
+Make the input video rotation oscillating with a period of T
+seconds and an amplitude of A radians:
+@example
+rotate=A*sin(2*PI/T*t)
+@end example
+
+@item
+Rotate the video, output size is choosen so that the whole rotating
+input video is always completely contained in the output:
+@example
+rotate='2*PI*t:ow=hypot(iw,ih):oh=ow'
+@end example
+
+@item
+Rotate the video, reduce the output size so that no background is ever
+shown:
+@example
+rotate=2*PI*t:ow='min(iw,ih)/sqrt(2)':oh=ow:c=none
+@end example
 @end itemize
 
+@subsection Commands
+
+The filter supports the following commands:
+
+@table @option
+@item a, angle
+Set the angle expression.
+The command accepts the same syntax of the corresponding option.
+
+If the specified expression is not valid, it is kept at its current
+value.
+@end table
+
+@section sab
+
+Apply Shape Adaptive Blur.
+
+The filter accepts the following options:
+
+@table @option
+@item luma_radius, lr
+Set luma blur filter strength, must be a value in range 0.1-4.0, default
+value is 1.0. A greater value will result in a more blurred image, and
+in slower processing.
+
+@item luma_pre_filter_radius, lpfr
+Set luma pre-filter radius, must be a value in the 0.1-2.0 range, default
+value is 1.0.
+
+@item luma_strength, ls
+Set luma maximum difference between pixels to still be considered, must
+be a value in the 0.1-100.0 range, default value is 1.0.
+
+@item chroma_radius, cr
+Set chroma blur filter strength, must be a value in range 0.1-4.0. A
+greater value will result in a more blurred image, and in slower
+processing.
+
+@item chroma_pre_filter_radius, cpfr
+Set chroma pre-filter radius, must be a value in the 0.1-2.0 range.
+
+@item chroma_strength, cs
+Set chroma maximum difference between pixels to still be considered,
+must be a value in the 0.1-100.0 range.
+@end table
+
+Each chroma option value, if not explicitly specified, is set to the
+corresponding luma option value.
 
 @section scale
 
@@ -5449,35 +6307,45 @@
 The scale filter forces the output display aspect ratio to be the same
 of the input, by changing the output sample aspect ratio.
 
+If the input image format is different from the format requested by
+the next filter, the scale filter will convert the input to the
+requested format.
+
+@subsection Options
 The filter accepts the following options:
 
 @table @option
 @item width, w
-Output video width.
-default value is @code{iw}. See below
-for the list of accepted constants.
-
 @item height, h
-Output video height.
-default value is @code{ih}.
-See below for the list of accepted constants.
+Set the output video dimension expression. Default value is the input
+dimension.
+
+If the value is 0, the input width is used for the output.
+
+If one of the values is -1, the scale filter will use a value that
+maintains the aspect ratio of the input image, calculated from the
+other specified dimension. If both of them are -1, the input size is
+used
+
+See below for the list of accepted constants for use in the dimension
+expression.
 
 @item interl
-Set the interlacing. It accepts the following values:
+Set the interlacing mode. It accepts the following values:
 
-@table @option
+@table @samp
 @item 1
-force interlaced aware scaling
+Force interlaced aware scaling.
 
 @item 0
-do not apply interlaced scaling
+Do not apply interlaced scaling.
 
 @item -1
-select interlaced aware scaling depending on whether the source frames
-are flagged as interlaced or not
+Select interlaced aware scaling depending on whether the source frames
+are flagged as interlaced or not.
 @end table
 
-Default value is @code{0}.
+Default value is @samp{0}.
 
 @item flags
 Set libswscale scaling flags. If not explictly specified the filter
@@ -5486,22 +6354,132 @@
 @item size, s
 Set the video size, the value must be a valid abbreviation or in the
 form @var{width}x@var{height}.
+
+@item in_color_matrix
+@item out_color_matrix
+Set in/output YCbCr color space type.
+
+This allows the autodetected value to be overridden as well as allows forcing
+a specific value used for the output and encoder.
+
+If not specified, the color space type depends on the pixel format.
+
+Possible values:
+
+@table @samp
+@item auto
+Choose automatically.
+
+@item bt709
+Format conforming to International Telecommunication Union (ITU)
+Recommendation BT.709.
+
+@item fcc
+Set color space conforming to the United States Federal Communications
+Commission (FCC) Code of Federal Regulations (CFR) Title 47 (2003) 73.682 (a).
+
+@item bt601
+Set color space conforming to:
+
+@itemize
+@item
+ITU Radiocommunication Sector (ITU-R) Recommendation BT.601
+
+@item
+ITU-R Rec. BT.470-6 (1998) Systems B, B1, and G
+
+@item
+Society of Motion Picture and Television Engineers (SMPTE) ST 170:2004
+
+@end itemize
+
+@item smpte240m
+Set color space conforming to SMPTE ST 240:1999.
 @end table
 
-The values of the @var{w} and @var{h} options are expressions
+@item in_range
+@item out_range
+Set in/output YCbCr sample range.
+
+This allows the autodetected value to be overridden as well as allows forcing
+a specific value used for the output and encoder. If not specified, the
+range depends on the pixel format. Possible values:
+
+@table @samp
+@item auto
+Choose automatically.
+
+@item jpeg/full/pc
+Set full range (0-255 in case of 8-bit luma).
+
+@item mpeg/tv
+Set "MPEG" range (16-235 in case of 8-bit luma).
+@end table
+
+@item sws_dither
+Set the dithering algorithm
+
+@table @samp
+@item auto
+Choose automatically.
+
+@item none
+No dithering
+
+@item bayer
+bayer dither
+
+@item ed
+error diffusion dither
+@end table
+
+@item force_original_aspect_ratio
+Enable decreasing or increasing output video width or height if necessary to
+keep the original aspect ratio. Possible values:
+
+@table @samp
+@item disable
+Scale the video as specified and disable this feature.
+
+@item decrease
+The output video dimensions will automatically be decreased if needed.
+
+@item increase
+The output video dimensions will automatically be increased if needed.
+
+@end table
+
+One useful instance of this option is that when you know a specific device's
+maximum allowed resolution, you can use this to limit the output video to
+that, while retaining the aspect ratio. For example, device A allows
+1280x720 playback, and your video is 1920x800. Using this option (set it to
+decrease) and specifying 1280x720 to the command line makes the output
+1280x533.
+
+Please note that this is a different thing than specifying -1 for @option{w}
+or @option{h}, you still need to specify the output resolution for this option
+to work.
+
+@end table
+
+The values of the @option{w} and @option{h} options are expressions
 containing the following constants:
 
-@table @option
-@item in_w, in_h
+@table @var
+@item in_w
+@item in_h
 the input width and height
 
-@item iw, ih
+@item iw
+@item ih
 same as @var{in_w} and @var{in_h}
 
-@item out_w, out_h
-the output (cropped) width and height
+@item out_w
+@item out_h
+the output (scaled) width and height
 
-@item ow, oh
+@item ow
+@item oh
 same as @var{out_w} and @var{out_h}
 
 @item a
@@ -5511,24 +6489,14 @@
 input sample aspect ratio
 
 @item dar
-input display aspect ratio, it is the same as (@var{iw} / @var{ih}) * @var{sar}
+input display aspect ratio. Calculated from @code{(iw / ih) * sar}.
 
-@item hsub, vsub
+@item hsub
+@item vsub
 horizontal and vertical chroma subsample values. For example for the
 pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
 @end table
 
-If the input image format is different from the format requested by
-the next filter, the scale filter will convert the input to the
-requested format.
-
-If the value for @var{w} or @var{h} is 0, the respective input
-size is used for the output.
-
-If the value for @var{w} or @var{h} is -1, the scale filter will use, for the
-respective output size, a value that maintains the aspect ratio of the input
-image.
-
 @subsection Examples
 
 @itemize
@@ -5540,7 +6508,7 @@
 
 This is equivalent to:
 @example
-scale=w=200:h=100
+scale=200:100
 @end example
 
 or:
@@ -5793,6 +6761,7 @@
 expressed in the form "[@var{c0} @var{c1} @var{c2} @var{c3}]"
 @end table
 
+@anchor{smartblur}
 @section smartblur
 
 Blur the input video without impacting the outlines.
@@ -5840,92 +6809,6 @@
 If a chroma option is not explicitly set, the corresponding luma value
 is set.
 
-@anchor{vidstabdetect}
-@section vidstabdetect
-
-Video stabilization/deshaking: pass 1 of 2, see @ref{vidstabtransform}
-for pass 2.
-
-Generates a file with relative transform information translation,
-rotation about subsequent frames.
-
-To enable compilation of this filter you need to configure FFmpeg with
-@code{--enable-libvidstab}.
-
-This filter accepts the following options:
-
-@table @option
-@item result
-path to the file used to write the transforms (default:@file{transforms.trf})
-
-@item shakiness
-how shaky is the video and how quick is the camera? (default: 5)
-@table @samp
-@item 1
- little (fast)
-@item ...
-@item 10
- very strong/quick (slow)
-@end table
-
-@item accuracy
-accuracy of detection process (>=shakiness) (default: 9)
-@table @samp
-@item 1
- low (fast)
-@item 15
- high (slow)
-@end table
-
-@item stepsize
-stepsize of search process, region around minimum is scanned with 1 pixel
-resolution (default: 6)
-
-@item mincontrast
-below this contrast a local measurement field is discarded (0-1) (default: 0.3)
-
-@item tripod
-virtual tripod mode: @code{tripod=framenum} if framenum>0 otherwise disabled.
-The motion of the frames is compared to a reference frame (framenum).
-The idea is to compensate all movements in a more-or-less static scene
- and keep the camera view absolutely still.
-(default: 0 (disabled))
-
-@item show
-draw nothing (default); 1,2: show fields and transforms in the resulting frames
-
-@end table
-
-@subsection Examples
-
-@itemize
-@item
-use default values:
-@example
-vidstabdetect
-@end example
-
-@item
-strongly shaky movie and put the results in @code{mytransforms.trf}
-@example
-vidstabdetect=shakiness=10:accuracy=15:result="mytransforms.trf"
-@end example
-
-@item
-visualize some internals in the resulting video
-@example
-vidstabdetect=show=1
-@end example
-
-
-@item
-Typical call with visualization
-@example
-ffmpeg -i input -vf vidstabdetect=shakiness=5:show=1 dummy.avi
-@end example
-@end itemize
-
-
 @section stereo3d
 
 Convert between different stereoscopic image formats.
@@ -5966,6 +6849,12 @@
 above-below with half height resolution
 (right eye above, left eye below)
 
+@item al
+alternating frames (left eye first, right eye second)
+
+@item ar
+alternating frames (right eye first, left eye second)
+
 Default value is @samp{sbsl}.
 @end table
 
@@ -6062,6 +6951,42 @@
 @end example
 @end itemize
 
+@section spp
+
+Apply a simple postprocessing filter that compresses and decompresses the image
+at several (or - in the case of @option{quality} level @code{6} - all) shifts
+and average the results.
+
+The filter accepts the following options:
+
+@table @option
+@item quality
+Set quality. This option defines the number of levels for averaging. It accepts
+an integer in the range 0-6. If set to @code{0}, the filter will have no
+effect. A value of @code{6} means the higher quality. For each increment of
+that value the speed drops by a factor of approximately 2.  Default value is
+@code{3}.
+
+@item qp
+Force a constant quantization parameter. If not set, the filter will use the QP
+from the video stream (if available).
+
+@item mode
+Set thresholding mode. Available modes are:
+
+@table @samp
+@item hard
+Set hard thresholding (default).
+@item soft
+Set soft thresholding (better de-ringing effect, but likely blurrier).
+@end table
+
+@item use_bframe_qp
+Enable the use of the QP from the B-Frames if set to @code{1}. Using this
+option may cause flicker since the B-Frames have often larger QP. Default is
+@code{0} (not enabled).
+@end table
+
 @anchor{subtitles}
 @section subtitles
 
@@ -6207,6 +7132,10 @@
 more advanced padding options (such as having different values for the edges),
 refer to the pad video filter.
 
+@item color
+Specify the color of the unused area, it can be the name of a color
+(case insensitive match) or a 0xRRGGBB[AA] sequence.
+The default value of @var{color} is "black".
 @end table
 
 @subsection Examples
@@ -6313,8 +7242,9 @@
 @table @option
 
 @item dir
-The direction of the transpose.
+Specify the transposition direction.
 
+Can assume the following values:
 @table @samp
 @item 0, 4, cclock_flip
 Rotate by 90 degrees counterclockwise and vertically flip (default), that is:
@@ -6353,6 +7283,9 @@
 video geometry is portrait and not landscape. These values are
 deprecated, the @code{passthrough} option should be used instead.
 
+Numerical values are deprecated, and should be dropped in favor of
+symbolic constants.
+
 @item passthrough
 Do not apply the transposition if the input geometry matches the one
 specified by the specified value. It accepts the following values:
@@ -6379,6 +7312,73 @@
 transpose=1:portrait
 @end example
 
+@section trim
+Trim the input so that the output contains one continuous subpart of the input.
+
+This filter accepts the following options:
+@table @option
+@item start
+Specify time of the start of the kept section, i.e. the frame with the
+timestamp @var{start} will be the first frame in the output.
+
+@item end
+Specify time of the first frame that will be dropped, i.e. the frame
+immediately preceding the one with the timestamp @var{end} will be the last
+frame in the output.
+
+@item start_pts
+Same as @var{start}, except this option sets the start timestamp in timebase
+units instead of seconds.
+
+@item end_pts
+Same as @var{end}, except this option sets the end timestamp in timebase units
+instead of seconds.
+
+@item duration
+Specify maximum duration of the output.
+
+@item start_frame
+Number of the first frame that should be passed to output.
+
+@item end_frame
+Number of the first frame that should be dropped.
+@end table
+
+@option{start}, @option{end}, @option{duration} are expressed as time
+duration specifications, check the "Time duration" section in the
+ffmpeg-utils manual.
+
+Note that the first two sets of the start/end options and the @option{duration}
+option look at the frame timestamp, while the _frame variants simply count the
+frames that pass through the filter. Also note that this filter does not modify
+the timestamps. If you wish that the output timestamps start at zero, insert a
+setpts filter after the trim filter.
+
+If multiple start or end options are set, this filter tries to be greedy and
+keep all the frames that match at least one of the specified constraints. To keep
+only the part that matches all the constraints at once, chain multiple trim
+filters.
+
+The defaults are such that all the input is kept. So it is possible to set e.g.
+just the end values to keep everything before the specified time.
+
+Examples:
+@itemize
+@item
+drop everything except the second minute of input
+@example
+ffmpeg -i INPUT -vf trim=60:120
+@end example
+
+@item
+keep only the first second
+@example
+ffmpeg -i INPUT -vf trim=duration=1
+@end example
+
+@end itemize
+
+
 @section unsharp
 
 Sharpen or blur the input video.
@@ -6419,6 +7419,11 @@
 sharpen it, a value of zero will disable the effect.
 
 Default value is 0.0.
+
+@item opencl
+If set to 1, specify using OpenCL capabilities, only available if
+FFmpeg was configured with @code{--enable-opencl}. Default value is 0.
+
 @end table
 
 All parameters are optional and default to the equivalent of the
@@ -6440,6 +7445,224 @@
 @end example
 @end itemize
 
+@anchor{vidstabdetect}
+@section vidstabdetect
+
+Analyze video stabilization/deshaking. Perform pass 1 of 2, see
+@ref{vidstabtransform} for pass 2.
+
+This filter generates a file with relative translation and rotation
+transform information about subsequent frames, which is then used by
+the @ref{vidstabtransform} filter.
+
+To enable compilation of this filter you need to configure FFmpeg with
+@code{--enable-libvidstab}.
+
+This filter accepts the following options:
+
+@table @option
+@item result
+Set the path to the file used to write the transforms information.
+Default value is @file{transforms.trf}.
+
+@item shakiness
+Set how shaky the video is and how quick the camera is. It accepts an
+integer in the range 1-10, a value of 1 means little shakiness, a
+value of 10 means strong shakiness. Default value is 5.
+
+@item accuracy
+Set the accuracy of the detection process. It must be a value in the
+range 1-15. A value of 1 means low accuracy, a value of 15 means high
+accuracy. Default value is 9.
+
+@item stepsize
+Set stepsize of the search process. The region around minimum is
+scanned with 1 pixel resolution. Default value is 6.
+
+@item mincontrast
+Set minimum contrast. Below this value a local measurement field is
+discarded. Must be a floating point value in the range 0-1. Default
+value is 0.3.
+
+@item tripod
+Set reference frame number for tripod mode.
+
+If enabled, the motion of the frames is compared to a reference frame
+in the filtered stream, identified by the specified number. The idea
+is to compensate all movements in a more-or-less static scene and keep
+the camera view absolutely still.
+
+If set to 0, it is disabled. The frames are counted starting from 1.
+
+@item show
+Show fields and transforms in the resulting frames. It accepts an
+integer in the range 0-2. Default value is 0, which disables any
+visualization.
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Use default values:
+@example
+vidstabdetect
+@end example
+
+@item
+Analyze strongly shaky movie and put the results in file
+@file{mytransforms.trf}:
+@example
+vidstabdetect=shakiness=10:accuracy=15:result="mytransforms.trf"
+@end example
+
+@item
+Visualize the result of internal transformations in the resulting
+video:
+@example
+vidstabdetect=show=1
+@end example
+
+@item
+Analyze a video with medium shakiness using @command{ffmpeg}:
+@example
+ffmpeg -i input -vf vidstabdetect=shakiness=5:show=1 dummy.avi
+@end example
+@end itemize
+
+@anchor{vidstabtransform}
+@section vidstabtransform
+
+Video stabilization/deshaking: pass 2 of 2,
+see @ref{vidstabdetect} for pass 1.
+
+Read a file with transform information for each frame and
+apply/compensate them. Together with the @ref{vidstabdetect}
+filter this can be used to deshake videos. See also
+@url{http://public.hronopik.de/vid.stab}. It is important to also use
+the unsharp filter, see below.
+
+To enable compilation of this filter you need to configure FFmpeg with
+@code{--enable-libvidstab}.
+
+This filter accepts the following options:
+
+@table @option
+
+@item input
+path to the file used to read the transforms (default: @file{transforms.trf})
+
+@item smoothing
+number of frames (value*2 + 1) used for lowpass filtering the camera movements
+(default: 10). For example a number of 10 means that 21 frames are used
+(10 in the past and 10 in the future) to smoothen the motion in the
+video. A larger values leads to a smoother video, but limits the
+acceleration of the camera (pan/tilt movements).
+
+@item maxshift
+maximal number of pixels to translate frames (default: -1 no limit)
+
+@item maxangle
+maximal angle in radians (degree*PI/180) to rotate frames (default: -1
+no limit)
+
+@item crop
+How to deal with borders that may be visible due to movement
+compensation. Available values are:
+
+@table @samp
+@item keep
+keep image information from previous frame (default)
+@item black
+fill the border black
+@end table
+
+@item invert
+@table @samp
+@item 0
+ keep transforms normal (default)
+@item 1
+ invert transforms
+@end table
+
+
+@item relative
+consider transforms as
+@table @samp
+@item 0
+ absolute
+@item 1
+ relative to previous frame (default)
+@end table
+
+
+@item zoom
+percentage to zoom (default: 0)
+@table @samp
+@item >0
+  zoom in
+@item <0
+  zoom out
+@end table
+
+@item optzoom
+if 1 then optimal zoom value is determined (default).
+Optimal zoom means no (or only little) border should be visible.
+Note that the value given at zoom is added to the one calculated
+here.
+
+@item interpol
+type of interpolation
+
+Available values are:
+@table @samp
+@item no
+no interpolation
+@item linear
+linear only horizontal
+@item bilinear
+linear in both directions (default)
+@item bicubic
+cubic in both directions (slow)
+@end table
+
+@item tripod
+virtual tripod mode means that the video is stabilized such that the
+camera stays stationary. Use also @code{tripod} option of
+@ref{vidstabdetect}.
+@table @samp
+@item 0
+off (default)
+@item 1
+virtual tripod mode: equivalent to @code{relative=0:smoothing=0}
+@end table
+
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+typical call with default default values:
+ (note the unsharp filter which is always recommended)
+@example
+ffmpeg -i inp.mpeg -vf vidstabtransform,unsharp=5:5:0.8:3:3:0.4 inp_stabilized.mpeg
+@end example
+
+@item
+zoom in a bit more and load transform data from a given file
+@example
+vidstabtransform=zoom=5:input="mytransforms.trf"
+@end example
+
+@item
+smoothen the video even more
+@example
+vidstabtransform=smoothing=30
+@end example
+
+@end itemize
+
 @section vflip
 
 Flip the input video vertically.
@@ -6449,6 +7672,116 @@
 ffmpeg -i in.avi -vf "vflip" out.avi
 @end example
 
+@section vignette
+
+Make or reverse a natural vignetting effect.
+
+The filter accepts the following options:
+
+@table @option
+@item angle, a
+Set lens angle expression as a number of radians.
+
+The value is clipped in the @code{[0,PI/2]} range.
+
+Default value: @code{"PI/5"}
+
+@item x0
+@item y0
+Set center coordinates expressions. Respectively @code{"w/2"} and @code{"h/2"}
+by default.
+
+@item mode
+Set forward/backward mode.
+
+Available modes are:
+@table @samp
+@item forward
+The larger the distance from the central point, the darker the image becomes.
+
+@item backward
+The larger the distance from the central point, the brighter the image becomes.
+This can be used to reverse a vignette effect, though there is no automatic
+detection to extract the lens @option{angle} and other settings (yet). It can
+also be used to create a burning effect.
+@end table
+
+Default value is @samp{forward}.
+
+@item eval
+Set evaluation mode for the expressions (@option{angle}, @option{x0}, @option{y0}).
+
+It accepts the following values:
+@table @samp
+@item init
+Evaluate expressions only once during the filter initialization.
+
+@item frame
+Evaluate expressions for each incoming frame. This is way slower than the
+@samp{init} mode since it requires all the scalers to be re-computed, but it
+allows advanced dynamic expressions.
+@end table
+
+Default value is @samp{init}.
+
+@item dither
+Set dithering to reduce the circular banding effects. Default is @code{1}
+(enabled).
+
+@item aspect
+Set vignette aspect. This setting allows to adjust the shape of the vignette.
+Setting this value to the SAR of the input will make a rectangular vignetting
+following the dimensions of the video.
+
+Default is @code{1/1}.
+@end table
+
+@subsection Expressions
+
+The @option{alpha}, @option{x0} and @option{y0} expressions can contain the
+following parameters.
+
+@table @option
+@item w
+@item h
+input width and height
+
+@item n
+the number of input frame, starting from 0
+
+@item pts
+the PTS (Presentation TimeStamp) time of the filtered video frame, expressed in
+@var{TB} units, NAN if undefined
+
+@item r
+frame rate of the input video, NAN if the input frame rate is unknown
+
+@item t
+the PTS (Presentation TimeStamp) of the filtered video frame,
+expressed in seconds, NAN if undefined
+
+@item tb
+time base of the input video
+@end table
+
+
+@subsection Examples
+
+@itemize
+@item
+Apply simple strong vignetting effect:
+@example
+vignette=PI/4
+@end example
+
+@item
+Make a flickering vignetting:
+@example
+vignette='PI/4+random(1)*PI/50':eval=frame
+@end example
+
+@end itemize
+
 @anchor{yadif}
 @section yadif
 
@@ -6974,10 +8307,20 @@
 @end example
 @end itemize
 
-@section color, nullsrc, rgbtestsrc, smptebars, smptehdbars, testsrc
+@anchor{color}
+@anchor{haldclutsrc}
+@anchor{nullsrc}
+@anchor{rgbtestsrc}
+@anchor{smptebars}
+@anchor{smptehdbars}
+@anchor{testsrc}
+@section color, haldclutsrc, nullsrc, rgbtestsrc, smptebars, smptehdbars, testsrc
 
 The @code{color} source provides an uniformly colored input.
 
+The @code{haldclutsrc} source provides an identity Hald CLUT. See also
+@ref{haldclut} filter.
+
 The @code{nullsrc} source returns unprocessed video frames. It is
 mainly useful to be employed in analysis / debugging tools, or as the
 source for filters which ignore the input data.
@@ -7001,16 +8344,24 @@
 @table @option
 
 @item color, c
-Specify the color of the source, only used in the @code{color}
+Specify the color of the source, only available in the @code{color}
 source. It can be the name of a color (case insensitive match) or a
 0xRRGGBB[AA] sequence, possibly followed by an alpha specifier. The
 default value is "black".
 
+@item level
+Specify the level of the Hald CLUT, only available in the @code{haldclutsrc}
+source. A level of @code{N} generates a picture of @code{N*N*N} by @code{N*N*N}
+pixels to be used as identity matrix for 3D lookup tables. Each component is
+coded on a @code{1/(N*N)} scale.
+
 @item size, s
 Specify the size of the sourced video, it may be a string of the form
 @var{width}x@var{height}, or the name of a size abbreviation. The
 default value is "320x240".
 
+This option is not available with the @code{haldclutsrc} filter.
+
 @item rate, r
 Specify the frame rate of the sourced video, as the number of frames
 generated per second. It has to be a string in the format
@@ -7033,7 +8384,7 @@
 supposed to be generated forever.
 
 @item decimals, n
-Set the number of decimals to show in the timestamp, only used in the
+Set the number of decimals to show in the timestamp, only available in the
 @code{testsrc} source.
 
 The displayed timestamp value will correspond to the original
@@ -7063,6 +8414,16 @@
 nullsrc=s=256x256, geq=random(1)*255:128:128
 @end example
 
+@subsection Commands
+
+The @code{color} source supports the following commands:
+
+@table @option
+@item c, color
+Set the color of the created image. Accepts the same syntax of the
+corresponding @option{color} option.
+@end table
+
 @c man end VIDEO SOURCES
 
 @chapter Video Sinks
@@ -7096,6 +8457,68 @@
 
 Below is a description of the currently available multimedia filters.
 
+@section avectorscope
+
+Convert input audio to a video output, representing the audio vector
+scope.
+
+The filter is used to measure the difference between channels of stereo
+audio stream. A monoaural signal, consisting of identical left and right
+signal, results in straight vertical line. Any stereo separation is visible
+as a deviation from this line, creating a Lissajous figure.
+If the straight (or deviation from it) but horizontal line appears this
+indicates that the left and right channels are out of phase.
+
+The filter accepts the following options:
+
+@table @option
+@item mode, m
+Set the vectorscope mode.
+
+Available values are:
+@table @samp
+@item lissajous
+Lissajous rotated by 45 degrees.
+
+@item lissajous_xy
+Same as above but not rotated.
+@end table
+
+Default value is @samp{lissajous}.
+
+@item size, s
+Set the video size for the output. Default value is @code{400x400}.
+
+@item rate, r
+Set the output frame rate. Default value is @code{25}.
+
+@item rc
+@item gc
+@item bc
+Specify the red, green and blue contrast. Default values are @code{40}, @code{160} and @code{80}.
+Allowed range is @code{[0, 255]}.
+
+@item rf
+@item gf
+@item bf
+Specify the red, green and blue fade. Default values are @code{15}, @code{10} and @code{5}.
+Allowed range is @code{[0, 255]}.
+
+@item zoom
+Set the zoom factor. Default value is @code{1}. Allowed range is @code{[1, 10]}.
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Complete example using @command{ffplay}:
+@example
+ffplay -f lavfi 'amovie=input.mp3, asplit [a][out1];
+             [a] avectorscope=zoom=1.3:rc=2:gc=200:bc=10:rf=1:gf=8:bf=7 [out0]'
+@end example
+@end itemize
+
 @section concat
 
 Concatenate audio and video streams, joining them together one after the
@@ -7678,16 +9101,17 @@
 the presentation timestamp in input
 
 @item N
-the count of the input frame, starting from 0.
+the count of the input frame for video or the number of consumed samples,
+not including the current frame for audio, starting from 0.
 
 @item NB_CONSUMED_SAMPLES
 the number of consumed samples, not including the current frame (only
 audio)
 
-@item NB_SAMPLES
+@item NB_SAMPLES, S
 the number of samples in the current frame (only audio)
 
-@item SAMPLE_RATE
+@item SAMPLE_RATE, SR
 audio sample rate
 
 @item STARTPTS
@@ -7773,6 +9197,13 @@
 @example
 setpts='(RTCTIME - RTCSTART) / (TB * 1000000)'
 @end example
+
+@item
+Generate timestamps by counting samples:
+@example
+asetpts=N/SR/TB
+@end example
+
 @end itemize
 
 @section settb, asettb
@@ -8008,6 +9439,74 @@
 @end example
 @end itemize
 
+@section zmq, azmq
+
+Receive commands sent through a libzmq client, and forward them to
+filters in the filtergraph.
+
+@code{zmq} and @code{azmq} work as a pass-through filters. @code{zmq}
+must be inserted between two video filters, @code{azmq} between two
+audio filters.
+
+To enable these filters you need to install the libzmq library and
+headers and configure FFmpeg with @code{--enable-libzmq}.
+
+For more information about libzmq see:
+@url{http://www.zeromq.org/}
+
+The @code{zmq} and @code{azmq} filters work as a libzmq server, which
+receives messages sent through a network interface defined by the
+@option{bind_address} option.
+
+The received message must be in the form:
+@example
+@var{TARGET} @var{COMMAND} [@var{ARG}]
+@end example
+
+@var{TARGET} specifies the target of the command, usually the name of
+the filter class or a specific filter instance name.
+
+@var{COMMAND} specifies the name of the command for the target filter.
+
+@var{ARG} is optional and specifies the optional argument list for the
+given @var{COMMAND}.
+
+Upon reception, the message is processed and the corresponding command
+is injected into the filtergraph. Depending on the result, the filter
+will send a reply to the client, adopting the format:
+@example
+@var{ERROR_CODE} @var{ERROR_REASON}
+@var{MESSAGE}
+@end example
+
+@var{MESSAGE} is optional.
+
+@subsection Examples
+
+Look at @file{tools/zmqsend} for an example of a zmq client which can
+be used to send commands processed by these filters.
+
+Consider the following filtergraph generated by @command{ffplay}
+@example
+ffplay -dumpgraph 1 -f lavfi "
+color=s=100x100:c=red  [l];
+color=s=100x100:c=blue [r];
+nullsrc=s=200x100, zmq [bg];
+[bg][l]   overlay      [bg+l];
+[bg+l][r] overlay=x=100 "
+@end example
+
+To change the color of the left side of the video, the following
+command can be used:
+@example
+echo Parsed_color_0 c yellow | tools/zmqsend
+@end example
+
+To change the right side:
+@example
+echo Parsed_color_1 c pink | tools/zmqsend
+@end example
+
 @c man end MULTIMEDIA FILTERS
 
 @chapter Multimedia Sources
diff --git a/doc/formats.texi b/doc/formats.texi
index 44e4532..e179755 100644
--- a/doc/formats.texi
+++ b/doc/formats.texi
@@ -121,7 +121,7 @@
 Use wallclock as timestamps.
 
 @item avoid_negative_ts @var{integer} (@emph{output})
-Shift timestamps to make them positive. A value of 1 enables shifting,
+Shift timestamps to make them non-negative. A value of 1 enables shifting,
 a value of 0 disables it, the default value of -1 enables shifting
 when required by the target format.
 
@@ -141,6 +141,37 @@
 
 @c man end FORMAT OPTIONS
 
+@anchor{Format stream specifiers}
+@section Format stream specifiers
+
+Format stream specifiers allow selection of one or more streams that
+match specific properties.
+
+Possible forms of stream specifiers are:
+@table @option
+@item @var{stream_index}
+Matches the stream with this index.
+
+@item @var{stream_type}[:@var{stream_index}]
+@var{stream_type} is one of following: 'v' for video, 'a' for audio,
+'s' for subtitle, 'd' for data, and 't' for attachments. If
+@var{stream_index} is given, then it matches the stream number
+@var{stream_index} of this type. Otherwise, it matches all streams of
+this type.
+
+@item p:@var{program_id}[:@var{stream_index}]
+If @var{stream_index} is given, then it matches the stream with number
+@var{stream_index} in the program with the id
+@var{program_id}. Otherwise, it matches all streams in the program.
+
+@item #@var{stream_id}
+Matches the stream by a format-specific ID.
+@end table
+
+The exact semantics of stream specifiers is defined by the
+@code{avformat_match_stream_specifier()} function declared in the
+@file{libavformat/avformat.h} header.
+
 @include demuxers.texi
 @include muxers.texi
 @include metadata.texi
diff --git a/doc/general.texi b/doc/general.texi
index b6e731a..b755c18 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -24,7 +24,7 @@
 @file{./configure}.
 
 
-@section OpenCORE and VisualOn libraries
+@section OpenCORE, VisualOn, and Fraunhofer libraries
 
 Spun off Google Android sources, OpenCore, VisualOn and Fraunhofer
 libraries provide encoders for a number of audio codecs.
@@ -32,9 +32,14 @@
 @float NOTE
 OpenCORE and VisualOn libraries are under the Apache License 2.0
 (see @url{http://www.apache.org/licenses/LICENSE-2.0} for details), which is
-incompatible with the LGPL version 2.1 and GPL version 2. You have to
+incompatible to the LGPL version 2.1 and GPL version 2. You have to
 upgrade FFmpeg's license to LGPL version 3 (or if you have enabled
-GPL components, GPL version 3) to use it.
+GPL components, GPL version 3) by passing @code{--enable-version3} to configure in
+order to use it.
+
+The Fraunhofer AAC library is licensed under a license incompatible to the GPL
+and is not known to be compatible to the LGPL. Therefore, you have to pass
+@code{--enable-nonfree} to configure to use it.
 @end float
 
 @subsection OpenCORE AMR
@@ -95,6 +100,14 @@
 installing the library. Then pass @code{--enable-libvpx} to configure to
 enable it.
 
+@section libwavpack
+
+FFmpeg can make use of the libwavpack library for WavPack encoding.
+
+Go to @url{http://www.wavpack.com/} and follow the instructions for
+installing the library. Then pass @code{--enable-libwavpack} to configure to
+enable it.
+
 @section x264
 
 FFmpeg can make use of the x264 library for H.264 encoding.
@@ -147,13 +160,15 @@
     @tab Multimedia format used in game Heart Of Darkness.
 @item Apple HTTP Live Streaming @tab   @tab X
 @item Artworx Data Format       @tab   @tab X
+@item ADP                       @tab   @tab X
+    @tab Audio format used on the Nintendo Gamecube.
 @item AFC                       @tab   @tab X
     @tab Audio format used on the Nintendo Gamecube.
 @item ASF                       @tab X @tab X
 @item AST                       @tab X @tab X
     @tab Audio format used on the Nintendo Wii.
 @item AVI                       @tab X @tab X
-@item AVISynth                  @tab   @tab X
+@item AviSynth                  @tab   @tab X
 @item AVR                       @tab   @tab X
     @tab Audio format used on Mac.
 @item AVS                       @tab   @tab X
@@ -322,7 +337,7 @@
 @item raw Shorten               @tab   @tab X
 @item raw TAK                   @tab   @tab X
 @item raw TrueHD                @tab X @tab X
-@item raw VC-1                  @tab   @tab X
+@item raw VC-1                  @tab X @tab X
 @item raw PCM A-law             @tab X @tab X
 @item raw PCM mu-law            @tab X @tab X
 @item raw PCM signed 8 bit      @tab X @tab X
@@ -348,11 +363,13 @@
     @tab File format used by RED Digital cameras, contains JPEG 2000 frames and PCM audio.
 @item RealMedia                 @tab X @tab X
 @item Redirector                @tab   @tab X
+@item RedSpark                  @tab   @tab X
 @item Renderware TeXture Dictionary @tab   @tab X
 @item RL2                       @tab   @tab X
     @tab Audio and video format used in some games by Entertainment Software Partners.
 @item RPL/ARMovie               @tab   @tab X
 @item Lego Mindstorms RSO       @tab X @tab X
+@item RSD                       @tab   @tab X
 @item RTMP                      @tab X @tab X
     @tab Output is performed by publishing stream to RTMP server
 @item RTP                       @tab X @tab X
@@ -484,6 +501,7 @@
 @item AMV Video              @tab  X  @tab  X
     @tab Used in Chinese MP3 players.
 @item ANSI/ASCII art         @tab     @tab  X
+@item Apple Intermediate Codec @tab     @tab  X
 @item Apple MJPEG-B          @tab     @tab  X
 @item Apple ProRes           @tab  X  @tab  X
 @item Apple QuickDraw        @tab     @tab  X
@@ -566,6 +584,8 @@
     @tab Sorenson H.263 used in Flash
 @item Forward Uncompressed   @tab     @tab  X
 @item Fraps                  @tab     @tab  X
+@item Go2Webinar             @tab     @tab  X
+    @tab fourcc: G2M4
 @item H.261                  @tab  X  @tab  X
 @item H.263 / H.263-1996     @tab  X  @tab  X
 @item H.263+ / H.263-1998 / H.263 version 2  @tab  X  @tab  X
@@ -768,9 +788,11 @@
     @tab Used in some Sega Saturn console games.
 @item ADPCM IMA Duck DK4     @tab     @tab  X
     @tab Used in some Sega Saturn console games.
+@item ADPCM IMA Radical      @tab     @tab  X
 @item ADPCM Microsoft        @tab  X  @tab  X
 @item ADPCM MS IMA           @tab  X  @tab  X
 @item ADPCM Nintendo Gamecube AFC  @tab     @tab  X
+@item ADPCM Nintendo Gamecube DTK  @tab     @tab  X
 @item ADPCM Nintendo Gamecube THP  @tab     @tab  X
 @item ADPCM QT IMA           @tab  X  @tab  X
 @item ADPCM SEGA CRI ADX     @tab  X  @tab  X
@@ -830,7 +852,6 @@
 @item MLP (Meridian Lossless Packing)  @tab     @tab  X
     @tab Used in DVD-Audio discs.
 @item Monkey's Audio         @tab     @tab  X
-    @tab Only versions 3.97-3.99 are supported.
 @item MP1 (MPEG audio layer 1)  @tab     @tab IX
 @item MP2 (MPEG audio layer 2)  @tab IX  @tab IX
     @tab libtwolame can be used alternatively for encoding.
@@ -885,7 +906,7 @@
 @item Sierra VMD audio       @tab     @tab  X
     @tab Used in Sierra VMD files.
 @item Smacker audio          @tab     @tab  X
-@item SMPTE 302M AES3 audio  @tab     @tab  X
+@item SMPTE 302M AES3 audio  @tab  X  @tab  X
 @item Sonic                  @tab  X  @tab  X
     @tab experimental codec
 @item Sonic lossless         @tab  X  @tab  X
@@ -893,7 +914,7 @@
 @item Speex                  @tab  E  @tab  E
     @tab supported through external library libspeex
 @item TAK (Tom's lossless Audio Kompressor)  @tab     @tab  X
-@item True Audio (TTA)       @tab     @tab  X
+@item True Audio (TTA)       @tab  X  @tab  X
 @item TrueHD                 @tab     @tab  X
     @tab Used in HD-DVD and Blu-Ray discs.
 @item TwinVQ (VQF flavor)    @tab     @tab  X
@@ -901,7 +922,9 @@
     @tab Used in LucasArts SMUSH animations.
 @item Vorbis                 @tab  E  @tab  X
     @tab A native but very primitive encoder exists.
-@item WavPack                @tab     @tab  X
+@item Voxware MetaSound      @tab     @tab  X
+    @tab imperfect and incomplete support
+@item WavPack                @tab  X  @tab  X
 @item Westwood Audio (SND1)  @tab     @tab  X
 @item Windows Media Audio 1  @tab  X  @tab  X
 @item Windows Media Audio 2  @tab  X  @tab  X
@@ -940,7 +963,7 @@
 @item TED Talks captions @tab @tab X @tab   @tab X
 @item VobSub (IDX+SUB) @tab   @tab X @tab   @tab X
 @item VPlayer          @tab   @tab X @tab   @tab X
-@item WebVTT           @tab   @tab X @tab   @tab X
+@item WebVTT           @tab X @tab X @tab   @tab X
 @item XSUB             @tab   @tab   @tab X @tab X
 @end multitable
 
@@ -993,7 +1016,7 @@
 @item OSS               @tab X      @tab X
 @item Pulseaudio        @tab X      @tab
 @item SDL               @tab        @tab X
-@item Video4Linux2      @tab X      @tab
+@item Video4Linux2      @tab X      @tab X
 @item VfW capture       @tab X      @tab
 @item X11 grabbing      @tab X      @tab
 @end multitable
diff --git a/doc/indevs.texi b/doc/indevs.texi
index 5e8d215..5cc03f9 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -590,8 +590,8 @@
 "v4l2" can be used as alias for "video4linux2".
 
 If FFmpeg is built with v4l-utils support (by using the
-@code{--enable-libv4l2} configure option), the device will always rely
-on libv4l2.
+@code{--enable-libv4l2} configure option), it is possible to use it with the
+@code{-use_libv4l2} input device option.
 
 The name of the device to grab is a file device node, usually Linux
 systems tend to automatically create such nodes when the device
diff --git a/doc/issue_tracker.txt b/doc/issue_tracker.txt
index d487f66..27b0009 100644
--- a/doc/issue_tracker.txt
+++ b/doc/issue_tracker.txt
@@ -24,7 +24,7 @@
 The subscription URL for the ffmpeg-trac list is:
 http(s)://ffmpeg.org/mailman/listinfo/ffmpeg-trac
 The URL of the webinterface of the tracker is:
-http(s)://ffmpeg.org/trac/ffmpeg
+http(s)://trac.ffmpeg.org
 
 Type:
 -----
diff --git a/doc/libswresample.texi b/doc/libswresample.texi
index 1a5b01f..383e537 100644
--- a/doc/libswresample.texi
+++ b/doc/libswresample.texi
@@ -20,7 +20,7 @@
 @itemize
 @item
 @emph{Resampling}: is the process of changing the audio rate, for
-example from an high sample rate of 44100Hz to 8000Hz. Audio
+example from a high sample rate of 44100Hz to 8000Hz. Audio
 conversion from high to low sample rate is a lossy process. Several
 resampling options and algorithms are available.
 
diff --git a/doc/metadata.texi b/doc/metadata.texi
index 2a28575..b7fc789 100644
--- a/doc/metadata.texi
+++ b/doc/metadata.texi
@@ -65,4 +65,20 @@
 title=multi\
 line
 @end example
+
+By using the ffmetadata muxer and demuxer it is possible to extract
+metadata from an input file to an ffmetadata file, and then transcode
+the file into an output file with the edited ffmetadata file.
+
+Extracting an ffmetadata file with @file{ffmpeg} goes as follows:
+@example
+ffmpeg -i INPUT -f ffmetadata FFMETADATAFILE
+@end example
+
+Reinserting edited metadata information from the FFMETADATAFILE file can
+be done as:
+@example
+ffmpeg -i INPUT -i FFMETADATAFILE -map_metadata 1 -codec copy OUTPUT
+@end example
+
 @c man end METADATA
diff --git a/doc/mips.txt b/doc/mips.txt
index 051b819..8c6779f 100644
--- a/doc/mips.txt
+++ b/doc/mips.txt
@@ -47,6 +47,11 @@
 * libavutil/mips/
       float_dsp_mips.c
       libm_mips.h
+* libavcodec/
+      fft_fixed_32.c
+      fft_init_table.c
+      fft_table.h
+      mdct_fixed_32.c
 * libavcodec/mips/
       aaccoder_mips.c
       aacpsy_mips.h
diff --git a/doc/muxers.texi b/doc/muxers.texi
index f127494..cc78b6e 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -18,6 +18,23 @@
 
 A description of some of the currently available muxers follows.
 
+@anchor{aiff}
+@section aiff
+
+Audio Interchange File Format muxer.
+
+It accepts the following options:
+
+@table @option
+@item write_id3v2
+Enable ID3v2 tags writing when set to 1. Default is 0 (disabled).
+
+@item id3v2_version
+Select ID3v2 version to write. Currently only version 3 and 4 (aka.
+ID3v2.3 and ID3v2.4) are supported. The default is version 4.
+
+@end table
+
 @anchor{crc}
 @section crc
 
@@ -243,7 +260,7 @@
 @table @option
 @item start_number @var{number}
 Start the sequence from @var{number}. Default value is 1. Must be a
-positive number.
+non-negative number.
 
 @item -update @var{number}
 If @var{number} is nonzero, the filename will always be interpreted as just a
@@ -258,6 +275,90 @@
 specify the name of the '.Y' file. The muxer will automatically open the
 '.U' and '.V' files as required.
 
+@section matroska
+
+Matroska container muxer.
+
+This muxer implements the matroska and webm container specs.
+
+The recognized metadata settings in this muxer are:
+
+@table @option
+
+@item title=@var{title name}
+Name provided to a single track
+@end table
+
+@table @option
+
+@item language=@var{language name}
+Specifies the language of the track in the Matroska languages form
+@end table
+
+@table @option
+
+@item stereo_mode=@var{mode}
+Stereo 3D video layout of two views in a single video track
+@table @option
+@item mono
+video is not stereo
+@item left_right
+Both views are arranged side by side, Left-eye view is on the left
+@item bottom_top
+Both views are arranged in top-bottom orientation, Left-eye view is at bottom
+@item top_bottom
+Both views are arranged in top-bottom orientation, Left-eye view is on top
+@item checkerboard_rl
+Each view is arranged in a checkerboard interleaved pattern, Left-eye view being first
+@item checkerboard_lr
+Each view is arranged in a checkerboard interleaved pattern, Right-eye view being first
+@item row_interleaved_rl
+Each view is constituted by a row based interleaving, Right-eye view is first row
+@item row_interleaved_lr
+Each view is constituted by a row based interleaving, Left-eye view is first row
+@item col_interleaved_rl
+Both views are arranged in a column based interleaving manner, Right-eye view is first column
+@item col_interleaved_lr
+Both views are arranged in a column based interleaving manner, Left-eye view is first column
+@item anaglyph_cyan_red
+All frames are in anaglyph format viewable through red-cyan filters
+@item right_left
+Both views are arranged side by side, Right-eye view is on the left
+@item anaglyph_green_magenta
+All frames are in anaglyph format viewable through green-magenta filters
+@item block_lr
+Both eyes laced in one Block, Left-eye view is first
+@item block_rl
+Both eyes laced in one Block, Right-eye view is first
+@end table
+@end table
+
+For example a 3D WebM clip can be created using the following command line:
+@example
+ffmpeg -i sample_left_right_clip.mpg -an -c:v libvpx -metadata stereo_mode=left_right -y stereo_clip.webm
+@end example
+
+This muxer supports the following options:
+
+@table @option
+
+@item reserve_index_space
+By default, this muxer writes the index for seeking (called cues in Matroska
+terms) at the end of the file, because it cannot know in advance how much space
+to leave for the index at the beginning of the file. However for some use cases
+-- e.g.  streaming where seeking is possible but slow -- it is useful to put the
+index at the beginning of the file.
+
+If this option is set to a non-zero value, the muxer will reserve a given amount
+of space in the file header and then try to write the cues there when the muxing
+finishes. If the available space does not suffice, muxing will fail. A safe size
+for most use cases should be about 50kB per hour of video.
+
+Note that cues are only written if the output is seekable and this option will
+have no effect if it is not.
+
+@end table
+
 @anchor{md5}
 @section md5
 
@@ -350,8 +451,8 @@
 
 This option is implicitly set when writing ismv (Smooth Streaming) files.
 @item -movflags faststart
-Run a second pass moving the moov atom on top of the file. This
-operation can take a while, and will not work in various situations such
+Run a second pass moving the index (moov atom) to the beginning of the file.
+This operation can take a while, and will not work in various situations such
 as fragmented output, thus it is not enabled by default.
 @item -movflags rtphint
 Add RTP hinting tracks to the output file.
@@ -363,6 +464,42 @@
 ffmpeg -re @var{<normal input/transcoding options>} -movflags isml+frag_keyframe -f ismv http://server/publishingpoint.isml/Streams(Encoder1)
 @end example
 
+@section mp3
+
+The MP3 muxer writes a raw MP3 stream with an ID3v2 header at the beginning and
+optionally an ID3v1 tag at the end. ID3v2.3 and ID3v2.4 are supported, the
+@code{id3v2_version} option controls which one is used. The legacy ID3v1 tag is
+not written by default, but may be enabled with the @code{write_id3v1} option.
+
+For seekable output the muxer also writes a Xing frame at the beginning, which
+contains the number of frames in the file. It is useful for computing duration
+of VBR files.
+
+The muxer supports writing ID3v2 attached pictures (APIC frames). The pictures
+are supplied to the muxer in form of a video stream with a single packet. There
+can be any number of those streams, each will correspond to a single APIC frame.
+The stream metadata tags @var{title} and @var{comment} map to APIC
+@var{description} and @var{picture type} respectively. See
+@url{http://id3.org/id3v2.4.0-frames} for allowed picture types.
+
+Note that the APIC frames must be written at the beginning, so the muxer will
+buffer the audio frames until it gets all the pictures. It is therefore advised
+to provide the pictures as soon as possible to avoid excessive buffering.
+
+Examples:
+
+Write an mp3 with an ID3v2.3 header and an ID3v1 footer:
+@example
+ffmpeg -i INPUT -id3v2_version 3 -write_id3v1 1 out.mp3
+@end example
+
+To attach a picture to an mp3 file select both the audio and the picture stream
+with @code{map}:
+@example
+ffmpeg -i input.mp3 -i cover.png -c copy -map 0 -map 1
+-metadata:s:v title="Album cover" -metadata:s:v comment="Cover (Front)" out.mp3
+@end example
+
 @section mpegts
 
 MPEG transport stream muxer.
@@ -385,6 +522,40 @@
 Set the first PID for PMT (default 0x1000, max 0x1f00).
 @item -mpegts_start_pid @var{number}
 Set the first PID for data packets (default 0x0100, max 0x0f00).
+@item -mpegts_m2ts_mode @var{number}
+Enable m2ts mode if set to 1. Default value is -1 which disables m2ts mode.
+@item -muxrate @var{number}
+Set muxrate.
+@item -pes_payload_size @var{number}
+Set minimum PES packet payload in bytes.
+@item -mpegts_flags @var{flags}
+Set flags (see below).
+@item -mpegts_copyts @var{number}
+Preserve original timestamps, if value is set to 1. Default value is -1, which
+results in shifting timestamps so that they start from 0.
+@item -tables_version @var{number}
+Set PAT, PMT and SDT version (default 0, valid values are from 0 to 31, inclusively).
+This option allows updating stream structure so that standard consumer may
+detect the change. To do so, reopen output AVFormatContext (in case of API
+usage) or restart ffmpeg instance, cyclically changing tables_version value:
+@example
+ffmpeg -i source1.ts -codec copy -f mpegts -tables_version 0 udp://1.1.1.1:1111
+ffmpeg -i source2.ts -codec copy -f mpegts -tables_version 1 udp://1.1.1.1:1111
+...
+ffmpeg -i source3.ts -codec copy -f mpegts -tables_version 31 udp://1.1.1.1:1111
+ffmpeg -i source1.ts -codec copy -f mpegts -tables_version 0 udp://1.1.1.1:1111
+ffmpeg -i source2.ts -codec copy -f mpegts -tables_version 1 udp://1.1.1.1:1111
+...
+@end example
+@end table
+
+Option mpegts_flags may take a set of such flags:
+
+@table @option
+@item resend_headers
+Reemit PAT/PMT before writing the next packet.
+@item latm
+Use LATM packetization for AAC.
 @end table
 
 The recognized metadata settings in mpegts muxer are @code{service_provider}
@@ -426,69 +597,21 @@
 ffmpeg -benchmark -i INPUT -f null -
 @end example
 
-@section matroska
+@section ogg
 
-Matroska container muxer.
-
-This muxer implements the matroska and webm container specs.
-
-The recognized metadata settings in this muxer are:
+Ogg container muxer.
 
 @table @option
-
-@item title=@var{title name}
-Name provided to a single track
+@item -page_duration @var{duration}
+Preferred page duration, in microseconds. The muxer will attempt to create
+pages that are approximately @var{duration} microseconds long. This allows the
+user to compromise between seek granularity and container overhead. The default
+is 1 second. A value of 0 will fill all segments, making pages as large as
+possible. A value of 1 will effectively use 1 packet-per-page in most
+situations, giving a small seek granularity at the cost of additional container
+overhead.
 @end table
 
-@table @option
-
-@item language=@var{language name}
-Specifies the language of the track in the Matroska languages form
-@end table
-
-@table @option
-
-@item stereo_mode=@var{mode}
-Stereo 3D video layout of two views in a single video track
-@table @option
-@item mono
-video is not stereo
-@item left_right
-Both views are arranged side by side, Left-eye view is on the left
-@item bottom_top
-Both views are arranged in top-bottom orientation, Left-eye view is at bottom
-@item top_bottom
-Both views are arranged in top-bottom orientation, Left-eye view is on top
-@item checkerboard_rl
-Each view is arranged in a checkerboard interleaved pattern, Left-eye view being first
-@item checkerboard_lr
-Each view is arranged in a checkerboard interleaved pattern, Right-eye view being first
-@item row_interleaved_rl
-Each view is constituted by a row based interleaving, Right-eye view is first row
-@item row_interleaved_lr
-Each view is constituted by a row based interleaving, Left-eye view is first row
-@item col_interleaved_rl
-Both views are arranged in a column based interleaving manner, Right-eye view is first column
-@item col_interleaved_lr
-Both views are arranged in a column based interleaving manner, Left-eye view is first column
-@item anaglyph_cyan_red
-All frames are in anaglyph format viewable through red-cyan filters
-@item right_left
-Both views are arranged side by side, Right-eye view is on the left
-@item anaglyph_green_magenta
-All frames are in anaglyph format viewable through green-magenta filters
-@item block_lr
-Both eyes laced in one Block, Left-eye view is first
-@item block_rl
-Both eyes laced in one Block, Right-eye view is first
-@end table
-@end table
-
-For example a 3D WebM clip can be created using the following command line:
-@example
-ffmpeg -i sample_left_right_clip.mpg -an -c:v libvpx -metadata stereo_mode=left_right -y stereo_clip.webm
-@end example
-
 @section segment, stream_segment, ssegment
 
 Basic stream segmenter.
@@ -525,7 +648,7 @@
 If @var{specifier} is set to @code{auto}, the reference is choosen
 automatically. Otherwise it must be a stream specifier (see the ``Stream
 specifiers'' chapter in the ffmpeg manual) which specifies the
-reference stream. The default value is ``auto''.
+reference stream. The default value is @code{auto}.
 
 @item segment_format @var{format}
 Override the inner container format, by default it is guessed by the filename
@@ -539,7 +662,7 @@
 Set flags affecting the segment list generation.
 
 It currently supports the following flags:
-@table @var
+@table @samp
 @item cache
 Allow caching (only affects M3U8 list files).
 
@@ -547,18 +670,18 @@
 Allow live-friendly file generation.
 @end table
 
-Default value is @code{cache}.
+Default value is @code{samp}.
 
 @item segment_list_size @var{size}
 Update the list file so that it contains at most the last @var{size}
 segments. If 0 the list file will contain all the segments. Default
 value is 0.
 
-@item segment_list type @var{type}
+@item segment_list_type @var{type}
 Specify the format for the segment list file.
 
 The following values are recognized:
-@table @option
+@table @samp
 @item flat
 Generate a flat list for the created segments, one segment per line.
 
@@ -579,7 +702,7 @@
 A list file with the suffix @code{".csv"} or @code{".ext"} will
 auto-select this format.
 
-@code{ext} is deprecated in favor or @code{csv}.
+@samp{ext} is deprecated in favor or @samp{csv}.
 
 @item ffconcat
 Generate an ffconcat file for the created segments. The resulting file
@@ -652,6 +775,10 @@
 will start with near-zero timestamps. It is meant to ease the playback
 of the generated segments. May not work with some combinations of
 muxers/codecs. It is set to @code{0} by default.
+
+@item initial_offset @var{offset}
+Specify timestamp offset to apply to the output packet timestamps. The
+argument must be a time duration specification, and defaults to 0.
 @end table
 
 @subsection Examples
@@ -673,9 +800,9 @@
 @end example
 
 @item
-As the example above, but use the @code{ffmpeg} @var{force_key_frames}
+As the example above, but use the @command{ffmpeg} @option{force_key_frames}
 option to force key frames in the input at the specified location, together
-with the segment option @var{segment_time_delta} to account for
+with the segment option @option{segment_time_delta} to account for
 possible roundings operated when setting key frame times.
 @example
 ffmpeg -i in.mkv -force_key_frames 1,2,3,5,8,13,21 -codec:v mpeg4 -codec:a pcm_s16le -map 0 \
@@ -686,7 +813,7 @@
 
 @item
 Segment the input file by splitting the input file according to the
-frame numbers sequence specified with the @var{segment_frames} option:
+frame numbers sequence specified with the @option{segment_frames} option:
 @example
 ffmpeg -i in.mkv -codec copy -map 0 -f segment -segment_list out.csv -segment_frames 100,200,300,500,800 out%03d.nut
 @end example
@@ -707,57 +834,6 @@
 @end example
 @end itemize
 
-@section mp3
-
-The MP3 muxer writes a raw MP3 stream with an ID3v2 header at the beginning and
-optionally an ID3v1 tag at the end. ID3v2.3 and ID3v2.4 are supported, the
-@code{id3v2_version} option controls which one is used. The legacy ID3v1 tag is
-not written by default, but may be enabled with the @code{write_id3v1} option.
-
-For seekable output the muxer also writes a Xing frame at the beginning, which
-contains the number of frames in the file. It is useful for computing duration
-of VBR files.
-
-The muxer supports writing ID3v2 attached pictures (APIC frames). The pictures
-are supplied to the muxer in form of a video stream with a single packet. There
-can be any number of those streams, each will correspond to a single APIC frame.
-The stream metadata tags @var{title} and @var{comment} map to APIC
-@var{description} and @var{picture type} respectively. See
-@url{http://id3.org/id3v2.4.0-frames} for allowed picture types.
-
-Note that the APIC frames must be written at the beginning, so the muxer will
-buffer the audio frames until it gets all the pictures. It is therefore advised
-to provide the pictures as soon as possible to avoid excessive buffering.
-
-Examples:
-
-Write an mp3 with an ID3v2.3 header and an ID3v1 footer:
-@example
-ffmpeg -i INPUT -id3v2_version 3 -write_id3v1 1 out.mp3
-@end example
-
-To attach a picture to an mp3 file select both the audio and the picture stream
-with @code{map}:
-@example
-ffmpeg -i input.mp3 -i cover.png -c copy -map 0 -map 1
--metadata:s:v title="Album cover" -metadata:s:v comment="Cover (Front)" out.mp3
-@end example
-
-@section ogg
-
-Ogg container muxer.
-
-@table @option
-@item -page_duration @var{duration}
-Preferred page duration, in microseconds. The muxer will attempt to create
-pages that are approximately @var{duration} microseconds long. This allows the
-user to compromise between seek granularity and container overhead. The default
-is 1 second. A value of 0 will fill all segments, making pages as large as
-possible. A value of 1 will effectively use 1 packet-per-page in most
-situations, giving a small seek granularity at the cost of additional container
-overhead.
-@end table
-
 @section tee
 
 The tee muxer can be used to write the same data to several files or any
@@ -776,11 +852,32 @@
 escaped (see the ``Quoting and escaping'' section in the ffmpeg-utils
 manual).
 
-Options can be specified for each slave by prepending them as a list of
+Muxer options can be specified for each slave by prepending them as a list of
 @var{key}=@var{value} pairs separated by ':', between square brackets. If
 the options values contain a special character or the ':' separator, they
 must be escaped; note that this is a second level escaping.
 
+The following special options are also recognized:
+@table @option
+@item f
+Specify the format name. Useful if it cannot be guessed from the
+output name suffix.
+
+@item bsfs[/@var{spec}]
+Specify a list of bitstream filters to apply to the specified
+output. It is possible to specify to which streams a given bitstream
+filter applies, by appending a stream specifier to the option
+separated by @code{/}. If the stream specifier is not specified, the
+bistream filters will be applied to all streams in the output.
+
+Several bitstream filters can be specified, separated by ",".
+
+@item select
+Select the streams that should be mapped to the slave output,
+specified by a stream specifier. If not specified, this defaults to
+all the input streams.
+@end table
+
 Example: encode something and both archive it in a WebM file and stream it
 as MPEG-TS over UDP (the streams need to be explicitly mapped):
 
@@ -789,6 +886,17 @@
   "archive-20121107.mkv|[f=mpegts]udp://10.0.1.255:1234/"
 @end example
 
+Example: use @command{ffmpeg} to encode the input, and send the output
+to three different destinations. The @code{dump_extra} bitstream
+filter is used to add extradata information to all the output video
+keyframes packets, as requested by the MPEG-TS format. The select
+option is applied to @file{out.aac} in order to make it contain only
+audio packets.
+@example
+ffmpeg -i ... -map 0 -flags +global_header -c:v libx264 -c:a aac -strict experimental
+       -f tee "[bsfs/v=dump_extra]out.ts|[movflags=+faststart]out.mp4|[select=a]out.aac"
+@end example
+
 Note: some codecs may need different options depending on the output format;
 the auto-detection of this can not work with the tee muxer. The main example
 is the @option{global_header} flag.
diff --git a/doc/outdevs.texi b/doc/outdevs.texi
index 371d63a..730b47b 100644
--- a/doc/outdevs.texi
+++ b/doc/outdevs.texi
@@ -1,7 +1,7 @@
 @chapter Output Devices
 @c man begin OUTPUT DEVICES
 
-Output devices are configured elements in FFmpeg which allow to write
+Output devices are configured elements in FFmpeg that can write
 multimedia data to an output device attached to your system.
 
 When you configure your FFmpeg build, all the supported output devices
@@ -26,7 +26,7 @@
 
 CACA output device.
 
-This output devices allows to show a video stream in CACA window.
+This output device allows to show a video stream in CACA window.
 Only one CACA window is allowed per application, so you can
 have only one instance of this output device in an application.
 
@@ -112,7 +112,7 @@
 
 SDL (Simple DirectMedia Layer) output device.
 
-This output devices allows to show a video stream in an SDL
+This output device allows to show a video stream in an SDL
 window. Only one SDL window is allowed per application, so you can
 have only one instance of this output device in an application.
 
@@ -153,4 +153,69 @@
 
 sndio audio output device.
 
+@section xv
+
+XV (XVideo) output device.
+
+This output device allows to show a video stream in a X Window System
+window.
+
+@subsection Options
+
+@table @option
+@item display_name
+Specify the hardware display name, which determines the display and
+communications domain to be used.
+
+The display name or DISPLAY environment variable can be a string in
+the format @var{hostname}[:@var{number}[.@var{screen_number}]].
+
+@var{hostname} specifies the name of the host machine on which the
+display is physically attached. @var{number} specifies the number of
+the display server on that host machine. @var{screen_number} specifies
+the screen to be used on that server.
+
+If unspecified, it defaults to the value of the DISPLAY environment
+variable.
+
+For example, @code{dual-headed:0.1} would specify screen 1 of display
+0 on the machine named ``dual-headed''.
+
+Check the X11 specification for more detailed information about the
+display name format.
+
+@item window_size
+Set the created window size, can be a string of the form
+@var{width}x@var{height} or a video size abbreviation. If not
+specified it defaults to the size of the input video.
+
+@item window_x
+@item window_y
+Set the X and Y window offsets for the created window. They are both
+set to 0 by default. The values may be ignored by the window manager.
+
+@item window_title
+Set the window title, if not specified default to the filename
+specified for the output device.
+@end table
+
+For more information about XVideo see @url{http://www.x.org/}.
+
+@subsection Examples
+
+@itemize
+@item
+Decode, display and encode video input with @command{ffmpeg} at the
+same time:
+@example
+ffmpeg -i INPUT OUTPUT -f xv display
+@end example
+
+@item
+Decode and display the input video to multiple X11 windows:
+@example
+ffmpeg -i INPUT -f xv normal -vf negate -f xv negated
+@end example
+@end itemize
+
 @c man end OUTPUT DEVICES
diff --git a/doc/platform.texi b/doc/platform.texi
index 0703000..6d01e0e 100644
--- a/doc/platform.texi
+++ b/doc/platform.texi
@@ -106,10 +106,10 @@
 
 @end itemize
 
-@section Microsoft Visual C++
+@section Microsoft Visual C++ or Intel C++ Compiler for Windows
 
-FFmpeg can be built with MSVC using a C99-to-C89 conversion utility and
-wrapper.
+FFmpeg can be built with MSVC or ICL using a C99-to-C89 conversion utility and
+wrapper. For ICL, only the wrapper is used, since ICL supports C99.
 
 You will need the following prerequisites:
 
@@ -122,28 +122,33 @@
 you want to run @uref{fate.html, FATE}.
 @end itemize
 
-To set up a proper MSVC environment in MSYS, you simply need to run
-@code{msys.bat} from the Visual Studio command prompt.
+To set up a proper environment in MSYS, you need to run @code{msys.bat} from
+the Visual Studio or Intel Compiler command prompt.
 
 Place @code{makedef}, @code{c99wrap.exe}, @code{c99conv.exe}, and @code{yasm.exe}
 somewhere in your @code{PATH}.
 
 Next, make sure @code{inttypes.h} and any other headers and libs you want to use
-are located in a spot that MSVC can see. Do so by modifying the @code{LIB} and
-@code{INCLUDE} environment variables to include the @strong{Windows} paths to
+are located in a spot that the compiler can see. Do so by modifying the @code{LIB}
+and @code{INCLUDE} environment variables to include the @strong{Windows} paths to
 these directories. Alternatively, you can try and use the
 @code{--extra-cflags}/@code{--extra-ldflags} configure options.
 
 Finally, run:
 
 @example
+For MSVC:
 ./configure --toolchain=msvc
+
+For ICL:
+./configure --toolchain=icl
+
 make
 make install
 @end example
 
 If you wish to compile shared libraries, add @code{--enable-shared} to your
-configure options. Note that due to the way MSVC handles DLL imports and
+configure options. Note that due to the way MSVC and ICL handle DLL imports and
 exports, you cannot compile static and shared libraries at the same time, and
 enabling shared libraries will automatically disable the static ones.
 
@@ -173,7 +178,12 @@
 can see.
 @end enumerate
 
-@item FFmpeg has been tested with Visual Studio 2010 and 2012, Pro and Express.
+@item FFmpeg has been tested with the following on i686 and x86_64:
+@itemize
+@item Visual Studio 2010 Pro and Express
+@item Visual Studio 2012 Pro and Express
+@item Intel Composer XE 2013
+@end itemize
 Anything else is not officially supported.
 
 @end itemize
diff --git a/doc/print_options.c b/doc/print_options.c
index c369cfd..05a7991 100644
--- a/doc/print_options.c
+++ b/doc/print_options.c
@@ -27,7 +27,9 @@
 #include <float.h>
 
 #include "libavformat/avformat.h"
+#include "libavformat/options_table.h"
 #include "libavcodec/avcodec.h"
+#include "libavcodec/options_table.h"
 #include "libavutil/opt.h"
 
 static void print_usage(void)
@@ -96,18 +98,14 @@
 
 static void show_format_opts(void)
 {
-#include "libavformat/options_table.h"
-
     printf("@section Format AVOptions\n");
-    show_opts(options, 0);
+    show_opts(avformat_options, 0);
 }
 
 static void show_codec_opts(void)
 {
-#include "libavcodec/options_table.h"
-
     printf("@section Codec AVOptions\n");
-    show_opts(options, 1);
+    show_opts(avcodec_options, 1);
 }
 
 int main(int argc, char **argv)
diff --git a/doc/protocols.texi b/doc/protocols.texi
index 0c56b8b..5c43f01 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -1,8 +1,8 @@
 @chapter Protocols
 @c man begin PROTOCOLS
 
-Protocols are configured elements in FFmpeg which allow to access
-resources which require the use of a particular protocol.
+Protocols are configured elements in FFmpeg that enable access to
+resources that require specific protocols.
 
 When you configure your FFmpeg build, all the supported protocols are
 enabled by default. You can list all available ones using the
@@ -49,6 +49,16 @@
 -playlist 4 -angle 2 -chapter 2 bluray:/mnt/bluray
 @end example
 
+@section cache
+
+Caching wrapper for input stream.
+
+Cache the input stream to temporary file. It brings seeking capability to live streams.
+
+@example
+cache:@var{URL}
+@end example
+
 @section concat
 
 Physical concatenation protocol.
@@ -75,6 +85,25 @@
 Note that you may need to escape the character "|" which is special for
 many shells.
 
+@section crypto
+
+AES-encrypted stream reading protocol.
+
+The accepted options are:
+@table @option
+@item key
+Set the AES decryption key binary block from given hexadecimal representation.
+
+@item iv
+Set the AES decryption initialization vector binary block from given hexadecimal representation.
+@end table
+
+Accepted URL formats:
+@example
+crypto:@var{URL}
+crypto+@var{URL}
+@end example
+
 @section data
 
 Data in-line in the URI. See @url{http://en.wikipedia.org/wiki/Data_URI_scheme}.
@@ -100,6 +129,54 @@
 specified with the name "FILE.mpeg" is interpreted as the URL
 "file:FILE.mpeg".
 
+This protocol accepts the following options:
+
+@table @option
+@item truncate
+Truncate existing files on write, if set to 1. A value of 0 prevents
+truncating. Default value is 1.
+
+@item blocksize
+Set I/O operation maximum block size, in bytes. Default value is
+@code{INT_MAX}, which results in not limiting the requested block size.
+Setting this value reasonably low improves user termination request reaction
+time, which is valuable for files on slow medium.
+@end table
+
+@section ftp
+
+FTP (File Transfer Protocol).
+
+Allow to read from or write to remote resources using FTP protocol.
+
+Following syntax is required.
+@example
+ftp://[user[:password]@@]server[:port]/path/to/remote/resource.mpeg
+@end example
+
+This protocol accepts the following options.
+
+@table @option
+@item timeout
+Set timeout of socket I/O operations used by the underlying low level
+operation. By default it is set to -1, which means that the timeout is
+not specified.
+
+@item ftp-anonymous-password
+Password used when login as anonymous user. Typically an e-mail address
+should be used.
+
+@item ftp-write-seekable
+Control seekability of connection during encoding. If set to 1 the
+resource is supposed to be seekable, if set to 0 it is assumed not
+to be seekable. Default value is 0.
+@end table
+
+NOTE: Protocol can be used as output, but it is recommended to not do
+it, unless special care is taken (tests, customized server configuration
+etc.). Different FTP servers behave in different way during seek
+operation. ff* tools may produce incomplete content due to server limitations.
+
 @section gopher
 
 Gopher protocol.
@@ -165,6 +242,20 @@
 @item mime_type
 Set MIME type.
 
+@item icy
+If set to 1 request ICY (SHOUTcast) metadata from the server. If the server
+supports this, the metadata has to be retrieved by the application by reading
+the @option{icy_metadata_headers} and @option{icy_metadata_packet} options.
+The default is 0.
+
+@item icy_metadata_headers
+If the server supports ICY metadata, this contains the ICY specific HTTP reply
+headers, separated with newline characters.
+
+@item icy_metadata_packet
+If the server supports ICY metadata, and @option{icy} was set to 1, this
+contains the last non-empty metadata packet sent by the server.
+
 @item cookies
 Set the cookies to be sent in future requests. The format of each cookie is the
 same as the value of a Set-Cookie HTTP response field. Multiple cookies can be
@@ -248,6 +339,16 @@
 ffmpeg -i test.wav -f avi pipe: | cat > test.avi
 @end example
 
+This protocol accepts the following options:
+
+@table @option
+@item blocksize
+Set I/O operation maximum block size, in bytes. Default value is
+@code{INT_MAX}, which results in not limiting the requested block size.
+Setting this value reasonably low improves user termination request reaction
+time, which is valuable if data transmission is slow.
+@end table
+
 Note that some formats (typically MOV), require the output protocol to
 be seekable, so they will fail with the pipe output protocol.
 
@@ -260,12 +361,18 @@
 
 The required syntax is:
 @example
-rtmp://@var{server}[:@var{port}][/@var{app}][/@var{instance}][/@var{playpath}]
+rtmp://[@var{username}:@var{password}@@]@var{server}[:@var{port}][/@var{app}][/@var{instance}][/@var{playpath}]
 @end example
 
 The accepted parameters are:
 @table @option
 
+@item username
+An optional username (mostly for publishing).
+
+@item password
+An optional password (mostly for publishing).
+
 @item server
 The address of the RTMP server.
 
@@ -316,7 +423,8 @@
 
 @item rtmp_flashver
 Version of the Flash plugin used to run the SWF player. The default
-is LNX 9,0,124,2.
+is LNX 9,0,124,2. (When publishing, the default is FMLE/3.0 (compatible;
+<libavformat version>).)
 
 @item rtmp_flush_interval
 Number of packets flushed in the same request (RTMPT only). The default
@@ -366,6 +474,12 @@
 ffplay rtmp://myserver/vod/sample
 @end example
 
+To publish to a password protected server, passing the playpath and
+app names separately:
+@example
+ffmpeg -re -i <input> -f flv -rtmp_playpath some/long/path -rtmp_app long/app/name rtmp://username:password@@myserver/
+@end example
+
 @section rtmpe
 
 Encrypted Real-Time Messaging Protocol.
@@ -406,7 +520,7 @@
 for streaming multimedia content within HTTPS requests to traverse
 firewalls.
 
-@section rtmp, rtmpe, rtmps, rtmpt, rtmpte
+@section librtmp rtmp, rtmpe, rtmps, rtmpt, rtmpte
 
 Real-Time Messaging Protocol and its variants supported through
 librtmp.
@@ -635,6 +749,50 @@
 ffplay sap://[ff0e::2:7ffe]
 @end example
 
+@section sctp
+
+Stream Control Transmission Protocol.
+
+The accepted URL syntax is:
+@example
+sctp://@var{host}:@var{port}[?@var{options}]
+@end example
+
+The protocol accepts the following options:
+@table @option
+@item listen
+If set to any value, listen for an incoming connection. Outgoing connection is done by default.
+
+@item max_streams
+Set the maximum number of streams. By default no limit is set.
+@end table
+
+@section srtp
+
+Secure Real-time Transport Protocol.
+
+The accepted options are:
+@table @option
+@item srtp_in_suite
+@item srtp_out_suite
+Select input and output encoding suites.
+
+Supported values:
+@table @samp
+@item AES_CM_128_HMAC_SHA1_80
+@item SRTP_AES128_CM_HMAC_SHA1_80
+@item AES_CM_128_HMAC_SHA1_32
+@item SRTP_AES128_CM_HMAC_SHA1_32
+@end table
+
+@item srtp_in_params
+@item srtp_out_params
+Set input and output encoding parameters, which are expressed by a
+base64-encoded representation of a binary block. The first 16 bytes of
+this binary block are used as master key, the following 14 bytes are
+used as master salt.
+@end table
+
 @section tcp
 
 Trasmission Control Protocol.
@@ -792,4 +950,24 @@
 ffmpeg -i udp://[@var{multicast-address}]:@var{port}
 @end example
 
+@section unix
+
+Unix local socket
+
+The required syntax for a Unix socket URL is:
+
+@example
+unix://@var{filepath}
+@end example
+
+The following parameters can be set via command line options
+(or in code via @code{AVOption}s):
+
+@table @option
+@item timeout
+Timeout in ms.
+@item listen
+Create the Unix socket in listening mode.
+@end table
+
 @c man end PROTOCOLS
diff --git a/doc/resampler.texi b/doc/resampler.texi
index d37d53d..6a7e559 100644
--- a/doc/resampler.texi
+++ b/doc/resampler.texi
@@ -63,6 +63,11 @@
 @item rmvol, rematrix_volume
 Set rematrix volume. Default value is 1.0.
 
+@item rematrix_maxval
+Set maximum output value for rematrixing.
+This can be used to prevent clipping vs. preventing volumn reduction
+A value of 1.0 prevents cliping.
+
 @item flags, swr_flags
 Set flags used by the converter. Default value is 0.
 
@@ -217,6 +222,10 @@
 For swr only, set Kaiser Window Beta value. Must be an integer in the
 interval [2,16], default value is 9.
 
+@item output_sample_bits
+For swr only, set number of used output sample bits for dithering. Must be an integer in the
+interval [0,64], default value is 0, which means it's not used.
+
 @end table
 
 @c man end RESAMPLER OPTIONS
diff --git a/ffmpeg.c b/ffmpeg.c
index 30b69d3..886b373 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -46,7 +46,6 @@
 #include "libavutil/channel_layout.h"
 #include "libavutil/parseutils.h"
 #include "libavutil/samplefmt.h"
-#include "libavutil/colorspace.h"
 #include "libavutil/fifo.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/dict.h"
@@ -162,6 +161,8 @@
 static int restore_tty;
 #endif
 
+static void free_input_threads(void);
+
 
 /* sub2video hack:
    Convert subtitles to video with alpha to insert them in filter graphs.
@@ -318,7 +319,7 @@
     received_nb_signals++;
     term_exit();
     if(received_nb_signals > 3)
-        exit(123);
+        exit_program(123);
 }
 
 void term_init(void)
@@ -333,7 +334,6 @@
         if (istty && tcgetattr (0, &tty) == 0) {
             oldtty = tty;
             restore_tty = 1;
-            atexit(term_exit);
 
             tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
                              |INLCR|IGNCR|ICRNL|IXON);
@@ -421,7 +421,7 @@
 
 const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL };
 
-static void exit_program(void)
+static void ffmpeg_cleanup(int ret)
 {
     int i, j;
 
@@ -452,7 +452,7 @@
     /* close files */
     for (i = 0; i < nb_output_files; i++) {
         AVFormatContext *s = output_files[i]->ctx;
-        if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
+        if (s && s->oformat && !(s->oformat->flags & AVFMT_NOFILE) && s->pb)
             avio_close(s->pb);
         avformat_free_context(s);
         av_dict_free(&output_files[i]->opts);
@@ -474,6 +474,9 @@
         av_freep(&output_streams[i]->logfile_prefix);
         av_freep(&output_streams[i]);
     }
+#if HAVE_PTHREADS
+    free_input_threads();
+#endif
     for (i = 0; i < nb_input_files; i++) {
         avformat_close_input(&input_files[i]->ctx);
         av_freep(&input_files[i]);
@@ -505,6 +508,7 @@
         av_log(NULL, AV_LOG_INFO, "Received signal %d: terminating.\n",
                (int) received_sigterm);
     }
+    term_exit();
 }
 
 void assert_avoptions(AVDictionary *m)
@@ -512,13 +516,13 @@
     AVDictionaryEntry *t;
     if ((t = av_dict_get(m, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
         av_log(NULL, AV_LOG_FATAL, "Option %s not found.\n", t->key);
-        exit(1);
+        exit_program(1);
     }
 }
 
 static void abort_codec_experimental(AVCodec *c, int encoder)
 {
-    exit(1);
+    exit_program(1);
 }
 
 static void update_benchmark(const char *fmt, ...)
@@ -548,17 +552,6 @@
         (avctx->codec_type == AVMEDIA_TYPE_AUDIO && audio_sync_method < 0))
         pkt->pts = pkt->dts = AV_NOPTS_VALUE;
 
-    if ((avctx->codec_type == AVMEDIA_TYPE_AUDIO || avctx->codec_type == AVMEDIA_TYPE_VIDEO) && pkt->dts != AV_NOPTS_VALUE) {
-        int64_t max = ost->st->cur_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
-        if (ost->st->cur_dts && ost->st->cur_dts != AV_NOPTS_VALUE &&  max > pkt->dts) {
-            av_log(s, max - pkt->dts > 2 || avctx->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG,
-                   "st:%d PTS: %"PRId64" DTS: %"PRId64" < %"PRId64" invalid, clipping\n", pkt->stream_index, pkt->pts, pkt->dts, max);
-            if(pkt->pts >= pkt->dts)
-                pkt->pts = FFMAX(pkt->pts, max);
-            pkt->dts = max;
-        }
-    }
-
     /*
      * Audio encoders may split the packets --  #frames in != #packets out.
      * But there is no reordering, so we can limit the number of output packets
@@ -596,20 +589,44 @@
             new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size,
                                            av_buffer_default_free, NULL, 0);
             if (!new_pkt.buf)
-                exit(1);
+                exit_program(1);
         } else if (a < 0) {
             av_log(NULL, AV_LOG_ERROR, "Failed to open bitstream filter %s for stream %d with codec %s",
                    bsfc->filter->name, pkt->stream_index,
                    avctx->codec ? avctx->codec->name : "copy");
             print_error("", a);
             if (exit_on_error)
-                exit(1);
+                exit_program(1);
         }
         *pkt = new_pkt;
 
         bsfc = bsfc->next;
     }
 
+    if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS) &&
+        (avctx->codec_type == AVMEDIA_TYPE_AUDIO || avctx->codec_type == AVMEDIA_TYPE_VIDEO) &&
+        pkt->dts != AV_NOPTS_VALUE &&
+        ost->last_mux_dts != AV_NOPTS_VALUE) {
+      int64_t max = ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
+      if (pkt->dts < max) {
+        int loglevel = max - pkt->dts > 2 || avctx->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG;
+        av_log(s, loglevel, "Non-monotonous DTS in output stream "
+               "%d:%d; previous: %"PRId64", current: %"PRId64"; ",
+               ost->file_index, ost->st->index, ost->last_mux_dts, pkt->dts);
+        if (exit_on_error) {
+            av_log(NULL, AV_LOG_FATAL, "aborting.\n");
+            exit_program(1);
+        }
+        av_log(s, loglevel, "changing to %"PRId64". This may result "
+               "in incorrect timestamps in the output file.\n",
+               max);
+        if(pkt->pts >= pkt->dts)
+            pkt->pts = FFMAX(pkt->pts, max);
+        pkt->dts = max;
+      }
+    }
+    ost->last_mux_dts = pkt->dts;
+
     pkt->stream_index = ost->index;
 
     if (debug_ts) {
@@ -625,7 +642,7 @@
     ret = av_interleaved_write_frame(s, pkt);
     if (ret < 0) {
         print_error("av_interleaved_write_frame()", ret);
-        exit(1);
+        exit_program(1);
     }
 }
 
@@ -675,7 +692,7 @@
     update_benchmark(NULL);
     if (avcodec_encode_audio2(enc, &pkt, frame, &got_packet) < 0) {
         av_log(NULL, AV_LOG_FATAL, "Audio encoding failed (avcodec_encode_audio2)\n");
-        exit(1);
+        exit_program(1);
     }
     update_benchmark("encode_audio %d.%d", ost->file_index, ost->index);
 
@@ -715,7 +732,7 @@
     if (sub->pts == AV_NOPTS_VALUE) {
         av_log(NULL, AV_LOG_ERROR, "Subtitle packets must have a pts\n");
         if (exit_on_error)
-            exit(1);
+            exit_program(1);
         return;
     }
 
@@ -734,7 +751,9 @@
         nb = 1;
 
     /* shift timestamp to honor -ss and make check_recording_time() work with -t */
-    pts = sub->pts - output_files[ost->file_index]->start_time;
+    pts = sub->pts;
+    if (output_files[ost->file_index]->start_time != AV_NOPTS_VALUE)
+        pts -= output_files[ost->file_index]->start_time;
     for (i = 0; i < nb; i++) {
         ost->sync_opts = av_rescale_q(pts, AV_TIME_BASE_Q, enc->time_base);
         if (!check_recording_time(ost))
@@ -751,7 +770,7 @@
                                                     subtitle_out_max_size, sub);
         if (subtitle_out_size < 0) {
             av_log(NULL, AV_LOG_FATAL, "Subtitle encoding failed\n");
-            exit(1);
+            exit_program(1);
         }
 
         av_init_packet(&pkt);
@@ -846,7 +865,11 @@
 
     in_picture->pts = ost->sync_opts;
 
+#if 1
     if (!check_recording_time(ost))
+#else
+    if (ost->frame_number >= ost->max_frames)
+#endif
         return;
 
     if (s->oformat->flags & AVFMT_RAWPICTURE &&
@@ -926,7 +949,7 @@
         update_benchmark("encode_video %d.%d", ost->file_index, ost->index);
         if (ret < 0) {
             av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n");
-            exit(1);
+            exit_program(1);
         }
 
         if (got_packet) {
@@ -985,7 +1008,7 @@
         vstats_file = fopen(vstats_filename, "w");
         if (!vstats_file) {
             perror("fopen");
-            exit(1);
+            exit_program(1);
         }
     }
 
@@ -1049,17 +1072,13 @@
             }
             frame_pts = AV_NOPTS_VALUE;
             if (filtered_frame->pts != AV_NOPTS_VALUE) {
+                int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time;
                 filtered_frame->pts = frame_pts = av_rescale_q(filtered_frame->pts,
                                                 ost->filter->filter->inputs[0]->time_base,
                                                 ost->st->codec->time_base) -
-                                    av_rescale_q(of->start_time,
+                                    av_rescale_q(start_time,
                                                 AV_TIME_BASE_Q,
                                                 ost->st->codec->time_base);
-
-                if (of->start_time && filtered_frame->pts < 0) {
-                    av_frame_unref(filtered_frame);
-                    continue;
-                }
             }
             //if (ost->source_index >= 0)
             //    *filtered_frame= *input_streams[ost->source_index]->decoded_frame; //for me_threshold
@@ -1322,7 +1341,7 @@
                 update_benchmark("flush %s %d.%d", desc, ost->file_index, ost->index);
                 if (ret < 0) {
                     av_log(NULL, AV_LOG_FATAL, "%s encoding failed\n", desc);
-                    exit(1);
+                    exit_program(1);
                 }
                 *size += pkt.size;
                 if (ost->logfile && enc->stats_out) {
@@ -1361,7 +1380,7 @@
     if (ost->source_index != ist_index)
         return 0;
 
-    if (of->start_time && ist->pts < of->start_time)
+    if (of->start_time != AV_NOPTS_VALUE && ist->pts < of->start_time)
         return 0;
 
     return 1;
@@ -1370,7 +1389,10 @@
 static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *pkt)
 {
     OutputFile *of = output_files[ost->file_index];
-    int64_t ost_tb_start_time = av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base);
+    InputFile   *f = input_files [ist->file_index];
+    int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time;
+    int64_t ost_tb_start_time = av_rescale_q(start_time, AV_TIME_BASE_Q, ost->st->time_base);
+    int64_t ist_tb_start_time = av_rescale_q(start_time, AV_TIME_BASE_Q, ist->st->time_base);
     AVPicture pict;
     AVPacket opkt;
 
@@ -1380,16 +1402,32 @@
         !ost->copy_initial_nonkeyframes)
         return;
 
-    if (!ost->frame_number && ist->pts < of->start_time &&
-        !ost->copy_prior_start)
-        return;
+    if (pkt->pts == AV_NOPTS_VALUE) {
+        if (!ost->frame_number && ist->pts < start_time &&
+            !ost->copy_prior_start)
+            return;
+    } else {
+        if (!ost->frame_number && pkt->pts < ist_tb_start_time &&
+            !ost->copy_prior_start)
+            return;
+    }
 
     if (of->recording_time != INT64_MAX &&
-        ist->pts >= of->recording_time + of->start_time) {
+        ist->pts >= of->recording_time + start_time) {
         close_output_stream(ost);
         return;
     }
 
+    if (f->recording_time != INT64_MAX) {
+        start_time = f->ctx->start_time;
+        if (f->start_time != AV_NOPTS_VALUE)
+            start_time += f->start_time;
+        if (ist->pts >= f->recording_time + start_time) {
+            close_output_stream(ost);
+            return;
+        }
+    }
+
     /* force the input stream PTS */
     if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
         audio_size += pkt->size;
@@ -1432,7 +1470,7 @@
         if (av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY)) {
             opkt.buf = av_buffer_create(opkt.data, opkt.size, av_buffer_default_free, NULL, 0);
             if (!opkt.buf)
-                exit(1);
+                exit_program(1);
         }
     } else {
         opkt.data = pkt->data;
@@ -1451,16 +1489,6 @@
     ost->st->codec->frame_number++;
 }
 
-static void rate_emu_sleep(InputStream *ist)
-{
-    if (input_files[ist->file_index]->rate_emu) {
-        int64_t pts = av_rescale(ist->dts, 1000000, AV_TIME_BASE);
-        int64_t now = av_gettime() - ist->start;
-        if (pts > now)
-            av_usleep(pts - now);
-    }
-}
-
 int guess_input_channel_layout(InputStream *ist)
 {
     AVCodecContext *dec = ist->st->codec;
@@ -1527,8 +1555,6 @@
                      avctx->sample_rate;
 #endif
 
-    rate_emu_sleep(ist);
-
     resample_changed = ist->resample_sample_fmt     != decoded_frame->format         ||
                        ist->resample_channels       != avctx->channels               ||
                        ist->resample_channel_layout != decoded_frame->channel_layout ||
@@ -1540,7 +1566,7 @@
             av_log(NULL, AV_LOG_FATAL, "Unable to find default channel "
                    "layout for Input Stream #%d.%d\n", ist->file_index,
                    ist->st->index);
-            exit(1);
+            exit_program(1);
         }
         decoded_frame->channel_layout = avctx->channel_layout;
 
@@ -1568,7 +1594,7 @@
                 int j;
                 if (configure_filtergraph(fg) < 0) {
                     av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n");
-                    exit(1);
+                    exit_program(1);
                 }
                 for (j = 0; j < fg->nb_outputs; j++) {
                     OutputStream *ost = fg->outputs[j]->ost;
@@ -1611,6 +1637,8 @@
             f = decoded_frame;
         err = av_buffersrc_add_frame_flags(ist->filters[i]->filter, f,
                                      AV_BUFFERSRC_FLAG_PUSH);
+        if (err == AVERROR_EOF)
+            err = 0; /* ignore */
         if (err < 0)
             break;
     }
@@ -1675,8 +1703,6 @@
 
     pkt->size = 0;
 
-    rate_emu_sleep(ist);
-
     if (ist->st->sample_aspect_ratio.num)
         decoded_frame->sample_aspect_ratio = ist->st->sample_aspect_ratio;
 
@@ -1698,7 +1724,7 @@
             if (ist_in_filtergraph(filtergraphs[i], ist) && ist->reinit_filters &&
                 configure_filtergraph(filtergraphs[i]) < 0) {
                 av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n");
-                exit(1);
+                exit_program(1);
             }
         }
     }
@@ -1716,10 +1742,12 @@
         } else
             f = decoded_frame;
         ret = av_buffersrc_add_frame_flags(ist->filters[i]->filter, f, AV_BUFFERSRC_FLAG_PUSH);
-        if (ret < 0) {
+        if (ret == AVERROR_EOF) {
+            ret = 0; /* ignore */
+        } else if (ret < 0) {
             av_log(NULL, AV_LOG_FATAL,
                    "Failed to inject frame into filter network: %s\n", av_err2str(ret));
-            exit(1);
+            exit_program(1);
         }
     }
 
@@ -1765,8 +1793,6 @@
     if (!*got_output || !subtitle.num_rects)
         return ret;
 
-    rate_emu_sleep(ist);
-
     for (i = 0; i < nb_output_streams; i++) {
         OutputStream *ost = output_streams[i];
 
@@ -1883,7 +1909,6 @@
 
     /* handle stream copy */
     if (!ist->decoding_needed) {
-        rate_emu_sleep(ist);
         ist->dts = ist->next_dts;
         switch (ist->st->codec->codec_type) {
         case AVMEDIA_TYPE_AUDIO:
@@ -1928,7 +1953,7 @@
     AVFormatContext **avc = av_malloc(sizeof(*avc) * nb_output_files);
 
     if (!avc)
-        exit(1);
+        exit_program(1);
     for (i = 0; i < nb_output_files; i++)
         avc[i] = output_files[i]->ctx;
 
@@ -1956,10 +1981,16 @@
         if (!av_dict_get(ist->opts, "threads", NULL, 0))
             av_dict_set(&ist->opts, "threads", "auto", 0);
         if ((ret = avcodec_open2(ist->st->codec, codec, &ist->opts)) < 0) {
+            char errbuf[128];
             if (ret == AVERROR_EXPERIMENTAL)
                 abort_codec_experimental(codec, 0);
-            snprintf(error, error_len, "Error while opening decoder for input stream #%d:%d",
-                    ist->file_index, ist->st->index);
+
+            av_strerror(ret, errbuf, sizeof(errbuf));
+
+            snprintf(error, error_len,
+                     "Error while opening decoder for input stream "
+                     "#%d:%d : %s",
+                     ist->file_index, ist->st->index, errbuf);
             return ret;
         }
         assert_avoptions(ist->opts);
@@ -1999,7 +2030,7 @@
     pts = av_malloc(sizeof(*pts) * size);
     if (!pts) {
         av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n");
-        exit(1);
+        exit_program(1);
     }
 
     p = kf;
@@ -2019,7 +2050,7 @@
                                      sizeof(*pts)))) {
                 av_log(NULL, AV_LOG_FATAL,
                        "Could not allocate forced key frames array.\n");
-                exit(1);
+                exit_program(1);
             }
             t = p[8] ? parse_time_or_die("force_key_frames", p + 8, 1) : 0;
             t = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base);
@@ -2117,6 +2148,7 @@
         }
 
         if (ost->stream_copy) {
+            AVRational sar;
             uint64_t extra_size;
 
             av_assert0(ist && !ost->filter);
@@ -2206,7 +2238,7 @@
             case AVMEDIA_TYPE_AUDIO:
                 if (audio_volume != 256) {
                     av_log(NULL, AV_LOG_FATAL, "-acodec copy and -vol are incompatible (frames are not decoded)\n");
-                    exit(1);
+                    exit_program(1);
                 }
                 codec->channel_layout     = icodec->channel_layout;
                 codec->sample_rate        = icodec->sample_rate;
@@ -2225,19 +2257,17 @@
                 codec->height             = icodec->height;
                 codec->has_b_frames       = icodec->has_b_frames;
                 if (ost->frame_aspect_ratio.num) { // overridden by the -aspect cli option
-                    codec->sample_aspect_ratio   =
-                    ost->st->sample_aspect_ratio =
+                    sar =
                         av_mul_q(ost->frame_aspect_ratio,
                                  (AVRational){ codec->height, codec->width });
                     av_log(NULL, AV_LOG_WARNING, "Overriding aspect ratio "
                            "with stream copy may produce invalid files\n");
-                } else if (!codec->sample_aspect_ratio.num) {
-                    codec->sample_aspect_ratio   =
-                    ost->st->sample_aspect_ratio =
-                        ist->st->sample_aspect_ratio.num ? ist->st->sample_aspect_ratio :
-                        ist->st->codec->sample_aspect_ratio.num ?
-                        ist->st->codec->sample_aspect_ratio : (AVRational){0, 1};
                 }
+                else if (ist->st->sample_aspect_ratio.num)
+                    sar = ist->st->sample_aspect_ratio;
+                else
+                    sar = icodec->sample_aspect_ratio;
+                ost->st->sample_aspect_ratio = codec->sample_aspect_ratio = sar;
                 ost->st->avg_frame_rate = ist->st->avg_frame_rate;
                 break;
             case AVMEDIA_TYPE_SUBTITLE:
@@ -2272,7 +2302,7 @@
                     fg = init_simple_filtergraph(ist, ost);
                     if (configure_filtergraph(fg)) {
                         av_log(NULL, AV_LOG_FATAL, "Error opening filters!\n");
-                        exit(1);
+                        exit_program(1);
                     }
             }
 
@@ -2321,10 +2351,17 @@
                 if (!strncmp(ost->enc->name, "libx264", 7) &&
                     codec->pix_fmt == AV_PIX_FMT_NONE &&
                     ost->filter->filter->inputs[0]->format != AV_PIX_FMT_YUV420P)
-                    av_log(NULL, AV_LOG_INFO,
+                    av_log(NULL, AV_LOG_WARNING,
                            "No pixel format specified, %s for H.264 encoding chosen.\n"
                            "Use -pix_fmt yuv420p for compatibility with outdated media players.\n",
                            av_get_pix_fmt_name(ost->filter->filter->inputs[0]->format));
+                if (!strncmp(ost->enc->name, "mpeg2video", 10) &&
+                    codec->pix_fmt == AV_PIX_FMT_NONE &&
+                    ost->filter->filter->inputs[0]->format != AV_PIX_FMT_YUV420P)
+                    av_log(NULL, AV_LOG_WARNING,
+                           "No pixel format specified, %s for MPEG-2 encoding chosen.\n"
+                           "Use -pix_fmt yuv420p for compatibility with outdated media players.\n",
+                           av_get_pix_fmt_name(ost->filter->filter->inputs[0]->format));
                 codec->pix_fmt = ost->filter->filter->inputs[0]->format;
 
                 if (!icodec ||
@@ -2381,7 +2418,7 @@
                         if (cmdutils_read_file(logfilename, &logbuffer, &logbuffer_size) < 0) {
                             av_log(NULL, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n",
                                    logfilename);
-                            exit(1);
+                            exit_program(1);
                         }
                         codec->stats_in = logbuffer;
                     }
@@ -2390,7 +2427,7 @@
                         if (!f) {
                             av_log(NULL, AV_LOG_FATAL, "Cannot write log file '%s' for pass-1 encoding: %s\n",
                                 logfilename, strerror(errno));
-                            exit(1);
+                            exit_program(1);
                         }
                         ost->logfile = f;
                     }
@@ -2476,10 +2513,11 @@
         oc->interrupt_callback = int_cb;
         if ((ret = avformat_write_header(oc, &output_files[i]->opts)) < 0) {
             char errbuf[128];
-            const char *errbuf_ptr = errbuf;
-            if (av_strerror(ret, errbuf, sizeof(errbuf)) < 0)
-                errbuf_ptr = strerror(AVUNERROR(ret));
-            snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?): %s", i, errbuf_ptr);
+            av_strerror(ret, errbuf, sizeof(errbuf));
+            snprintf(error, sizeof(error),
+                     "Could not write header for output file #%d "
+                     "(incorrect codec parameters ?): %s",
+                     i, errbuf);
             ret = AVERROR(EINVAL);
             goto dump_format;
         }
@@ -2818,6 +2856,17 @@
 
 static int get_input_packet(InputFile *f, AVPacket *pkt)
 {
+    if (f->rate_emu) {
+        int i;
+        for (i = 0; i < f->nb_streams; i++) {
+            InputStream *ist = input_streams[f->ist_index + i];
+            int64_t pts = av_rescale(ist->dts, 1000000, AV_TIME_BASE);
+            int64_t now = av_gettime() - ist->start;
+            if (pts > now)
+                return AVERROR(EAGAIN);
+        }
+    }
+
 #if HAVE_PTHREADS
     if (nb_input_files > 1)
         return get_input_packet_mt(f, pkt);
@@ -2869,7 +2918,7 @@
         if (ret != AVERROR_EOF) {
             print_error(is->filename, ret);
             if (exit_on_error)
-                exit(1);
+                exit_program(1);
         }
         ifile->eof_reached = 1;
 
@@ -3040,7 +3089,7 @@
         av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d: %s\n",
                 ist->file_index, ist->st->index, buf);
         if (exit_on_error)
-            exit(1);
+            exit_program(1);
     }
 
 discard_packet:
@@ -3253,7 +3302,8 @@
                     ost->logfile = NULL;
                 }
                 av_freep(&ost->st->codec->subtitle_header);
-                av_free(ost->forced_kf_pts);
+                av_freep(&ost->forced_kf_pts);
+                av_freep(&ost->apad);
                 av_dict_free(&ost->opts);
                 av_dict_free(&ost->swr_opts);
                 av_dict_free(&ost->resample_opts);
@@ -3309,7 +3359,7 @@
     int ret;
     int64_t ti;
 
-    atexit(exit_program);
+    register_exit(ffmpeg_cleanup);
 
     setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */
 
@@ -3338,28 +3388,28 @@
     /* parse options and open all input/output files */
     ret = ffmpeg_parse_options(argc, argv);
     if (ret < 0)
-        exit(1);
+        exit_program(1);
 
     if (nb_output_files <= 0 && nb_input_files == 0) {
         show_usage();
         av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
-        exit(1);
+        exit_program(1);
     }
 
     /* file converter / grab */
     if (nb_output_files <= 0) {
         av_log(NULL, AV_LOG_FATAL, "At least one output file must be specified\n");
-        exit(1);
+        exit_program(1);
     }
 
 //     if (nb_input_files == 0) {
 //         av_log(NULL, AV_LOG_FATAL, "At least one input file must be specified\n");
-//         exit(1);
+//         exit_program(1);
 //     }
 
     current_time = ti = getutime();
     if (transcode() < 0)
-        exit(1);
+        exit_program(1);
     ti = getutime() - ti;
     if (do_benchmark) {
         printf("bench: utime=%0.3fs\n", ti / 1000000.0);
@@ -3367,8 +3417,8 @@
     av_log(NULL, AV_LOG_DEBUG, "%"PRIu64" frames successfully decoded, %"PRIu64" decoding errors\n",
            decode_error_stat[0], decode_error_stat[1]);
     if (2*decode_error_stat[0] < decode_error_stat[1])
-        exit(254);
+        exit_program(254);
 
-    exit(received_nb_signals ? 255 : 0);
+    exit_program(received_nb_signals ? 255 : 0);
     return 0;
 }
diff --git a/ffmpeg.h b/ffmpeg.h
index 3641a62..09b29a9 100644
--- a/ffmpeg.h
+++ b/ffmpeg.h
@@ -93,6 +93,7 @@
     /* input options */
     int64_t input_ts_offset;
     int rate_emu;
+    int accurate_seek;
 
     SpecifierOpt *ts_scale;
     int        nb_ts_scale;
@@ -178,6 +179,8 @@
     int        nb_passlogfiles;
     SpecifierOpt *guess_layout_max;
     int        nb_guess_layout_max;
+    SpecifierOpt *apad;
+    int        nb_apad;
 } OptionsContext;
 
 typedef struct InputFilter {
@@ -280,10 +283,13 @@
     int ist_index;        /* index of first stream in input_streams */
     int64_t ts_offset;
     int64_t last_ts;
+    int64_t start_time;   /* user-specified start time in AV_TIME_BASE or AV_NOPTS_VALUE */
+    int64_t recording_time;
     int nb_streams;       /* number of stream that ffmpeg is aware of; may be different
                              from ctx.nb_streams if new streams appear during av_read_frame() */
     int nb_streams_warn;  /* number of streams that the user was warned of */
     int rate_emu;
+    int accurate_seek;
 
 #if HAVE_PTHREADS
     pthread_t thread;           /* thread reading from this file */
@@ -320,6 +326,8 @@
     /* pts of the first frame encoded for this stream, used for limiting
      * recording time */
     int64_t first_pts;
+    /* dts of the last packet sent to the muxer */
+    int64_t last_mux_dts;
     AVBitStreamFilterContext *bitstream_filters;
     AVCodec *enc;
     int64_t max_frames;
@@ -354,6 +362,7 @@
     AVDictionary *opts;
     AVDictionary *swr_opts;
     AVDictionary *resample_opts;
+    char *apad;
     int finished;        /* no more packets should be written for this stream */
     int unavailable;                     /* true if the steram is unavailable (possibly temporarily) */
     int stream_copy;
diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c
index e7e7242..80089ff 100644
--- a/ffmpeg_filter.c
+++ b/ffmpeg_filter.c
@@ -109,7 +109,7 @@
         int len;
 
         if (avio_open_dyn_buf(&s) < 0)
-            exit(1);
+            exit_program(1);
 
         p = ost->enc->pix_fmts;
         if (ost->st->codec->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
@@ -147,7 +147,7 @@
         int len;                                                               \
                                                                                \
         if (avio_open_dyn_buf(&s) < 0)                                         \
-            exit(1);                                                           \
+            exit_program(1);                                                           \
                                                                                \
         for (p = ost->enc->supported_list; *p != none; p++) {                  \
             get_name(*p);                                                      \
@@ -177,12 +177,12 @@
     FilterGraph *fg = av_mallocz(sizeof(*fg));
 
     if (!fg)
-        exit(1);
+        exit_program(1);
     fg->index = nb_filtergraphs;
 
     GROW_ARRAY(fg->outputs, fg->nb_outputs);
     if (!(fg->outputs[0] = av_mallocz(sizeof(*fg->outputs[0]))))
-        exit(1);
+        exit_program(1);
     fg->outputs[0]->ost   = ost;
     fg->outputs[0]->graph = fg;
 
@@ -190,7 +190,7 @@
 
     GROW_ARRAY(fg->inputs, fg->nb_inputs);
     if (!(fg->inputs[0] = av_mallocz(sizeof(*fg->inputs[0]))))
-        exit(1);
+        exit_program(1);
     fg->inputs[0]->ist   = ist;
     fg->inputs[0]->graph = fg;
 
@@ -213,7 +213,7 @@
     if (type != AVMEDIA_TYPE_VIDEO && type != AVMEDIA_TYPE_AUDIO) {
         av_log(NULL, AV_LOG_FATAL, "Only video and audio filters supported "
                "currently.\n");
-        exit(1);
+        exit_program(1);
     }
 
     if (in->name) {
@@ -225,7 +225,7 @@
         if (file_idx < 0 || file_idx >= nb_input_files) {
             av_log(NULL, AV_LOG_FATAL, "Invalid file index %d in filtergraph description %s.\n",
                    file_idx, fg->graph_desc);
-            exit(1);
+            exit_program(1);
         }
         s = input_files[file_idx]->ctx;
 
@@ -243,7 +243,7 @@
         if (!st) {
             av_log(NULL, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s "
                    "matches no streams.\n", p, fg->graph_desc);
-            exit(1);
+            exit_program(1);
         }
         ist = input_streams[input_files[file_idx]->ist_index + st->index];
     } else {
@@ -257,7 +257,7 @@
             av_log(NULL, AV_LOG_FATAL, "Cannot find a matching stream for "
                    "unlabeled input pad %d on filter %s\n", in->pad_idx,
                    in->filter_ctx->name);
-            exit(1);
+            exit_program(1);
         }
     }
     av_assert0(ist);
@@ -268,7 +268,7 @@
 
     GROW_ARRAY(fg->inputs, fg->nb_inputs);
     if (!(fg->inputs[fg->nb_inputs - 1] = av_mallocz(sizeof(*fg->inputs[0]))))
-        exit(1);
+        exit_program(1);
     fg->inputs[fg->nb_inputs - 1]->ist   = ist;
     fg->inputs[fg->nb_inputs - 1]->graph = fg;
 
@@ -276,10 +276,62 @@
     ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1];
 }
 
+static int insert_trim(int64_t start_time, int64_t duration,
+                       AVFilterContext **last_filter, int *pad_idx,
+                       const char *filter_name)
+{
+    AVFilterGraph *graph = (*last_filter)->graph;
+    AVFilterContext *ctx;
+    const AVFilter *trim;
+    enum AVMediaType type = avfilter_pad_get_type((*last_filter)->output_pads, *pad_idx);
+    const char *name = (type == AVMEDIA_TYPE_VIDEO) ? "trim" : "atrim";
+    int ret = 0;
+
+    if (duration == INT64_MAX && start_time == AV_NOPTS_VALUE)
+        return 0;
+
+    trim = avfilter_get_by_name(name);
+    if (!trim) {
+        av_log(NULL, AV_LOG_ERROR, "%s filter not present, cannot limit "
+               "recording time.\n", name);
+        return AVERROR_FILTER_NOT_FOUND;
+    }
+
+    ctx = avfilter_graph_alloc_filter(graph, trim, filter_name);
+    if (!ctx)
+        return AVERROR(ENOMEM);
+
+    if (duration != INT64_MAX) {
+        ret = av_opt_set_int(ctx, "durationi", duration,
+                                AV_OPT_SEARCH_CHILDREN);
+    }
+    if (ret >= 0 && start_time != AV_NOPTS_VALUE) {
+        ret = av_opt_set_int(ctx, "starti", start_time,
+                                AV_OPT_SEARCH_CHILDREN);
+    }
+    if (ret < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Error configuring the %s filter", name);
+        return ret;
+    }
+
+    ret = avfilter_init_str(ctx, NULL);
+    if (ret < 0)
+        return ret;
+
+    ret = avfilter_link(*last_filter, *pad_idx, ctx, 0);
+    if (ret < 0)
+        return ret;
+
+    *last_filter = ctx;
+    *pad_idx     = 0;
+    return 0;
+}
+
 static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
 {
     char *pix_fmts;
     OutputStream *ost = ofilter->ost;
+    OutputFile    *of = output_files[ost->file_index];
     AVCodecContext *codec = ost->st->codec;
     AVFilterContext *last_filter = out->filter_ctx;
     int pad_idx = out->pad_idx;
@@ -298,7 +350,7 @@
         char args[255];
         AVFilterContext *filter;
 
-        snprintf(args, sizeof(args), "%d:%d:flags=0x%X",
+        snprintf(args, sizeof(args), "%d:%d:0x%X",
                  codec->width,
                  codec->height,
                  (unsigned)ost->sws_flags);
@@ -352,6 +404,14 @@
         pad_idx = 0;
     }
 
+    snprintf(name, sizeof(name), "trim for output stream %d:%d",
+             ost->file_index, ost->index);
+    ret = insert_trim(of->start_time, of->recording_time,
+                      &last_filter, &pad_idx, name);
+    if (ret < 0)
+        return ret;
+
+
     if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
         return ret;
 
@@ -361,6 +421,7 @@
 static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
 {
     OutputStream *ost = ofilter->ost;
+    OutputFile    *of = output_files[ost->file_index];
     AVCodecContext *codec  = ost->st->codec;
     AVFilterContext *last_filter = out->filter_ctx;
     int pad_idx = out->pad_idx;
@@ -458,6 +519,27 @@
         AUTO_INSERT_FILTER("-vol", "volume", args);
     }
 
+    if (ost->apad && of->shortest) {
+        char args[256];
+        int i;
+
+        for (i=0; i<of->ctx->nb_streams; i++)
+            if (of->ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
+                break;
+
+        if (i<of->ctx->nb_streams) {
+            snprintf(args, sizeof(args), "%s", ost->apad);
+            AUTO_INSERT_FILTER("-apad", "apad", args);
+        }
+    }
+
+    snprintf(name, sizeof(name), "trim for output stream %d:%d",
+             ost->file_index, ost->index);
+    ret = insert_trim(of->start_time, of->recording_time,
+                      &last_filter, &pad_idx, name);
+    if (ret < 0)
+        return ret;
+
     if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
         return ret;
 
@@ -468,11 +550,11 @@
 {                                                                  \
     AVFilterContext *ctx = inout->filter_ctx;                      \
     AVFilterPad *pads = in ? ctx->input_pads  : ctx->output_pads;  \
-    int       nb_pads = in ? ctx->input_count : ctx->output_count; \
+    int       nb_pads = in ? ctx->nb_inputs   : ctx->nb_outputs;   \
     AVIOContext *pb;                                               \
                                                                    \
     if (avio_open_dyn_buf(&pb) < 0)                                \
-        exit(1);                                                   \
+        exit_program(1);                                           \
                                                                    \
     avio_printf(pb, "%s", ctx->filter->name);                      \
     if (nb_pads > 1)                                               \
@@ -532,17 +614,22 @@
 static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
                                         AVFilterInOut *in)
 {
-    AVFilterContext *first_filter = in->filter_ctx;
-    AVFilter *filter = avfilter_get_by_name("buffer");
+    AVFilterContext *last_filter;
+    const AVFilter *buffer_filt = avfilter_get_by_name("buffer");
     InputStream *ist = ifilter->ist;
+    InputFile     *f = input_files[ist->file_index];
     AVRational tb = ist->framerate.num ? av_inv_q(ist->framerate) :
                                          ist->st->time_base;
     AVRational fr = ist->framerate;
     AVRational sar;
     AVBPrint args;
     char name[255];
-    int pad_idx = in->pad_idx;
-    int ret;
+    int ret, pad_idx = 0;
+
+    if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+        av_log(NULL, AV_LOG_ERROR, "Cannot connect video filter to audio input\n");
+        return AVERROR(EINVAL);
+    }
 
     if (!fr.num)
         fr = av_guess_frame_rate(input_files[ist->file_index]->ctx, ist->st, NULL);
@@ -570,9 +657,10 @@
     snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
              ist->file_index, ist->st->index);
 
-    if ((ret = avfilter_graph_create_filter(&ifilter->filter, filter, name,
+    if ((ret = avfilter_graph_create_filter(&ifilter->filter, buffer_filt, name,
                                             args.str, NULL, fg->graph)) < 0)
         return ret;
+    last_filter = ifilter->filter;
 
     if (ist->framerate.num) {
         AVFilterContext *setpts;
@@ -585,11 +673,10 @@
                                                 fg->graph)) < 0)
             return ret;
 
-        if ((ret = avfilter_link(setpts, 0, first_filter, pad_idx)) < 0)
+        if ((ret = avfilter_link(last_filter, 0, setpts, 0)) < 0)
             return ret;
 
-        first_filter = setpts;
-        pad_idx = 0;
+        last_filter = setpts;
     }
 
     if (do_deinterlace) {
@@ -603,14 +690,20 @@
                                                 fg->graph)) < 0)
             return ret;
 
-        if ((ret = avfilter_link(yadif, 0, first_filter, pad_idx)) < 0)
+        if ((ret = avfilter_link(last_filter, 0, yadif, 0)) < 0)
             return ret;
 
-        first_filter = yadif;
-        pad_idx = 0;
+        last_filter = yadif;
     }
 
-    if ((ret = avfilter_link(ifilter->filter, 0, first_filter, pad_idx)) < 0)
+    snprintf(name, sizeof(name), "trim for input stream %d:%d",
+             ist->file_index, ist->st->index);
+    ret = insert_trim(((f->start_time == AV_NOPTS_VALUE) || !f->accurate_seek) ?
+                      AV_NOPTS_VALUE : 0, f->recording_time, &last_filter, &pad_idx, name);
+    if (ret < 0)
+        return ret;
+
+    if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
         return ret;
     return 0;
 }
@@ -618,13 +711,18 @@
 static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
                                         AVFilterInOut *in)
 {
-    AVFilterContext *first_filter = in->filter_ctx;
-    AVFilter *filter = avfilter_get_by_name("abuffer");
+    AVFilterContext *last_filter;
+    const AVFilter *abuffer_filt = avfilter_get_by_name("abuffer");
     InputStream *ist = ifilter->ist;
-    int pad_idx = in->pad_idx;
+    InputFile     *f = input_files[ist->file_index];
     AVBPrint args;
     char name[255];
-    int ret;
+    int ret, pad_idx = 0;
+
+    if (ist->st->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
+        av_log(NULL, AV_LOG_ERROR, "Cannot connect audio filter to non audio input\n");
+        return AVERROR(EINVAL);
+    }
 
     av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC);
     av_bprintf(&args, "time_base=%d/%d:sample_rate=%d:sample_fmt=%s",
@@ -639,10 +737,11 @@
     snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
              ist->file_index, ist->st->index);
 
-    if ((ret = avfilter_graph_create_filter(&ifilter->filter, filter,
+    if ((ret = avfilter_graph_create_filter(&ifilter->filter, abuffer_filt,
                                             name, args.str, NULL,
                                             fg->graph)) < 0)
         return ret;
+    last_filter = ifilter->filter;
 
 #define AUTO_INSERT_FILTER_INPUT(opt_name, filter_name, arg) do {                 \
     AVFilterContext *filt_ctx;                                              \
@@ -658,11 +757,11 @@
     if (ret < 0)                                                            \
         return ret;                                                         \
                                                                             \
-    ret = avfilter_link(filt_ctx, 0, first_filter, pad_idx);                \
+    ret = avfilter_link(last_filter, 0, filt_ctx, 0);                       \
     if (ret < 0)                                                            \
         return ret;                                                         \
                                                                             \
-    first_filter = filt_ctx;                                                  \
+    last_filter = filt_ctx;                                                 \
 } while (0)
 
     if (audio_sync_method > 0) {
@@ -698,7 +797,15 @@
         snprintf(args, sizeof(args), "%f", audio_volume / 256.);
         AUTO_INSERT_FILTER_INPUT("-vol", "volume", args);
     }
-    if ((ret = avfilter_link(ifilter->filter, 0, first_filter, pad_idx)) < 0)
+
+    snprintf(name, sizeof(name), "trim for input stream %d:%d",
+             ist->file_index, ist->st->index);
+    ret = insert_trim(((f->start_time == AV_NOPTS_VALUE) || !f->accurate_seek) ?
+                      AV_NOPTS_VALUE : 0, f->recording_time, &last_filter, &pad_idx, name);
+    if (ret < 0)
+        return ret;
+
+    if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
         return ret;
 
     return 0;
@@ -786,7 +893,7 @@
         for (cur = outputs; cur;) {
             GROW_ARRAY(fg->outputs, fg->nb_outputs);
             if (!(fg->outputs[fg->nb_outputs - 1] = av_mallocz(sizeof(*fg->outputs[0]))))
-                exit(1);
+                exit_program(1);
             fg->outputs[fg->nb_outputs - 1]->graph   = fg;
             fg->outputs[fg->nb_outputs - 1]->out_tmp = cur;
             cur = cur->next;
diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c
index f03f29b..8ff5bdf 100644
--- a/ffmpeg_opt.c
+++ b/ffmpeg_opt.c
@@ -49,7 +49,7 @@
         if ((ret = check_stream_specifier(fmtctx, st, spec)) > 0)\
             outvar = o->name[i].u.type;\
         else if (ret < 0)\
-            exit(1);\
+            exit_program(1);\
     }\
 }
 
@@ -93,10 +93,9 @@
 static int intra_dc_precision = 8;
 static int do_psnr            = 0;
 static int input_sync;
+static int override_ffserver  = 0;
 
-static int64_t recording_time = INT64_MAX;
-
-static void uninit_options(OptionsContext *o, int is_input)
+static void uninit_options(OptionsContext *o)
 {
     const OptionDef *po = options;
     int i;
@@ -126,28 +125,19 @@
     av_freep(&o->audio_channel_maps);
     av_freep(&o->streamid_map);
     av_freep(&o->attachments);
-
-    if (is_input)
-        recording_time = o->recording_time;
-    else
-        recording_time = INT64_MAX;
 }
 
-static void init_options(OptionsContext *o, int is_input)
+static void init_options(OptionsContext *o)
 {
     memset(o, 0, sizeof(*o));
 
-    if (!is_input && recording_time != INT64_MAX) {
-        o->recording_time = recording_time;
-        av_log(NULL, AV_LOG_WARNING,
-                "-t is not an input option, keeping it for the next output;"
-                " consider fixing your command line.\n");
-    } else
-        o->recording_time = INT64_MAX;
     o->stop_time = INT64_MAX;
     o->mux_max_delay  = 0.7;
+    o->start_time     = AV_NOPTS_VALUE;
+    o->recording_time = INT64_MAX;
     o->limit_filesize = UINT64_MAX;
     o->chapters_input_file = INT_MAX;
+    o->accurate_seek  = 1;
 }
 
 /* return a copy of the input with the stream specifiers removed from the keys */
@@ -234,7 +224,7 @@
         sync_file_idx = strtol(sync + 1, &sync, 0);
         if (sync_file_idx >= nb_input_files || sync_file_idx < 0) {
             av_log(NULL, AV_LOG_FATAL, "Invalid sync file index: %d.\n", sync_file_idx);
-            exit(1);
+            exit_program(1);
         }
         if (*sync)
             sync++;
@@ -247,7 +237,7 @@
         if (i == input_files[sync_file_idx]->nb_streams) {
             av_log(NULL, AV_LOG_FATAL, "Sync stream specification in map %s does not "
                                        "match any streams.\n", arg);
-            exit(1);
+            exit_program(1);
         }
     }
 
@@ -260,13 +250,13 @@
         m->linklabel = av_get_token(&c, "]");
         if (!m->linklabel) {
             av_log(NULL, AV_LOG_ERROR, "Invalid output link label: %s.\n", map);
-            exit(1);
+            exit_program(1);
         }
     } else {
         file_idx = strtol(map, &p, 0);
         if (file_idx >= nb_input_files || file_idx < 0) {
             av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);
-            exit(1);
+            exit_program(1);
         }
         if (negative)
             /* disable some already defined maps */
@@ -301,7 +291,7 @@
 
     if (!m) {
         av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n", arg);
-        exit(1);
+        exit_program(1);
     }
 
     av_freep(&map);
@@ -343,7 +333,7 @@
     if (n != 3 && n != 5) {
         av_log(NULL, AV_LOG_FATAL, "Syntax error, mapchan usage: "
                "[file.stream.channel|-1][:syncfile:syncstream]\n");
-        exit(1);
+        exit_program(1);
     }
 
     if (n != 5) // only file.stream.channel specified
@@ -353,24 +343,24 @@
     if (m->file_idx < 0 || m->file_idx >= nb_input_files) {
         av_log(NULL, AV_LOG_FATAL, "mapchan: invalid input file index: %d\n",
                m->file_idx);
-        exit(1);
+        exit_program(1);
     }
     if (m->stream_idx < 0 ||
         m->stream_idx >= input_files[m->file_idx]->nb_streams) {
         av_log(NULL, AV_LOG_FATAL, "mapchan: invalid input file stream index #%d.%d\n",
                m->file_idx, m->stream_idx);
-        exit(1);
+        exit_program(1);
     }
     st = input_files[m->file_idx]->ctx->streams[m->stream_idx];
     if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
         av_log(NULL, AV_LOG_FATAL, "mapchan: stream #%d.%d is not an audio stream.\n",
                m->file_idx, m->stream_idx);
-        exit(1);
+        exit_program(1);
     }
     if (m->channel_idx < 0 || m->channel_idx >= st->codec->channels) {
         av_log(NULL, AV_LOG_FATAL, "mapchan: invalid audio channel #%d.%d.%d\n",
                m->file_idx, m->stream_idx, m->channel_idx);
-        exit(1);
+        exit_program(1);
     }
     return 0;
 }
@@ -392,7 +382,7 @@
         case 's':
             if (*(++arg) && *arg != ':') {
                 av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg);
-                exit(1);
+                exit_program(1);
             }
             *stream_spec = *arg == ':' ? arg + 1 : "";
             break;
@@ -403,7 +393,7 @@
             break;
         default:
             av_log(NULL, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg);
-            exit(1);
+            exit_program(1);
         }
     } else
         *type = 'g';
@@ -446,7 +436,7 @@
     if ((index) < 0 || (index) >= (nb_elems)) {\
         av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\
                 (desc), (index));\
-        exit(1);\
+        exit_program(1);\
     }
 
 #define SET_DICT(type, meta, context, index)\
@@ -477,11 +467,11 @@
                 meta_in = &ic->streams[i]->metadata;
                 break;
             } else if (ret < 0)
-                exit(1);
+                exit_program(1);
         }
         if (!meta_in) {
             av_log(NULL, AV_LOG_FATAL, "Stream specifier %s does not match  any streams.\n", istream_spec);
-            exit(1);
+            exit_program(1);
         }
     }
 
@@ -491,7 +481,7 @@
                 meta_out = &oc->streams[i]->metadata;
                 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
             } else if (ret < 0)
-                exit(1);
+                exit_program(1);
         }
     } else
         av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
@@ -533,11 +523,11 @@
 
     if (!codec) {
         av_log(NULL, AV_LOG_FATAL, "Unknown %s '%s'\n", codec_string, name);
-        exit(1);
+        exit_program(1);
     }
     if (codec->type != type) {
         av_log(NULL, AV_LOG_FATAL, "Invalid %s type '%s'\n", codec_string, name);
-        exit(1);
+        exit_program(1);
     }
     return codec;
 }
@@ -569,7 +559,7 @@
         char *framerate = NULL;
 
         if (!ist)
-            exit(1);
+            exit_program(1);
 
         GROW_ARRAY(input_streams, nb_input_streams);
         input_streams[nb_input_streams - 1] = ist;
@@ -615,7 +605,7 @@
                                                  framerate) < 0) {
                 av_log(NULL, AV_LOG_ERROR, "Error parsing framerate %s.\n",
                        framerate);
-                exit(1);
+                exit_program(1);
             }
 
             ist->top_field_first = -1;
@@ -643,7 +633,7 @@
             if (canvas_size &&
                 av_parse_video_size(&dec->width, &dec->height, canvas_size) < 0) {
                 av_log(NULL, AV_LOG_FATAL, "Invalid canvas size: %s.\n", canvas_size);
-                exit(1);
+                exit_program(1);
             }
             break;
         }
@@ -658,24 +648,29 @@
 
 static void assert_file_overwrite(const char *filename)
 {
-    if ((!file_overwrite || no_file_overwrite) &&
+    if (file_overwrite && no_file_overwrite) {
+        fprintf(stderr, "Error, both -y and -n supplied. Exiting.\n");
+        exit_program(1);
+    }
+
+    if (!file_overwrite &&
         (strchr(filename, ':') == NULL || filename[1] == ':' ||
          av_strstart(filename, "file:", NULL))) {
         if (avio_check(filename, 0) == 0) {
-            if (stdin_interaction && (!no_file_overwrite || file_overwrite)) {
+            if (stdin_interaction && !no_file_overwrite) {
                 fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
                 fflush(stderr);
                 term_exit();
                 signal(SIGINT, SIG_DFL);
                 if (!read_yesno()) {
                     av_log(NULL, AV_LOG_FATAL, "Not overwriting - exiting\n");
-                    exit(1);
+                    exit_program(1);
                 }
                 term_init();
             }
             else {
                 av_log(NULL, AV_LOG_FATAL, "File '%s' already exists. Exiting.\n", filename);
-                exit(1);
+                exit_program(1);
             }
         }
     }
@@ -697,7 +692,7 @@
     if (!*filename) {
         av_log(NULL, AV_LOG_FATAL, "No filename specified and no 'filename' tag"
                "in stream #%d:%d.\n", nb_input_files - 1, st->index);
-        exit(1);
+        exit_program(1);
     }
 
     assert_file_overwrite(filename);
@@ -705,7 +700,7 @@
     if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) {
         av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n",
                filename);
-        exit(1);
+        exit_program(1);
     }
 
     avio_write(out, st->codec->extradata, st->codec->extradata_size);
@@ -732,7 +727,7 @@
     if (o->format) {
         if (!(file_iformat = av_find_input_format(o->format))) {
             av_log(NULL, AV_LOG_FATAL, "Unknown input format: '%s'\n", o->format);
-            exit(1);
+            exit_program(1);
         }
     }
 
@@ -746,7 +741,7 @@
     ic = avformat_alloc_context();
     if (!ic) {
         print_error(filename, AVERROR(ENOMEM));
-        exit(1);
+        exit_program(1);
     }
     if (o->nb_audio_sample_rate) {
         snprintf(buf, sizeof(buf), "%d", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i);
@@ -797,7 +792,7 @@
     err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
     if (err < 0) {
         print_error(filename, err);
-        exit(1);
+        exit_program(1);
     }
     assert_avoptions(o->g->format_opts);
 
@@ -815,16 +810,16 @@
     if (ret < 0) {
         av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename);
         avformat_close_input(&ic);
-        exit(1);
+        exit_program(1);
     }
 
-    timestamp = o->start_time;
+    timestamp = (o->start_time == AV_NOPTS_VALUE) ? 0 : o->start_time;
     /* add the stream start time */
     if (ic->start_time != AV_NOPTS_VALUE)
         timestamp += ic->start_time;
 
     /* if seeking requested, we execute it */
-    if (o->start_time != 0) {
+    if (o->start_time != AV_NOPTS_VALUE) {
         ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, timestamp, 0);
         if (ret < 0) {
             av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
@@ -841,14 +836,17 @@
     GROW_ARRAY(input_files, nb_input_files);
     f = av_mallocz(sizeof(*f));
     if (!f)
-        exit(1);
+        exit_program(1);
     input_files[nb_input_files - 1] = f;
 
     f->ctx        = ic;
     f->ist_index  = nb_input_streams - ic->nb_streams;
+    f->start_time = o->start_time;
+    f->recording_time = o->recording_time;
     f->ts_offset  = o->input_ts_offset - (copy_ts ? 0 : timestamp);
     f->nb_streams = ic->nb_streams;
     f->rate_emu   = o->rate_emu;
+    f->accurate_seek = o->accurate_seek;
 
     /* check if all codec options have been used */
     unused_opts = strip_specifiers(o->g->codec_opts);
@@ -871,7 +869,7 @@
                    "input file #%d (%s) is not a decoding option.\n", e->key,
                    option->help ? option->help : "", nb_input_files - 1,
                    filename);
-            exit(1);
+            exit_program(1);
         }
 
         av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
@@ -909,7 +907,7 @@
 
     if (avio_open_dyn_buf(&line) < 0) {
         av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n");
-        exit(1);
+        exit_program(1);
     }
 
     while ((c = avio_r8(s)) && c != '\n')
@@ -975,7 +973,7 @@
 
     if (!st) {
         av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n");
-        exit(1);
+        exit_program(1);
     }
 
     if (oc->nb_streams - 1 < o->nb_streamid_map)
@@ -983,10 +981,10 @@
 
     GROW_ARRAY(output_streams, nb_output_streams);
     if (!(ost = av_mallocz(sizeof(*ost))))
-        exit(1);
+        exit_program(1);
     output_streams[nb_output_streams - 1] = ost;
 
-    ost->file_index = nb_output_files;
+    ost->file_index = nb_output_files - 1;
     ost->index      = idx;
     ost->st         = st;
     st->codec->codec_type = type;
@@ -1007,7 +1005,7 @@
                 }
                 if (!(arg = strchr(buf, '='))) {
                     av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n");
-                    exit(1);
+                    exit_program(1);
                 }
                 *arg++ = 0;
                 av_dict_set(&ost->opts, buf, arg, AV_DICT_DONT_OVERWRITE);
@@ -1019,7 +1017,7 @@
             av_log(NULL, AV_LOG_FATAL,
                    "Preset %s specified for stream %d:%d, but could not be opened.\n",
                    preset, ost->file_index, ost->index);
-            exit(1);
+            exit_program(1);
         }
     } else {
         ost->opts = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, NULL);
@@ -1047,7 +1045,7 @@
             *next++ = 0;
         if (!(bsfc = av_bitstream_filter_init(bsf))) {
             av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf);
-            exit(1);
+            exit_program(1);
         }
         if (bsfc_prev)
             bsfc_prev->next = bsfc;
@@ -1089,6 +1087,7 @@
         input_streams[source_index]->discard = 0;
         input_streams[source_index]->st->discard = AVDISCARD_NONE;
     }
+    ost->last_mux_dts = AV_NOPTS_VALUE;
 
     return ost;
 }
@@ -1104,7 +1103,7 @@
         p = strchr(p, ',');
         if (!p) {
             av_log(NULL, AV_LOG_FATAL, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
-            exit(1);
+            exit_program(1);
         }
         p++;
     }
@@ -1151,7 +1150,7 @@
     if (filter_script && filter) {
         av_log(NULL, AV_LOG_ERROR, "Both -filter and -filter_script set for "
                "output stream #%d:%d.\n", nb_output_files, st->index);
-        exit(1);
+        exit_program(1);
     }
 
     if (filter_script)
@@ -1177,7 +1176,7 @@
     MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);
     if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) {
         av_log(NULL, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate);
-        exit(1);
+        exit_program(1);
     }
 
     MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
@@ -1186,7 +1185,7 @@
         if (av_parse_ratio(&q, frame_aspect_ratio, 255, 0, NULL) < 0 ||
             q.num <= 0 || q.den <= 0) {
             av_log(NULL, AV_LOG_FATAL, "Invalid aspect ratio: %s\n", frame_aspect_ratio);
-            exit(1);
+            exit_program(1);
         }
         ost->frame_aspect_ratio = q;
     }
@@ -1202,7 +1201,7 @@
         MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
         if (frame_size && av_parse_video_size(&video_enc->width, &video_enc->height, frame_size) < 0) {
             av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
-            exit(1);
+            exit_program(1);
         }
 
         video_enc->bits_per_raw_sample = frame_bits_per_raw_sample;
@@ -1214,7 +1213,7 @@
         }
         if (frame_pix_fmt && (video_enc->pix_fmt = av_get_pix_fmt(frame_pix_fmt)) == AV_PIX_FMT_NONE) {
             av_log(NULL, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", frame_pix_fmt);
-            exit(1);
+            exit_program(1);
         }
         st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
 
@@ -1224,7 +1223,7 @@
         if (intra_matrix) {
             if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64))) {
                 av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n");
-                exit(1);
+                exit_program(1);
             }
             parse_matrix_coeffs(video_enc->intra_matrix, intra_matrix);
         }
@@ -1232,7 +1231,7 @@
         if (inter_matrix) {
             if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64))) {
                 av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for inter matrix.\n");
-                exit(1);
+                exit_program(1);
             }
             parse_matrix_coeffs(video_enc->inter_matrix, inter_matrix);
         }
@@ -1243,7 +1242,7 @@
             int e = sscanf(p, "%d,%d,%d", &start, &end, &q);
             if (e != 3) {
                 av_log(NULL, AV_LOG_FATAL, "error parsing rc_override\n");
-                exit(1);
+                exit_program(1);
             }
             /* FIXME realloc failure */
             video_enc->rc_override =
@@ -1284,7 +1283,7 @@
         MATCH_PER_STREAM_OPT(passlogfiles, str, ost->logfile_prefix, oc, st);
         if (ost->logfile_prefix &&
             !(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))
-            exit(1);
+            exit_program(1);
 
         MATCH_PER_STREAM_OPT(forced_key_frames, str, ost->forced_keyframes, oc, st);
         if (ost->forced_keyframes)
@@ -1298,7 +1297,7 @@
 
         ost->avfilter = get_ost_filters(o, oc, ost);
         if (!ost->avfilter)
-            exit(1);
+            exit_program(1);
     } else {
         MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st);
     }
@@ -1328,14 +1327,17 @@
         if (sample_fmt &&
             (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) {
             av_log(NULL, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt);
-            exit(1);
+            exit_program(1);
         }
 
         MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
 
+        MATCH_PER_STREAM_OPT(apad, str, ost->apad, oc, st);
+        ost->apad = av_strdup(ost->apad);
+
         ost->avfilter = get_ost_filters(o, oc, ost);
         if (!ost->avfilter)
-            exit(1);
+            exit_program(1);
 
         /* check for channel mapping for this audio stream */
         for (n = 0; n < o->nb_audio_channel_maps; n++) {
@@ -1363,7 +1365,7 @@
     ost = new_output_stream(o, oc, AVMEDIA_TYPE_DATA, source_index);
     if (!ost->stream_copy) {
         av_log(NULL, AV_LOG_FATAL, "Data stream encoding not supported yet (only streamcopy)\n");
-        exit(1);
+        exit_program(1);
     }
 
     return ost;
@@ -1397,7 +1399,7 @@
         MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
         if (frame_size && av_parse_video_size(&subtitle_enc->width, &subtitle_enc->height, frame_size) < 0) {
             av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
-            exit(1);
+            exit_program(1);
         }
     }
 
@@ -1418,7 +1420,7 @@
         av_log(NULL, AV_LOG_FATAL,
                "Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
                arg, opt);
-        exit(1);
+        exit_program(1);
     }
     *p++ = '\0';
     idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, MAX_STREAMS-1);
@@ -1441,7 +1443,8 @@
 
     for (i = 0; i < is->nb_chapters; i++) {
         AVChapter *in_ch = is->chapters[i], *out_ch;
-        int64_t ts_off   = av_rescale_q(ofile->start_time - ifile->ts_offset,
+        int64_t start_time = (ofile->start_time == AV_NOPTS_VALUE) ? 0 : ofile->start_time;
+        int64_t ts_off   = av_rescale_q(start_time - ifile->ts_offset,
                                        AV_TIME_BASE_Q, in_ch->time_base);
         int64_t rt       = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
                            av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
@@ -1505,9 +1508,6 @@
             choose_pixel_fmt(st, codec, st->codec->pix_fmt);
     }
 
-    /* ffserver seeking with date=... needs a date reference */
-    err = parse_option(o, "metadata", "creation_time=now", options);
-
     avformat_close_input(&ic);
     return err;
 }
@@ -1524,7 +1524,7 @@
     default:
         av_log(NULL, AV_LOG_FATAL, "Only video and audio filters are supported "
                "currently.\n");
-        exit(1);
+        exit_program(1);
     }
 
     ost->source_index = -1;
@@ -1536,12 +1536,12 @@
         av_log(NULL, AV_LOG_ERROR, "Streamcopy requested for output stream %d:%d, "
                "which is fed from a complex filtergraph. Filtering and streamcopy "
                "cannot be used together.\n", ost->file_index, ost->index);
-        exit(1);
+        exit_program(1);
     }
 
     if (configure_output_filter(ofilter->graph, ofilter, ofilter->out_tmp) < 0) {
         av_log(NULL, AV_LOG_FATAL, "Error configuring filter.\n");
-        exit(1);
+        exit_program(1);
     }
     avfilter_inout_free(&ofilter->out_tmp);
 }
@@ -1570,17 +1570,50 @@
 
     if (configure_complex_filters() < 0) {
         av_log(NULL, AV_LOG_FATAL, "Error configuring filters.\n");
-        exit(1);
+        exit_program(1);
     }
 
+    if (o->stop_time != INT64_MAX && o->recording_time != INT64_MAX) {
+        o->stop_time = INT64_MAX;
+        av_log(NULL, AV_LOG_WARNING, "-t and -to cannot be used together; using -t.\n");
+    }
+
+    if (o->stop_time != INT64_MAX && o->recording_time == INT64_MAX) {
+        int64_t start_time = o->start_time == AV_NOPTS_VALUE ? 0 : o->start_time;
+        if (o->stop_time <= start_time) {
+            av_log(NULL, AV_LOG_WARNING, "-to value smaller than -ss; ignoring -to.\n");
+            o->stop_time = INT64_MAX;
+        } else {
+            o->recording_time = o->stop_time - start_time;
+        }
+    }
+
+    GROW_ARRAY(output_files, nb_output_files);
+    of = av_mallocz(sizeof(*of));
+    if (!of)
+        exit_program(1);
+    output_files[nb_output_files - 1] = of;
+
+    of->ost_index      = nb_output_streams;
+    of->recording_time = o->recording_time;
+    of->start_time     = o->start_time;
+    of->limit_filesize = o->limit_filesize;
+    of->shortest       = o->shortest;
+    av_dict_copy(&of->opts, o->g->format_opts, 0);
+
     if (!strcmp(filename, "-"))
         filename = "pipe:";
 
     err = avformat_alloc_output_context2(&oc, NULL, o->format, filename);
     if (!oc) {
         print_error(filename, err);
-        exit(1);
+        exit_program(1);
     }
+
+    of->ctx = oc;
+    if (o->recording_time != INT64_MAX)
+        oc->duration = o->recording_time;
+
     file_oformat= oc->oformat;
     oc->interrupt_callback = int_cb;
 
@@ -1603,15 +1636,25 @@
         }
     }
 
+    /* ffserver seeking with date=... needs a date reference */
     if (!strcmp(file_oformat->name, "ffm") &&
         av_strstart(filename, "http:", NULL)) {
+        int err = parse_option(o, "metadata", "creation_time=now", options);
+        if (err < 0) {
+            print_error(filename, err);
+            exit_program(1);
+        }
+    }
+
+    if (!strcmp(file_oformat->name, "ffm") && !override_ffserver &&
+        av_strstart(filename, "http:", NULL)) {
         int j;
         /* special case for files sent to ffserver: we get the stream
            parameters from ffserver */
         int err = read_ffserver_streams(o, oc, filename);
         if (err < 0) {
             print_error(filename, err);
-            exit(1);
+            exit_program(1);
         }
         for(j = nb_output_streams - oc->nb_streams; j < nb_output_streams; j++) {
             ost = output_streams[j];
@@ -1629,7 +1672,7 @@
             }
             if(!ost->sync_ist){
                 av_log(NULL, AV_LOG_FATAL, "Missing %s stream which is required by this ffm\n", av_get_media_type_string(ost->st->codec->codec_type));
-                exit(1);
+                exit_program(1);
             }
         }
     } else if (!o->nb_stream_maps) {
@@ -1686,7 +1729,6 @@
     } else {
         for (i = 0; i < o->nb_stream_maps; i++) {
             StreamMap *map = &o->stream_maps[i];
-            int src_idx = input_files[map->file_index]->ist_index + map->stream_index;
 
             if (map->disabled)
                 continue;
@@ -1710,10 +1752,12 @@
                 if (!ofilter) {
                     av_log(NULL, AV_LOG_FATAL, "Output with label '%s' does not exist "
                            "in any defined filter graph, or was already used elsewhere.\n", map->linklabel);
-                    exit(1);
+                    exit_program(1);
                 }
                 init_output_filter(ofilter, o, oc);
             } else {
+                int src_idx = input_files[map->file_index]->ist_index + map->stream_index;
+
                 ist = input_streams[input_files[map->file_index]->ist_index + map->stream_index];
                 if(o->subtitle_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE)
                     continue;
@@ -1733,7 +1777,7 @@
                 default:
                     av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n",
                            map->file_index, map->stream_index);
-                    exit(1);
+                    exit_program(1);
                 }
             }
         }
@@ -1749,17 +1793,17 @@
         if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
             av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n",
                    o->attachments[i]);
-            exit(1);
+            exit_program(1);
         }
         if ((len = avio_size(pb)) <= 0) {
             av_log(NULL, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",
                    o->attachments[i]);
-            exit(1);
+            exit_program(1);
         }
         if (!(attachment = av_malloc(len))) {
             av_log(NULL, AV_LOG_FATAL, "Attachment %s too large to fit into memory.\n",
                    o->attachments[i]);
-            exit(1);
+            exit_program(1);
         }
         avio_read(pb, attachment, len);
 
@@ -1783,40 +1827,9 @@
             && (e = av_dict_get(o->g->codec_opts, "flags", NULL, AV_DICT_IGNORE_SUFFIX))
             && (!e->key[5] || check_stream_specifier(oc, ost->st, e->key+6)))
             if (av_opt_set(ost->st->codec, "flags", e->value, 0) < 0)
-                exit(1);
+                exit_program(1);
     }
 
-    if (o->stop_time != INT64_MAX && o->recording_time != INT64_MAX) {
-        o->stop_time = INT64_MAX;
-        av_log(NULL, AV_LOG_WARNING, "-t and -to cannot be used together; using -t.\n");
-    }
-
-    if (o->stop_time != INT64_MAX && o->recording_time == INT64_MAX) {
-        if (o->stop_time <= o->start_time) {
-            av_log(NULL, AV_LOG_WARNING, "-to value smaller than -ss; ignoring -to.\n");
-            o->stop_time = INT64_MAX;
-        } else {
-            o->recording_time = o->stop_time - o->start_time;
-        }
-    }
-
-    GROW_ARRAY(output_files, nb_output_files);
-    of = av_mallocz(sizeof(*of));
-    if (!of)
-        exit(1);
-    output_files[nb_output_files - 1] = of;
-
-    of->ctx            = oc;
-    of->ost_index      = nb_output_streams - oc->nb_streams;
-    of->recording_time = o->recording_time;
-    if (o->recording_time != INT64_MAX)
-        oc->duration = o->recording_time;
-    of->start_time     = o->start_time;
-    of->limit_filesize = o->limit_filesize;
-    of->shortest       = o->shortest;
-    av_dict_copy(&of->opts, o->g->format_opts, 0);
-
-
     /* check if all codec options have been used */
     unused_opts = strip_specifiers(o->g->codec_opts);
     for (i = of->ost_index; i < nb_output_streams; i++) {
@@ -1838,9 +1851,13 @@
                    "output file #%d (%s) is not an encoding option.\n", e->key,
                    option->help ? option->help : "", nb_output_files - 1,
                    filename);
-            exit(1);
+            exit_program(1);
         }
 
+        // gop_timecode is injected by generic code but not always used
+        if (!strcmp(e->key, "gop_timecode"))
+            continue;
+
         av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
                "output file #%d (%s) has not been used for any stream. The most "
                "likely reason is either wrong type (e.g. a video option with "
@@ -1854,7 +1871,7 @@
     if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
         if (!av_filename_number_test(oc->filename)) {
             print_error(oc->filename, AVERROR(EINVAL));
-            exit(1);
+            exit_program(1);
         }
     }
 
@@ -1867,7 +1884,7 @@
                               &oc->interrupt_callback,
                               &of->opts)) < 0) {
             print_error(filename, err);
-            exit(1);
+            exit_program(1);
         }
     } else if (strcmp(oc->oformat->name, "image2")==0 && !av_filename_number_test(filename))
         assert_file_overwrite(filename);
@@ -1886,7 +1903,7 @@
 
         if (in_file_index >= nb_input_files) {
             av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d while processing metadata maps\n", in_file_index);
-            exit(1);
+            exit_program(1);
         }
         copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc,
                       in_file_index >= 0 ?
@@ -1906,7 +1923,7 @@
         } else {
             av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n",
                    o->chapters_input_file);
-            exit(1);
+            exit_program(1);
         }
     }
     if (o->chapters_input_file >= 0)
@@ -1941,7 +1958,7 @@
         if (!val) {
             av_log(NULL, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",
                    o->metadata[i].u.str);
-            exit(1);
+            exit_program(1);
         }
         *val++ = 0;
 
@@ -1951,7 +1968,7 @@
                 if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
                     av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);
                 } else if (ret < 0)
-                    exit(1);
+                    exit_program(1);
             }
         }
         else {
@@ -1962,13 +1979,13 @@
             case 'c':
                 if (index < 0 || index >= oc->nb_chapters) {
                     av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);
-                    exit(1);
+                    exit_program(1);
                 }
                 m = &oc->chapters[index]->metadata;
                 break;
             default:
                 av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
-                exit(1);
+                exit_program(1);
             }
             av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
         }
@@ -2022,7 +2039,7 @@
         av_log(NULL, AV_LOG_FATAL, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n");
         av_log(NULL, AV_LOG_FATAL, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n");
         av_log(NULL, AV_LOG_FATAL, "or set a framerate with \"-r xxx\".\n");
-        exit(1);
+        exit_program(1);
     }
 
     if (!strcmp(arg, "vcd")) {
@@ -2188,7 +2205,7 @@
             av_log(NULL, AV_LOG_FATAL, "Please use -preset <speed> -qp 0\n");
         }else
             av_log(NULL, AV_LOG_FATAL, "File for preset '%s' not found\n", arg);
-        exit(1);
+        exit_program(1);
     }
 
     while (fgets(line, sizeof(line), f)) {
@@ -2200,7 +2217,7 @@
         if (!av_strtok(key,   "=",    &value) ||
             !av_strtok(value, "\r\n", &endptr)) {
             av_log(NULL, AV_LOG_FATAL, "%s: Invalid syntax: '%s'\n", filename, line);
-            exit(1);
+            exit_program(1);
         }
         av_log(NULL, AV_LOG_DEBUG, "ffpreset[%s]: set '%s' = '%s'\n", filename, key, value);
 
@@ -2211,7 +2228,7 @@
         else if (opt_default_new(o, key, value) < 0) {
             av_log(NULL, AV_LOG_FATAL, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n",
                    filename, line, key, value);
-            exit(1);
+            exit_program(1);
         }
     }
 
@@ -2463,7 +2480,7 @@
         OptionGroup *g = &l->groups[i];
         OptionsContext o;
 
-        init_options(&o, !strcmp(inout, "input"));
+        init_options(&o);
         o.g = g;
 
         ret = parse_optgroup(&o, g);
@@ -2475,7 +2492,7 @@
 
         av_log(NULL, AV_LOG_DEBUG, "Opening an %s file: %s.\n", inout, g->arg);
         ret = open_file(&o, g->arg);
-        uninit_options(&o, !strcmp(inout, "input"));
+        uninit_options(&o);
         if (ret < 0) {
             av_log(NULL, AV_LOG_ERROR, "Error opening %s file %s.\n",
                    inout, g->arg);
@@ -2560,7 +2577,7 @@
     { "y",              OPT_BOOL,                                    {              &file_overwrite },
         "overwrite output files" },
     { "n",              OPT_BOOL,                                    {              &no_file_overwrite },
-        "do not overwrite output files" },
+        "never overwrite output files" },
     { "c",              HAS_ARG | OPT_STRING | OPT_SPEC |
                         OPT_INPUT | OPT_OUTPUT,                      { .off       = OFFSET(codec_names) },
         "codec name", "codec" },
@@ -2583,7 +2600,8 @@
     { "map_chapters",   HAS_ARG | OPT_INT | OPT_EXPERT | OPT_OFFSET |
                         OPT_OUTPUT,                                  { .off = OFFSET(chapters_input_file) },
         "set chapters mapping", "input_file_index" },
-    { "t",              HAS_ARG | OPT_TIME | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(recording_time) },
+    { "t",              HAS_ARG | OPT_TIME | OPT_OFFSET |
+                        OPT_INPUT | OPT_OUTPUT,                      { .off = OFFSET(recording_time) },
         "record or transcode \"duration\" seconds of audio/video",
         "duration" },
     { "to",             HAS_ARG | OPT_TIME | OPT_OFFSET | OPT_OUTPUT,  { .off = OFFSET(stop_time) },
@@ -2593,6 +2611,9 @@
     { "ss",             HAS_ARG | OPT_TIME | OPT_OFFSET |
                         OPT_INPUT | OPT_OUTPUT,                      { .off = OFFSET(start_time) },
         "set the start time offset", "time_off" },
+    { "accurate_seek",  OPT_BOOL | OPT_OFFSET | OPT_EXPERT |
+                        OPT_INPUT,                                   { .off = OFFSET(accurate_seek) },
+        "enable/disable accurate seeking with -ss" },
     { "itsoffset",      HAS_ARG | OPT_TIME | OPT_OFFSET |
                         OPT_EXPERT | OPT_INPUT,                      { .off = OFFSET(input_ts_offset) },
         "set the input ts offset", "time_off" },
@@ -2639,6 +2660,9 @@
     { "shortest",       OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
                         OPT_OUTPUT,                                  { .off = OFFSET(shortest) },
         "finish encoding within shortest input" },
+    { "apad",           OPT_STRING | HAS_ARG | OPT_SPEC |
+                        OPT_OUTPUT,                                  { .off = OFFSET(apad) },
+        "audio pad", "" },
     { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,       { &dts_delta_threshold },
         "timestamp discontinuity delta threshold", "threshold" },
     { "dts_error_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,       { &dts_error_threshold },
@@ -2820,6 +2844,8 @@
         "set the maximum demux-decode delay", "seconds" },
     { "muxpreload", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(mux_preload) },
         "set the initial demux-decode delay", "seconds" },
+    { "override_ffserver", OPT_BOOL | OPT_EXPERT | OPT_OUTPUT, { &override_ffserver },
+        "override the options from ffserver", "" },
 
     { "bsf", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(bitstream_filters) },
         "A comma-separated list of bitstream filters", "bitstream_filters" },
diff --git a/ffplay.c b/ffplay.c
index ca0a828..26a1452 100644
--- a/ffplay.c
+++ b/ffplay.c
@@ -69,8 +69,12 @@
    A/V sync as SDL does not have hardware buffer fullness info. */
 #define SDL_AUDIO_BUFFER_SIZE 1024
 
-/* no AV sync correction is done if below the AV sync threshold */
-#define AV_SYNC_THRESHOLD 0.01
+/* no AV sync correction is done if below the minimum AV sync threshold */
+#define AV_SYNC_THRESHOLD_MIN 0.01
+/* AV sync correction is done if above the maximum AV sync threshold */
+#define AV_SYNC_THRESHOLD_MAX 0.1
+/* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
+#define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
 /* no AV correction is done if too big error */
 #define AV_NOSYNC_THRESHOLD 10.0
 
@@ -112,7 +116,7 @@
     SDL_cond *cond;
 } PacketQueue;
 
-#define VIDEO_PICTURE_QUEUE_SIZE 4
+#define VIDEO_PICTURE_QUEUE_SIZE 3
 #define SUBPICTURE_QUEUE_SIZE 4
 
 typedef struct VideoPicture {
@@ -130,6 +134,7 @@
 typedef struct SubPicture {
     double pts; /* presentation time stamp for this picture */
     AVSubtitle sub;
+    int serial;
 } SubPicture;
 
 typedef struct AudioParams {
@@ -139,6 +144,16 @@
     enum AVSampleFormat fmt;
 } AudioParams;
 
+typedef struct Clock {
+    double pts;           /* clock base */
+    double pts_drift;     /* clock base minus time at which we updated the clock */
+    double last_updated;
+    double speed;
+    int serial;           /* clock is based on a packet with this serial */
+    int paused;
+    int *queue_serial;    /* pointer to the current packet queue serial, used for obsolete clock detection */
+} Clock;
+
 enum {
     AV_SYNC_AUDIO_MASTER, /* default choice */
     AV_SYNC_VIDEO_MASTER,
@@ -162,14 +177,16 @@
     int read_pause_return;
     AVFormatContext *ic;
     int realtime;
+    int audio_finished;
+    int video_finished;
+
+    Clock audclk;
+    Clock vidclk;
+    Clock extclk;
 
     int audio_stream;
 
     int av_sync_type;
-    double external_clock;                   ///< external clock base
-    double external_clock_drift;             ///< external clock base - time (av_gettime) at which we updated external_clock
-    int64_t external_clock_time;             ///< last reference time
-    double external_clock_speed;             ///< speed of the external clock
 
     double audio_clock;
     int audio_clock_serial;
@@ -198,11 +215,10 @@
 #endif
     struct AudioParams audio_tgt;
     struct SwrContext *swr_ctx;
-    double audio_current_pts;
-    double audio_current_pts_drift;
     int frame_drops_early;
     int frame_drops_late;
     AVFrame *frame;
+    int64_t audio_frame_next_pts;
 
     enum ShowMode {
         SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
@@ -218,7 +234,6 @@
 
     SDL_Thread *subtitle_tid;
     int subtitle_stream;
-    int subtitle_stream_changed;
     AVStream *subtitle_st;
     PacketQueue subtitleq;
     SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
@@ -237,11 +252,8 @@
     int video_stream;
     AVStream *video_st;
     PacketQueue videoq;
-    double video_current_pts;       // current displayed pts
-    double video_current_pts_drift; // video_current_pts - time (av_gettime) at which we updated video_current_pts - used to have running video pts
     int64_t video_current_pos;      // current displayed file pos
     double max_frame_duration;      // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
-    int video_clock_serial;
     VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
     int pictq_size, pictq_rindex, pictq_windex;
     SDL_mutex *pictq_mutex;
@@ -296,7 +308,6 @@
 static int fast = 0;
 static int genpts = 0;
 static int lowres = 0;
-static int idct = FF_IDCT_AUTO;
 static int error_concealment = 3;
 static int decoder_reorder_pts = -1;
 static int autoexit;
@@ -966,7 +977,8 @@
                 }
                 av_rdft_calc(s->rdft, data[ch]);
             }
-            // least efficient way to do this, we should of course directly access it but its more than fast enough
+            /* Least efficient way to do this, we should of course
+             * directly access it but it is more than fast enough. */
             for (y = 0; y < s->height; y++) {
                 double w = 1 / sqrt(nb_freq);
                 int a = sqrt(w * sqrt(data[0][2 * y + 0] * data[0][2 * y + 0] + data[0][2 * y + 1] * data[0][2 * y + 1]));
@@ -1008,6 +1020,8 @@
             vp->bmp = NULL;
         }
     }
+    for (i = 0; i < SUBPICTURE_QUEUE_SIZE; i++)
+        free_subpicture(&is->subpq[i]);
     SDL_DestroyMutex(is->pictq_mutex);
     SDL_DestroyCond(is->pictq_cond);
     SDL_DestroyMutex(is->subpq_mutex);
@@ -1067,12 +1081,13 @@
         w = default_width;
         h = default_height;
     }
+    w = FFMIN(16383, w);
     if (screen && is->width == screen->w && screen->w == w
        && is->height== screen->h && screen->h == h && !force_set_video_mode)
         return 0;
     screen = SDL_SetVideoMode(w, h, 0, flags);
     if (!screen) {
-        fprintf(stderr, "SDL: could not set video mode - exiting\n");
+        av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
         do_exit(is);
     }
     if (!window_title)
@@ -1096,41 +1111,54 @@
         video_image_display(is);
 }
 
-/* get the current audio clock value */
-static double get_audio_clock(VideoState *is)
+static double get_clock(Clock *c)
 {
-    if (is->audio_clock_serial != is->audioq.serial)
+    if (*c->queue_serial != c->serial)
         return NAN;
-    if (is->paused) {
-        return is->audio_current_pts;
-    } else {
-        return is->audio_current_pts_drift + av_gettime() / 1000000.0;
-    }
-}
-
-/* get the current video clock value */
-static double get_video_clock(VideoState *is)
-{
-    if (is->video_clock_serial != is->videoq.serial)
-        return NAN;
-    if (is->paused) {
-        return is->video_current_pts;
-    } else {
-        return is->video_current_pts_drift + av_gettime() / 1000000.0;
-    }
-}
-
-/* get the current external clock value */
-static double get_external_clock(VideoState *is)
-{
-    if (is->paused) {
-        return is->external_clock;
+    if (c->paused) {
+        return c->pts;
     } else {
         double time = av_gettime() / 1000000.0;
-        return is->external_clock_drift + time - (time - is->external_clock_time / 1000000.0) * (1.0 - is->external_clock_speed);
+        return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
     }
 }
 
+static void set_clock_at(Clock *c, double pts, int serial, double time)
+{
+    c->pts = pts;
+    c->last_updated = time;
+    c->pts_drift = c->pts - time;
+    c->serial = serial;
+}
+
+static void set_clock(Clock *c, double pts, int serial)
+{
+    double time = av_gettime() / 1000000.0;
+    set_clock_at(c, pts, serial, time);
+}
+
+static void set_clock_speed(Clock *c, double speed)
+{
+    set_clock(c, get_clock(c), c->serial);
+    c->speed = speed;
+}
+
+static void init_clock(Clock *c, int *queue_serial)
+{
+    c->speed = 1.0;
+    c->paused = 0;
+    c->queue_serial = queue_serial;
+    set_clock(c, NAN, -1);
+}
+
+static void sync_clock_to_slave(Clock *c, Clock *slave)
+{
+    double clock = get_clock(c);
+    double slave_clock = get_clock(slave);
+    if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
+        set_clock(c, slave_clock, slave->serial);
+}
+
 static int get_master_sync_type(VideoState *is) {
     if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
         if (is->video_st)
@@ -1154,48 +1182,29 @@
 
     switch (get_master_sync_type(is)) {
         case AV_SYNC_VIDEO_MASTER:
-            val = get_video_clock(is);
+            val = get_clock(&is->vidclk);
             break;
         case AV_SYNC_AUDIO_MASTER:
-            val = get_audio_clock(is);
+            val = get_clock(&is->audclk);
             break;
         default:
-            val = get_external_clock(is);
+            val = get_clock(&is->extclk);
             break;
     }
     return val;
 }
 
-static void update_external_clock_pts(VideoState *is, double pts)
-{
-   is->external_clock_time = av_gettime();
-   is->external_clock = pts;
-   is->external_clock_drift = pts - is->external_clock_time / 1000000.0;
-}
-
-static void check_external_clock_sync(VideoState *is, double pts) {
-    double ext_clock = get_external_clock(is);
-    if (isnan(ext_clock) || fabs(ext_clock - pts) > AV_NOSYNC_THRESHOLD) {
-        update_external_clock_pts(is, pts);
-    }
-}
-
-static void update_external_clock_speed(VideoState *is, double speed) {
-    update_external_clock_pts(is, get_external_clock(is));
-    is->external_clock_speed = speed;
-}
-
 static void check_external_clock_speed(VideoState *is) {
    if (is->video_stream >= 0 && is->videoq.nb_packets <= MIN_FRAMES / 2 ||
        is->audio_stream >= 0 && is->audioq.nb_packets <= MIN_FRAMES / 2) {
-       update_external_clock_speed(is, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->external_clock_speed - EXTERNAL_CLOCK_SPEED_STEP));
+       set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
    } else if ((is->video_stream < 0 || is->videoq.nb_packets > MIN_FRAMES * 2) &&
               (is->audio_stream < 0 || is->audioq.nb_packets > MIN_FRAMES * 2)) {
-       update_external_clock_speed(is, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->external_clock_speed + EXTERNAL_CLOCK_SPEED_STEP));
+       set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
    } else {
-       double speed = is->external_clock_speed;
+       double speed = is->extclk.speed;
        if (speed != 1.0)
-           update_external_clock_speed(is, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
+           set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
    }
 }
 
@@ -1217,14 +1226,14 @@
 static void stream_toggle_pause(VideoState *is)
 {
     if (is->paused) {
-        is->frame_timer += av_gettime() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts;
+        is->frame_timer += av_gettime() / 1000000.0 + is->vidclk.pts_drift - is->vidclk.pts;
         if (is->read_pause_return != AVERROR(ENOSYS)) {
-            is->video_current_pts = is->video_current_pts_drift + av_gettime() / 1000000.0;
+            is->vidclk.paused = 0;
         }
-        is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
+        set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
     }
-    update_external_clock_pts(is, get_external_clock(is));
-    is->paused = !is->paused;
+    set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
+    is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
 }
 
 static void toggle_pause(VideoState *is)
@@ -1249,15 +1258,17 @@
     if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
         /* if video is slave, we try to correct big delays by
            duplicating or deleting a frame */
-        diff = get_video_clock(is) - get_master_clock(is);
+        diff = get_clock(&is->vidclk) - get_master_clock(is);
 
         /* skip or repeat frame. We take into account the
            delay to compute the threshold. I still don't know
            if it is the best guess */
-        sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
-        if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
+        sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
+        if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
             if (diff <= -sync_threshold)
-                delay = 0;
+                delay = FFMAX(0, delay + diff);
+            else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
+                delay = delay + diff;
             else if (diff >= sync_threshold)
                 delay = 2 * delay;
         }
@@ -1287,7 +1298,7 @@
     prevvp = &is->pictq[(is->pictq_rindex + VIDEO_PICTURE_QUEUE_SIZE - 1) % VIDEO_PICTURE_QUEUE_SIZE];
     if (prevvp->allocated && prevvp->serial == is->videoq.serial) {
         SDL_LockMutex(is->pictq_mutex);
-        if (is->pictq_size < VIDEO_PICTURE_QUEUE_SIZE - 1) {
+        if (is->pictq_size < VIDEO_PICTURE_QUEUE_SIZE) {
             if (--is->pictq_rindex == -1)
                 is->pictq_rindex = VIDEO_PICTURE_QUEUE_SIZE - 1;
             is->pictq_size++;
@@ -1300,15 +1311,11 @@
 }
 
 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
-    double time = av_gettime() / 1000000.0;
     /* update current video pts */
-    is->video_current_pts = pts;
-    is->video_current_pts_drift = is->video_current_pts - time;
+    set_clock(&is->vidclk, pts, serial);
+    sync_clock_to_slave(&is->extclk, &is->vidclk);
     is->video_current_pos = pos;
     is->frame_last_pts = pts;
-    is->video_clock_serial = serial;
-    if (is->videoq.serial == serial)
-        check_external_clock_sync(is, is->video_current_pts);
 }
 
 /* called to display each frame */
@@ -1365,19 +1372,23 @@
                 /* if duration of the last frame was sane, update last_duration in video state */
                 is->frame_last_duration = last_duration;
             }
-            delay = compute_target_delay(is->frame_last_duration, is);
+            if (redisplay)
+                delay = 0.0;
+            else
+                delay = compute_target_delay(is->frame_last_duration, is);
 
             time= av_gettime()/1000000.0;
-            if (time < is->frame_timer + delay) {
+            if (time < is->frame_timer + delay && !redisplay) {
                 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
                 return;
             }
 
-            if (delay > 0)
-                is->frame_timer += delay * FFMAX(1, floor((time-is->frame_timer) / delay));
+            is->frame_timer += delay;
+            if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
+                is->frame_timer = time;
 
             SDL_LockMutex(is->pictq_mutex);
-            if (!isnan(vp->pts))
+            if (!redisplay && !isnan(vp->pts))
                 update_video_pts(is, vp->pts, vp->pos, vp->serial);
             SDL_UnlockMutex(is->pictq_mutex);
 
@@ -1394,24 +1405,7 @@
             }
 
             if (is->subtitle_st) {
-                if (is->subtitle_stream_changed) {
-                    SDL_LockMutex(is->subpq_mutex);
-
-                    while (is->subpq_size) {
-                        free_subpicture(&is->subpq[is->subpq_rindex]);
-
-                        /* update queue size and signal for next picture */
-                        if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
-                            is->subpq_rindex = 0;
-
-                        is->subpq_size--;
-                    }
-                    is->subtitle_stream_changed = 0;
-
-                    SDL_CondSignal(is->subpq_cond);
-                    SDL_UnlockMutex(is->subpq_mutex);
-                } else {
-                    if (is->subpq_size > 0) {
+                    while (is->subpq_size > 0) {
                         sp = &is->subpq[is->subpq_rindex];
 
                         if (is->subpq_size > 1)
@@ -1419,8 +1413,9 @@
                         else
                             sp2 = NULL;
 
-                        if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
-                                || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
+                        if (sp->serial != is->subtitleq.serial
+                                || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
+                                || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
                         {
                             free_subpicture(sp);
 
@@ -1432,9 +1427,10 @@
                             is->subpq_size--;
                             SDL_CondSignal(is->subpq_cond);
                             SDL_UnlockMutex(is->subpq_mutex);
+                        } else {
+                            break;
                         }
                     }
-                }
             }
 
 display:
@@ -1468,9 +1464,15 @@
                 sqsize = is->subtitleq.size;
             av_diff = 0;
             if (is->audio_st && is->video_st)
-                av_diff = get_audio_clock(is) - get_video_clock(is);
-            printf("%7.2f A-V:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64"   \r",
+                av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
+            else if (is->video_st)
+                av_diff = get_master_clock(is) - get_clock(&is->vidclk);
+            else if (is->audio_st)
+                av_diff = get_master_clock(is) - get_clock(&is->audclk);
+            av_log(NULL, AV_LOG_INFO,
+                   "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64"   \r",
                    get_master_clock(is),
+                   (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : "   ")),
                    av_diff,
                    is->frame_drops_early + is->frame_drops_late,
                    aqsize / 1024,
@@ -1489,6 +1491,7 @@
 static void alloc_picture(VideoState *is)
 {
     VideoPicture *vp;
+    int64_t bufferdiff;
 
     vp = &is->pictq[is->pictq_windex];
 
@@ -1500,10 +1503,12 @@
     vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
                                    SDL_YV12_OVERLAY,
                                    screen);
-    if (!vp->bmp || vp->bmp->pitches[0] < vp->width) {
+    bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
+    if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
         /* SDL allocates a buffer smaller than requested if the video
          * overlay hardware is unable to support the requested size. */
-        fprintf(stderr, "Error: the video system does not support an image\n"
+        av_log(NULL, AV_LOG_FATAL,
+               "Error: the video system does not support an image\n"
                         "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
                         "to reduce the image size.\n", vp->width, vp->height );
         do_exit(is);
@@ -1546,7 +1551,7 @@
     SDL_LockMutex(is->pictq_mutex);
 
     /* keep the last already displayed picture in the queue */
-    while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE - 2 &&
+    while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE - 1 &&
            !is->videoq.abort_request) {
         SDL_CondWait(is->pictq_cond, is->pictq_mutex);
     }
@@ -1618,7 +1623,7 @@
             vp->width, vp->height, src_frame->format, vp->width, vp->height,
             AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
         if (is->img_convert_ctx == NULL) {
-            fprintf(stderr, "Cannot initialize the conversion context\n");
+            av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
             exit(1);
         }
         sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
@@ -1670,6 +1675,9 @@
     if(avcodec_decode_video2(is->video_st->codec, frame, &got_picture, pkt) < 0)
         return 0;
 
+    if (!got_picture && !pkt->data)
+        is->video_finished = *serial;
+
     if (got_picture) {
         int ret = 1;
         double dpts = NAN;
@@ -1690,7 +1698,7 @@
         if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
             SDL_LockMutex(is->pictq_mutex);
             if (is->frame_last_pts != AV_NOPTS_VALUE && frame->pts != AV_NOPTS_VALUE) {
-                double clockdiff = get_video_clock(is) - get_master_clock(is);
+                double clockdiff = get_clock(&is->vidclk) - get_master_clock(is);
                 double ptsdiff = dpts - is->frame_last_pts;
                 if (!isnan(clockdiff) && fabs(clockdiff) < AV_NOSYNC_THRESHOLD &&
                     !isnan(ptsdiff) && ptsdiff > 0 && ptsdiff < AV_NOSYNC_THRESHOLD &&
@@ -1737,7 +1745,7 @@
         inputs->pad_idx     = 0;
         inputs->next        = NULL;
 
-        if ((ret = avfilter_graph_parse(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
+        if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
             goto fail;
     } else {
         if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
@@ -1948,6 +1956,8 @@
 
             ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
             if (ret < 0) {
+                if (ret == AVERROR_EOF)
+                    is->video_finished = serial;
                 ret = 0;
                 break;
             }
@@ -1985,6 +1995,7 @@
     SubPicture *sp;
     AVPacket pkt1, *pkt = &pkt1;
     int got_subtitle;
+    int serial;
     double pts;
     int i, j;
     int r, g, b, y, u, v, a;
@@ -1993,7 +2004,7 @@
         while (is->paused && !is->subtitleq.abort_request) {
             SDL_Delay(10);
         }
-        if (packet_queue_get(&is->subtitleq, pkt, 1, NULL) < 0)
+        if (packet_queue_get(&is->subtitleq, pkt, 1, &serial) < 0)
             break;
 
         if (pkt->data == flush_pkt.data) {
@@ -2024,6 +2035,7 @@
             if (sp->sub.pts != AV_NOPTS_VALUE)
                 pts = sp->sub.pts / (double)AV_TIME_BASE;
             sp->pts = pts;
+            sp->serial = serial;
 
             for (i = 0; i < sp->sub.num_rects; i++)
             {
@@ -2043,6 +2055,8 @@
             SDL_LockMutex(is->subpq_mutex);
             is->subpq_size++;
             SDL_UnlockMutex(is->subpq_mutex);
+        } else if (got_subtitle) {
+            avsubtitle_free(&sp->sub);
         }
         av_free_packet(pkt);
     }
@@ -2079,7 +2093,7 @@
         double diff, avg_diff;
         int min_nb_samples, max_nb_samples;
 
-        diff = get_audio_clock(is) - get_master_clock(is);
+        diff = get_clock(&is->audclk) - get_master_clock(is);
 
         if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
             is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
@@ -2127,8 +2141,6 @@
     int64_t dec_channel_layout;
     int got_frame;
     av_unused double audio_clock0;
-    int new_packet = 0;
-    int flush_complete = 0;
     int wanted_nb_samples;
     AVRational tb;
     int ret;
@@ -2136,7 +2148,7 @@
 
     for (;;) {
         /* NOTE: the audio packet can contain several frames */
-        while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet) || is->audio_buf_frames_pending) {
+        while (pkt_temp->stream_index != -1 || is->audio_buf_frames_pending) {
             if (!is->frame) {
                 if (!(is->frame = avcodec_alloc_frame()))
                     return AVERROR(ENOMEM);
@@ -2152,9 +2164,6 @@
                 return -1;
 
             if (!is->audio_buf_frames_pending) {
-                if (flush_complete)
-                    break;
-                new_packet = 0;
                 len1 = avcodec_decode_audio4(dec, is->frame, &got_frame, pkt_temp);
                 if (len1 < 0) {
                     /* if error, we skip the frame */
@@ -2162,23 +2171,32 @@
                     break;
                 }
 
+                pkt_temp->dts =
+                pkt_temp->pts = AV_NOPTS_VALUE;
                 pkt_temp->data += len1;
                 pkt_temp->size -= len1;
+                if (pkt_temp->data && pkt_temp->size <= 0 || !pkt_temp->data && !got_frame)
+                    pkt_temp->stream_index = -1;
+                if (!pkt_temp->data && !got_frame)
+                    is->audio_finished = is->audio_pkt_temp_serial;
 
-                if (!got_frame) {
-                    /* stop sending empty packets if the decoder is finished */
-                    if (!pkt_temp->data && dec->codec->capabilities & CODEC_CAP_DELAY)
-                        flush_complete = 1;
+                if (!got_frame)
                     continue;
-                }
 
                 tb = (AVRational){1, is->frame->sample_rate};
                 if (is->frame->pts != AV_NOPTS_VALUE)
                     is->frame->pts = av_rescale_q(is->frame->pts, dec->time_base, tb);
-                if (is->frame->pts == AV_NOPTS_VALUE && pkt_temp->pts != AV_NOPTS_VALUE)
-                    is->frame->pts = av_rescale_q(pkt_temp->pts, is->audio_st->time_base, tb);
-                if (pkt_temp->pts != AV_NOPTS_VALUE)
-                    pkt_temp->pts += (double) is->frame->nb_samples / is->frame->sample_rate / av_q2d(is->audio_st->time_base);
+                else if (is->frame->pkt_pts != AV_NOPTS_VALUE)
+                    is->frame->pts = av_rescale_q(is->frame->pkt_pts, is->audio_st->time_base, tb);
+                else if (is->audio_frame_next_pts != AV_NOPTS_VALUE)
+#if CONFIG_AVFILTER
+                    is->frame->pts = av_rescale_q(is->audio_frame_next_pts, (AVRational){1, is->audio_filter_src.freq}, tb);
+#else
+                    is->frame->pts = av_rescale_q(is->audio_frame_next_pts, (AVRational){1, is->audio_src.freq}, tb);
+#endif
+
+                if (is->frame->pts != AV_NOPTS_VALUE)
+                    is->audio_frame_next_pts = is->frame->pts + is->frame->nb_samples;
 
 #if CONFIG_AVFILTER
                 dec_channel_layout = get_valid_channel_layout(is->frame->channel_layout, av_frame_get_channels(is->frame));
@@ -2220,6 +2238,8 @@
                     is->audio_buf_frames_pending = 0;
                     continue;
                 }
+                if (ret == AVERROR_EOF)
+                    is->audio_finished = is->audio_pkt_temp_serial;
                 return ret;
             }
             is->audio_buf_frames_pending = 1;
@@ -2245,7 +2265,8 @@
                                                  dec_channel_layout,           is->frame->format, is->frame->sample_rate,
                                                  0, NULL);
                 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
-                    fprintf(stderr, "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
+                    av_log(NULL, AV_LOG_ERROR,
+                           "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
                             is->frame->sample_rate, av_get_sample_fmt_name(is->frame->format), av_frame_get_channels(is->frame),
                             is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
                     break;
@@ -2263,13 +2284,13 @@
                 int out_size  = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
                 int len2;
                 if (out_size < 0) {
-                    fprintf(stderr, "av_samples_get_buffer_size() failed\n");
+                    av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
                     break;
                 }
                 if (wanted_nb_samples != is->frame->nb_samples) {
                     if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - is->frame->nb_samples) * is->audio_tgt.freq / is->frame->sample_rate,
                                                 wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate) < 0) {
-                        fprintf(stderr, "swr_set_compensation() failed\n");
+                        av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
                         break;
                     }
                 }
@@ -2278,11 +2299,11 @@
                     return AVERROR(ENOMEM);
                 len2 = swr_convert(is->swr_ctx, out, out_count, in, is->frame->nb_samples);
                 if (len2 < 0) {
-                    fprintf(stderr, "swr_convert() failed\n");
+                    av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
                     break;
                 }
                 if (len2 == out_count) {
-                    fprintf(stderr, "warning: audio buffer is probably too small\n");
+                    av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
                     swr_init(is->swr_ctx);
                 }
                 is->audio_buf = is->audio_buf1;
@@ -2294,10 +2315,11 @@
 
             audio_clock0 = is->audio_clock;
             /* update the audio clock with the pts */
-            if (is->frame->pts != AV_NOPTS_VALUE) {
+            if (is->frame->pts != AV_NOPTS_VALUE)
                 is->audio_clock = is->frame->pts * av_q2d(tb) + (double) is->frame->nb_samples / is->frame->sample_rate;
-                is->audio_clock_serial = is->audio_pkt_temp_serial;
-            }
+            else
+                is->audio_clock = NAN;
+            is->audio_clock_serial = is->audio_pkt_temp_serial;
 #ifdef DEBUG
             {
                 static double last_clock;
@@ -2314,6 +2336,7 @@
         if (pkt->data)
             av_free_packet(pkt);
         memset(pkt_temp, 0, sizeof(*pkt_temp));
+        pkt_temp->stream_index = -1;
 
         if (is->audioq.abort_request) {
             return -1;
@@ -2323,13 +2346,15 @@
             SDL_CondSignal(is->continue_read_thread);
 
         /* read next packet */
-        if ((new_packet = packet_queue_get(&is->audioq, pkt, 1, &is->audio_pkt_temp_serial)) < 0)
+        if ((packet_queue_get(&is->audioq, pkt, 1, &is->audio_pkt_temp_serial)) < 0)
             return -1;
 
         if (pkt->data == flush_pkt.data) {
             avcodec_flush_buffers(dec);
-            flush_complete = 0;
             is->audio_buf_frames_pending = 0;
+            is->audio_frame_next_pts = AV_NOPTS_VALUE;
+            if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek)
+                is->audio_frame_next_pts = is->audio_st->start_time;
         }
 
         *pkt_temp = *pkt;
@@ -2371,10 +2396,10 @@
     bytes_per_sec = is->audio_tgt.freq * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
     is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
     /* Let's assume the audio driver that is used by SDL has two periods. */
-    is->audio_current_pts = is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / bytes_per_sec;
-    is->audio_current_pts_drift = is->audio_current_pts - audio_callback_time / 1000000.0;
-    if (is->audioq.serial == is->audio_clock_serial)
-        check_external_clock_sync(is, is->audio_current_pts);
+    if (!isnan(is->audio_clock)) {
+        set_clock_at(&is->audclk, is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / bytes_per_sec, is->audio_clock_serial, audio_callback_time / 1000000.0);
+        sync_clock_to_slave(&is->extclk, &is->audclk);
+    }
 }
 
 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
@@ -2395,7 +2420,7 @@
     wanted_spec.channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
     wanted_spec.freq = wanted_sample_rate;
     if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
-        fprintf(stderr, "Invalid sample rate or channel count!\n");
+        av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
         return -1;
     }
     wanted_spec.format = AUDIO_S16SYS;
@@ -2404,22 +2429,25 @@
     wanted_spec.callback = sdl_audio_callback;
     wanted_spec.userdata = opaque;
     while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
-        fprintf(stderr, "SDL_OpenAudio (%d channels): %s\n", wanted_spec.channels, SDL_GetError());
+        av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels): %s\n", wanted_spec.channels, SDL_GetError());
         wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
         if (!wanted_spec.channels) {
-            fprintf(stderr, "No more channel combinations to try, audio open failed\n");
+            av_log(NULL, AV_LOG_ERROR,
+                   "No more channel combinations to try, audio open failed\n");
             return -1;
         }
         wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
     }
     if (spec.format != AUDIO_S16SYS) {
-        fprintf(stderr, "SDL advised audio format %d is not supported!\n", spec.format);
+        av_log(NULL, AV_LOG_ERROR,
+               "SDL advised audio format %d is not supported!\n", spec.format);
         return -1;
     }
     if (spec.channels != wanted_spec.channels) {
         wanted_channel_layout = av_get_default_channel_layout(spec.channels);
         if (!wanted_channel_layout) {
-            fprintf(stderr, "SDL advised channel count %d is not supported!\n", spec.channels);
+            av_log(NULL, AV_LOG_ERROR,
+                   "SDL advised channel count %d is not supported!\n", spec.channels);
             return -1;
         }
     }
@@ -2458,8 +2486,10 @@
     if (forced_codec_name)
         codec = avcodec_find_decoder_by_name(forced_codec_name);
     if (!codec) {
-        if (forced_codec_name) fprintf(stderr, "No codec could be found with name '%s'\n", forced_codec_name);
-        else                   fprintf(stderr, "No codec could be found with id %d\n", avctx->codec_id);
+        if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
+                                      "No codec could be found with name '%s'\n", forced_codec_name);
+        else                   av_log(NULL, AV_LOG_WARNING,
+                                      "No codec could be found with id %d\n", avctx->codec_id);
         return -1;
     }
 
@@ -2471,7 +2501,6 @@
                 codec->max_lowres);
         avctx->lowres= codec->max_lowres;
     }
-    avctx->idct_algo         = idct;
     avctx->error_concealment = error_concealment;
 
     if(avctx->lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
@@ -2482,6 +2511,8 @@
     opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
     if (!av_dict_get(opts, "threads", NULL, 0))
         av_dict_set(&opts, "threads", "auto", 0);
+    if (avctx->lowres)
+        av_dict_set(&opts, "lowres", av_asprintf("%d", avctx->lowres), AV_DICT_DONT_STRDUP_VAL);
     if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
         av_dict_set(&opts, "refcounted_frames", "1", 0);
     if (avcodec_open2(avctx, codec, &opts) < 0)
@@ -2532,6 +2563,7 @@
 
         memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
         memset(&is->audio_pkt_temp, 0, sizeof(is->audio_pkt_temp));
+        is->audio_pkt_temp.stream_index = -1;
 
         is->audio_stream = stream_index;
         is->audio_st = ic->streams[stream_index];
@@ -2612,8 +2644,6 @@
         /* note: we also signal this mutex to make sure we deblock the
            video thread in all cases */
         SDL_LockMutex(is->subpq_mutex);
-        is->subtitle_stream_changed = 1;
-
         SDL_CondSignal(is->subpq_cond);
         SDL_UnlockMutex(is->subpq_mutex);
 
@@ -2676,6 +2706,7 @@
     int st_index[AVMEDIA_TYPE_NB];
     AVPacket pkt1, *pkt = &pkt1;
     int eof = 0;
+    int64_t stream_start_time;
     int pkt_in_play_range = 0;
     AVDictionaryEntry *t;
     AVDictionary **opts;
@@ -2711,7 +2742,8 @@
 
     err = avformat_find_stream_info(ic, opts);
     if (err < 0) {
-        fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
+        av_log(NULL, AV_LOG_WARNING,
+               "%s: could not find codec parameters\n", is->filename);
         ret = -1;
         goto fail;
     }
@@ -2740,7 +2772,7 @@
             timestamp += ic->start_time;
         ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
         if (ret < 0) {
-            fprintf(stderr, "%s: could not seek to position %0.3f\n",
+            av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
                     is->filename, (double)timestamp / AV_TIME_BASE);
         }
     }
@@ -2790,7 +2822,8 @@
     }
 
     if (is->video_stream < 0 && is->audio_stream < 0) {
-        fprintf(stderr, "%s: could not open codecs\n", is->filename);
+        av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
+               is->filename);
         ret = -1;
         goto fail;
     }
@@ -2827,7 +2860,8 @@
 
             ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
             if (ret < 0) {
-                fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
+                av_log(NULL, AV_LOG_ERROR,
+                       "%s: error while seeking\n", is->ic->filename);
             } else {
                 if (is->audio_stream >= 0) {
                     packet_queue_flush(&is->audioq);
@@ -2842,9 +2876,9 @@
                     packet_queue_put(&is->videoq, &flush_pkt);
                 }
                 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
-                   update_external_clock_pts(is, NAN);
+                   set_clock(&is->extclk, NAN, 0);
                 } else {
-                   update_external_clock_pts(is, seek_target / (double)AV_TIME_BASE);
+                   set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
                 }
             }
             is->seek_req = 0;
@@ -2876,6 +2910,16 @@
             SDL_UnlockMutex(wait_mutex);
             continue;
         }
+        if (!is->paused &&
+            (!is->audio_st || is->audio_finished == is->audioq.serial) &&
+            (!is->video_st || (is->video_finished == is->videoq.serial && is->pictq_size == 0))) {
+            if (loop != 1 && (!loop || --loop)) {
+                stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
+            } else if (autoexit) {
+                ret = AVERROR_EOF;
+                goto fail;
+            }
+        }
         if (eof) {
             if (is->video_stream >= 0) {
                 av_init_packet(pkt);
@@ -2884,8 +2928,7 @@
                 pkt->stream_index = is->video_stream;
                 packet_queue_put(&is->videoq, pkt);
             }
-            if (is->audio_stream >= 0 &&
-                is->audio_st->codec->codec->capabilities & CODEC_CAP_DELAY) {
+            if (is->audio_stream >= 0) {
                 av_init_packet(pkt);
                 pkt->data = NULL;
                 pkt->size = 0;
@@ -2893,14 +2936,6 @@
                 packet_queue_put(&is->audioq, pkt);
             }
             SDL_Delay(10);
-            if (is->audioq.size + is->videoq.size + is->subtitleq.size == 0) {
-                if (loop != 1 && (!loop || --loop)) {
-                    stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
-                } else if (autoexit) {
-                    ret = AVERROR_EOF;
-                    goto fail;
-                }
-            }
             eof=0;
             continue;
         }
@@ -2916,8 +2951,9 @@
             continue;
         }
         /* check if packet is in play range specified by user, then queue, otherwise discard */
+        stream_start_time = ic->streams[pkt->stream_index]->start_time;
         pkt_in_play_range = duration == AV_NOPTS_VALUE ||
-                (pkt->pts - ic->streams[pkt->stream_index]->start_time) *
+                (pkt->pts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
                 av_q2d(ic->streams[pkt->stream_index]->time_base) -
                 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
                 <= ((double)duration / 1000000);
@@ -2986,12 +3022,10 @@
 
     is->continue_read_thread = SDL_CreateCond();
 
-    update_external_clock_pts(is, NAN);
-    update_external_clock_speed(is, 1.0);
-    is->audio_current_pts_drift = -av_gettime() / 1000000.0;
-    is->video_current_pts_drift = is->audio_current_pts_drift;
+    init_clock(&is->vidclk, &is->videoq.serial);
+    init_clock(&is->audclk, &is->audioq.serial);
+    init_clock(&is->extclk, &is->extclk.serial);
     is->audio_clock_serial = -1;
-    is->video_clock_serial = -1;
     is->audio_last_serial = -1;
     is->av_sync_type = av_sync_type;
     is->read_tid     = SDL_CreateThread(read_thread, is);
@@ -3228,7 +3262,8 @@
                     hh   = ns / 3600;
                     mm   = (ns % 3600) / 60;
                     ss   = (ns % 60);
-                    fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
+                    av_log(NULL, AV_LOG_INFO,
+                           "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
                             hh, mm, ss, thh, tmm, tss);
                     ts = frac * cur_stream->ic->duration;
                     if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
@@ -3237,10 +3272,14 @@
                 }
             break;
         case SDL_VIDEORESIZE:
-                screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
+                screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
                                           SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
-                screen_width  = cur_stream->width  = event.resize.w;
-                screen_height = cur_stream->height = event.resize.h;
+                if (!screen) {
+                    av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
+                    do_exit(cur_stream);
+                }
+                screen_width  = cur_stream->width  = screen->w;
+                screen_height = cur_stream->height = screen->h;
                 cur_stream->force_refresh = 1;
             break;
         case SDL_QUIT:
@@ -3278,7 +3317,7 @@
 {
     file_iformat = av_find_input_format(arg);
     if (!file_iformat) {
-        fprintf(stderr, "Unknown input format: %s\n", arg);
+        av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
         return AVERROR(EINVAL);
     }
     return 0;
@@ -3299,7 +3338,7 @@
     else if (!strcmp(arg, "ext"))
         av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
     else {
-        fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
+        av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
         exit(1);
     }
     return 0;
@@ -3329,7 +3368,8 @@
 static void opt_input_file(void *optctx, const char *filename)
 {
     if (input_filename) {
-        fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n",
+        av_log(NULL, AV_LOG_FATAL,
+               "Argument '%s' provided as input filename, but '%s' was already specified.\n",
                 filename, input_filename);
         exit(1);
     }
@@ -3342,7 +3382,8 @@
 {
    const char *spec = strchr(opt, ':');
    if (!spec) {
-       fprintf(stderr, "No media specifier was specified in '%s' in option '%s'\n",
+       av_log(NULL, AV_LOG_ERROR,
+              "No media specifier was specified in '%s' in option '%s'\n",
                arg, opt);
        return AVERROR(EINVAL);
    }
@@ -3352,7 +3393,8 @@
    case 's' : subtitle_codec_name = arg; break;
    case 'v' :    video_codec_name = arg; break;
    default:
-       fprintf(stderr, "Invalid media specifier '%s' in option '%s'\n", spec, opt);
+       av_log(NULL, AV_LOG_ERROR,
+              "Invalid media specifier '%s' in option '%s'\n", spec, opt);
        return AVERROR(EINVAL);
    }
    return 0;
@@ -3384,7 +3426,6 @@
     { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
     { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
     { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
-    { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, { &idct }, "set idct algo",  "algo" },
     { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, { &error_concealment }, "set error concealment options",  "bit_mask" },
     { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
     { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
@@ -3497,8 +3538,9 @@
 
     if (!input_filename) {
         show_usage();
-        fprintf(stderr, "An input file must be specified\n");
-        fprintf(stderr, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
+        av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
+        av_log(NULL, AV_LOG_FATAL,
+               "Use -h to get full help or, even better, run 'man %s'\n", program_name);
         exit(1);
     }
 
@@ -3514,8 +3556,8 @@
     flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
 #endif
     if (SDL_Init (flags)) {
-        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
-        fprintf(stderr, "(Did you set the DISPLAY variable?)\n");
+        av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
+        av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
         exit(1);
     }
 
@@ -3530,16 +3572,16 @@
     SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
 
     if (av_lockmgr_register(lockmgr)) {
-        fprintf(stderr, "Could not initialize lock manager!\n");
+        av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
         do_exit(NULL);
     }
 
     av_init_packet(&flush_pkt);
-    flush_pkt.data = (char *)(intptr_t)"FLUSH";
+    flush_pkt.data = (uint8_t *)&flush_pkt;
 
     is = stream_open(input_filename, file_iformat);
     if (!is) {
-        fprintf(stderr, "Failed to initialize VideoState!\n");
+        av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");
         do_exit(NULL);
     }
 
diff --git a/ffprobe.c b/ffprobe.c
index 4d2d3e1..8a65e1a 100644
--- a/ffprobe.c
+++ b/ffprobe.c
@@ -52,10 +52,12 @@
 static int do_count_packets = 0;
 static int do_read_frames  = 0;
 static int do_read_packets = 0;
+static int do_show_chapters = 0;
 static int do_show_error   = 0;
 static int do_show_format  = 0;
 static int do_show_frames  = 0;
 static int do_show_packets = 0;
+static int do_show_programs = 0;
 static int do_show_streams = 0;
 static int do_show_stream_disposition = 0;
 static int do_show_data    = 0;
@@ -93,6 +95,9 @@
 
 typedef enum {
     SECTION_ID_NONE = -1,
+    SECTION_ID_CHAPTER,
+    SECTION_ID_CHAPTER_TAGS,
+    SECTION_ID_CHAPTERS,
     SECTION_ID_ERROR,
     SECTION_ID_FORMAT,
     SECTION_ID_FORMAT_TAGS,
@@ -104,7 +109,14 @@
     SECTION_ID_PACKET,
     SECTION_ID_PACKETS,
     SECTION_ID_PACKETS_AND_FRAMES,
+    SECTION_ID_PROGRAM_STREAM_DISPOSITION,
+    SECTION_ID_PROGRAM_STREAM_TAGS,
+    SECTION_ID_PROGRAM,
+    SECTION_ID_PROGRAM_STREAMS,
+    SECTION_ID_PROGRAM_STREAM,
+    SECTION_ID_PROGRAM_TAGS,
     SECTION_ID_PROGRAM_VERSION,
+    SECTION_ID_PROGRAMS,
     SECTION_ID_ROOT,
     SECTION_ID_STREAM,
     SECTION_ID_STREAM_DISPOSITION,
@@ -113,6 +125,9 @@
 } SectionID;
 
 static struct section sections[] = {
+    [SECTION_ID_CHAPTERS] =           { SECTION_ID_CHAPTERS, "chapters", SECTION_FLAG_IS_ARRAY, { SECTION_ID_CHAPTER, -1 } },
+    [SECTION_ID_CHAPTER] =            { SECTION_ID_CHAPTER, "chapter", 0, { SECTION_ID_CHAPTER_TAGS, -1 } },
+    [SECTION_ID_CHAPTER_TAGS] =       { SECTION_ID_CHAPTER_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "chapter_tags" },
     [SECTION_ID_ERROR] =              { SECTION_ID_ERROR, "error", 0, { -1 } },
     [SECTION_ID_FORMAT] =             { SECTION_ID_FORMAT, "format", 0, { SECTION_ID_FORMAT_TAGS, -1 } },
     [SECTION_ID_FORMAT_TAGS] =        { SECTION_ID_FORMAT_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "format_tags" },
@@ -124,10 +139,17 @@
     [SECTION_ID_PACKETS] =            { SECTION_ID_PACKETS, "packets", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PACKET, -1} },
     [SECTION_ID_PACKETS_AND_FRAMES] = { SECTION_ID_PACKETS_AND_FRAMES, "packets_and_frames", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PACKET, -1} },
     [SECTION_ID_PACKET] =             { SECTION_ID_PACKET, "packet", 0, { -1 } },
+    [SECTION_ID_PROGRAM_STREAM_DISPOSITION] = { SECTION_ID_PROGRAM_STREAM_DISPOSITION, "disposition", 0, { -1 }, .unique_name = "program_stream_disposition" },
+    [SECTION_ID_PROGRAM_STREAM_TAGS] =        { SECTION_ID_PROGRAM_STREAM_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "program_stream_tags" },
+    [SECTION_ID_PROGRAM] =                    { SECTION_ID_PROGRAM, "program", 0, { SECTION_ID_PROGRAM_TAGS, SECTION_ID_PROGRAM_STREAMS, -1 } },
+    [SECTION_ID_PROGRAM_STREAMS] =            { SECTION_ID_PROGRAM_STREAMS, "streams", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PROGRAM_STREAM, -1 }, .unique_name = "program_streams" },
+    [SECTION_ID_PROGRAM_STREAM] =             { SECTION_ID_PROGRAM_STREAM, "stream", 0, { SECTION_ID_PROGRAM_STREAM_DISPOSITION, SECTION_ID_PROGRAM_STREAM_TAGS, -1 }, .unique_name = "program_stream" },
+    [SECTION_ID_PROGRAM_TAGS] =               { SECTION_ID_PROGRAM_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "program_tags" },
     [SECTION_ID_PROGRAM_VERSION] =    { SECTION_ID_PROGRAM_VERSION, "program_version", 0, { -1 } },
+    [SECTION_ID_PROGRAMS] =                   { SECTION_ID_PROGRAMS, "programs", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PROGRAM, -1 } },
     [SECTION_ID_ROOT] =               { SECTION_ID_ROOT, "root", SECTION_FLAG_IS_WRAPPER,
-                                        { SECTION_ID_FORMAT, SECTION_ID_FRAMES, SECTION_ID_STREAMS, SECTION_ID_PACKETS,
-                                          SECTION_ID_ERROR, SECTION_ID_PROGRAM_VERSION, SECTION_ID_LIBRARY_VERSIONS, -1} },
+                                        { SECTION_ID_CHAPTERS, SECTION_ID_FORMAT, SECTION_ID_FRAMES, SECTION_ID_PROGRAMS, SECTION_ID_STREAMS,
+                                          SECTION_ID_PACKETS, SECTION_ID_ERROR, SECTION_ID_PROGRAM_VERSION, SECTION_ID_LIBRARY_VERSIONS, -1} },
     [SECTION_ID_STREAMS] =            { SECTION_ID_STREAMS, "streams", SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM, -1 } },
     [SECTION_ID_STREAM] =             { SECTION_ID_STREAM, "stream", 0, { SECTION_ID_STREAM_DISPOSITION, SECTION_ID_STREAM_TAGS, -1 } },
     [SECTION_ID_STREAM_DISPOSITION] = { SECTION_ID_STREAM_DISPOSITION, "disposition", 0, { -1 }, .unique_name = "stream_disposition" },
@@ -152,7 +174,7 @@
 static uint64_t *nb_streams_frames;
 static int *selected_streams;
 
-static void exit_program(void)
+static void ffprobe_cleanup(int ret)
 {
     int i;
     for (i = 0; i < FF_ARRAY_ELEMS(sections); i++)
@@ -668,6 +690,8 @@
     char *escape_mode_str;
     const char * (*escape_str)(AVBPrint *dst, const char *src, const char sep, void *log_ctx);
     int nested_section[SECTION_MAX_NB_LEVELS];
+    int has_nested_elems[SECTION_MAX_NB_LEVELS];
+    int terminate_line[SECTION_MAX_NB_LEVELS];
 } CompactContext;
 
 #undef OFFSET
@@ -715,18 +739,28 @@
     const struct section *section = wctx->section[wctx->level];
     const struct section *parent_section = wctx->level ?
         wctx->section[wctx->level-1] : NULL;
+    compact->terminate_line[wctx->level] = 1;
+    compact->has_nested_elems[wctx->level] = 0;
 
     av_bprint_clear(&wctx->section_pbuf[wctx->level]);
-    if (parent_section &&
+    if (!(section->flags & SECTION_FLAG_IS_ARRAY) && parent_section &&
         !(parent_section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY))) {
         compact->nested_section[wctx->level] = 1;
+        compact->has_nested_elems[wctx->level-1] = 1;
         av_bprintf(&wctx->section_pbuf[wctx->level], "%s%s:",
                    wctx->section_pbuf[wctx->level-1].str,
                    (char *)av_x_if_null(section->element_name, section->name));
         wctx->nb_item[wctx->level] = wctx->nb_item[wctx->level-1];
-    } else if (compact->print_section &&
-        !(section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY)))
-       printf("%s%c", section->name, compact->item_sep);
+    } else {
+        if (parent_section && compact->has_nested_elems[wctx->level-1] &&
+            (section->flags & SECTION_FLAG_IS_ARRAY)) {
+            compact->terminate_line[wctx->level-1] = 0;
+            printf("\n");
+        }
+        if (compact->print_section &&
+            !(section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY)))
+            printf("%s%c", section->name, compact->item_sep);
+    }
 }
 
 static void compact_print_section_footer(WriterContext *wctx)
@@ -734,6 +768,7 @@
     CompactContext *compact = wctx->priv;
 
     if (!compact->nested_section[wctx->level] &&
+        compact->terminate_line[wctx->level] &&
         !(wctx->section[wctx->level]->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY)))
         printf("\n");
 }
@@ -1591,7 +1626,7 @@
     }
 }
 
-static void show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_idx)
+static void show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_idx, int in_program)
 {
     AVStream *stream = fmt_ctx->streams[stream_idx];
     AVCodecContext *dec_ctx;
@@ -1603,7 +1638,7 @@
 
     av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
 
-    writer_print_section_header(w, SECTION_ID_STREAM);
+    writer_print_section_header(w, in_program ? SECTION_ID_PROGRAM_STREAM : SECTION_ID_STREAM);
 
     print_int("index", stream->index);
 
@@ -1719,7 +1754,7 @@
     } while (0)
 
     if (do_show_stream_disposition) {
-    writer_print_section_header(w, SECTION_ID_STREAM_DISPOSITION);
+    writer_print_section_header(w, in_program ? SECTION_ID_PROGRAM_STREAM_DISPOSITION : SECTION_ID_STREAM_DISPOSITION);
     PRINT_DISPOSITION(DEFAULT,          "default");
     PRINT_DISPOSITION(DUB,              "dub");
     PRINT_DISPOSITION(ORIGINAL,         "original");
@@ -1734,7 +1769,7 @@
     writer_print_section_footer(w);
     }
 
-    show_tags(w, stream->metadata, SECTION_ID_STREAM_TAGS);
+    show_tags(w, stream->metadata, in_program ? SECTION_ID_PROGRAM_STREAM_TAGS : SECTION_ID_STREAM_TAGS);
 
     writer_print_section_footer(w);
     av_bprint_finalize(&pbuf, NULL);
@@ -1747,7 +1782,68 @@
     writer_print_section_header(w, SECTION_ID_STREAMS);
     for (i = 0; i < fmt_ctx->nb_streams; i++)
         if (selected_streams[i])
-            show_stream(w, fmt_ctx, i);
+            show_stream(w, fmt_ctx, i, 0);
+    writer_print_section_footer(w);
+}
+
+static void show_program(WriterContext *w, AVFormatContext *fmt_ctx, AVProgram *program)
+{
+    int i;
+
+    writer_print_section_header(w, SECTION_ID_PROGRAM);
+    print_int("program_id", program->id);
+    print_int("program_num", program->program_num);
+    print_int("nb_streams", program->nb_stream_indexes);
+    print_int("pmt_pid", program->pmt_pid);
+    print_int("pcr_pid", program->pcr_pid);
+    print_ts("start_pts", program->start_time);
+    print_time("start_time", program->start_time, &AV_TIME_BASE_Q);
+    print_ts("end_pts", program->end_time);
+    print_time("end_time", program->end_time, &AV_TIME_BASE_Q);
+    show_tags(w, program->metadata, SECTION_ID_PROGRAM_TAGS);
+
+    writer_print_section_header(w, SECTION_ID_PROGRAM_STREAMS);
+    for (i = 0; i < program->nb_stream_indexes; i++) {
+        if (selected_streams[program->stream_index[i]])
+            show_stream(w, fmt_ctx, program->stream_index[i], 1);
+    }
+    writer_print_section_footer(w);
+
+    writer_print_section_footer(w);
+}
+
+static void show_programs(WriterContext *w, AVFormatContext *fmt_ctx)
+{
+    int i;
+
+    writer_print_section_header(w, SECTION_ID_PROGRAMS);
+    for (i = 0; i < fmt_ctx->nb_programs; i++) {
+        AVProgram *program = fmt_ctx->programs[i];
+        if (!program)
+            continue;
+        show_program(w, fmt_ctx, program);
+    }
+    writer_print_section_footer(w);
+}
+
+static void show_chapters(WriterContext *w, AVFormatContext *fmt_ctx)
+{
+    int i;
+
+    writer_print_section_header(w, SECTION_ID_CHAPTERS);
+    for (i = 0; i < fmt_ctx->nb_chapters; i++) {
+        AVChapter *chapter = fmt_ctx->chapters[i];
+
+        writer_print_section_header(w, SECTION_ID_CHAPTER);
+        print_int("id", chapter->id);
+        print_q  ("time_base", chapter->time_base, '/');
+        print_int("start", chapter->start);
+        print_time("start_time", chapter->start, &chapter->time_base);
+        print_int("end", chapter->end);
+        print_time("end_time", chapter->end, &chapter->time_base);
+        show_tags(w, chapter->metadata, SECTION_ID_CHAPTER_TAGS);
+        writer_print_section_footer(w);
+    }
     writer_print_section_footer(w);
 }
 
@@ -1759,6 +1855,7 @@
     writer_print_section_header(w, SECTION_ID_FORMAT);
     print_str("filename",         fmt_ctx->filename);
     print_int("nb_streams",       fmt_ctx->nb_streams);
+    print_int("nb_programs",      fmt_ctx->nb_programs);
     print_str("format_name",      fmt_ctx->iformat->name);
     if (!do_bitexact) {
         if (fmt_ctx->iformat->long_name) print_str    ("format_long_name", fmt_ctx->iformat->long_name);
@@ -1876,50 +1973,57 @@
     do_read_packets = do_show_packets || do_count_packets;
 
     ret = open_input_file(&fmt_ctx, filename);
-    if (ret >= 0) {
-        nb_streams_frames  = av_calloc(fmt_ctx->nb_streams, sizeof(*nb_streams_frames));
-        nb_streams_packets = av_calloc(fmt_ctx->nb_streams, sizeof(*nb_streams_packets));
-        selected_streams   = av_calloc(fmt_ctx->nb_streams, sizeof(*selected_streams));
+    if (ret < 0)
+        return ret;
 
-        for (i = 0; i < fmt_ctx->nb_streams; i++) {
-            if (stream_specifier) {
-                ret = avformat_match_stream_specifier(fmt_ctx,
-                                                      fmt_ctx->streams[i],
-                                                      stream_specifier);
-                if (ret < 0)
-                    goto end;
-                else
-                    selected_streams[i] = ret;
-            } else {
-                selected_streams[i] = 1;
-            }
+    nb_streams_frames  = av_calloc(fmt_ctx->nb_streams, sizeof(*nb_streams_frames));
+    nb_streams_packets = av_calloc(fmt_ctx->nb_streams, sizeof(*nb_streams_packets));
+    selected_streams   = av_calloc(fmt_ctx->nb_streams, sizeof(*selected_streams));
+
+    for (i = 0; i < fmt_ctx->nb_streams; i++) {
+        if (stream_specifier) {
+            ret = avformat_match_stream_specifier(fmt_ctx,
+                                                  fmt_ctx->streams[i],
+                                                  stream_specifier);
+            if (ret < 0)
+                goto end;
+            else
+                selected_streams[i] = ret;
+            ret = 0;
+        } else {
+            selected_streams[i] = 1;
         }
-
-        if (do_read_frames || do_read_packets) {
-            if (do_show_frames && do_show_packets &&
-                wctx->writer->flags & WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER)
-                section_id = SECTION_ID_PACKETS_AND_FRAMES;
-            else if (do_show_packets && !do_show_frames)
-                section_id = SECTION_ID_PACKETS;
-            else // (!do_show_packets && do_show_frames)
-                section_id = SECTION_ID_FRAMES;
-            if (do_show_frames || do_show_packets)
-                writer_print_section_header(wctx, section_id);
-            read_packets(wctx, fmt_ctx);
-            if (do_show_frames || do_show_packets)
-                writer_print_section_footer(wctx);
-        }
-        if (do_show_streams)
-            show_streams(wctx, fmt_ctx);
-        if (do_show_format)
-            show_format(wctx, fmt_ctx);
-
-    end:
-        close_input_file(&fmt_ctx);
-        av_freep(&nb_streams_frames);
-        av_freep(&nb_streams_packets);
-        av_freep(&selected_streams);
     }
+
+    if (do_read_frames || do_read_packets) {
+        if (do_show_frames && do_show_packets &&
+            wctx->writer->flags & WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER)
+            section_id = SECTION_ID_PACKETS_AND_FRAMES;
+        else if (do_show_packets && !do_show_frames)
+            section_id = SECTION_ID_PACKETS;
+        else // (!do_show_packets && do_show_frames)
+            section_id = SECTION_ID_FRAMES;
+        if (do_show_frames || do_show_packets)
+            writer_print_section_header(wctx, section_id);
+        read_packets(wctx, fmt_ctx);
+        if (do_show_frames || do_show_packets)
+            writer_print_section_footer(wctx);
+    }
+    if (do_show_programs)
+        show_programs(wctx, fmt_ctx);
+    if (do_show_streams)
+        show_streams(wctx, fmt_ctx);
+    if (do_show_chapters)
+        show_chapters(wctx, fmt_ctx);
+    if (do_show_format)
+        show_format(wctx, fmt_ctx);
+
+end:
+    close_input_file(&fmt_ctx);
+    av_freep(&nb_streams_frames);
+    av_freep(&nb_streams_packets);
+    av_freep(&selected_streams);
+
     return ret;
 }
 
@@ -2090,7 +2194,7 @@
         av_log(NULL, AV_LOG_ERROR,
                 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
                 arg, input_filename);
-        exit(1);
+        exit_program(1);
     }
     if (!strcmp(arg, "-"))
         arg = "pipe:";
@@ -2165,6 +2269,7 @@
         return 0;                                                       \
     }
 
+DEFINE_OPT_SHOW_SECTION(chapters,         CHAPTERS);
 DEFINE_OPT_SHOW_SECTION(error,            ERROR);
 DEFINE_OPT_SHOW_SECTION(format,           FORMAT);
 DEFINE_OPT_SHOW_SECTION(frames,           FRAMES);
@@ -2172,6 +2277,7 @@
 DEFINE_OPT_SHOW_SECTION(packets,          PACKETS);
 DEFINE_OPT_SHOW_SECTION(program_version,  PROGRAM_VERSION);
 DEFINE_OPT_SHOW_SECTION(streams,          STREAMS);
+DEFINE_OPT_SHOW_SECTION(programs,         PROGRAMS);
 
 static const OptionDef real_options[] = {
 #include "cmdutils_common_opts.h"
@@ -2198,7 +2304,9 @@
     { "show_entries", HAS_ARG, {.func_arg = opt_show_entries},
       "show a set of specified entries", "entry_list" },
     { "show_packets", 0, {(void*)&opt_show_packets}, "show packets info" },
+    { "show_programs", 0, {(void*)&opt_show_programs}, "show programs info" },
     { "show_streams", 0, {(void*)&opt_show_streams}, "show streams info" },
+    { "show_chapters", 0, {(void*)&opt_show_chapters}, "show chapters info" },
     { "count_frames", OPT_BOOL, {(void*)&do_count_frames}, "count the number of frames per stream" },
     { "count_packets", OPT_BOOL, {(void*)&do_count_packets}, "count the number of packets per stream" },
     { "show_program_version",  0, {(void*)&opt_show_program_version},  "show ffprobe version" },
@@ -2238,7 +2346,7 @@
     int ret, i;
 
     av_log_set_flags(AV_LOG_SKIP_REPEATED);
-    atexit(exit_program);
+    register_exit(ffprobe_cleanup);
 
     options = real_options;
     parse_loglevel(argc, argv, options);
@@ -2253,14 +2361,17 @@
     parse_options(NULL, argc, argv, options, opt_input_file);
 
     /* mark things to show, based on -show_entries */
+    SET_DO_SHOW(CHAPTERS, chapters);
     SET_DO_SHOW(ERROR, error);
     SET_DO_SHOW(FORMAT, format);
     SET_DO_SHOW(FRAMES, frames);
     SET_DO_SHOW(LIBRARY_VERSIONS, library_versions);
     SET_DO_SHOW(PACKETS, packets);
     SET_DO_SHOW(PROGRAM_VERSION, program_version);
+    SET_DO_SHOW(PROGRAMS, programs);
     SET_DO_SHOW(STREAMS, streams);
     SET_DO_SHOW(STREAM_DISPOSITION, stream_disposition);
+    SET_DO_SHOW(PROGRAM_STREAM_DISPOSITION, stream_disposition);
 
     if (do_bitexact && (do_show_program_version || do_show_library_versions)) {
         av_log(NULL, AV_LOG_ERROR,
@@ -2298,7 +2409,7 @@
             ffprobe_show_library_versions(wctx);
 
         if (!input_filename &&
-            ((do_show_format || do_show_streams || do_show_packets || do_show_error) ||
+            ((do_show_format || do_show_programs || do_show_streams || do_show_chapters || do_show_packets || do_show_error) ||
              (!do_show_program_version && !do_show_library_versions))) {
             show_usage();
             av_log(NULL, AV_LOG_ERROR, "You have to specify one input file.\n");
@@ -2323,5 +2434,5 @@
 
     avformat_network_deinit();
 
-    return ret;
+    return ret < 0;
 }
diff --git a/ffserver.c b/ffserver.c
index ac9627f..4215265 100644
--- a/ffserver.c
+++ b/ffserver.c
@@ -36,6 +36,7 @@
 #include "libavformat/network.h"
 #include "libavformat/os_support.h"
 #include "libavformat/rtpdec.h"
+#include "libavformat/rtpproto.h"
 #include "libavformat/rtsp.h"
 #include "libavformat/avio_internal.h"
 #include "libavformat/internal.h"
@@ -63,9 +64,6 @@
 #include <time.h>
 #include <sys/wait.h>
 #include <signal.h>
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
 
 #include "cmdutils.h"
 
@@ -3906,7 +3904,7 @@
         av->rc_buffer_aggressivity = 1.0;
 
         if (!av->rc_eq)
-            av->rc_eq = "tex^qComp";
+            av->rc_eq = av_strdup("tex^qComp");
         if (!av->i_quant_factor)
             av->i_quant_factor = -0.8;
         if (!av->b_quant_factor)
@@ -3954,32 +3952,6 @@
     return p->id;
 }
 
-/* simplistic plugin support */
-
-#if HAVE_DLOPEN
-static void load_module(const char *filename)
-{
-    void *dll;
-    void (*init_func)(void);
-    dll = dlopen(filename, RTLD_NOW);
-    if (!dll) {
-        fprintf(stderr, "Could not load module '%s' - %s\n",
-                filename, dlerror());
-        return;
-    }
-
-    init_func = dlsym(dll, "ffserver_module_init");
-    if (!init_func) {
-        fprintf(stderr,
-                "%s: init function 'ffserver_module_init()' not found\n",
-                filename);
-        dlclose(dll);
-    }
-
-    init_func();
-}
-#endif
-
 static int ffserver_opt_default(const char *opt, const char *arg,
                        AVCodecContext *avctx, int type)
 {
@@ -4151,7 +4123,7 @@
         } else if (!av_strcasecmp(cmd, "MaxBandwidth")) {
             int64_t llval;
             get_arg(arg, sizeof(arg), &p);
-            llval = atoll(arg);
+            llval = strtoll(arg, NULL, 10);
             if (llval < 10 || llval > 10000000) {
                 ERROR("Invalid MaxBandwidth: %s\n", arg);
             } else
@@ -4636,12 +4608,7 @@
                 redirect = NULL;
             }
         } else if (!av_strcasecmp(cmd, "LoadModule")) {
-            get_arg(arg, sizeof(arg), &p);
-#if HAVE_DLOPEN
-            load_module(arg);
-#else
-            ERROR("Module support not compiled into this version: '%s'\n", arg);
-#endif
+            ERROR("Loadable modules no longer supported\n");
         } else {
             ERROR("Incorrect keyword: '%s'\n", cmd);
         }
@@ -4706,6 +4673,8 @@
 {
     struct sigaction sigact = { { 0 } };
 
+    config_filename = av_strdup("/etc/ffserver.conf");
+
     parse_loglevel(argc, argv, options);
     av_register_all();
     avformat_network_init();
@@ -4716,9 +4685,6 @@
 
     parse_options(NULL, argc, argv, options, NULL);
 
-    if (!config_filename)
-        config_filename = av_strdup("/etc/ffserver.conf");
-
     unsetenv("http_proxy");             /* Kill the http_proxy */
 
     av_lfg_init(&random_state, av_get_random_seed());
diff --git a/libavcodec/012v.c b/libavcodec/012v.c
index 58e3cd6..f694769 100644
--- a/libavcodec/012v.c
+++ b/libavcodec/012v.c
@@ -49,6 +49,12 @@
         av_log(avctx, AV_LOG_ERROR, "Width 1 not supported.\n");
         return AVERROR_INVALIDDATA;
     }
+
+    if (   avctx->codec_tag == MKTAG('0', '1', '2', 'v')
+        && avpkt->size % avctx->height == 0
+        && avpkt->size / avctx->height * 3 >= width * 8)
+        stride = avpkt->size / avctx->height;
+
     if (avpkt->size < avctx->height * stride) {
         av_log(avctx, AV_LOG_ERROR, "Packet too small: %d instead of %d\n",
                avpkt->size, avctx->height * stride);
diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c
index cd22aa4..d66e130 100644
--- a/libavcodec/4xm.c
+++ b/libavcodec/4xm.c
@@ -24,6 +24,7 @@
  * 4XM codec.
  */
 
+#include "libavutil/avassert.h"
 #include "libavutil/frame.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
@@ -32,7 +33,6 @@
 #include "get_bits.h"
 #include "internal.h"
 
-#include "libavutil/avassert.h"
 
 #define BLOCK_TYPE_VLC_BITS 5
 #define ACDC_VLC_BITS 9
@@ -329,12 +329,12 @@
         }
         break;
     default:
-        av_assert2(0);
+        av_assert0(0);
     }
 }
 
-static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
-                           int log2w, int log2h, int stride)
+static int decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
+                          int log2w, int log2h, int stride)
 {
     const int index = size2index[log2h][log2w];
     const int h     = 1 << log2h;
@@ -343,57 +343,30 @@
                                BLOCK_TYPE_VLC_BITS, 1);
     uint16_t *start = (uint16_t *)f->last_picture->data[0];
     uint16_t *end   = start + stride * (f->avctx->height - h + 1) - (1 << log2w);
+    int ret;
+    int scale   = 1;
+    unsigned dc = 0;
 
-    av_assert2(code >= 0 && code <= 6);
+    av_assert0(code >= 0 && code <= 6 && log2w >= 0);
 
-    if (code == 0) {
-        if (bytestream2_get_bytes_left(&f->g) < 1) {
-            av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n");
-            return;
-        }
-        src += f->mv[bytestream2_get_byteu(&f->g)];
-        if (start > src || src > end) {
-            av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
-            return;
-        }
-        mcdc(dst, src, log2w, h, stride, 1, 0);
-    } else if (code == 1) {
+    if (code == 1) {
         log2h--;
-        decode_p_block(f, dst, src, log2w, log2h, stride);
-        decode_p_block(f, dst + (stride << log2h),
-                          src + (stride << log2h), log2w, log2h, stride);
+        if ((ret = decode_p_block(f, dst, src, log2w, log2h, stride)) < 0)
+            return ret;
+        return decode_p_block(f, dst + (stride << log2h),
+                              src + (stride << log2h),
+                              log2w, log2h, stride);
     } else if (code == 2) {
         log2w--;
-        decode_p_block(f, dst , src, log2w, log2h, stride);
-        decode_p_block(f, dst + (1 << log2w),
-                          src + (1 << log2w), log2w, log2h, stride);
-    } else if (code == 3 && f->version < 2) {
-        mcdc(dst, src, log2w, h, stride, 1, 0);
-    } else if (code == 4) {
-        if (bytestream2_get_bytes_left(&f->g) < 1) {
-            av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n");
-            return;
-        }
-        src += f->mv[bytestream2_get_byteu(&f->g)];
-        if (start > src || src > end) {
-            av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
-            return;
-        }
-        if (bytestream2_get_bytes_left(&f->g2) < 2){
-            av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
-            return;
-        }
-        mcdc(dst, src, log2w, h, stride, 1, bytestream2_get_le16u(&f->g2));
-    } else if (code == 5) {
-        if (bytestream2_get_bytes_left(&f->g2) < 2) {
-            av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
-            return;
-        }
-        mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16u(&f->g2));
+        if ((ret = decode_p_block(f, dst , src, log2w, log2h, stride)) < 0)
+            return ret;
+        return decode_p_block(f, dst + (1 << log2w),
+                              src + (1 << log2w),
+                              log2w, log2h, stride);
     } else if (code == 6) {
         if (bytestream2_get_bytes_left(&f->g2) < 4) {
             av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
-            return;
+            return AVERROR_INVALIDDATA;
         }
         if (log2w) {
             dst[0]      = bytestream2_get_le16u(&f->g2);
@@ -402,7 +375,43 @@
             dst[0]      = bytestream2_get_le16u(&f->g2);
             dst[stride] = bytestream2_get_le16u(&f->g2);
         }
+        return 0;
     }
+
+    if ((code&3)==0 && bytestream2_get_bytes_left(&f->g) < 1) {
+        av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (code == 0) {
+        src  += f->mv[bytestream2_get_byte(&f->g)];
+    } else if (code == 3 && f->version >= 2) {
+        return 0;
+    } else if (code == 4) {
+        src  += f->mv[bytestream2_get_byte(&f->g)];
+        if (bytestream2_get_bytes_left(&f->g2) < 2){
+            av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
+            return AVERROR_INVALIDDATA;
+        }
+        dc    = bytestream2_get_le16(&f->g2);
+    } else if (code == 5) {
+        if (bytestream2_get_bytes_left(&f->g2) < 2){
+            av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
+            return AVERROR_INVALIDDATA;
+        }
+        av_assert0(start <= src && src <= end);
+        scale = 0;
+        dc    = bytestream2_get_le16(&f->g2);
+    }
+
+    if (start > src || src > end) {
+        av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    mcdc(dst, src, log2w, h, stride, scale, dc);
+
+    return 0;
 }
 
 static int decode_p_frame(FourXContext *f, AVFrame *frame,
@@ -411,16 +420,28 @@
     int x, y;
     const int width  = f->avctx->width;
     const int height = f->avctx->height;
-    uint16_t *src    = (uint16_t *)f->last_picture->data[0];
     uint16_t *dst    = (uint16_t *)frame->data[0];
     const int stride =             frame->linesize[0] >> 1;
+    uint16_t *src;
     unsigned int bitstream_size, bytestream_size, wordstream_size, extra,
                  bytestream_offset, wordstream_offset;
+    int ret;
+
+    if (!f->last_picture->data[0]) {
+        if ((ret = ff_get_buffer(f->avctx, f->last_picture,
+                                 AV_GET_BUFFER_FLAG_REF)) < 0) {
+            return ret;
+        }
+        for (y=0; y<f->avctx->height; y++)
+            memset(f->last_picture->data[0] + y*f->last_picture->linesize[0], 0, 2*f->avctx->width);
+    }
+
+    src = (uint16_t *)f->last_picture->data[0];
 
     if (f->version > 1) {
         extra           = 20;
         if (length < extra)
-            return -1;
+            return AVERROR_INVALIDDATA;
         bitstream_size  = AV_RL32(buf + 8);
         wordstream_size = AV_RL32(buf + 12);
         bytestream_size = AV_RL32(buf + 16);
@@ -461,7 +482,8 @@
 
     for (y = 0; y < height; y += 8) {
         for (x = 0; x < width; x += 8)
-            decode_p_block(f, dst + x, src + x, 3, 3, stride);
+            if ((ret = decode_p_block(f, dst + x, src + x, 3, 3, stride)) < 0)
+                return ret;
         src += 8 * stride;
         dst += 8 * stride;
     }
@@ -484,8 +506,10 @@
 
     /* DC coef */
     val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
-    if (val >> 4)
+    if (val >> 4) {
         av_log(f->avctx, AV_LOG_ERROR, "error dc run != 0\n");
+        return AVERROR_INVALIDDATA;
+    }
 
     if (val)
         val = get_xbits(&f->gb, val);
@@ -503,7 +527,12 @@
         if (code == 0xf0) {
             i += 16;
         } else {
-            level = get_xbits(&f->gb, code & 0xf);
+            if (code & 0xf) {
+                level = get_xbits(&f->gb, code & 0xf);
+            } else {
+                av_log(f->avctx, AV_LOG_ERROR, "0 coeff\n");
+                return AVERROR_INVALIDDATA;
+            }
             i    += code >> 4;
             if (i >= 64) {
                 av_log(f->avctx, AV_LOG_ERROR, "run %d oveflow\n", i);
@@ -582,7 +611,8 @@
 }
 
 static const uint8_t *read_huffman_tables(FourXContext *f,
-                                          const uint8_t * const buf, int buf_size)
+                                          const uint8_t * const buf,
+                                          int buf_size)
 {
     int frequency[512] = { 0 };
     uint8_t flag[512];
@@ -605,6 +635,7 @@
             av_log(f->avctx, AV_LOG_ERROR, "invalid data in read_huffman_tables\n");
             return NULL;
         }
+
         for (i = start; i <= end; i++)
             frequency[i] = *ptr++;
         start = *ptr++;
@@ -711,9 +742,9 @@
             color[1] = bytestream2_get_le16u(&g3);
 
             if (color[0] & 0x8000)
-                av_log(NULL, AV_LOG_ERROR, "unk bit 1\n");
+                av_log(f->avctx, AV_LOG_ERROR, "unk bit 1\n");
             if (color[1] & 0x8000)
-                av_log(NULL, AV_LOG_ERROR, "unk bit 2\n");
+                av_log(f->avctx, AV_LOG_ERROR, "unk bit 2\n");
 
             color[2] = mix(color[0], color[1]);
             color[3] = mix(color[1], color[0]);
@@ -742,7 +773,10 @@
     unsigned int prestream_size;
     const uint8_t *prestream;
 
-    if (bitstream_size > (1<<26) || length < bitstream_size + 12) {
+    if (bitstream_size > (1 << 26))
+        return AVERROR_INVALIDDATA;
+
+    if (length < bitstream_size + 12) {
         av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n");
         return AVERROR_INVALIDDATA;
     }
@@ -751,14 +785,13 @@
     prestream      =             buf + bitstream_size + 12;
 
     if (prestream_size + bitstream_size + 12 != length
-        || bitstream_size > (1 << 26)
         || prestream_size > (1 << 26)) {
         av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n",
                prestream_size, bitstream_size, length);
         return AVERROR_INVALIDDATA;
     }
 
-    prestream = read_huffman_tables(f, prestream, buf + length - prestream);
+    prestream = read_huffman_tables(f, prestream, prestream_size);
     if (!prestream) {
         av_log(f->avctx, AV_LOG_ERROR, "Error reading Huffman tables.\n");
         return AVERROR_INVALIDDATA;
@@ -806,30 +839,38 @@
     AVFrame *picture      = data;
     int i, frame_4cc, frame_size, ret;
 
-    if (buf_size < 12)
+    if (buf_size < 20)
         return AVERROR_INVALIDDATA;
-    frame_4cc = AV_RL32(buf);
-    if (buf_size != AV_RL32(buf + 4) + 8 || buf_size < 20)
+
+    av_assert0(avctx->width % 16 == 0 && avctx->height % 16 == 0);
+
+    if (buf_size < AV_RL32(buf + 4) + 8) {
         av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n",
                buf_size, AV_RL32(buf + 4));
+        return AVERROR_INVALIDDATA;
+    }
+
+    frame_4cc = AV_RL32(buf);
 
     if (frame_4cc == AV_RL32("cfrm")) {
         int free_index       = -1;
+        int id, whole_size;
         const int data_size  = buf_size - 20;
-        const int id         = AV_RL32(buf + 12);
-        const int whole_size = AV_RL32(buf + 16);
         CFrameBuffer *cfrm;
 
-        if (data_size < 0 || whole_size < 0) {
-            av_log(f->avctx, AV_LOG_ERROR, "sizes invalid\n");
-            return AVERROR_INVALIDDATA;
-        }
-
         if (f->version <= 1) {
             av_log(f->avctx, AV_LOG_ERROR, "cfrm in version %d\n", f->version);
             return AVERROR_INVALIDDATA;
         }
 
+        id         = AV_RL32(buf + 12);
+        whole_size = AV_RL32(buf + 16);
+
+        if (data_size < 0 || whole_size < 0) {
+            av_log(f->avctx, AV_LOG_ERROR, "sizes invalid\n");
+            return AVERROR_INVALIDDATA;
+        }
+
         for (i = 0; i < CFRAME_BUFFER_COUNT; i++)
             if (f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number)
                 av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n",
@@ -870,6 +911,9 @@
                 av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n",
                        id, avctx->frame_number);
 
+            if (f->version <= 1)
+                return AVERROR_INVALIDDATA;
+
             cfrm->size = cfrm->id = 0;
             frame_4cc  = AV_RL32("pfrm");
         } else
@@ -900,14 +944,6 @@
             return ret;
         }
     } else if (frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")) {
-        if (!f->last_picture->data[0]) {
-            if ((ret = ff_get_buffer(avctx, f->last_picture,
-                                     AV_GET_BUFFER_FLAG_REF)) < 0)
-                return ret;
-            for (i=0; i<avctx->height; i++)
-                memset(f->last_picture->data[0] + i*f->last_picture->linesize[0], 0, 2*avctx->width);
-        }
-
         f->current_picture->pict_type = AV_PICTURE_TYPE_P;
         if ((ret = decode_p_frame(f, f->current_picture, buf, frame_size)) < 0) {
             av_log(f->avctx, AV_LOG_ERROR, "decode p frame failed\n");
diff --git a/libavcodec/8bps.c b/libavcodec/8bps.c
index a910551..0e09146 100644
--- a/libavcodec/8bps.c
+++ b/libavcodec/8bps.c
@@ -64,7 +64,7 @@
     unsigned char *pixptr, *pixptr_end;
     unsigned int height = avctx->height; // Real image height
     unsigned int dlen, p, row;
-    const unsigned char *lp, *dp;
+    const unsigned char *lp, *dp, *ep;
     unsigned char count;
     unsigned int planes     = c->planes;
     unsigned char *planemap = c->planemap;
@@ -73,6 +73,8 @@
     if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
         return ret;
 
+    ep = encoded + buf_size;
+
     /* Set data pointer after line lengths */
     dp = encoded + planes * (height << 1);
 
@@ -84,19 +86,19 @@
         for (row = 0; row < height; row++) {
             pixptr = frame->data[0] + row * frame->linesize[0] + planemap[p];
             pixptr_end = pixptr + frame->linesize[0];
-            if(lp - encoded + row*2 + 1 >= buf_size)
-                return -1;
+            if (ep - lp < row * 2 + 2)
+                return AVERROR_INVALIDDATA;
             dlen = av_be2ne16(*(const unsigned short *)(lp + row * 2));
             /* Decode a row of this plane */
             while (dlen > 0) {
-                if (dp + 1 >= buf + buf_size)
+                if (ep - dp <= 1)
                     return AVERROR_INVALIDDATA;
                 if ((count = *dp++) <= 127) {
                     count++;
                     dlen -= count + 1;
-                    if (pixptr + count * planes > pixptr_end)
+                    if (pixptr_end - pixptr < count * planes)
                         break;
-                    if (dp + count > buf + buf_size)
+                    if (ep - dp < count)
                         return AVERROR_INVALIDDATA;
                     while (count--) {
                         *pixptr = *dp++;
@@ -104,7 +106,7 @@
                     }
                 } else {
                     count = 257 - count;
-                    if (pixptr + count * planes > pixptr_end)
+                    if (pixptr_end - pixptr < count * planes)
                         break;
                     while (count--) {
                         *pixptr = *dp;
@@ -157,17 +159,7 @@
     case 32:
         avctx->pix_fmt = AV_PIX_FMT_RGB32;
         c->planes      = 4;
-#if HAVE_BIGENDIAN
-        c->planemap[0] = 1; // 1st plane is red
-        c->planemap[1] = 2; // 2nd plane is green
-        c->planemap[2] = 3; // 3rd plane is blue
-        c->planemap[3] = 0; // 4th plane is alpha
-#else
-        c->planemap[0] = 2; // 1st plane is red
-        c->planemap[1] = 1; // 2nd plane is green
-        c->planemap[2] = 0; // 3rd plane is blue
-        c->planemap[3] = 3; // 4th plane is alpha
-#endif
+        /* handle planemap setup later for decoding rgb24 data as rbg32 */
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "Error: Unsupported color depth: %u.\n",
@@ -175,6 +167,12 @@
         return AVERROR_INVALIDDATA;
     }
 
+    if (avctx->pix_fmt == AV_PIX_FMT_RGB32) {
+        c->planemap[0] = HAVE_BIGENDIAN ? 1 : 2; // 1st plane is red
+        c->planemap[1] = HAVE_BIGENDIAN ? 2 : 1; // 2nd plane is green
+        c->planemap[2] = HAVE_BIGENDIAN ? 3 : 0; // 3rd plane is blue
+        c->planemap[3] = HAVE_BIGENDIAN ? 0 : 3; // 4th plane is alpha
+    }
     return 0;
 }
 
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 6f98649..ec2cbfb 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -31,6 +31,8 @@
        resample2.o                                                      \
        utils.o                                                          \
 
+OBJS-$(HAVE_MSVCRT) += file_open.o
+
 # parts needed for many different codecs
 OBJS-$(CONFIG_AANDCTTABLES)            += aandcttab.o
 OBJS-$(CONFIG_AC3DSP)                  += ac3dsp.o
@@ -42,8 +44,10 @@
                                           simple_idct.o jrevdct.o
 OBJS-$(CONFIG_ENCODERS)                += faandct.o jfdctfst.o jfdctint.o
 OBJS-$(CONFIG_ERROR_RESILIENCE)        += error_resilience.o
+OBJS-$(CONFIG_EXIF)                    += exif.o tiff_common.o
 FFT-OBJS-$(CONFIG_HARDCODED_TABLES)    += cos_tables.o cos_fixed_tables.o
 OBJS-$(CONFIG_FFT)                     += avfft.o fft_fixed.o fft_float.o \
+                                          fft_fixed_32.o fft_init_table.o \
                                           $(FFT-OBJS-yes)
 OBJS-$(CONFIG_GOLOMB)                  += golomb.o
 OBJS-$(CONFIG_H264CHROMA)              += h264chroma.o
@@ -55,7 +59,7 @@
 OBJS-$(CONFIG_LIBXVID)                 += libxvid_rc.o
 OBJS-$(CONFIG_LPC)                     += lpc.o
 OBJS-$(CONFIG_LSP)                     += lsp.o
-OBJS-$(CONFIG_MDCT)                    += mdct_fixed.o mdct_float.o
+OBJS-$(CONFIG_MDCT)                    += mdct_fixed.o mdct_float.o mdct_fixed_32.o
 OBJS-$(CONFIG_MPEGAUDIO)               += mpegaudio.o mpegaudiodata.o   \
                                           mpegaudiodecheader.o
 OBJS-$(CONFIG_MPEGAUDIODSP)            += mpegaudiodsp.o                \
@@ -91,6 +95,7 @@
 OBJS-$(CONFIG_AC3_ENCODER)             += ac3enc_float.o ac3enc.o ac3tab.o \
                                           ac3.o kbdwin.o
 OBJS-$(CONFIG_AC3_FIXED_ENCODER)       += ac3enc_fixed.o ac3enc.o ac3tab.o ac3.o
+OBJS-$(CONFIG_AIC_DECODER)             += aic.o
 OBJS-$(CONFIG_ALAC_DECODER)            += alac.o alac_data.o
 OBJS-$(CONFIG_ALAC_ENCODER)            += alacenc.o alac_data.o
 OBJS-$(CONFIG_ALS_DECODER)             += alsdec.o bgmc.o mpeg4audio.o
@@ -207,6 +212,7 @@
 OBJS-$(CONFIG_FOURXM_DECODER)          += 4xm.o
 OBJS-$(CONFIG_FRAPS_DECODER)           += fraps.o
 OBJS-$(CONFIG_FRWU_DECODER)            += frwu.o
+OBJS-$(CONFIG_G2M_DECODER)             += g2meet.o mjpeg.o
 OBJS-$(CONFIG_G723_1_DECODER)          += g723_1.o acelp_vectors.o \
                                           celp_filters.o celp_math.o
 OBJS-$(CONFIG_G723_1_ENCODER)          += g723_1.o acelp_vectors.o celp_math.o
@@ -242,8 +248,8 @@
 OBJS-$(CONFIG_INTERPLAY_DPCM_DECODER)  += dpcm.o
 OBJS-$(CONFIG_INTERPLAY_VIDEO_DECODER) += interplayvideo.o
 OBJS-$(CONFIG_JACOSUB_DECODER)         += jacosubdec.o ass.o
-OBJS-$(CONFIG_J2K_DECODER)             += j2kdec.o mqcdec.o mqc.o j2k.o j2k_dwt.o
-OBJS-$(CONFIG_J2K_ENCODER)             += j2kenc.o mqcenc.o mqc.o j2k.o j2k_dwt.o
+OBJS-$(CONFIG_JPEG2000_ENCODER)        += j2kenc.o mqcenc.o mqc.o jpeg2000.o \
+                                          jpeg2000dwt.o
 OBJS-$(CONFIG_JPEG2000_DECODER)        += jpeg2000dec.o jpeg2000.o      \
                                           jpeg2000dwt.o mqcdec.o mqc.o
 OBJS-$(CONFIG_JPEGLS_DECODER)          += jpeglsdec.o jpegls.o \
@@ -258,6 +264,8 @@
 OBJS-$(CONFIG_MACE3_DECODER)           += mace.o
 OBJS-$(CONFIG_MACE6_DECODER)           += mace.o
 OBJS-$(CONFIG_MDEC_DECODER)            += mdec.o mpeg12.o mpeg12data.o
+OBJS-$(CONFIG_METASOUND_DECODER)       += metasound.o metasound_data.o \
+                                          twinvq.o
 OBJS-$(CONFIG_MICRODVD_DECODER)        += microdvddec.o ass.o
 OBJS-$(CONFIG_MIMIC_DECODER)           += mimic.o
 OBJS-$(CONFIG_MJPEG_DECODER)           += mjpegdec.o mjpeg.o
@@ -374,6 +382,7 @@
 OBJS-$(CONFIG_RV40_DECODER)            += rv40.o rv34.o rv34dsp.o rv40dsp.o
 OBJS-$(CONFIG_SAMI_DECODER)            += samidec.o ass.o
 OBJS-$(CONFIG_S302M_DECODER)           += s302m.o
+OBJS-$(CONFIG_S302M_ENCODER)           += s302menc.o
 OBJS-$(CONFIG_SANM_DECODER)            += sanm.o
 OBJS-$(CONFIG_SGI_DECODER)             += sgidec.o
 OBJS-$(CONFIG_SGI_ENCODER)             += sgienc.o rle.o
@@ -386,6 +395,7 @@
 OBJS-$(CONFIG_SMACKAUD_DECODER)        += smacker.o
 OBJS-$(CONFIG_SMACKER_DECODER)         += smacker.o
 OBJS-$(CONFIG_SMC_DECODER)             += smc.o
+OBJS-$(CONFIG_SMVJPEG_DECODER)         += smvjpegdec.o
 OBJS-$(CONFIG_SNOW_DECODER)            += snowdec.o snow.o snow_dwt.o
 OBJS-$(CONFIG_SNOW_ENCODER)            += snowenc.o snow.o snow_dwt.o             \
                                           h263.o ituh263enc.o
@@ -417,7 +427,7 @@
 OBJS-$(CONFIG_THEORA_DECODER)          += xiph.o
 OBJS-$(CONFIG_THP_DECODER)             += mjpegdec.o mjpeg.o
 OBJS-$(CONFIG_TIERTEXSEQVIDEO_DECODER) += tiertexseqv.o
-OBJS-$(CONFIG_TIFF_DECODER)            += tiff.o lzw.o faxcompr.o tiff_data.o
+OBJS-$(CONFIG_TIFF_DECODER)            += tiff.o lzw.o faxcompr.o tiff_data.o tiff_common.o
 OBJS-$(CONFIG_TIFF_ENCODER)            += tiffenc.o rle.o lzwenc.o tiff_data.o
 OBJS-$(CONFIG_TMV_DECODER)             += tmv.o cga_data.o
 OBJS-$(CONFIG_TRUEHD_DECODER)          += mlpdec.o mlpdsp.o
@@ -426,8 +436,9 @@
 OBJS-$(CONFIG_TRUESPEECH_DECODER)      += truespeech.o
 OBJS-$(CONFIG_TSCC_DECODER)            += tscc.o msrledec.o
 OBJS-$(CONFIG_TSCC2_DECODER)           += tscc2.o
-OBJS-$(CONFIG_TTA_DECODER)             += tta.o
-OBJS-$(CONFIG_TWINVQ_DECODER)          += twinvq.o
+OBJS-$(CONFIG_TTA_DECODER)             += tta.o ttadata.o
+OBJS-$(CONFIG_TTA_ENCODER)             += ttaenc.o ttadata.o
+OBJS-$(CONFIG_TWINVQ_DECODER)          += twinvqdec.o twinvq.o
 OBJS-$(CONFIG_TXD_DECODER)             += txd.o s3tc.o
 OBJS-$(CONFIG_ULTI_DECODER)            += ulti.o
 OBJS-$(CONFIG_UTVIDEO_DECODER)         += utvideodec.o utvideo.o
@@ -445,7 +456,7 @@
 OBJS-$(CONFIG_VBLE_DECODER)            += vble.o
 OBJS-$(CONFIG_VC1_DECODER)             += vc1dec.o vc1.o vc1data.o vc1dsp.o \
                                           msmpeg4dec.o msmpeg4.o msmpeg4data.o \
-                                          intrax8.o intrax8dsp.o
+                                          intrax8.o intrax8dsp.o wmv2dsp.o
 OBJS-$(CONFIG_VCR1_DECODER)            += vcr1.o
 OBJS-$(CONFIG_VMDAUDIO_DECODER)        += vmdav.o
 OBJS-$(CONFIG_VMDVIDEO_DECODER)        += vmdav.o
@@ -463,6 +474,7 @@
 OBJS-$(CONFIG_VPLAYER_DECODER)         += textdec.o ass.o
 OBJS-$(CONFIG_VQA_DECODER)             += vqavideo.o
 OBJS-$(CONFIG_WAVPACK_DECODER)         += wavpack.o
+OBJS-$(CONFIG_WAVPACK_ENCODER)         += wavpackenc.o
 OBJS-$(CONFIG_WEBP_DECODER)            += vp8.o vp8dsp.o vp56rac.o
 OBJS-$(CONFIG_WEBVTT_DECODER)          += webvttdec.o
 OBJS-$(CONFIG_WMALOSSLESS_DECODER)     += wmalosslessdec.o wma_common.o
@@ -569,6 +581,7 @@
 OBJS-$(CONFIG_ADPCM_ADX_ENCODER)          += adxenc.o adx.o
 OBJS-$(CONFIG_ADPCM_AFC_DECODER)          += adpcm.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_CT_DECODER)           += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_DTK_DECODER)          += adpcm.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_EA_DECODER)           += adpcm.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_EA_MAXIS_XA_DECODER)  += adpcm.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_EA_R1_DECODER)        += adpcm.o adpcm_data.o
@@ -589,6 +602,7 @@
 OBJS-$(CONFIG_ADPCM_IMA_OKI_DECODER)      += adpcm.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_IMA_QT_DECODER)       += adpcm.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_IMA_QT_ENCODER)       += adpcmenc.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_RAD_DECODER)      += adpcm.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_IMA_SMJPEG_DECODER)   += adpcm.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_IMA_WAV_DECODER)      += adpcm.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_IMA_WAV_ENCODER)      += adpcmenc.o adpcm_data.o
@@ -615,12 +629,12 @@
 OBJS-$(CONFIG_H264_VDPAU_HWACCEL)         += vdpau_h264.o
 OBJS-$(CONFIG_MPEG1_VDPAU_HWACCEL)        += vdpau_mpeg12.o
 OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL)        += dxva2_mpeg2.o
-OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL)        += vaapi_mpeg2.o
+OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL)        += vaapi_mpeg2.o vaapi_mpeg.o
 OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL)        += vdpau_mpeg12.o
-OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL)        += vaapi_mpeg4.o
+OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL)        += vaapi_mpeg4.o vaapi_mpeg.o
 OBJS-$(CONFIG_MPEG4_VDPAU_HWACCEL)        += vdpau_mpeg4.o
 OBJS-$(CONFIG_VC1_DXVA2_HWACCEL)          += dxva2_vc1.o
-OBJS-$(CONFIG_VC1_VAAPI_HWACCEL)          += vaapi_vc1.o
+OBJS-$(CONFIG_VC1_VAAPI_HWACCEL)          += vaapi_vc1.o vaapi_mpeg.o
 OBJS-$(CONFIG_VC1_VDPAU_HWACCEL)          += vdpau_vc1.o
 
 # libavformat dependencies
@@ -670,6 +684,7 @@
 OBJS-$(CONFIG_LIBAACPLUS_ENCODER)         += libaacplus.o
 OBJS-$(CONFIG_LIBCELT_DECODER)            += libcelt_dec.o
 OBJS-$(CONFIG_LIBFAAC_ENCODER)            += libfaac.o
+OBJS-$(CONFIG_LIBFDK_AAC_DECODER)         += libfdk-aacdec.o
 OBJS-$(CONFIG_LIBFDK_AAC_ENCODER)         += libfdk-aacenc.o
 OBJS-$(CONFIG_LIBGSM_DECODER)             += libgsm.o
 OBJS-$(CONFIG_LIBGSM_ENCODER)             += libgsm.o
@@ -708,6 +723,7 @@
 OBJS-$(CONFIG_LIBVPX_VP8_ENCODER)         += libvpxenc.o
 OBJS-$(CONFIG_LIBVPX_VP9_DECODER)         += libvpxdec.o
 OBJS-$(CONFIG_LIBVPX_VP9_ENCODER)         += libvpxenc.o
+OBJS-$(CONFIG_LIBWAVPACK_ENCODER)         += libwavpackenc.o
 OBJS-$(CONFIG_LIBX264_ENCODER)            += libx264.o
 OBJS-$(CONFIG_LIBXAVS_ENCODER)            += libxavs.o
 OBJS-$(CONFIG_LIBXVID_ENCODER)            += libxvid.o
@@ -797,14 +813,13 @@
 SKIPHEADERS-$(CONFIG_MPEG_XVMC_DECODER) += xvmc.h
 SKIPHEADERS-$(CONFIG_VAAPI)            += vaapi_internal.h
 SKIPHEADERS-$(CONFIG_VDA)              += vda.h
-SKIPHEADERS-$(CONFIG_VDPAU)            += vdpau.h
-SKIPHEADERS-$(HAVE_OS2THREADS)         += os2threads.h
-SKIPHEADERS-$(HAVE_W32THREADS)         += w32pthreads.h
+SKIPHEADERS-$(CONFIG_VDPAU)            += vdpau.h vdpau_internal.h
 
 TESTPROGS = cabac                                                       \
             dct                                                         \
             fft                                                         \
             fft-fixed                                                   \
+            fft-fixed32                                                 \
             golomb                                                      \
             iirfilter                                                   \
             imgconvert                                                  \
diff --git a/libavcodec/aac.h b/libavcodec/aac.h
index d586e27..209c715 100644
--- a/libavcodec/aac.h
+++ b/libavcodec/aac.h
@@ -157,7 +157,7 @@
 typedef struct IndividualChannelStream {
     uint8_t max_sfb;            ///< number of scalefactor bands per group
     enum WindowSequence window_sequence[2];
-    uint8_t use_kb_window[2];   ///< If set, use Kaiser-Bessel window, otherwise use a sinus window.
+    uint8_t use_kb_window[2];   ///< If set, use Kaiser-Bessel window, otherwise use a sine window.
     int num_window_groups;
     uint8_t group_len[8];
     LongTermPrediction ltp;
diff --git a/libavcodec/aac_tablegen.h b/libavcodec/aac_tablegen.h
index 2b080ba..1c19a15 100644
--- a/libavcodec/aac_tablegen.h
+++ b/libavcodec/aac_tablegen.h
@@ -35,7 +35,7 @@
 {
     int i;
     for (i = 0; i < 428; i++)
-        ff_aac_pow2sf_tab[i] = pow(2, (i - POW_SF2_ZERO) / 4.);
+        ff_aac_pow2sf_tab[i] = pow(2, (i - POW_SF2_ZERO) / 4.0);
 }
 #endif /* CONFIG_HARDCODED_TABLES */
 
diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c
index 994de28..45fbc2d 100644
--- a/libavcodec/aaccoder.c
+++ b/libavcodec/aaccoder.c
@@ -710,7 +710,7 @@
                                           const float lambda)
 {
     int start = 0, i, w, w2, g;
-    int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels;
+    int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels * (lambda / 120.f);
     float dists[128] = { 0 }, uplims[128];
     float maxvals[128];
     int fflag, minscaler;
diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
index a22eb20..12e09f0 100644
--- a/libavcodec/aacdec.c
+++ b/libavcodec/aacdec.c
@@ -148,6 +148,8 @@
                                  enum ChannelPosition che_pos,
                                  int type, int id, int *channels)
 {
+    if (*channels >= MAX_CHANNELS)
+        return AVERROR_INVALIDDATA;
     if (che_pos) {
         if (!ac->che[type][id]) {
             if (!(ac->che[type][id] = av_mallocz(sizeof(ChannelElement))))
@@ -213,28 +215,39 @@
 
 static int assign_pair(struct elem_to_channel e2c_vec[MAX_ELEM_ID],
                        uint8_t (*layout_map)[3], int offset, uint64_t left,
-    uint64_t right, int pos)
+                       uint64_t right, int pos)
 {
     if (layout_map[offset][0] == TYPE_CPE) {
         e2c_vec[offset] = (struct elem_to_channel) {
-            .av_position = left | right, .syn_ele = TYPE_CPE,
-            .elem_id = layout_map[offset    ][1], .aac_position = pos };
+            .av_position  = left | right,
+            .syn_ele      = TYPE_CPE,
+            .elem_id      = layout_map[offset][1],
+            .aac_position = pos
+        };
         return 1;
     } else {
-        e2c_vec[offset]   = (struct elem_to_channel) {
-            .av_position = left, .syn_ele = TYPE_SCE,
-            .elem_id = layout_map[offset    ][1], .aac_position = pos };
+        e2c_vec[offset] = (struct elem_to_channel) {
+            .av_position  = left,
+            .syn_ele      = TYPE_SCE,
+            .elem_id      = layout_map[offset][1],
+            .aac_position = pos
+        };
         e2c_vec[offset + 1] = (struct elem_to_channel) {
-            .av_position = right, .syn_ele = TYPE_SCE,
-            .elem_id = layout_map[offset + 1][1], .aac_position = pos };
+            .av_position  = right,
+            .syn_ele      = TYPE_SCE,
+            .elem_id      = layout_map[offset + 1][1],
+            .aac_position = pos
+        };
         return 2;
     }
 }
 
-static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos, int *current) {
+static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos,
+                                 int *current)
+{
     int num_pos_channels = 0;
-    int first_cpe = 0;
-    int sce_parity = 0;
+    int first_cpe        = 0;
+    int sce_parity       = 0;
     int i;
     for (i = *current; i < tags; i++) {
         if (layout_map[i][2] != pos)
@@ -248,7 +261,7 @@
                 }
             }
             num_pos_channels += 2;
-            first_cpe = 1;
+            first_cpe         = 1;
         } else {
             num_pos_channels++;
             sce_parity ^= 1;
@@ -256,7 +269,7 @@
     }
     if (sce_parity &&
         ((pos == AAC_CHANNEL_FRONT && first_cpe) || pos == AAC_CHANNEL_SIDE))
-            return -1;
+        return -1;
     *current = i;
     return num_pos_channels;
 }
@@ -264,7 +277,7 @@
 static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags)
 {
     int i, n, total_non_cc_elements;
-    struct elem_to_channel e2c_vec[4*MAX_ELEM_ID] = {{ 0 }};
+    struct elem_to_channel e2c_vec[4 * MAX_ELEM_ID] = { { 0 } };
     int num_front_channels, num_side_channels, num_back_channels;
     uint64_t layout;
 
@@ -288,8 +301,11 @@
     i = 0;
     if (num_front_channels & 1) {
         e2c_vec[i] = (struct elem_to_channel) {
-            .av_position = AV_CH_FRONT_CENTER, .syn_ele = TYPE_SCE,
-            .elem_id = layout_map[i][1], .aac_position = AAC_CHANNEL_FRONT };
+            .av_position  = AV_CH_FRONT_CENTER,
+            .syn_ele      = TYPE_SCE,
+            .elem_id      = layout_map[i][1],
+            .aac_position = AAC_CHANNEL_FRONT
+        };
         i++;
         num_front_channels--;
     }
@@ -346,22 +362,31 @@
     }
     if (num_back_channels) {
         e2c_vec[i] = (struct elem_to_channel) {
-          .av_position = AV_CH_BACK_CENTER, .syn_ele = TYPE_SCE,
-          .elem_id = layout_map[i][1], .aac_position = AAC_CHANNEL_BACK };
+            .av_position  = AV_CH_BACK_CENTER,
+            .syn_ele      = TYPE_SCE,
+            .elem_id      = layout_map[i][1],
+            .aac_position = AAC_CHANNEL_BACK
+        };
         i++;
         num_back_channels--;
     }
 
     if (i < tags && layout_map[i][2] == AAC_CHANNEL_LFE) {
         e2c_vec[i] = (struct elem_to_channel) {
-          .av_position = AV_CH_LOW_FREQUENCY, .syn_ele = TYPE_LFE,
-          .elem_id = layout_map[i][1], .aac_position = AAC_CHANNEL_LFE };
+            .av_position  = AV_CH_LOW_FREQUENCY,
+            .syn_ele      = TYPE_LFE,
+            .elem_id      = layout_map[i][1],
+            .aac_position = AAC_CHANNEL_LFE
+        };
         i++;
     }
     while (i < tags && layout_map[i][2] == AAC_CHANNEL_LFE) {
         e2c_vec[i] = (struct elem_to_channel) {
-          .av_position = UINT64_MAX, .syn_ele = TYPE_LFE,
-          .elem_id = layout_map[i][1], .aac_position = AAC_CHANNEL_LFE };
+            .av_position  = UINT64_MAX,
+            .syn_ele      = TYPE_LFE,
+            .elem_id      = layout_map[i][1],
+            .aac_position = AAC_CHANNEL_LFE
+        };
         i++;
     }
 
@@ -369,12 +394,11 @@
     total_non_cc_elements = n = i;
     do {
         int next_n = 0;
-        for (i = 1; i < n; i++) {
-            if (e2c_vec[i-1].av_position > e2c_vec[i].av_position) {
-                FFSWAP(struct elem_to_channel, e2c_vec[i-1], e2c_vec[i]);
+        for (i = 1; i < n; i++)
+            if (e2c_vec[i - 1].av_position > e2c_vec[i].av_position) {
+                FFSWAP(struct elem_to_channel, e2c_vec[i - 1], e2c_vec[i]);
                 next_n = i;
             }
-        }
         n = next_n;
     } while (n > 0);
 
@@ -416,12 +440,13 @@
 }
 
 /**
- * Configure output channel order based on the current program configuration element.
+ * Configure output channel order based on the current program
+ * configuration element.
  *
  * @return  Returns error status. 0 - OK, !0 - error
  */
 static int output_configure(AACContext *ac,
-                            uint8_t layout_map[MAX_ELEM_ID*4][3], int tags,
+                            uint8_t layout_map[MAX_ELEM_ID * 4][3], int tags,
                             enum OCStatus oc_type, int get_new_frame)
 {
     AVCodecContext *avctx = ac->avctx;
@@ -457,8 +482,8 @@
 
     memcpy(ac->tag_che_map, ac->che, 4 * MAX_ELEM_ID * sizeof(ac->che[0][0]));
     if (layout) avctx->channel_layout = layout;
-    ac->oc[1].channel_layout = layout;
-    avctx->channels = ac->oc[1].channels = channels;
+                            ac->oc[1].channel_layout = layout;
+    avctx->channels       = ac->oc[1].channels       = channels;
     ac->oc[1].status = oc_type;
 
     if (get_new_frame) {
@@ -493,36 +518,40 @@
  * @return  Returns error status. 0 - OK, !0 - error
  */
 static int set_default_channel_config(AVCodecContext *avctx,
-                                              uint8_t (*layout_map)[3],
-                                              int *tags,
-                                              int channel_config)
+                                      uint8_t (*layout_map)[3],
+                                      int *tags,
+                                      int channel_config)
 {
     if (channel_config < 1 || channel_config > 7) {
-        av_log(avctx, AV_LOG_ERROR, "invalid default channel configuration (%d)\n",
+        av_log(avctx, AV_LOG_ERROR,
+               "invalid default channel configuration (%d)\n",
                channel_config);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     *tags = tags_per_config[channel_config];
-    memcpy(layout_map, aac_channel_layout_map[channel_config-1], *tags * sizeof(*layout_map));
+    memcpy(layout_map, aac_channel_layout_map[channel_config - 1],
+           *tags * sizeof(*layout_map));
     return 0;
 }
 
 static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
 {
-    // For PCE based channel configurations map the channels solely based on tags.
+    /* For PCE based channel configurations map the channels solely based
+     * on tags. */
     if (!ac->oc[1].m4ac.chan_config) {
         return ac->tag_che_map[type][elem_id];
     }
     // Allow single CPE stereo files to be signalled with mono configuration.
-    if (!ac->tags_mapped && type == TYPE_CPE && ac->oc[1].m4ac.chan_config == 1) {
+    if (!ac->tags_mapped && type == TYPE_CPE &&
+        ac->oc[1].m4ac.chan_config == 1) {
         uint8_t layout_map[MAX_ELEM_ID*4][3];
         int layout_map_tags;
         push_output_configuration(ac);
 
         av_log(ac->avctx, AV_LOG_DEBUG, "mono with CPE\n");
 
-        if (set_default_channel_config(ac->avctx, layout_map, &layout_map_tags,
-                                       2) < 0)
+        if (set_default_channel_config(ac->avctx, layout_map,
+                                       &layout_map_tags, 2) < 0)
             return NULL;
         if (output_configure(ac, layout_map, layout_map_tags,
                              OC_TRIAL_FRAME, 1) < 0)
@@ -532,15 +561,16 @@
         ac->oc[1].m4ac.ps = 0;
     }
     // And vice-versa
-    if (!ac->tags_mapped && type == TYPE_SCE && ac->oc[1].m4ac.chan_config == 2) {
-        uint8_t layout_map[MAX_ELEM_ID*4][3];
+    if (!ac->tags_mapped && type == TYPE_SCE &&
+        ac->oc[1].m4ac.chan_config == 2) {
+        uint8_t layout_map[MAX_ELEM_ID * 4][3];
         int layout_map_tags;
         push_output_configuration(ac);
 
         av_log(ac->avctx, AV_LOG_DEBUG, "stereo with SCE\n");
 
-        if (set_default_channel_config(ac->avctx, layout_map, &layout_map_tags,
-                                       1) < 0)
+        if (set_default_channel_config(ac->avctx, layout_map,
+                                       &layout_map_tags, 1) < 0)
             return NULL;
         if (output_configure(ac, layout_map, layout_map_tags,
                              OC_TRIAL_FRAME, 1) < 0)
@@ -550,7 +580,8 @@
         if (ac->oc[1].m4ac.sbr)
             ac->oc[1].m4ac.ps = -1;
     }
-    // For indexed channel configurations map the channels solely based on position.
+    /* For indexed channel configurations map the channels solely based
+     * on position. */
     switch (ac->oc[1].m4ac.chan_config) {
     case 7:
         if (ac->tags_mapped == 3 && type == TYPE_CPE) {
@@ -558,9 +589,12 @@
             return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][2];
         }
     case 6:
-        /* Some streams incorrectly code 5.1 audio as SCE[0] CPE[0] CPE[1] SCE[1]
-           instead of SCE[0] CPE[0] CPE[1] LFE[0]. If we seem to have
-           encountered such a stream, transfer the LFE[0] element to the SCE[1]'s mapping */
+        /* Some streams incorrectly code 5.1 audio as
+         * SCE[0] CPE[0] CPE[1] SCE[1]
+         * instead of
+         * SCE[0] CPE[0] CPE[1] LFE[0].
+         * If we seem to have encountered such a stream, transfer
+         * the LFE[0] element to the SCE[1]'s mapping */
         if (ac->tags_mapped == tags_per_config[ac->oc[1].m4ac.chan_config] - 1 && (type == TYPE_LFE || type == TYPE_SCE)) {
             ac->tags_mapped++;
             return ac->tag_che_map[type][elem_id] = ac->che[TYPE_LFE][0];
@@ -571,13 +605,16 @@
             return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][1];
         }
     case 4:
-        if (ac->tags_mapped == 2 && ac->oc[1].m4ac.chan_config == 4 && type == TYPE_SCE) {
+        if (ac->tags_mapped == 2 &&
+            ac->oc[1].m4ac.chan_config == 4 &&
+            type == TYPE_SCE) {
             ac->tags_mapped++;
             return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][1];
         }
     case 3:
     case 2:
-        if (ac->tags_mapped == (ac->oc[1].m4ac.chan_config != 2) && type == TYPE_CPE) {
+        if (ac->tags_mapped == (ac->oc[1].m4ac.chan_config != 2) &&
+            type == TYPE_CPE) {
             ac->tags_mapped++;
             return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][0];
         } else if (ac->oc[1].m4ac.chan_config == 2) {
@@ -594,7 +631,8 @@
 }
 
 /**
- * Decode an array of 4 bit element IDs, optionally interleaved with a stereo/mono switching bit.
+ * Decode an array of 4 bit element IDs, optionally interleaved with a
+ * stereo/mono switching bit.
  *
  * @param type speaker type/position for these channels
  */
@@ -636,7 +674,8 @@
                       uint8_t (*layout_map)[3],
                       GetBitContext *gb)
 {
-    int num_front, num_side, num_back, num_lfe, num_assoc_data, num_cc, sampling_index;
+    int num_front, num_side, num_back, num_lfe, num_assoc_data, num_cc;
+    int sampling_index;
     int comment_len;
     int tags;
 
@@ -644,7 +683,9 @@
 
     sampling_index = get_bits(gb, 4);
     if (m4ac->sampling_index != sampling_index)
-        av_log(avctx, AV_LOG_WARNING, "Sample rate index in program config element does not match the sample rate index configured by the container.\n");
+        av_log(avctx, AV_LOG_WARNING,
+               "Sample rate index in program config element does not "
+               "match the sample rate index configured by the container.\n");
 
     num_front       = get_bits(gb, 4);
     num_side        = get_bits(gb, 4);
@@ -685,7 +726,7 @@
     comment_len = get_bits(gb, 8) * 8;
     if (get_bits_left(gb) < comment_len) {
         av_log(avctx, AV_LOG_ERROR, "decode_pce: " overread_err);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     skip_bits_long(gb, comment_len);
     return tags;
@@ -727,7 +768,8 @@
         if (tags < 0)
             return tags;
     } else {
-        if ((ret = set_default_channel_config(avctx, layout_map, &tags, channel_config)))
+        if ((ret = set_default_channel_config(avctx, layout_map,
+                                              &tags, channel_config)))
             return ret;
     }
 
@@ -749,7 +791,7 @@
         case AOT_ER_AAC_LTP:
         case AOT_ER_AAC_SCALABLE:
         case AOT_ER_AAC_LD:
-            skip_bits(gb, 3);  /* aacSectionDataResilienceFlag
+            skip_bits(gb, 3);      /* aacSectionDataResilienceFlag
                                     * aacScalefactorDataResilienceFlag
                                     * aacSpectralDataResilienceFlag
                                     */
@@ -779,22 +821,24 @@
                                         int sync_extension)
 {
     GetBitContext gb;
-    int i;
-    int ret;
+    int i, ret;
 
     av_dlog(avctx, "audio specific config size %d\n", bit_size >> 3);
     for (i = 0; i < bit_size >> 3; i++)
-         av_dlog(avctx, "%02x ", data[i]);
+        av_dlog(avctx, "%02x ", data[i]);
     av_dlog(avctx, "\n");
 
     if ((ret = init_get_bits(&gb, data, bit_size)) < 0)
         return ret;
 
-    if ((i = avpriv_mpeg4audio_get_config(m4ac, data, bit_size, sync_extension)) < 0)
-        return -1;
+    if ((i = avpriv_mpeg4audio_get_config(m4ac, data, bit_size,
+                                          sync_extension)) < 0)
+        return AVERROR_INVALIDDATA;
     if (m4ac->sampling_index > 12) {
-        av_log(avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", m4ac->sampling_index);
-        return -1;
+        av_log(avctx, AV_LOG_ERROR,
+               "invalid sampling rate index %d\n",
+               m4ac->sampling_index);
+        return AVERROR_INVALIDDATA;
     }
 
     skip_bits_long(&gb, i);
@@ -803,18 +847,23 @@
     case AOT_AAC_MAIN:
     case AOT_AAC_LC:
     case AOT_AAC_LTP:
-        if (decode_ga_specific_config(ac, avctx, &gb, m4ac, m4ac->chan_config))
-            return -1;
+        if ((ret = decode_ga_specific_config(ac, avctx, &gb,
+                                            m4ac, m4ac->chan_config)) < 0)
+            return ret;
         break;
     default:
-        av_log(avctx, AV_LOG_ERROR, "Audio object type %s%d is not supported.\n",
-               m4ac->sbr == 1? "SBR+" : "", m4ac->object_type);
-        return -1;
+        av_log(avctx, AV_LOG_ERROR,
+               "Audio object type %s%d is not supported.\n",
+               m4ac->sbr == 1 ? "SBR+" : "",
+               m4ac->object_type);
+        return AVERROR(ENOSYS);
     }
 
-    av_dlog(avctx, "AOT %d chan config %d sampling index %d (%d) SBR %d PS %d\n",
+    av_dlog(avctx,
+            "AOT %d chan config %d sampling index %d (%d) SBR %d PS %d\n",
             m4ac->object_type, m4ac->chan_config, m4ac->sampling_index,
-            m4ac->sample_rate, m4ac->sbr, m4ac->ps);
+            m4ac->sample_rate, m4ac->sbr,
+            m4ac->ps);
 
     return get_bits_count(&gb);
 }
@@ -872,10 +921,12 @@
         reset_predict_state(&ps[i]);
 }
 
-#define AAC_INIT_VLC_STATIC(num, size) \
-    INIT_VLC_STATIC(&vlc_spectral[num], 8, ff_aac_spectral_sizes[num], \
-         ff_aac_spectral_bits[num], sizeof( ff_aac_spectral_bits[num][0]), sizeof( ff_aac_spectral_bits[num][0]), \
-        ff_aac_spectral_codes[num], sizeof(ff_aac_spectral_codes[num][0]), sizeof(ff_aac_spectral_codes[num][0]), \
+#define AAC_INIT_VLC_STATIC(num, size)                                     \
+    INIT_VLC_STATIC(&vlc_spectral[num], 8, ff_aac_spectral_sizes[num],     \
+         ff_aac_spectral_bits[num], sizeof(ff_aac_spectral_bits[num][0]),  \
+                                    sizeof(ff_aac_spectral_bits[num][0]),  \
+        ff_aac_spectral_codes[num], sizeof(ff_aac_spectral_codes[num][0]), \
+                                    sizeof(ff_aac_spectral_codes[num][0]), \
         size);
 
 static void aacdec_init(AACContext *ac);
@@ -883,6 +934,7 @@
 static av_cold int aac_decode_init(AVCodecContext *avctx)
 {
     AACContext *ac = avctx->priv_data;
+    int ret;
 
     ac->avctx = avctx;
     ac->oc[1].m4ac.sample_rate = avctx->sample_rate;
@@ -892,10 +944,11 @@
     avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
 
     if (avctx->extradata_size > 0) {
-        if (decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac,
-                                         avctx->extradata,
-                                         avctx->extradata_size*8, 1) < 0)
-            return -1;
+        if ((ret = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac,
+                                                avctx->extradata,
+                                                avctx->extradata_size * 8,
+                                                1)) < 0)
+            return ret;
     } else {
         int sr, i;
         uint8_t layout_map[MAX_ELEM_ID*4][3];
@@ -952,9 +1005,14 @@
 
     ff_aac_tableinit();
 
-    INIT_VLC_STATIC(&vlc_scalefactors,7,FF_ARRAY_ELEMS(ff_aac_scalefactor_code),
-                    ff_aac_scalefactor_bits, sizeof(ff_aac_scalefactor_bits[0]), sizeof(ff_aac_scalefactor_bits[0]),
-                    ff_aac_scalefactor_code, sizeof(ff_aac_scalefactor_code[0]), sizeof(ff_aac_scalefactor_code[0]),
+    INIT_VLC_STATIC(&vlc_scalefactors, 7,
+                    FF_ARRAY_ELEMS(ff_aac_scalefactor_code),
+                    ff_aac_scalefactor_bits,
+                    sizeof(ff_aac_scalefactor_bits[0]),
+                    sizeof(ff_aac_scalefactor_bits[0]),
+                    ff_aac_scalefactor_code,
+                    sizeof(ff_aac_scalefactor_code[0]),
+                    sizeof(ff_aac_scalefactor_code[0]),
                     352);
 
     ff_mdct_init(&ac->mdct,       11, 1, 1.0 / (32768.0 * 1024.0));
@@ -985,7 +1043,7 @@
 
     if (get_bits_left(gb) < 8 * count) {
         av_log(ac->avctx, AV_LOG_ERROR, "skip_data_stream_element: "overread_err);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     skip_bits_long(gb, 8 * count);
     return 0;
@@ -997,9 +1055,11 @@
     int sfb;
     if (get_bits1(gb)) {
         ics->predictor_reset_group = get_bits(gb, 5);
-        if (ics->predictor_reset_group == 0 || ics->predictor_reset_group > 30) {
-            av_log(ac->avctx, AV_LOG_ERROR, "Invalid Predictor Reset Group.\n");
-            return -1;
+        if (ics->predictor_reset_group == 0 ||
+            ics->predictor_reset_group > 30) {
+            av_log(ac->avctx, AV_LOG_ERROR,
+                   "Invalid Predictor Reset Group.\n");
+            return AVERROR_INVALIDDATA;
         }
     }
     for (sfb = 0; sfb < FFMIN(ics->max_sfb, ff_aac_pred_sfb_max[ac->oc[1].m4ac.sampling_index]); sfb++) {
@@ -1068,7 +1128,8 @@
                     goto fail;
                 }
             } else if (ac->oc[1].m4ac.object_type == AOT_AAC_LC) {
-                av_log(ac->avctx, AV_LOG_ERROR, "Prediction is not allowed in AAC-LC.\n");
+                av_log(ac->avctx, AV_LOG_ERROR,
+                       "Prediction is not allowed in AAC-LC.\n");
                 goto fail;
             } else {
                 if ((ics->ltp.present = get_bits(gb, 1)))
@@ -1079,7 +1140,8 @@
 
     if (ics->max_sfb > ics->num_swb) {
         av_log(ac->avctx, AV_LOG_ERROR,
-               "Number of scalefactor bands in group (%d) exceeds limit (%d).\n",
+               "Number of scalefactor bands in group (%d) "
+               "exceeds limit (%d).\n",
                ics->max_sfb, ics->num_swb);
         goto fail;
     }
@@ -1112,20 +1174,20 @@
             int sect_band_type = get_bits(gb, 4);
             if (sect_band_type == 12) {
                 av_log(ac->avctx, AV_LOG_ERROR, "invalid band type\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
             do {
                 sect_len_incr = get_bits(gb, bits);
                 sect_end += sect_len_incr;
                 if (get_bits_left(gb) < 0) {
                     av_log(ac->avctx, AV_LOG_ERROR, "decode_band_types: "overread_err);
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 if (sect_end > ics->max_sfb) {
                     av_log(ac->avctx, AV_LOG_ERROR,
                            "Number of bands (%d) exceeds limit (%d).\n",
                            sect_end, ics->max_sfb);
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
             } while (sect_len_incr == (1 << bits) - 1);
             for (; k < sect_end; k++) {
@@ -1162,8 +1224,9 @@
             int run_end = band_type_run_end[idx];
             if (band_type[idx] == ZERO_BT) {
                 for (; i < run_end; i++, idx++)
-                    sf[idx] = 0.;
-            } else if ((band_type[idx] == INTENSITY_BT) || (band_type[idx] == INTENSITY_BT2)) {
+                    sf[idx] = 0.0;
+            } else if ((band_type[idx] == INTENSITY_BT) ||
+                       (band_type[idx] == INTENSITY_BT2)) {
                 for (; i < run_end; i++, idx++) {
                     offset[2] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60;
                     clipped_offset = av_clip(offset[2], -155, 100);
@@ -1196,7 +1259,7 @@
                     if (offset[0] > 255U) {
                         av_log(ac->avctx, AV_LOG_ERROR,
                                "Scalefactor (%d) out of range.\n", offset[0]);
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     }
                     sf[idx] = -ff_aac_pow2sf_tab[offset[0] - 100 + POW_SF2_ZERO];
                 }
@@ -1251,10 +1314,11 @@
                 tns->length[w][filt] = get_bits(gb, 6 - 2 * is8);
 
                 if ((tns->order[w][filt] = get_bits(gb, 5 - 2 * is8)) > tns_max_order) {
-                    av_log(ac->avctx, AV_LOG_ERROR, "TNS filter order %d is greater than maximum %d.\n",
+                    av_log(ac->avctx, AV_LOG_ERROR,
+                           "TNS filter order %d is greater than maximum %d.\n",
                            tns->order[w][filt], tns_max_order);
                     tns->order[w][filt] = 0;
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 if (tns->order[w][filt]) {
                     tns->direction[w][filt] = get_bits1(gb);
@@ -1283,7 +1347,9 @@
 {
     int idx;
     if (ms_present == 1) {
-        for (idx = 0; idx < cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb; idx++)
+        for (idx = 0;
+             idx < cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb;
+             idx++)
             cpe->ms_mask[idx] = get_bits1(gb);
     } else if (ms_present == 2) {
         memset(cpe->ms_mask, 1,  sizeof(cpe->ms_mask[0]) * cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb);
@@ -1382,7 +1448,8 @@
     float *coef_base = coef;
 
     for (g = 0; g < ics->num_windows; g++)
-        memset(coef + g * 128 + offsets[ics->max_sfb], 0, sizeof(float) * (c - offsets[ics->max_sfb]));
+        memset(coef + g * 128 + offsets[ics->max_sfb], 0,
+               sizeof(float) * (c - offsets[ics->max_sfb]));
 
     for (g = 0; g < ics->num_window_groups; g++) {
         unsigned g_len = ics->group_len[g];
@@ -1537,7 +1604,7 @@
 
                                     if (b > 8) {
                                         av_log(ac->avctx, AV_LOG_ERROR, "error in spectral data, ESC overflow\n");
-                                        return -1;
+                                        return AVERROR_INVALIDDATA;
                                     }
 
                                     SKIP_BITS(re, gb, b + 1);
@@ -1652,14 +1719,20 @@
     }
 
     if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
-        for (sfb = 0; sfb < ff_aac_pred_sfb_max[ac->oc[1].m4ac.sampling_index]; sfb++) {
-            for (k = sce->ics.swb_offset[sfb]; k < sce->ics.swb_offset[sfb + 1]; k++) {
+        for (sfb = 0;
+             sfb < ff_aac_pred_sfb_max[ac->oc[1].m4ac.sampling_index];
+             sfb++) {
+            for (k = sce->ics.swb_offset[sfb];
+                 k < sce->ics.swb_offset[sfb + 1];
+                 k++) {
                 predict(&sce->predictor_state[k], &sce->coeffs[k],
-                        sce->ics.predictor_present && sce->ics.prediction_used[sfb]);
+                        sce->ics.predictor_present &&
+                        sce->ics.prediction_used[sfb]);
             }
         }
         if (sce->ics.predictor_reset_group)
-            reset_predictor_group(sce->predictor_state, sce->ics.predictor_reset_group);
+            reset_predictor_group(sce->predictor_state,
+                                  sce->ics.predictor_reset_group);
     } else
         reset_all_predictors(sce->predictor_state);
 }
@@ -1680,6 +1753,7 @@
     IndividualChannelStream *ics = &sce->ics;
     float *out = sce->coeffs;
     int global_gain, pulse_present = 0;
+    int ret;
 
     /* This assignment is to silence a GCC warning about the variable being used
      * uninitialized when in fact it always is.
@@ -1693,33 +1767,38 @@
             return AVERROR_INVALIDDATA;
     }
 
-    if (decode_band_types(ac, sce->band_type, sce->band_type_run_end, gb, ics) < 0)
-        return -1;
-    if (decode_scalefactors(ac, sce->sf, gb, global_gain, ics, sce->band_type, sce->band_type_run_end) < 0)
-        return -1;
+    if ((ret = decode_band_types(ac, sce->band_type,
+                                 sce->band_type_run_end, gb, ics)) < 0)
+        return ret;
+    if ((ret = decode_scalefactors(ac, sce->sf, gb, global_gain, ics,
+                                  sce->band_type, sce->band_type_run_end)) < 0)
+        return ret;
 
     pulse_present = 0;
     if (!scale_flag) {
         if ((pulse_present = get_bits1(gb))) {
             if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
-                av_log(ac->avctx, AV_LOG_ERROR, "Pulse tool not allowed in eight short sequence.\n");
-                return -1;
+                av_log(ac->avctx, AV_LOG_ERROR,
+                       "Pulse tool not allowed in eight short sequence.\n");
+                return AVERROR_INVALIDDATA;
             }
             if (decode_pulses(&pulse, gb, ics->swb_offset, ics->num_swb)) {
-                av_log(ac->avctx, AV_LOG_ERROR, "Pulse data corrupt or invalid.\n");
-                return -1;
+                av_log(ac->avctx, AV_LOG_ERROR,
+                       "Pulse data corrupt or invalid.\n");
+                return AVERROR_INVALIDDATA;
             }
         }
         if ((tns->present = get_bits1(gb)) && decode_tns(ac, tns, gb, ics))
-            return -1;
+            return AVERROR_INVALIDDATA;
         if (get_bits1(gb)) {
             avpriv_request_sample(ac->avctx, "SSR");
             return AVERROR_PATCHWELCOME;
         }
     }
 
-    if (decode_spectrum_and_dequant(ac, out, gb, sce->sf, pulse_present, &pulse, ics, sce->band_type) < 0)
-        return -1;
+    if (decode_spectrum_and_dequant(ac, out, gb, sce->sf, pulse_present,
+                                    &pulse, ics, sce->band_type) < 0)
+        return AVERROR_INVALIDDATA;
 
     if (ac->oc[1].m4ac.object_type == AOT_AAC_MAIN && !common_window)
         apply_prediction(ac, sce);
@@ -1740,7 +1819,8 @@
     for (g = 0; g < ics->num_window_groups; g++) {
         for (i = 0; i < ics->max_sfb; i++, idx++) {
             if (cpe->ms_mask[idx] &&
-                    cpe->ch[0].band_type[idx] < NOISE_BT && cpe->ch[1].band_type[idx] < NOISE_BT) {
+                cpe->ch[0].band_type[idx] < NOISE_BT &&
+                cpe->ch[1].band_type[idx] < NOISE_BT) {
                 for (group = 0; group < ics->group_len[g]; group++) {
                     ac->fdsp.butterflies_float(ch0 + group * 128 + offsets[i],
                                                ch1 + group * 128 + offsets[i],
@@ -1760,7 +1840,8 @@
  *                      [1] mask is decoded from bitstream; [2] mask is all 1s;
  *                      [3] reserved for scalable AAC
  */
-static void apply_intensity_stereo(AACContext *ac, ChannelElement *cpe, int ms_present)
+static void apply_intensity_stereo(AACContext *ac,
+                                   ChannelElement *cpe, int ms_present)
 {
     const IndividualChannelStream *ics = &cpe->ch[1].ics;
     SingleChannelElement         *sce1 = &cpe->ch[1];
@@ -1771,7 +1852,8 @@
     float scale;
     for (g = 0; g < ics->num_window_groups; g++) {
         for (i = 0; i < ics->max_sfb;) {
-            if (sce1->band_type[idx] == INTENSITY_BT || sce1->band_type[idx] == INTENSITY_BT2) {
+            if (sce1->band_type[idx] == INTENSITY_BT ||
+                sce1->band_type[idx] == INTENSITY_BT2) {
                 const int bt_run_end = sce1->band_type_run_end[idx];
                 for (; i < bt_run_end; i++, idx++) {
                     c = -1 + 2 * (sce1->band_type[idx] - 14);
@@ -1811,13 +1893,14 @@
         i = cpe->ch[1].ics.use_kb_window[0];
         cpe->ch[1].ics = cpe->ch[0].ics;
         cpe->ch[1].ics.use_kb_window[1] = i;
-        if (cpe->ch[1].ics.predictor_present && (ac->oc[1].m4ac.object_type != AOT_AAC_MAIN))
+        if (cpe->ch[1].ics.predictor_present &&
+            (ac->oc[1].m4ac.object_type != AOT_AAC_MAIN))
             if ((cpe->ch[1].ics.ltp.present = get_bits(gb, 1)))
                 decode_ltp(&cpe->ch[1].ics.ltp, gb, cpe->ch[1].ics.max_sfb);
         ms_present = get_bits(gb, 2);
         if (ms_present == 3) {
             av_log(ac->avctx, AV_LOG_ERROR, "ms_present = 3 is reserved.\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         } else if (ms_present)
             decode_mid_side_stereo(cpe, gb, ms_present);
     }
@@ -1885,7 +1968,7 @@
         int idx  = 0;
         int cge  = 1;
         int gain = 0;
-        float gain_cache = 1.;
+        float gain_cache = 1.0;
         if (c) {
             cge = coup->coupling_point == AFTER_IMDCT ? 1 : get_bits1(gb);
             gain = cge ? get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60: 0;
@@ -2423,7 +2506,7 @@
     int size;
     AACADTSHeaderInfo hdr_info;
     uint8_t layout_map[MAX_ELEM_ID*4][3];
-    int layout_map_tags;
+    int layout_map_tags, ret;
 
     size = avpriv_aac_parse_header(gb, &hdr_info);
     if (size > 0) {
@@ -2437,12 +2520,15 @@
         push_output_configuration(ac);
         if (hdr_info.chan_config) {
             ac->oc[1].m4ac.chan_config = hdr_info.chan_config;
-            if (set_default_channel_config(ac->avctx, layout_map,
-                    &layout_map_tags, hdr_info.chan_config))
-                return -7;
-            if (output_configure(ac, layout_map, layout_map_tags,
-                                 FFMAX(ac->oc[1].status, OC_TRIAL_FRAME), 0))
-                return -7;
+            if ((ret = set_default_channel_config(ac->avctx,
+                                                  layout_map,
+                                                  &layout_map_tags,
+                                                  hdr_info.chan_config)) < 0)
+                return ret;
+            if ((ret = output_configure(ac, layout_map, layout_map_tags,
+                                        FFMAX(ac->oc[1].status,
+                                              OC_TRIAL_FRAME), 0)) < 0)
+                return ret;
         } else {
             ac->oc[1].m4ac.chan_config = 0;
             /**
@@ -2489,22 +2575,19 @@
     ac->frame = data;
 
     if (show_bits(gb, 12) == 0xfff) {
-        if (parse_adts_frame_header(ac, gb) < 0) {
+        if ((err = parse_adts_frame_header(ac, gb)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "Error decoding AAC frame header.\n");
-            err = -1;
             goto fail;
         }
         if (ac->oc[1].m4ac.sampling_index > 12) {
             av_log(ac->avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->oc[1].m4ac.sampling_index);
-            err = -1;
+            err = AVERROR_INVALIDDATA;
             goto fail;
         }
     }
 
-    if (frame_configure_elements(avctx) < 0) {
-        err = -1;
+    if ((err = frame_configure_elements(avctx)) < 0)
         goto fail;
-    }
 
     ac->tags_mapped = 0;
     // parse
@@ -2515,7 +2598,7 @@
             if (!(che=get_che(ac, elem_type, elem_id))) {
                 av_log(ac->avctx, AV_LOG_ERROR, "channel element %d.%d is not allocated\n",
                        elem_type, elem_id);
-                err = -1;
+                err = AVERROR_INVALIDDATA;
                 goto fail;
             }
             samples = 1024;
@@ -2573,7 +2656,7 @@
                 elem_id += get_bits(gb, 8) - 1;
             if (get_bits_left(gb) < 8 * elem_id) {
                     av_log(avctx, AV_LOG_ERROR, "TYPE_FIL: "overread_err);
-                    err = -1;
+                    err = AVERROR_INVALIDDATA;
                     goto fail;
             }
             while (elem_id > 0)
@@ -2582,7 +2665,7 @@
             break;
 
         default:
-            err = -1; /* should not happen, but keeps compiler happy */
+            err = AVERROR_BUG; /* should not happen, but keeps compiler happy */
             break;
         }
 
@@ -2594,7 +2677,7 @@
 
         if (get_bits_left(gb) < 3) {
             av_log(avctx, AV_LOG_ERROR, overread_err);
-            err = -1;
+            err = AVERROR_INVALIDDATA;
             goto fail;
         }
     }
@@ -2683,7 +2766,8 @@
     if (INT_MAX / 8 <= buf_size)
         return AVERROR_INVALIDDATA;
 
-    init_get_bits(&gb, buf, buf_size * 8);
+    if ((err = init_get_bits(&gb, buf, buf_size * 8)) < 0)
+        return err;
 
     if ((err = aac_decode_frame_int(avctx, data, got_frame_ptr, &gb, avpkt)) < 0)
         return err;
@@ -2719,13 +2803,13 @@
 #define LOAS_SYNC_WORD   0x2b7       ///< 11 bits LOAS sync word
 
 struct LATMContext {
-    AACContext      aac_ctx;             ///< containing AACContext
-    int             initialized;         ///< initialized after a valid extradata was seen
+    AACContext aac_ctx;     ///< containing AACContext
+    int initialized;        ///< initialized after a valid extradata was seen
 
     // parser data
-    int             audio_mux_version_A; ///< LATM syntax version
-    int             frame_length_type;   ///< 0/1 variable/fixed frame length
-    int             frame_length;        ///< frame length for fixed frame length
+    int audio_mux_version_A; ///< LATM syntax version
+    int frame_length_type;   ///< 0/1 variable/fixed frame length
+    int frame_length;        ///< frame length for fixed frame length
 };
 
 static inline uint32_t latm_get_value(GetBitContext *b)
diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c
index 80dd3d8..362f02b 100644
--- a/libavcodec/aacenc.c
+++ b/libavcodec/aacenc.c
@@ -593,7 +593,7 @@
                 coeffs[ch] = cpe->ch[ch].coeffs;
             s->psy.model->analyze(&s->psy, start_ch, coeffs, wi);
             for (ch = 0; ch < chans; ch++) {
-                s->cur_channel = start_ch * 2 + ch;
+                s->cur_channel = start_ch + ch;
                 s->coder->search_for_quantizers(avctx, s, &cpe->ch[ch], s->lambda);
             }
             cpe->common_window = 0;
@@ -609,7 +609,7 @@
                     }
                 }
             }
-            s->cur_channel = start_ch * 2;
+            s->cur_channel = start_ch;
             if (s->options.stereo_mode && cpe->common_window) {
                 if (s->options.stereo_mode > 0) {
                     IndividualChannelStream *ics = &cpe->ch[0].ics;
diff --git a/libavcodec/aacps_tablegen.h b/libavcodec/aacps_tablegen.h
index 1f9c326..05a2af6 100644
--- a/libavcodec/aacps_tablegen.h
+++ b/libavcodec/aacps_tablegen.h
@@ -192,7 +192,7 @@
     for (k = 0; k < NR_ALLPASS_BANDS34; k++) {
         double f_center, theta;
         if (k < FF_ARRAY_ELEMS(f_center_34))
-            f_center = f_center_34[k] / 24.;
+            f_center = f_center_34[k] / 24.0;
         else
             f_center = k - 26.5f;
         for (m = 0; m < PS_AP_LINKS; m++) {
diff --git a/libavcodec/aacpsy.c b/libavcodec/aacpsy.c
index b3513c7..d2a782e 100644
--- a/libavcodec/aacpsy.c
+++ b/libavcodec/aacpsy.c
@@ -24,6 +24,7 @@
  * AAC encoder psychoacoustic model
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/libm.h"
 
 #include "avcodec.h"
@@ -254,7 +255,8 @@
 /**
  * LAME psy model specific initialization
  */
-static void lame_window_init(AacPsyContext *ctx, AVCodecContext *avctx) {
+static av_cold void lame_window_init(AacPsyContext *ctx, AVCodecContext *avctx)
+{
     int i, j;
 
     for (i = 0; i < avctx->channels; i++) {
@@ -316,7 +318,7 @@
         AacPsyCoeffs *coeffs = pctx->psy_coef[j];
         const uint8_t *band_sizes = ctx->bands[j];
         float line_to_frequency = ctx->avctx->sample_rate / (j ? 256.f : 2048.0f);
-        float avg_chan_bits = chan_bitrate / ctx->avctx->sample_rate * (j ? 128.0f : 1024.0f);
+        float avg_chan_bits = chan_bitrate * (j ? 128.0f : 1024.0f) / ctx->avctx->sample_rate;
         /* reference encoder uses 2.4% here instead of 60% like the spec says */
         float bark_pe = 0.024f * PSY_3GPP_BITS_TO_PE(avg_chan_bits) / num_bark;
         float en_spread_low = j ? PSY_3GPP_EN_SPREAD_LOW_S : PSY_3GPP_EN_SPREAD_LOW_L;
@@ -603,7 +605,8 @@
             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. */
+        /* 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;
     }
 }
diff --git a/libavcodec/aacpsy.h b/libavcodec/aacpsy.h
deleted file mode 100644
index 05c93cd..0000000
--- a/libavcodec/aacpsy.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * AAC encoder psychoacoustic model
- * Copyright (C) 2008 Konstantin Shishkov
- *
- * 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
- */
-
-#ifndef AVCODEC_AACPSY_H
-#define AVCODEC_AACPSY_H
-
-#include "avcodec.h"
-#include "aac.h"
-//#include "lowpass.h"
-
-enum AACPsyModelType{
-    AAC_PSY_TEST,              ///< a sample model to exercise encoder
-    AAC_PSY_3GPP,              ///< model following recommendations from 3GPP TS 26.403
-
-    AAC_NB_PSY_MODELS          ///< total number of psychoacoustic models, since it's not a part of the ABI new models can be added freely
-};
-
-/**
- * context used by psychoacoustic model
- */
-typedef struct AACPsyContext {
-    AVCodecContext *avctx;            ///< encoder context
-}AACPsyContext;
-
-/**
- * Cleanup model context at the end.
- *
- * @param ctx model context
- */
-void ff_aac_psy_end(AACPsyContext *ctx);
-
-#endif /* AVCODEC_AACPSY_H */
diff --git a/libavcodec/aasc.c b/libavcodec/aasc.c
index 26ba30d..45d131a 100644
--- a/libavcodec/aasc.c
+++ b/libavcodec/aasc.c
@@ -107,11 +107,9 @@
     switch (compr) {
     case 0:
         stride = (avctx->width * psize + psize) & ~psize;
+        if (buf_size < stride * avctx->height)
+            return AVERROR_INVALIDDATA;
         for (i = avctx->height - 1; i >= 0; i--) {
-            if (avctx->width * psize > buf_size) {
-                av_log(avctx, AV_LOG_ERROR, "Next line is beyond buffer bounds\n");
-                break;
-            }
             memcpy(s->frame->data[0] + i * s->frame->linesize[0], buf, avctx->width * psize);
             buf += stride;
             buf_size -= stride;
diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c
index a70d92a..fc15a41 100644
--- a/libavcodec/ac3dec.c
+++ b/libavcodec/ac3dec.c
@@ -429,7 +429,7 @@
     int end_freq   = s->end_freq[ch_index];
     uint8_t *baps  = s->bap[ch_index];
     int8_t *exps   = s->dexps[ch_index];
-    int *coeffs    = s->fixed_coeffs[ch_index];
+    int32_t *coeffs = s->fixed_coeffs[ch_index];
     int dither     = (ch_index == CPL_CH) || s->dither_flag[ch_index];
     GetBitContext *gbc = &s->gbc;
     int freq;
@@ -1308,7 +1308,7 @@
                 av_log(avctx, AV_LOG_ERROR, "unsupported frame type : "
                        "skipping frame\n");
                 *got_frame_ptr = 0;
-                return s->frame_size;
+                return buf_size;
             } else {
                 av_log(avctx, AV_LOG_ERROR, "invalid frame type\n");
             }
@@ -1374,7 +1374,7 @@
         avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE;
 
     /* get output buffer */
-    frame->nb_samples = s->num_blocks * 256;
+    frame->nb_samples = s->num_blocks * AC3_BLOCK_SIZE;
     if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
         return ret;
 
@@ -1395,7 +1395,7 @@
         }
         if (err)
             for (ch = 0; ch < s->out_channels; ch++)
-                memcpy(((float*)frame->data[ch]) + AC3_BLOCK_SIZE*blk, output[ch], 1024);
+                memcpy(((float*)frame->data[ch]) + AC3_BLOCK_SIZE*blk, output[ch], sizeof(**output) * AC3_BLOCK_SIZE);
         for (ch = 0; ch < s->out_channels; ch++)
             output[ch] = s->outptr[channel_map[ch]];
         for (ch = 0; ch < s->out_channels; ch++) {
@@ -1408,7 +1408,7 @@
 
     /* keep last block for error concealment in next frame */
     for (ch = 0; ch < s->out_channels; ch++)
-        memcpy(s->output[ch], output[ch], 1024);
+        memcpy(s->output[ch], output[ch], sizeof(**output) * AC3_BLOCK_SIZE);
 
     *got_frame_ptr = 1;
 
diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h
index 6c99ef6..ae72d80 100644
--- a/libavcodec/ac3dec.h
+++ b/libavcodec/ac3dec.h
@@ -209,7 +209,7 @@
     float *dlyptr[AC3_MAX_CHANNELS];
 
 ///@name Aligned arrays
-    DECLARE_ALIGNED(16, int,   fixed_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS];       ///< fixed-point transform coefficients
+    DECLARE_ALIGNED(16, int32_t, fixed_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS];     ///< fixed-point transform coefficients
     DECLARE_ALIGNED(32, float, transform_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS];   ///< transform coefficients
     DECLARE_ALIGNED(32, float, delay)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE];             ///< delay - added to the next block
     DECLARE_ALIGNED(32, float, window)[AC3_BLOCK_SIZE];                              ///< window coefficients
diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c
index 15ff343..37c496c 100644
--- a/libavcodec/ac3enc.c
+++ b/libavcodec/ac3enc.c
@@ -26,10 +26,9 @@
  * The simplest AC-3 encoder.
  */
 
-//#define ASSERT_LEVEL 2
-
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
@@ -754,7 +753,7 @@
  * Initialize bit allocation.
  * Set default parameter codes and calculate parameter values.
  */
-static void bit_alloc_init(AC3EncodeContext *s)
+static av_cold void bit_alloc_init(AC3EncodeContext *s)
 {
     int ch;
 
@@ -2018,6 +2017,7 @@
     AC3EncodeContext *s = avctx->priv_data;
 
     av_freep(&s->windowed_samples);
+    if (s->planar_samples)
     for (ch = 0; ch < s->channels; ch++)
         av_freep(&s->planar_samples[ch]);
     av_freep(&s->planar_samples);
diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c
index 0389c2e..354be53 100644
--- a/libavcodec/ac3enc_template.c
+++ b/libavcodec/ac3enc_template.c
@@ -361,7 +361,7 @@
         }
 
         for (bnd = 0; bnd < block->num_rematrixing_bands; bnd++) {
-            /* calculate calculate sum of squared coeffs for one band in one block */
+            /* calculate sum of squared coeffs for one band in one block */
             int start = ff_ac3_rematrix_band_tab[bnd];
             int end   = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]);
             CoefSumType sum[4];
diff --git a/libavcodec/ac3tab.c b/libavcodec/ac3tab.c
index 9d20d90..1ae7ddf 100644
--- a/libavcodec/ac3tab.c
+++ b/libavcodec/ac3tab.c
@@ -114,7 +114,7 @@
 };
 
 /**
- * Table to remap channels from from AC-3 order to SMPTE order.
+ * Table to remap channels from AC-3 order to SMPTE order.
  * [channel_mode][lfe][ch]
  */
 const uint8_t ff_ac3_dec_channel_map[8][2][6] = {
diff --git a/libavcodec/acelp_vectors.c b/libavcodec/acelp_vectors.c
index c9d6f87..86851a3 100644
--- a/libavcodec/acelp_vectors.c
+++ b/libavcodec/acelp_vectors.c
@@ -114,10 +114,10 @@
  0.898529  ,  0.865051  ,  0.769257  ,  0.624054  ,  0.448639  ,  0.265289   ,
  0.0959167 , -0.0412598 , -0.134338  , -0.178986  , -0.178528  , -0.142609   ,
 -0.0849304 , -0.0205078 ,  0.0369568 ,  0.0773926 ,  0.0955200 ,  0.0912781  ,
- 0.0689392 ,  0.0357056 ,  0.        , -0.0305481 , -0.0504150 , -0.0570068  ,
+ 0.0689392 ,  0.0357056 ,  0.0       , -0.0305481 , -0.0504150 , -0.0570068  ,
 -0.0508423 , -0.0350037 , -0.0141602 ,  0.00665283,  0.0230713 ,  0.0323486  ,
  0.0335388 ,  0.0275879 ,  0.0167847 ,  0.00411987, -0.00747681, -0.0156860  ,
--0.0193481 , -0.0183716 , -0.0137634 , -0.00704956,  0.        ,  0.00582886 ,
+-0.0193481 , -0.0183716 , -0.0137634 , -0.00704956,  0.0       ,  0.00582886 ,
  0.00939941,  0.0103760 ,  0.00903320,  0.00604248,  0.00238037, -0.00109863 ,
 -0.00366211, -0.00497437, -0.00503540, -0.00402832, -0.00241089, -0.000579834,
  0.00103760,  0.00222778,  0.00277710,  0.00271606,  0.00213623,  0.00115967 ,
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index f5af5d4..dbbb358 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -31,7 +31,6 @@
  */
 #include "avcodec.h"
 #include "get_bits.h"
-#include "put_bits.h"
 #include "bytestream.h"
 #include "adpcm.h"
 #include "adpcm_data.h"
@@ -96,6 +95,7 @@
     unsigned int max_channels = 2;
 
     switch(avctx->codec->id) {
+    case AV_CODEC_ID_ADPCM_DTK:
     case AV_CODEC_ID_ADPCM_EA:
         min_channels = 2;
         break;
@@ -118,10 +118,8 @@
         c->status[0].step = c->status[1].step = 511;
         break;
     case AV_CODEC_ID_ADPCM_IMA_WAV:
-        if (avctx->bits_per_coded_sample != 4) {
-            av_log(avctx, AV_LOG_ERROR, "Only 4-bit ADPCM IMA WAV files are supported\n");
-            return -1;
-        }
+        if (avctx->bits_per_coded_sample < 2 || avctx->bits_per_coded_sample > 5)
+            return AVERROR_INVALIDDATA;
         break;
     case AV_CODEC_ID_ADPCM_IMA_APC:
         if (avctx->extradata && avctx->extradata_size >= 8) {
@@ -148,6 +146,7 @@
         case AV_CODEC_ID_ADPCM_EA_XAS:
         case AV_CODEC_ID_ADPCM_THP:
         case AV_CODEC_ID_ADPCM_AFC:
+        case AV_CODEC_ID_ADPCM_DTK:
             avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
             break;
         case AV_CODEC_ID_ADPCM_IMA_WS:
@@ -187,6 +186,29 @@
     return (short)c->predictor;
 }
 
+static inline int16_t adpcm_ima_wav_expand_nibble(ADPCMChannelStatus *c, GetBitContext *gb, int bps)
+{
+    int nibble, step_index, predictor, sign, delta, diff, step, shift;
+
+    shift = bps - 1;
+    nibble = get_bits_le(gb, bps),
+    step = ff_adpcm_step_table[c->step_index];
+    step_index = c->step_index + ff_adpcm_index_tables[bps - 2][nibble];
+    step_index = av_clip(step_index, 0, 88);
+
+    sign = nibble & (1 << shift);
+    delta = nibble & ((1 << shift) - 1);
+    diff = ((2 * delta + 1) * step) >> shift;
+    predictor = c->predictor;
+    if (sign) predictor -= diff;
+    else predictor += diff;
+
+    c->predictor = av_clip_int16(predictor);
+    c->step_index = step_index;
+
+    return (int16_t)c->predictor;
+}
+
 static inline int adpcm_ima_qt_expand_nibble(ADPCMChannelStatus *c, int nibble, int shift)
 {
     int step_index;
@@ -550,11 +572,20 @@
             buf_size = FFMIN(buf_size, avctx->block_align);
         nb_samples = 1 + (buf_size - 4 * ch) * 2 / ch;
         break;
-    case AV_CODEC_ID_ADPCM_IMA_WAV:
+    case AV_CODEC_ID_ADPCM_IMA_RAD:
         if (avctx->block_align > 0)
             buf_size = FFMIN(buf_size, avctx->block_align);
-        nb_samples = 1 + (buf_size - 4 * ch) / (4 * ch) * 8;
+        nb_samples = (buf_size - 4 * ch) * 2 / ch;
         break;
+    case AV_CODEC_ID_ADPCM_IMA_WAV:
+    {
+        int bsize = ff_adpcm_ima_block_sizes[avctx->bits_per_coded_sample - 2];
+        int bsamples = ff_adpcm_ima_block_samples[avctx->bits_per_coded_sample - 2];
+        if (avctx->block_align > 0)
+            buf_size = FFMIN(buf_size, avctx->block_align);
+        nb_samples = 1 + (buf_size - 4 * ch) / (bsize * ch) * bsamples;
+        break;
+    }
     case AV_CODEC_ID_ADPCM_MS:
         if (avctx->block_align > 0)
             buf_size = FFMIN(buf_size, avctx->block_align);
@@ -591,6 +622,10 @@
         break;
     }
     case AV_CODEC_ID_ADPCM_THP:
+        if (avctx->extradata) {
+            nb_samples = buf_size / (8 * ch) * 14;
+            break;
+        }
         has_coded_samples = 1;
         bytestream2_skip(gb, 4); // channel size
         *coded_samples  = bytestream2_get_be32(gb);
@@ -603,6 +638,9 @@
     case AV_CODEC_ID_ADPCM_XA:
         nb_samples = (buf_size / 128) * 224 / ch;
         break;
+    case AV_CODEC_ID_ADPCM_DTK:
+        nb_samples = buf_size / (16 * ch) * 28;
+        break;
     }
 
     /* validate coded sample count */
@@ -707,6 +745,23 @@
             }
         }
 
+        if (avctx->bits_per_coded_sample != 4) {
+            int samples_per_block = ff_adpcm_ima_block_samples[avctx->bits_per_coded_sample - 2];
+            GetBitContext g;
+
+            init_get_bits8(&g, gb.buffer, bytestream2_get_bytes_left(&gb));
+            for (n = 0; n < (nb_samples - 1) / samples_per_block; n++) {
+                for (i = 0; i < avctx->channels; i++) {
+                    cs = &c->status[i];
+                    samples = &samples_p[i][1 + n * samples_per_block];
+                    for (m = 0; m < samples_per_block; m++) {
+                        samples[m] = adpcm_ima_wav_expand_nibble(cs, &g,
+                                          avctx->bits_per_coded_sample);
+                    }
+                }
+            }
+            bytestream2_skip(&gb, avctx->block_align - avctx->channels * 4);
+        } else {
         for (n = 0; n < (nb_samples - 1) / 8; n++) {
             for (i = 0; i < avctx->channels; i++) {
                 cs = &c->status[i];
@@ -718,6 +773,7 @@
                 }
             }
         }
+        }
         break;
     case AV_CODEC_ID_ADPCM_4XM:
         for (i = 0; i < avctx->channels; i++)
@@ -904,6 +960,31 @@
             *samples++ = adpcm_ima_oki_expand_nibble(&c->status[st], v & 0x0F);
         }
         break;
+    case AV_CODEC_ID_ADPCM_IMA_RAD:
+        for (channel = 0; channel < avctx->channels; channel++) {
+            cs = &c->status[channel];
+            cs->step_index = sign_extend(bytestream2_get_le16u(&gb), 16);
+            cs->predictor  = sign_extend(bytestream2_get_le16u(&gb), 16);
+            if (cs->step_index > 88u){
+                av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n",
+                       channel, cs->step_index);
+                return AVERROR_INVALIDDATA;
+            }
+        }
+        for (n = 0; n < nb_samples / 2; n++) {
+            int byte[2];
+
+            byte[0] = bytestream2_get_byteu(&gb);
+            if (st)
+                byte[1] = bytestream2_get_byteu(&gb);
+            for(channel = 0; channel < avctx->channels; channel++) {
+                *samples++ = adpcm_ima_expand_nibble(&c->status[channel], byte[channel] & 0x0F, 3);
+            }
+            for(channel = 0; channel < avctx->channels; channel++) {
+                *samples++ = adpcm_ima_expand_nibble(&c->status[channel], byte[channel] >> 4  , 3);
+            }
+        }
+        break;
     case AV_CODEC_ID_ADPCM_IMA_WS:
         if (c->vqa_version == 3) {
             for (channel = 0; channel < avctx->channels; channel++) {
@@ -1321,6 +1402,18 @@
         int table[6][16];
         int ch;
 
+        if (avctx->extradata) {
+            GetByteContext tb;
+            if (avctx->extradata_size < 32 * avctx->channels) {
+                av_log(avctx, AV_LOG_ERROR, "Missing coeff table\n");
+                return AVERROR_INVALIDDATA;
+            }
+
+            bytestream2_init(&tb, avctx->extradata, avctx->extradata_size);
+            for (i = 0; i < avctx->channels; i++)
+                for (n = 0; n < 16; n++)
+                    table[i][n] = sign_extend(bytestream2_get_be16u(&tb), 16);
+        } else {
         for (i = 0; i < avctx->channels; i++)
             for (n = 0; n < 16; n++)
                 table[i][n] = sign_extend(bytestream2_get_be16u(&gb), 16);
@@ -1330,6 +1423,7 @@
             c->status[i].sample1 = sign_extend(bytestream2_get_be16u(&gb), 16);
             c->status[i].sample2 = sign_extend(bytestream2_get_be16u(&gb), 16);
         }
+        }
 
         for (ch = 0; ch < avctx->channels; ch++) {
             samples = samples_p[ch];
@@ -1363,6 +1457,54 @@
         }
         break;
     }
+    case AV_CODEC_ID_ADPCM_DTK:
+        for (channel = 0; channel < avctx->channels; channel++) {
+            samples = samples_p[channel];
+
+            /* Read in every sample for this channel.  */
+            for (i = 0; i < nb_samples / 28; i++) {
+                int byte, header;
+                if (channel)
+                    bytestream2_skipu(&gb, 1);
+                header = bytestream2_get_byteu(&gb);
+                bytestream2_skipu(&gb, 3 - channel);
+
+                /* Decode 28 samples.  */
+                for (n = 0; n < 28; n++) {
+                    int32_t sampledat, prev;
+
+                    switch (header >> 4) {
+                    case 1:
+                        prev = (c->status[channel].sample1 * 0x3c);
+                        break;
+                    case 2:
+                        prev = (c->status[channel].sample1 * 0x73) - (c->status[channel].sample2 * 0x34);
+                        break;
+                    case 3:
+                        prev = (c->status[channel].sample1 * 0x62) - (c->status[channel].sample2 * 0x37);
+                        break;
+                    default:
+                        prev = 0;
+                    }
+
+                    prev = av_clip((prev + 0x20) >> 6, -0x200000, 0x1fffff);
+
+                    byte = bytestream2_get_byteu(&gb);
+                    if (!channel)
+                        sampledat = sign_extend(byte, 4);
+                    else
+                        sampledat = sign_extend(byte >> 4, 4);
+
+                    sampledat = (((sampledat << 12) >> (header & 0xf)) << 6) + prev;
+                    *samples++ = av_clip_int16(sampledat >> 6);
+                    c->status[channel].sample2 = c->status[channel].sample1;
+                    c->status[channel].sample1 = sampledat;
+                }
+            }
+            if (!channel)
+                bytestream2_seek(&gb, 0, SEEK_SET);
+        }
+        break;
 
     default:
         return -1;
@@ -1404,6 +1546,7 @@
 ADPCM_DECODER(AV_CODEC_ID_ADPCM_4XM,         sample_fmts_s16p, adpcm_4xm,         "ADPCM 4X Movie");
 ADPCM_DECODER(AV_CODEC_ID_ADPCM_AFC,         sample_fmts_s16p, adpcm_afc,         "ADPCM Nintendo Gamecube AFC");
 ADPCM_DECODER(AV_CODEC_ID_ADPCM_CT,          sample_fmts_s16,  adpcm_ct,          "ADPCM Creative Technology");
+ADPCM_DECODER(AV_CODEC_ID_ADPCM_DTK,         sample_fmts_s16p, adpcm_dtk,         "ADPCM Nintendo Gamecube DTK");
 ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA,          sample_fmts_s16,  adpcm_ea,          "ADPCM Electronic Arts");
 ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_MAXIS_XA, sample_fmts_s16,  adpcm_ea_maxis_xa, "ADPCM Electronic Arts Maxis CDROM XA");
 ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_R1,       sample_fmts_s16p, adpcm_ea_r1,       "ADPCM Electronic Arts R1");
@@ -1419,6 +1562,7 @@
 ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_ISS,     sample_fmts_s16,  adpcm_ima_iss,     "ADPCM IMA Funcom ISS");
 ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_OKI,     sample_fmts_s16,  adpcm_ima_oki,     "ADPCM IMA Dialogic OKI");
 ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_QT,      sample_fmts_s16p, adpcm_ima_qt,      "ADPCM IMA QuickTime");
+ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_RAD,     sample_fmts_s16,  adpcm_ima_rad,     "ADPCM IMA Radical");
 ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_SMJPEG,  sample_fmts_s16,  adpcm_ima_smjpeg,  "ADPCM IMA Loki SDL MJPEG");
 ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WAV,     sample_fmts_s16p, adpcm_ima_wav,     "ADPCM IMA WAV");
 ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WS,      sample_fmts_both, adpcm_ima_ws,      "ADPCM IMA Westwood");
diff --git a/libavcodec/adpcm.h b/libavcodec/adpcm.h
index 08fd23f..f43a28c 100644
--- a/libavcodec/adpcm.h
+++ b/libavcodec/adpcm.h
@@ -38,8 +38,8 @@
     int prev_sample;
 
     /* MS version */
-    int16_t sample1;
-    int16_t sample2;
+    int sample1;
+    int sample2;
     int coeff1;
     int coeff2;
     int idelta;
diff --git a/libavcodec/adpcm_data.c b/libavcodec/adpcm_data.c
index 0625fc9..1d3e579 100644
--- a/libavcodec/adpcm_data.c
+++ b/libavcodec/adpcm_data.c
@@ -27,12 +27,33 @@
 
 /* ff_adpcm_step_table[] and ff_adpcm_index_table[] are from the ADPCM
    reference source */
-/* This is the index table: */
+static const int8_t adpcm_index_table2[4] = {
+    -1,  2,
+    -1,  2,
+};
+
+static const int8_t adpcm_index_table3[8] = {
+    -1, -1,  1,  2,
+    -1, -1,  1,  2,
+};
+
 const int8_t ff_adpcm_index_table[16] = {
     -1, -1, -1, -1, 2, 4, 6, 8,
     -1, -1, -1, -1, 2, 4, 6, 8,
 };
 
+static const int8_t adpcm_index_table5[32] = {
+    -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16,
+    -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16,
+};
+
+const int8_t const *ff_adpcm_index_tables[4] = {
+    &adpcm_index_table2[0],
+    &adpcm_index_table3[0],
+    &ff_adpcm_index_table[0],
+    &adpcm_index_table5[0],
+};
+
 /**
  * This is the step table. Note that many programs use slight deviations from
  * this table, but such deviations are negligible:
diff --git a/libavcodec/adpcm_data.h b/libavcodec/adpcm_data.h
index 0ebb7c3..a14d520 100644
--- a/libavcodec/adpcm_data.h
+++ b/libavcodec/adpcm_data.h
@@ -28,6 +28,10 @@
 
 #include <stdint.h>
 
+static const uint8_t ff_adpcm_ima_block_sizes[4]   = {  4, 12, 4, 20 };
+static const uint8_t ff_adpcm_ima_block_samples[4] = { 16, 32, 8, 32 };
+
+extern const int8_t const *ff_adpcm_index_tables[4];
 extern const int8_t  ff_adpcm_index_table[16];
 extern const int16_t ff_adpcm_step_table[89];
 extern const int16_t ff_adpcm_oki_step_table[49];
diff --git a/libavcodec/aic.c b/libavcodec/aic.c
new file mode 100644
index 0000000..70e9f3f
--- /dev/null
+++ b/libavcodec/aic.c
@@ -0,0 +1,481 @@
+/*
+ * Apple Intermediate Codec decoder
+ *
+ * Copyright (c) 2013 Konstantin Shishkov
+ *
+ * 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
+ */
+
+#include "avcodec.h"
+#include "bytestream.h"
+#include "dsputil.h"
+#include "internal.h"
+#include "get_bits.h"
+#include "golomb.h"
+#include "unary.h"
+
+#define AIC_HDR_SIZE    24
+#define AIC_BAND_COEFFS (64 + 32 + 192 + 96)
+
+enum AICBands {
+    COEFF_LUMA = 0,
+    COEFF_CHROMA,
+    COEFF_LUMA_EXT,
+    COEFF_CHROMA_EXT,
+    NUM_BANDS
+};
+
+static const int aic_num_band_coeffs[NUM_BANDS] = { 64, 32, 192, 96 };
+
+static const int aic_band_off[NUM_BANDS] = { 0, 64, 96, 288 };
+
+static const uint8_t aic_quant_matrix[64] = {
+     8, 16, 19, 22, 22, 26, 26, 27,
+    16, 16, 22, 22, 26, 27, 27, 29,
+    19, 22, 26, 26, 27, 29, 29, 35,
+    22, 24, 27, 27, 29, 32, 34, 38,
+    26, 27, 29, 29, 32, 35, 38, 46,
+    27, 29, 34, 34, 35, 40, 46, 56,
+    29, 34, 34, 37, 40, 48, 56, 69,
+    34, 37, 38, 40, 48, 58, 69, 83,
+};
+
+static const uint8_t aic_y_scan[64] = {
+     0,  4,  1,  2,  5,  8, 12,  9,
+     6,  3,  7, 10, 13, 14, 11, 15,
+    47, 43, 46, 45, 42, 39, 35, 38,
+    41, 44, 40, 37, 34, 33, 36, 32,
+    16, 20, 17, 18, 21, 24, 28, 25,
+    22, 19, 23, 26, 29, 30, 27, 31,
+    63, 59, 62, 61, 58, 55, 51, 54,
+    57, 60, 56, 53, 50, 49, 52, 48,
+};
+
+static const uint8_t aic_y_ext_scan[192] = {
+     64,  72,  65,  66,  73,  80,  88,  81,
+     74,  67,  75,  82,  89,  90,  83,  91,
+      0,   4,   1,   2,   5,   8,  12,   9,
+      6,   3,   7,  10,  13,  14,  11,  15,
+     16,  20,  17,  18,  21,  24,  28,  25,
+     22,  19,  23,  26,  29,  30,  27,  31,
+    155, 147, 154, 153, 146, 139, 131, 138,
+    145, 152, 144, 137, 130, 129, 136, 128,
+     47,  43,  46,  45,  42,  39,  35,  38,
+     41,  44,  40,  37,  34,  33,  36,  32,
+     63,  59,  62,  61,  58,  55,  51,  54,
+     57,  60,  56,  53,  50,  49,  52,  48,
+     96, 104,  97,  98, 105, 112, 120, 113,
+    106,  99, 107, 114, 121, 122, 115, 123,
+     68,  76,  69,  70,  77,  84,  92,  85,
+     78,  71,  79,  86,  93,  94,  87,  95,
+    100, 108, 101, 102, 109, 116, 124, 117,
+    110, 103, 111, 118, 125, 126, 119, 127,
+    187, 179, 186, 185, 178, 171, 163, 170,
+    177, 184, 176, 169, 162, 161, 168, 160,
+    159, 151, 158, 157, 150, 143, 135, 142,
+    149, 156, 148, 141, 134, 133, 140, 132,
+    191, 183, 190, 189, 182, 175, 167, 174,
+    181, 188, 180, 173, 166, 165, 172, 164,
+};
+
+static const uint8_t aic_c_scan[64] = {
+     0,  4,  1,  2,  5,  8, 12,  9,
+     6,  3,  7, 10, 13, 14, 11, 15,
+    31, 27, 30, 29, 26, 23, 19, 22,
+    25, 28, 24, 21, 18, 17, 20, 16,
+    32, 36, 33, 34, 37, 40, 44, 41,
+    38, 35, 39, 42, 45, 46, 43, 47,
+    63, 59, 62, 61, 58, 55, 51, 54,
+    57, 60, 56, 53, 50, 49, 52, 48,
+};
+
+static const uint8_t aic_c_ext_scan[192] = {
+     16,  24,  17,  18,  25,  32,  40,  33,
+     26,  19,  27,  34,  41,  42,  35,  43,
+      0,   4,   1,   2,   5,   8,  12,   9,
+      6,   3,   7,  10,  13,  14,  11,  15,
+     20,  28,  21,  22,  29,  36,  44,  37,
+     30,  23,  31,  38,  45,  46,  39,  47,
+     95,  87,  94,  93,  86,  79,  71,  78,
+     85,  92,  84,  77,  70,  69,  76,  68,
+     63,  59,  62,  61,  58,  55,  51,  54,
+     57,  60,  56,  53,  50,  49,  52,  48,
+     91,  83,  90,  89,  82,  75,  67,  74,
+     81,  88,  80,  73,  66,  65,  72,  64,
+    112, 120, 113, 114, 121, 128, 136, 129,
+    122, 115, 123, 130, 137, 138, 131, 139,
+     96, 100,  97,  98, 101, 104, 108, 105,
+    102,  99, 103, 106, 109, 110, 107, 111,
+    116, 124, 117, 118, 125, 132, 140, 133,
+    126, 119, 127, 134, 141, 142, 135, 143,
+    191, 183, 190, 189, 182, 175, 167, 174,
+    181, 188, 180, 173, 166, 165, 172, 164,
+    159, 155, 158, 157, 154, 151, 147, 150,
+    153, 156, 152, 149, 146, 145, 148, 144,
+    187, 179, 186, 185, 178, 171, 163, 170,
+    177, 184, 176, 169, 162, 161, 168, 160,
+};
+
+static const uint8_t *aic_scan[NUM_BANDS] = {
+    aic_y_scan, aic_c_scan, aic_y_ext_scan, aic_c_ext_scan
+};
+
+typedef struct AICContext {
+    AVCodecContext *avctx;
+    AVFrame        *frame;
+    DSPContext     dsp;
+    ScanTable      scantable;
+
+    int            num_x_slices;
+    int            slice_width;
+    int            mb_width, mb_height;
+    int            quant;
+    int            interlaced;
+
+    int16_t        *slice_data;
+    int16_t        *data_ptr[NUM_BANDS];
+
+    DECLARE_ALIGNED(16, int16_t, block)[64];
+} AICContext;
+
+static int aic_decode_header(AICContext *ctx, const uint8_t *src, int size)
+{
+    uint32_t frame_size;
+    int width, height;
+
+    if (src[0] != 1) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "Invalid version %d\n", src[0]);
+        return AVERROR_INVALIDDATA;
+    }
+    if (src[1] != AIC_HDR_SIZE - 2) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "Invalid header size %d\n", src[1]);
+        return AVERROR_INVALIDDATA;
+    }
+    frame_size = AV_RB32(src + 2);
+    width      = AV_RB16(src + 6);
+    height     = AV_RB16(src + 8);
+    if (frame_size > size) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "Frame size should be %d got %d\n",
+               frame_size, size);
+        return AVERROR_INVALIDDATA;
+    }
+    if (width != ctx->avctx->width || height != ctx->avctx->height) {
+        av_log(ctx->avctx, AV_LOG_ERROR,
+               "Picture dimension changed: old: %d x %d, new: %d x %d\n",
+               ctx->avctx->width, ctx->avctx->height, width, height);
+        return AVERROR_INVALIDDATA;
+    }
+    ctx->quant      = src[15];
+    ctx->interlaced = ((src[16] >> 4) == 3);
+
+    return 0;
+}
+
+#define GET_CODE(val, type, add_bits)                         \
+    do {                                                      \
+        if (type)                                             \
+            val = get_ue_golomb(gb);                          \
+        else                                                  \
+            val = get_unary(gb, 1, 31);                       \
+        if (add_bits)                                         \
+            val = (val << add_bits) + get_bits(gb, add_bits); \
+    } while (0)
+
+static int aic_decode_coeffs(GetBitContext *gb, int16_t *dst,
+                             int band, int slice_width, int force_chroma)
+{
+    int has_skips, coeff_type, coeff_bits, skip_type, skip_bits;
+    const int num_coeffs = aic_num_band_coeffs[band];
+    const uint8_t *scan = aic_scan[band | force_chroma];
+    int mb, idx;
+    unsigned val;
+
+    has_skips  = get_bits1(gb);
+    coeff_type = get_bits1(gb);
+    coeff_bits = get_bits(gb, 3);
+
+    if (has_skips) {
+        skip_type = get_bits1(gb);
+        skip_bits = get_bits(gb, 3);
+
+        for (mb = 0; mb < slice_width; mb++) {
+            idx = -1;
+            do {
+                GET_CODE(val, skip_type, skip_bits);
+                if (val >= 0x10000)
+                    return AVERROR_INVALIDDATA;
+                idx += val + 1;
+                if (idx >= num_coeffs)
+                    break;
+                GET_CODE(val, coeff_type, coeff_bits);
+                val++;
+                if (val >= 0x10000)
+                    return AVERROR_INVALIDDATA;
+                dst[scan[idx]] = val;
+            } while (idx < num_coeffs - 1);
+            dst += num_coeffs;
+        }
+    } else {
+        for (mb = 0; mb < slice_width; mb++) {
+            for (idx = 0; idx < num_coeffs; idx++) {
+                GET_CODE(val, coeff_type, coeff_bits);
+                if (val >= 0x10000)
+                    return AVERROR_INVALIDDATA;
+                dst[scan[idx]] = val;
+            }
+            dst += num_coeffs;
+        }
+    }
+    return 0;
+}
+
+static void recombine_block(int16_t *dst, const uint8_t *scan,
+                            int16_t **base, int16_t **ext)
+{
+    int i, j;
+
+    for (i = 0; i < 4; i++) {
+        for (j = 0; j < 4; j++)
+            dst[scan[i * 8 + j]]     = (*base)[j];
+        for (j = 0; j < 4; j++)
+            dst[scan[i * 8 + j + 4]] = (*ext)[j];
+        *base += 4;
+        *ext  += 4;
+    }
+    for (; i < 8; i++) {
+        for (j = 0; j < 8; j++)
+            dst[scan[i * 8 + j]] = (*ext)[j];
+        *ext  += 8;
+    }
+}
+
+static void recombine_block_il(int16_t *dst, const uint8_t *scan,
+                               int16_t **base, int16_t **ext,
+                               int block_no)
+{
+    int i, j;
+
+    if (block_no < 2) {
+        for (i = 0; i < 8; i++) {
+            for (j = 0; j < 4; j++)
+                dst[scan[i * 8 + j]]     = (*base)[j];
+            for (j = 0; j < 4; j++)
+                dst[scan[i * 8 + j + 4]] = (*ext)[j];
+            *base += 4;
+            *ext  += 4;
+        }
+    } else {
+        for (i = 0; i < 64; i++)
+            dst[scan[i]] = (*ext)[i];
+        *ext += 64;
+    }
+}
+
+static void unquant_block(int16_t *block, int q)
+{
+    int i;
+
+    for (i = 0; i < 64; i++) {
+        int val  = (uint16_t)block[i];
+        int sign = val & 1;
+
+        block[i] = (((val >> 1) ^ -sign) * q * aic_quant_matrix[i] >> 4)
+                   + sign;
+    }
+}
+
+static int aic_decode_slice(AICContext *ctx, int mb_x, int mb_y,
+                            const uint8_t *src, int src_size)
+{
+    GetBitContext gb;
+    int ret, i, mb, blk;
+    int slice_width = FFMIN(ctx->slice_width, ctx->mb_width - mb_x);
+    uint8_t *Y, *C[2];
+    uint8_t *dst;
+    int16_t *base_y = ctx->data_ptr[COEFF_LUMA];
+    int16_t *base_c = ctx->data_ptr[COEFF_CHROMA];
+    int16_t *ext_y  = ctx->data_ptr[COEFF_LUMA_EXT];
+    int16_t *ext_c  = ctx->data_ptr[COEFF_CHROMA_EXT];
+    const int ystride = ctx->frame->linesize[0];
+
+    Y = ctx->frame->data[0] + mb_x * 16 + mb_y * 16 * ystride;
+    for (i = 0; i < 2; i++)
+        C[i] = ctx->frame->data[i + 1] + mb_x * 8
+               + mb_y * 8 * ctx->frame->linesize[i + 1];
+    init_get_bits(&gb, src, src_size * 8);
+
+    memset(ctx->slice_data, 0,
+           sizeof(*ctx->slice_data) * slice_width * AIC_BAND_COEFFS);
+    for (i = 0; i < NUM_BANDS; i++)
+        if ((ret = aic_decode_coeffs(&gb, ctx->data_ptr[i],
+                                     i, slice_width,
+                                     !ctx->interlaced)) < 0)
+            return ret;
+
+    for (mb = 0; mb < slice_width; mb++) {
+        for (blk = 0; blk < 4; blk++) {
+            if (!ctx->interlaced)
+                recombine_block(ctx->block, ctx->scantable.permutated,
+                                &base_y, &ext_y);
+            else
+                recombine_block_il(ctx->block, ctx->scantable.permutated,
+                                   &base_y, &ext_y, blk);
+            unquant_block(ctx->block, ctx->quant);
+            ctx->dsp.idct(ctx->block);
+
+            if (!ctx->interlaced) {
+                dst = Y + (blk >> 1) * 8 * ystride + (blk & 1) * 8;
+                ctx->dsp.put_signed_pixels_clamped(ctx->block, dst,
+                                                   ystride);
+            } else {
+                dst = Y + (blk & 1) * 8 + (blk >> 1) * ystride;
+                ctx->dsp.put_signed_pixels_clamped(ctx->block, dst,
+                                                   ystride * 2);
+            }
+        }
+        Y += 16;
+
+        for (blk = 0; blk < 2; blk++) {
+            recombine_block(ctx->block, ctx->scantable.permutated,
+                            &base_c, &ext_c);
+            unquant_block(ctx->block, ctx->quant);
+            ctx->dsp.idct(ctx->block);
+            ctx->dsp.put_signed_pixels_clamped(ctx->block, C[blk],
+                                               ctx->frame->linesize[blk + 1]);
+            C[blk] += 8;
+        }
+    }
+
+    return 0;
+}
+
+static int aic_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+                            AVPacket *avpkt)
+{
+    AICContext *ctx    = avctx->priv_data;
+    const uint8_t *buf = avpkt->data;
+    int buf_size       = avpkt->size;
+    GetByteContext gb;
+    uint32_t off;
+    int x, y, ret;
+    int slice_size;
+
+    ctx->frame            = data;
+    ctx->frame->pict_type = AV_PICTURE_TYPE_I;
+    ctx->frame->key_frame = 1;
+
+    off = FFALIGN(AIC_HDR_SIZE + ctx->num_x_slices * ctx->mb_height * 2, 4);
+
+    if (buf_size < off) {
+        av_log(avctx, AV_LOG_ERROR, "Too small frame\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    if ((ret = aic_decode_header(ctx, buf, buf_size)) < 0)
+        return ret;
+
+    if ((ret = ff_get_buffer(avctx, ctx->frame, 0)) < 0)
+        return ret;
+
+    bytestream2_init(&gb, buf + AIC_HDR_SIZE,
+                     ctx->num_x_slices * ctx->mb_height * 2);
+
+    for (y = 0; y < ctx->mb_height; y++) {
+        for (x = 0; x < ctx->mb_width; x += ctx->slice_width) {
+            slice_size = bytestream2_get_le16(&gb) * 4;
+            if (slice_size + off > buf_size || !slice_size) {
+                av_log(avctx, AV_LOG_ERROR, "Incorrect slice size\n");
+                return AVERROR_INVALIDDATA;
+            }
+
+            if ((ret = aic_decode_slice(ctx, x, y,
+                                        buf + off, slice_size)) < 0)
+                return ret;
+
+            off += slice_size;
+        }
+    }
+
+    *got_frame = 1;
+
+    return avpkt->size;
+}
+
+static av_cold int aic_decode_init(AVCodecContext *avctx)
+{
+    AICContext *ctx = avctx->priv_data;
+    int i;
+    uint8_t scan[64];
+
+    ctx->avctx = avctx;
+
+    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+
+    ff_dsputil_init(&ctx->dsp, avctx);
+
+    for (i = 0; i < 64; i++)
+        scan[i] = i;
+    ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, scan);
+
+    ctx->mb_width  = FFALIGN(avctx->width,  16) >> 4;
+    ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
+
+    ctx->num_x_slices = 16;
+    ctx->slice_width  = ctx->mb_width / 16;
+    for (i = 1; i < 32; i++) {
+        if (!(ctx->mb_width % i) && (ctx->mb_width / i < 32)) {
+            ctx->slice_width  = ctx->mb_width / i;
+            ctx->num_x_slices = i;
+            break;
+        }
+    }
+
+    ctx->slice_data = av_malloc(ctx->slice_width * AIC_BAND_COEFFS
+                                * sizeof(*ctx->slice_data));
+    if (!ctx->slice_data) {
+        av_log(avctx, AV_LOG_ERROR, "Error allocating slice buffer\n");
+
+        return AVERROR(ENOMEM);
+    }
+
+    for (i = 0; i < NUM_BANDS; i++)
+        ctx->data_ptr[i] = ctx->slice_data + ctx->slice_width
+                                             * aic_band_off[i];
+
+    return 0;
+}
+
+static av_cold int aic_decode_close(AVCodecContext *avctx)
+{
+    AICContext *ctx = avctx->priv_data;
+
+    av_freep(&ctx->slice_data);
+
+    return 0;
+}
+
+AVCodec ff_aic_decoder = {
+    .name           = "aic",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_AIC,
+    .priv_data_size = sizeof(AICContext),
+    .init           = aic_decode_init,
+    .close          = aic_decode_close,
+    .decode         = aic_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name      = NULL_IF_CONFIG_SMALL("Apple Intermediate Codec")
+};
diff --git a/libavcodec/alac.c b/libavcodec/alac.c
index 0018b9a..6ffc006 100644
--- a/libavcodec/alac.c
+++ b/libavcodec/alac.c
@@ -50,6 +50,7 @@
 #include "get_bits.h"
 #include "bytestream.h"
 #include "internal.h"
+#include "thread.h"
 #include "unary.h"
 #include "mathops.h"
 #include "alac_data.h"
@@ -287,9 +288,10 @@
         return AVERROR_INVALIDDATA;
     }
     if (!alac->nb_samples) {
+        ThreadFrame tframe = { .f = frame };
         /* get output buffer */
         frame->nb_samples = output_samples;
-        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+        if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
             return ret;
     } else if (output_samples != alac->nb_samples) {
         av_log(avctx, AV_LOG_ERROR, "sample count mismatch: %u != %d\n",
@@ -443,7 +445,8 @@
     int channels;
     int ch, ret, got_end;
 
-    init_get_bits(&alac->gb, avpkt->data, avpkt->size * 8);
+    if ((ret = init_get_bits8(&alac->gb, avpkt->data, avpkt->size)) < 0)
+        return ret;
 
     got_end = 0;
     alac->nb_samples = 0;
@@ -615,6 +618,13 @@
     return 0;
 }
 
+static int init_thread_copy(AVCodecContext *avctx)
+{
+    ALACContext *alac = avctx->priv_data;
+    alac->avctx = avctx;
+    return allocate_buffers(alac);
+}
+
 AVCodec ff_alac_decoder = {
     .name           = "alac",
     .type           = AVMEDIA_TYPE_AUDIO,
@@ -623,6 +633,7 @@
     .init           = alac_decode_init,
     .close          = alac_decode_close,
     .decode         = alac_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
+    .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
     .long_name      = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
 };
diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c
index 4ee558c..4206892 100644
--- a/libavcodec/alacenc.c
+++ b/libavcodec/alacenc.c
@@ -274,7 +274,7 @@
         // generate warm-up samples
         residual[0] = samples[0];
         for (i = 1; i <= lpc.lpc_order; i++)
-            residual[i] = samples[i] - samples[i-1];
+            residual[i] = sign_extend(samples[i] - samples[i-1], s->write_sample_size);
 
         // perform lpc on remaining samples
         for (i = lpc.lpc_order + 1; i < s->frame_size; i++) {
@@ -483,7 +483,6 @@
     ff_lpc_end(&s->lpc_ctx);
     av_freep(&avctx->extradata);
     avctx->extradata_size = 0;
-    av_freep(&avctx->coded_frame);
     return 0;
 }
 
@@ -579,12 +578,6 @@
         goto error;
     }
 
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame) {
-        ret = AVERROR(ENOMEM);
-        goto error;
-    }
-
     s->avctx = avctx;
 
     if ((ret = ff_lpc_init(&s->lpc_ctx, avctx->frame_size,
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index d5b6916..c930cc7 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -96,6 +96,7 @@
     REGISTER_ENCODER(A64MULTI,          a64multi);
     REGISTER_ENCODER(A64MULTI5,         a64multi5);
     REGISTER_DECODER(AASC,              aasc);
+    REGISTER_DECODER(AIC,               aic);
     REGISTER_ENCDEC (AMV,               amv);
     REGISTER_DECODER(ANM,               anm);
     REGISTER_DECODER(ANSI,              ansi);
@@ -153,6 +154,7 @@
     REGISTER_DECODER(FOURXM,            fourxm);
     REGISTER_DECODER(FRAPS,             fraps);
     REGISTER_DECODER(FRWU,              frwu);
+    REGISTER_DECODER(G2M,               g2m);
     REGISTER_ENCDEC (GIF,               gif);
     REGISTER_ENCDEC (H261,              h261);
     REGISTER_ENCDEC (H263,              h263);
@@ -171,8 +173,7 @@
     REGISTER_DECODER(INDEO4,            indeo4);
     REGISTER_DECODER(INDEO5,            indeo5);
     REGISTER_DECODER(INTERPLAY_VIDEO,   interplay_video);
-    REGISTER_ENCDEC (J2K,               j2k);
-    REGISTER_DECODER(JPEG2000,          jpeg2000);
+    REGISTER_ENCDEC (JPEG2000,          jpeg2000);
     REGISTER_ENCDEC (JPEGLS,            jpegls);
     REGISTER_DECODER(JV,                jv);
     REGISTER_DECODER(KGV1,              kgv1);
@@ -238,12 +239,13 @@
     REGISTER_ENCDEC (RV20,              rv20);
     REGISTER_DECODER(RV30,              rv30);
     REGISTER_DECODER(RV40,              rv40);
-    REGISTER_DECODER(S302M,             s302m);
+    REGISTER_ENCDEC (S302M,             s302m);
     REGISTER_DECODER(SANM,              sanm);
     REGISTER_ENCDEC (SGI,               sgi);
     REGISTER_DECODER(SGIRLE,            sgirle);
     REGISTER_DECODER(SMACKER,           smacker);
     REGISTER_DECODER(SMC,               smc);
+    REGISTER_DECODER(SMVJPEG,           smvjpeg);
     REGISTER_ENCDEC (SNOW,              snow);
     REGISTER_DECODER(SP5X,              sp5x);
     REGISTER_ENCDEC (SUNRAST,           sunrast);
@@ -336,6 +338,7 @@
     REGISTER_DECODER(IMC,               imc);
     REGISTER_DECODER(MACE3,             mace3);
     REGISTER_DECODER(MACE6,             mace6);
+    REGISTER_DECODER(METASOUND,         metasound);
     REGISTER_DECODER(MLP,               mlp);
     REGISTER_DECODER(MP1,               mp1);
     REGISTER_DECODER(MP1FLOAT,          mp1float);
@@ -364,11 +367,11 @@
     REGISTER_DECODER(TAK,               tak);
     REGISTER_DECODER(TRUEHD,            truehd);
     REGISTER_DECODER(TRUESPEECH,        truespeech);
-    REGISTER_DECODER(TTA,               tta);
+    REGISTER_ENCDEC (TTA,               tta);
     REGISTER_DECODER(TWINVQ,            twinvq);
     REGISTER_DECODER(VMDAUDIO,          vmdaudio);
     REGISTER_ENCDEC (VORBIS,            vorbis);
-    REGISTER_DECODER(WAVPACK,           wavpack);
+    REGISTER_ENCDEC (WAVPACK,           wavpack);
     REGISTER_DECODER(WMALOSSLESS,       wmalossless);
     REGISTER_DECODER(WMAPRO,            wmapro);
     REGISTER_ENCDEC (WMAV1,             wmav1);
@@ -419,6 +422,7 @@
     REGISTER_ENCDEC (ADPCM_ADX,         adpcm_adx);
     REGISTER_DECODER(ADPCM_AFC,         adpcm_afc);
     REGISTER_DECODER(ADPCM_CT,          adpcm_ct);
+    REGISTER_DECODER(ADPCM_DTK,         adpcm_dtk);
     REGISTER_DECODER(ADPCM_EA,          adpcm_ea);
     REGISTER_DECODER(ADPCM_EA_MAXIS_XA, adpcm_ea_maxis_xa);
     REGISTER_DECODER(ADPCM_EA_R1,       adpcm_ea_r1);
@@ -436,6 +440,7 @@
     REGISTER_DECODER(ADPCM_IMA_ISS,     adpcm_ima_iss);
     REGISTER_DECODER(ADPCM_IMA_OKI,     adpcm_ima_oki);
     REGISTER_ENCDEC (ADPCM_IMA_QT,      adpcm_ima_qt);
+    REGISTER_DECODER(ADPCM_IMA_RAD,     adpcm_ima_rad);
     REGISTER_DECODER(ADPCM_IMA_SMJPEG,  adpcm_ima_smjpeg);
     REGISTER_ENCDEC (ADPCM_IMA_WAV,     adpcm_ima_wav);
     REGISTER_DECODER(ADPCM_IMA_WS,      adpcm_ima_ws);
@@ -474,7 +479,7 @@
     /* external libraries */
     REGISTER_DECODER(LIBCELT,           libcelt);
     REGISTER_ENCODER(LIBFAAC,           libfaac);
-    REGISTER_ENCODER(LIBFDK_AAC,        libfdk_aac);
+    REGISTER_ENCDEC (LIBFDK_AAC,        libfdk_aac);
     REGISTER_ENCDEC (LIBGSM,            libgsm);
     REGISTER_ENCDEC (LIBGSM_MS,         libgsm_ms);
     REGISTER_ENCDEC (LIBILBC,           libilbc);
@@ -495,6 +500,7 @@
     REGISTER_ENCDEC (LIBVORBIS,         libvorbis);
     REGISTER_ENCDEC (LIBVPX_VP8,        libvpx_vp8);
     REGISTER_ENCDEC (LIBVPX_VP9,        libvpx_vp9);
+    REGISTER_ENCODER(LIBWAVPACK,        libwavpack);
     REGISTER_ENCODER(LIBX264,           libx264);
     REGISTER_ENCODER(LIBX264RGB,        libx264rgb);
     REGISTER_ENCODER(LIBXAVS,           libxavs);
diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c
index 96d467c..19f3486 100644
--- a/libavcodec/alsdec.c
+++ b/libavcodec/alsdec.c
@@ -1,6 +1,6 @@
 /*
  * MPEG-4 ALS decoder
- * Copyright (c) 2009 Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
+ * Copyright (c) 2009 Thilo Borgmann <thilo.borgmann _at_ mail.de>
  *
  * This file is part of FFmpeg.
  *
@@ -22,13 +22,9 @@
 /**
  * @file
  * MPEG-4 ALS decoder
- * @author Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
+ * @author Thilo Borgmann <thilo.borgmann _at_ mail.de>
  */
 
-
-//#define DEBUG
-
-
 #include "avcodec.h"
 #include "get_bits.h"
 #include "unary.h"
@@ -297,12 +293,12 @@
                                                  avctx->extradata_size * 8, 1);
 
     if (config_offset < 0)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     skip_bits_long(&gb, config_offset);
 
     if (get_bits_left(&gb) < (30 << 3))
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     // read the fixed items
     als_id                      = get_bits_long(&gb, 32);
@@ -337,7 +333,7 @@
 
     // check for ALSSpecificConfig struct
     if (als_id != MKBETAG('A','L','S','\0'))
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     ctx->cur_frame_length = sconf->frame_length;
 
@@ -352,7 +348,7 @@
         int chan_pos_bits = av_ceil_log2(avctx->channels);
         int bits_needed  = avctx->channels * chan_pos_bits + 7;
         if (get_bits_left(&gb) < bits_needed)
-            return -1;
+            return AVERROR_INVALIDDATA;
 
         if (!(sconf->chan_pos = av_malloc(avctx->channels * sizeof(*sconf->chan_pos))))
             return AVERROR(ENOMEM);
@@ -378,7 +374,7 @@
     // read fixed header and trailer sizes,
     // if size = 0xFFFFFFFF then there is no data field!
     if (get_bits_left(&gb) < 64)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     header_size  = get_bits_long(&gb, 32);
     trailer_size = get_bits_long(&gb, 32);
@@ -392,10 +388,10 @@
 
     // skip the header and trailer data
     if (get_bits_left(&gb) < ht_size)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     if (ht_size > INT32_MAX)
-        return -1;
+        return AVERROR_PATCHWELCOME;
 
     skip_bits_long(&gb, ht_size);
 
@@ -403,7 +399,7 @@
     // initialize CRC calculation
     if (sconf->crc_enabled) {
         if (get_bits_left(&gb) < 32)
-            return -1;
+            return AVERROR_INVALIDDATA;
 
         if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL)) {
             ctx->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE);
@@ -648,7 +644,7 @@
     if (bd->block_length & (sub_blocks - 1)) {
         av_log(avctx, AV_LOG_WARNING,
                "Block length is not evenly divisible by the number of subblocks.\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     sb_length = bd->block_length >> log2_sub_blocks;
@@ -979,20 +975,18 @@
  */
 static int read_block(ALSDecContext *ctx, ALSBlockData *bd)
 {
-    GetBitContext *gb        = &ctx->gb;
     int ret;
+    GetBitContext *gb        = &ctx->gb;
 
     *bd->shift_lsbs = 0;
     // read block type flag and read the samples accordingly
     if (get_bits1(gb)) {
-        if ((ret = read_var_block_data(ctx, bd)) < 0)
-            return ret;
+        ret = read_var_block_data(ctx, bd);
     } else {
-        if ((ret = read_const_block_data(ctx, bd)) < 0)
-            return ret;
+        ret = read_const_block_data(ctx, bd);
     }
 
-    return 0;
+    return ret;
 }
 
 
@@ -1001,12 +995,16 @@
 static int decode_block(ALSDecContext *ctx, ALSBlockData *bd)
 {
     unsigned int smp;
+    int ret = 0;
 
     // read block type flag and read the samples accordingly
     if (*bd->const_block)
         decode_const_block_data(ctx, bd);
-    else if (decode_var_block_data(ctx, bd))
-        return -1;
+    else
+        ret = decode_var_block_data(ctx, bd); // always return 0
+
+    if (ret < 0)
+        return ret;
 
     // TODO: read RLSLMS extension data
 
@@ -1024,14 +1022,10 @@
 {
     int ret;
 
-    ret = read_block(ctx, bd);
-
-    if (ret)
+    if ((ret = read_block(ctx, bd)) < 0)
         return ret;
 
-    ret = decode_block(ctx, bd);
-
-    return ret;
+    return decode_block(ctx, bd);
 }
 
 
@@ -1057,6 +1051,7 @@
                              unsigned int c, const unsigned int *div_blocks,
                              unsigned int *js_blocks)
 {
+    int ret;
     unsigned int b;
     ALSBlockData bd = { 0 };
 
@@ -1077,10 +1072,10 @@
     for (b = 0; b < ctx->num_blocks; b++) {
         bd.block_length     = div_blocks[b];
 
-        if (read_decode_block(ctx, &bd)) {
+        if ((ret = read_decode_block(ctx, &bd)) < 0) {
             // damaged block, write zero for the rest of the frame
             zero_remaining(b, ctx->num_blocks, div_blocks, bd.raw_samples);
-            return -1;
+            return ret;
         }
         bd.raw_samples += div_blocks[b];
         bd.ra_block     = 0;
@@ -1099,6 +1094,7 @@
     ALSSpecificConfig *sconf = &ctx->sconf;
     unsigned int offset = 0;
     unsigned int b;
+    int ret;
     ALSBlockData bd[2] = { { 0 } };
 
     bd[0].ra_block         = ra_frame;
@@ -1140,12 +1136,9 @@
         bd[0].raw_other    = bd[1].raw_samples;
         bd[1].raw_other    = bd[0].raw_samples;
 
-        if(read_decode_block(ctx, &bd[0]) || read_decode_block(ctx, &bd[1])) {
-            // damaged block, write zero for the rest of the frame
-            zero_remaining(b, ctx->num_blocks, div_blocks, bd[0].raw_samples);
-            zero_remaining(b, ctx->num_blocks, div_blocks, bd[1].raw_samples);
-            return -1;
-        }
+        if ((ret = read_decode_block(ctx, &bd[0])) < 0 ||
+            (ret = read_decode_block(ctx, &bd[1])) < 0)
+            goto fail;
 
         // reconstruct joint-stereo blocks
         if (bd[0].js_blocks) {
@@ -1171,8 +1164,19 @@
             sizeof(*ctx->raw_samples[c]) * sconf->max_order);
 
     return 0;
+fail:
+    // damaged block, write zero for the rest of the frame
+    zero_remaining(b, ctx->num_blocks, div_blocks, bd[0].raw_samples);
+    zero_remaining(b, ctx->num_blocks, div_blocks, bd[1].raw_samples);
+    return ret;
 }
 
+static inline int als_weighting(GetBitContext *gb, int k, int off)
+{
+    int idx = av_clip(decode_rice(gb, k) + off,
+                      0, FF_ARRAY_ELEMS(mcc_weightings) - 1);
+    return mcc_weightings[idx];
+}
 
 /** Read the channel data.
   */
@@ -1188,19 +1192,19 @@
 
         if (current->master_channel >= channels) {
             av_log(ctx->avctx, AV_LOG_ERROR, "Invalid master channel.\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
 
         if (current->master_channel != c) {
             current->time_diff_flag = get_bits1(gb);
-            current->weighting[0]   = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 31)];
-            current->weighting[1]   = mcc_weightings[av_clip(decode_rice(gb, 2) + 14, 0, 31)];
-            current->weighting[2]   = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 31)];
+            current->weighting[0]   = als_weighting(gb, 1, 16);
+            current->weighting[1]   = als_weighting(gb, 2, 14);
+            current->weighting[2]   = als_weighting(gb, 1, 16);
 
             if (current->time_diff_flag) {
-                current->weighting[3] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 31)];
-                current->weighting[4] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 31)];
-                current->weighting[5] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 31)];
+                current->weighting[3] = als_weighting(gb, 1, 16);
+                current->weighting[4] = als_weighting(gb, 1, 16);
+                current->weighting[5] = als_weighting(gb, 1, 16);
 
                 current->time_diff_sign  = get_bits1(gb);
                 current->time_diff_index = get_bits(gb, ctx->ltp_lag_length - 3) + 3;
@@ -1213,7 +1217,7 @@
 
     if (entries == channels) {
         av_log(ctx->avctx, AV_LOG_ERROR, "Damaged channel data.\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     align_get_bits(gb);
@@ -1245,7 +1249,7 @@
 
     if (dep == channels) {
         av_log(ctx->avctx, AV_LOG_WARNING, "Invalid channel correlation.\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     bd->const_block = ctx->const_block + c;
@@ -1316,8 +1320,8 @@
     unsigned int div_blocks[32];                ///< block sizes.
     unsigned int c;
     unsigned int js_blocks[2];
-
     uint32_t bs_info = 0;
+    int ret;
 
     // skip the size of the ra unit if present in the frame
     if (sconf->ra_flag == RA_FLAG_FRAMES && ra_frame)
@@ -1348,13 +1352,15 @@
                 independent_bs = 1;
 
             if (independent_bs) {
-                if (decode_blocks_ind(ctx, ra_frame, c, div_blocks, js_blocks))
-                    return -1;
-
+                ret = decode_blocks_ind(ctx, ra_frame, c,
+                                        div_blocks, js_blocks);
+                if (ret < 0)
+                    return ret;
                 independent_bs--;
             } else {
-                if (decode_blocks(ctx, ra_frame, c, div_blocks, js_blocks))
-                    return -1;
+                ret = decode_blocks(ctx, ra_frame, c, div_blocks, js_blocks);
+                if (ret < 0)
+                    return ret;
 
                 c++;
             }
@@ -1373,7 +1379,7 @@
         for (c = 0; c < avctx->channels; c++)
             if (ctx->chan_data[c] < ctx->chan_data_buffer) {
                 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid channel data.\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
 
         memset(reverted_channels, 0, sizeof(*reverted_channels) * avctx->channels);
@@ -1405,11 +1411,12 @@
                     return ret;
             }
 
-            for (c = 0; c < avctx->channels; c++)
-                if (revert_channel_correlation(ctx, &bd, ctx->chan_data,
-                                               reverted_channels, offset, c))
-                    return -1;
-
+            for (c = 0; c < avctx->channels; c++) {
+                ret = revert_channel_correlation(ctx, &bd, ctx->chan_data,
+                                                 reverted_channels, offset, c);
+                if (ret < 0)
+                    return ret;
+            }
             for (c = 0; c < avctx->channels; c++) {
                 bd.const_block = ctx->const_block + c;
                 bd.shift_lsbs  = ctx->shift_lsbs + c;
@@ -1611,30 +1618,30 @@
 {
     unsigned int c;
     unsigned int channel_size;
-    int num_buffers;
+    int num_buffers, ret;
     ALSDecContext *ctx = avctx->priv_data;
     ALSSpecificConfig *sconf = &ctx->sconf;
     ctx->avctx = avctx;
 
     if (!avctx->extradata) {
         av_log(avctx, AV_LOG_ERROR, "Missing required ALS extradata.\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    if (read_specific_config(ctx)) {
+    if ((ret = read_specific_config(ctx)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Reading ALSSpecificConfig failed.\n");
-        decode_end(avctx);
-        return -1;
+        goto fail;
     }
 
-    if (check_specific_config(ctx)) {
-        decode_end(avctx);
-        return -1;
+    if ((ret = check_specific_config(ctx)) < 0) {
+        goto fail;
     }
 
-    if (sconf->bgmc)
-        ff_bgmc_init(avctx, &ctx->bgmc_lut, &ctx->bgmc_lut_status);
-
+    if (sconf->bgmc) {
+        ret = ff_bgmc_init(avctx, &ctx->bgmc_lut, &ctx->bgmc_lut_status);
+        if (ret < 0)
+            goto fail;
+    }
     if (sconf->floating) {
         avctx->sample_fmt          = AV_SAMPLE_FMT_FLT;
         avctx->bits_per_raw_sample = 32;
@@ -1669,7 +1676,8 @@
         !ctx->quant_cof_buffer       || !ctx->lpc_cof_buffer ||
         !ctx->lpc_cof_reversed_buffer) {
         av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
-        return AVERROR(ENOMEM);
+        ret = AVERROR(ENOMEM);
+        goto fail;
     }
 
     // assign quantized parcor coefficient buffers
@@ -1694,8 +1702,8 @@
         !ctx->use_ltp  || !ctx->ltp_lag ||
         !ctx->ltp_gain || !ctx->ltp_gain_buffer) {
         av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
-        decode_end(avctx);
-        return AVERROR(ENOMEM);
+        ret = AVERROR(ENOMEM);
+        goto fail;
     }
 
     for (c = 0; c < num_buffers; c++)
@@ -1712,8 +1720,8 @@
 
         if (!ctx->chan_data_buffer || !ctx->chan_data || !ctx->reverted_channels) {
             av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
-            decode_end(avctx);
-            return AVERROR(ENOMEM);
+            ret = AVERROR(ENOMEM);
+            goto fail;
         }
 
         for (c = 0; c < num_buffers; c++)
@@ -1733,8 +1741,8 @@
     // allocate previous raw sample buffer
     if (!ctx->prev_raw_samples || !ctx->raw_buffer|| !ctx->raw_samples) {
         av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
-        decode_end(avctx);
-        return AVERROR(ENOMEM);
+        ret = AVERROR(ENOMEM);
+        goto fail;
     }
 
     // assign raw samples buffers
@@ -1751,14 +1759,18 @@
                                     av_get_bytes_per_sample(avctx->sample_fmt));
         if (!ctx->crc_buffer) {
             av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
-            decode_end(avctx);
-            return AVERROR(ENOMEM);
+            ret = AVERROR(ENOMEM);
+            goto fail;
         }
     }
 
     ff_dsputil_init(&ctx->dsp, avctx);
 
     return 0;
+
+fail:
+    decode_end(avctx);
+    return ret;
 }
 
 
diff --git a/libavcodec/ansi.c b/libavcodec/ansi.c
index 93915f8..68132df 100644
--- a/libavcodec/ansi.c
+++ b/libavcodec/ansi.c
@@ -116,7 +116,7 @@
     AnsiContext *s = avctx->priv_data;
     int i;
 
-    if (s->y < avctx->height - s->font_height) {
+    if (s->y <= avctx->height - 2*s->font_height) {
         s->y += s->font_height;
         return;
     }
@@ -169,7 +169,7 @@
     ff_draw_pc_font(s->frame->data[0] + s->y * s->frame->linesize[0] + s->x,
                     s->frame->linesize[0], s->font, s->font_height, c, fg, bg);
     s->x += FONT_WIDTH;
-    if (s->x >= avctx->width) {
+    if (s->x > avctx->width - FONT_WIDTH) {
         s->x = 0;
         hscroll(avctx);
     }
@@ -243,6 +243,8 @@
         default:
             avpriv_request_sample(avctx, "Unsupported screen mode");
         }
+        s->x = av_clip(s->x, 0, width  - FONT_WIDTH);
+        s->y = av_clip(s->y, 0, height - s->font_height);
         if (width != avctx->width || height != avctx->height) {
             av_frame_unref(s->frame);
             avcodec_set_dimensions(avctx, width, height);
@@ -336,6 +338,8 @@
         avpriv_request_sample(avctx, "Unknown escape code");
         break;
     }
+    s->x = av_clip(s->x, 0, avctx->width  - FONT_WIDTH);
+    s->y = av_clip(s->y, 0, avctx->height - s->font_height);
     return 0;
 }
 
diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c
index af5ac6f..1f55dab 100644
--- a/libavcodec/apedec.c
+++ b/libavcodec/apedec.c
@@ -489,9 +489,12 @@
 
     if (!rice->k)
         x = overflow;
-    else
+    else if(rice->k <= MIN_CACHE_BITS) {
         x = (overflow << rice->k) + get_bits(gb, rice->k);
-
+    } else {
+        av_log(ctx->avctx, AV_LOG_ERROR, "Too many bits: %d\n", rice->k);
+        return AVERROR_INVALIDDATA;
+    }
     rice->ksum += x - (rice->ksum + 8 >> 4);
     if (rice->ksum < (rice->k ? 1 << (rice->k + 4) : 0))
         rice->k--;
@@ -518,9 +521,13 @@
     } else
         tmpk = (rice->k < 1) ? 0 : rice->k - 1;
 
-    if (tmpk <= 16 || ctx->fileversion < 3910)
+    if (tmpk <= 16 || ctx->fileversion < 3910) {
+        if (tmpk > 23) {
+            av_log(ctx->avctx, AV_LOG_ERROR, "Too many bits: %d\n", tmpk);
+            return AVERROR_INVALIDDATA;
+        }
         x = range_decode_bits(ctx, tmpk);
-    else if (tmpk <= 32) {
+    } else if (tmpk <= 32) {
         x = range_decode_bits(ctx, 16);
         x |= (range_decode_bits(ctx, tmpk - 16) << 16);
     } else {
diff --git a/libavcodec/arm/Makefile b/libavcodec/arm/Makefile
index 5b717b7..9c64b36 100644
--- a/libavcodec/arm/Makefile
+++ b/libavcodec/arm/Makefile
@@ -1,115 +1,95 @@
 ARCH_HEADERS = mathops.h
 
+OBJS                                   += arm/fmtconvert_init_arm.o
+
+OBJS-$(CONFIG_AAC_DECODER)             += arm/aacpsdsp_init_arm.o       \
+                                          arm/sbrdsp_init_arm.o
 OBJS-$(CONFIG_AC3DSP)                  += arm/ac3dsp_init_arm.o         \
                                           arm/ac3dsp_arm.o
-
-OBJS-$(CONFIG_AAC_DECODER)             += arm/sbrdsp_init_arm.o         \
-                                          arm/aacpsdsp_init_arm.o
-
-OBJS-$(CONFIG_DCA_DECODER)             += arm/dcadsp_init_arm.o         \
-
-ARMV6-OBJS-$(CONFIG_AC3DSP)            += arm/ac3dsp_armv6.o
-
+OBJS-$(CONFIG_DCA_DECODER)             += arm/dcadsp_init_arm.o
+OBJS-$(CONFIG_DSPUTIL)                 += arm/dsputil_init_arm.o        \
+                                          arm/dsputil_arm.o             \
+                                          arm/jrevdct_arm.o             \
+                                          arm/simple_idct_arm.o
+OBJS-$(CONFIG_FFT)                     += arm/fft_init_arm.o            \
+                                          arm/fft_fixed_init_arm.o
 OBJS-$(CONFIG_FLAC_DECODER)            += arm/flacdsp_init_arm.o        \
-                                          arm/flacdsp_arm.o             \
-
+                                          arm/flacdsp_arm.o
+OBJS-$(CONFIG_H264CHROMA)              += arm/h264chroma_init_arm.o
+OBJS-$(CONFIG_H264DSP)                 += arm/h264dsp_init_arm.o
+OBJS-$(CONFIG_H264PRED)                += arm/h264pred_init_arm.o
+OBJS-$(CONFIG_H264QPEL)                += arm/h264qpel_init_arm.o
+OBJS-$(CONFIG_HPELDSP)                 += arm/hpeldsp_init_arm.o        \
+                                          arm/hpeldsp_arm.o
 OBJS-$(CONFIG_MPEGAUDIODSP)            += arm/mpegaudiodsp_init_arm.o
-ARMV6-OBJS-$(CONFIG_MPEGAUDIODSP)      += arm/mpegaudiodsp_fixed_armv6.o
-
 OBJS-$(CONFIG_MPEGVIDEO)               += arm/mpegvideo_arm.o
 OBJS-$(CONFIG_VORBIS_DECODER)          += arm/vorbisdsp_init_arm.o
 OBJS-$(CONFIG_VP3DSP)                  += arm/vp3dsp_init_arm.o
 OBJS-$(CONFIG_VP5_DECODER)             += arm/vp56dsp_init_arm.o
 OBJS-$(CONFIG_VP6_DECODER)             += arm/vp56dsp_init_arm.o
 OBJS-$(CONFIG_VP8_DECODER)             += arm/vp8dsp_init_arm.o
+OBJS-$(CONFIG_RV30_DECODER)            += arm/rv34dsp_init_arm.o
+OBJS-$(CONFIG_RV40_DECODER)            += arm/rv34dsp_init_arm.o        \
+                                          arm/rv40dsp_init_arm.o
+OBJS-$(CONFIG_VIDEODSP)                += arm/videodsp_init_arm.o       \
+
+ARMV5TE-OBJS-$(CONFIG_DSPUTIL)         += arm/dsputil_init_armv5te.o    \
+                                          arm/simple_idct_armv5te.o
+ARMV5TE-OBJS-$(CONFIG_MPEGVIDEO)       += arm/mpegvideo_armv5te.o       \
+                                          arm/mpegvideo_armv5te_s.o
+ARMV5TE-OBJS-$(CONFIG_VIDEODSP)        += arm/videodsp_init_armv5te.o   \
+                                          arm/videodsp_armv5te.o
+
+ARMV6-OBJS-$(CONFIG_DSPUTIL)           += arm/dsputil_init_armv6.o      \
+                                          arm/dsputil_armv6.o           \
+                                          arm/simple_idct_armv6.o       \
+
+ARMV6-OBJS-$(CONFIG_AC3DSP)            += arm/ac3dsp_armv6.o
+ARMV6-OBJS-$(CONFIG_H264DSP)           += arm/h264dsp_armv6.o
+ARMV6-OBJS-$(CONFIG_HPELDSP)           += arm/hpeldsp_init_armv6.o      \
+                                          arm/hpeldsp_armv6.o
+ARMV6-OBJS-$(CONFIG_MPEGAUDIODSP)      += arm/mpegaudiodsp_fixed_armv6.o
 ARMV6-OBJS-$(CONFIG_VP8_DECODER)       += arm/vp8_armv6.o               \
                                           arm/vp8dsp_init_armv6.o       \
                                           arm/vp8dsp_armv6.o
 
-OBJS-$(CONFIG_H264CHROMA)              += arm/h264chroma_init_arm.o
-OBJS-$(CONFIG_H264DSP)                 += arm/h264dsp_init_arm.o
-OBJS-$(CONFIG_H264PRED)                += arm/h264pred_init_arm.o
-OBJS-$(CONFIG_H264QPEL)                += arm/h264qpel_init_arm.o
-
-OBJS-$(CONFIG_HPELDSP)                 += arm/hpeldsp_init_arm.o        \
-                                          arm/hpeldsp_arm.o
-ARMV6-OBJS-$(CONFIG_HPELDSP)           += arm/hpeldsp_init_armv6.o      \
-                                          arm/hpeldsp_armv6.o
-
-OBJS-$(CONFIG_RV30_DECODER)            += arm/rv34dsp_init_arm.o
-OBJS-$(CONFIG_RV40_DECODER)            += arm/rv34dsp_init_arm.o        \
-                                          arm/rv40dsp_init_arm.o        \
-
-OBJS-$(CONFIG_VIDEODSP)                += arm/videodsp_init_arm.o       \
-
-OBJS                                   += arm/dsputil_init_arm.o        \
-                                          arm/dsputil_arm.o             \
-                                          arm/fft_init_arm.o            \
-                                          arm/fft_fixed_init_arm.o      \
-                                          arm/fmtconvert_init_arm.o     \
-                                          arm/jrevdct_arm.o             \
-                                          arm/simple_idct_arm.o         \
-
-ARMV5TE-OBJS-$(CONFIG_MPEGVIDEO)       += arm/mpegvideo_armv5te.o       \
-                                          arm/mpegvideo_armv5te_s.o     \
-
-ARMV5TE-OBJS-$(CONFIG_VIDEODSP)        += arm/videodsp_init_armv5te.o   \
-                                          arm/videodsp_armv5te.o        \
-
-ARMV5TE-OBJS                           += arm/dsputil_init_armv5te.o    \
-                                          arm/simple_idct_armv5te.o     \
-
-ARMV6-OBJS                             += arm/dsputil_init_armv6.o      \
-                                          arm/dsputil_armv6.o           \
-                                          arm/simple_idct_armv6.o       \
-
+VFP-OBJS-$(CONFIG_DCA_DECODER)         += arm/dcadsp_vfp.o              \
+                                          arm/synth_filter_vfp.o
+VFP-OBJS-$(CONFIG_FFT)                 += arm/fft_vfp.o
+VFP-OBJS-$(CONFIG_MDCT)                += arm/mdct_vfp.o
 VFP-OBJS-$(HAVE_ARMV6)                 += arm/fmtconvert_vfp.o
 
-NEON-OBJS-$(CONFIG_FFT)                += arm/fft_neon.o                \
-                                          arm/fft_fixed_neon.o          \
-
-NEON-OBJS-$(CONFIG_MDCT)               += arm/mdct_neon.o               \
-                                          arm/mdct_fixed_neon.o         \
-
-NEON-OBJS-$(CONFIG_RDFT)               += arm/rdft_neon.o               \
-
-NEON-OBJS-$(CONFIG_H264CHROMA)         += arm/h264cmc_neon.o
-NEON-OBJS-$(CONFIG_H264DSP)            += arm/h264dsp_neon.o            \
-                                          arm/h264idct_neon.o           \
-
-NEON-OBJS-$(CONFIG_H264PRED)           += arm/h264pred_neon.o           \
-
-NEON-OBJS-$(CONFIG_H264QPEL)           += arm/h264qpel_neon.o           \
+NEON-OBJS                              += arm/fmtconvert_neon.o
 
 NEON-OBJS-$(CONFIG_AC3DSP)             += arm/ac3dsp_neon.o
-
-NEON-OBJS-$(CONFIG_AAC_DECODER)        += arm/sbrdsp_neon.o             \
-                                          arm/aacpsdsp_neon.o
-
+NEON-OBJS-$(CONFIG_AAC_DECODER)        += arm/aacpsdsp_neon.o           \
+                                          arm/sbrdsp_neon.o
 NEON-OBJS-$(CONFIG_DCA_DECODER)        += arm/dcadsp_neon.o             \
-                                          arm/synth_filter_neon.o       \
-
+                                          arm/synth_filter_neon.o
+NEON-OBJS-$(CONFIG_DSPUTIL)            += arm/dsputil_init_neon.o       \
+                                          arm/dsputil_neon.o            \
+                                          arm/int_neon.o                \
+                                          arm/simple_idct_neon.o
+NEON-OBJS-$(CONFIG_FFT)                += arm/fft_neon.o                \
+                                          arm/fft_fixed_neon.o
+NEON-OBJS-$(CONFIG_H264CHROMA)         += arm/h264cmc_neon.o
+NEON-OBJS-$(CONFIG_H264DSP)            += arm/h264dsp_neon.o            \
+                                          arm/h264idct_neon.o
+NEON-OBJS-$(CONFIG_H264PRED)           += arm/h264pred_neon.o
+NEON-OBJS-$(CONFIG_H264QPEL)           += arm/h264qpel_neon.o           \
+                                          arm/hpeldsp_neon.o
 NEON-OBJS-$(CONFIG_HPELDSP)            += arm/hpeldsp_init_neon.o       \
                                           arm/hpeldsp_neon.o
-
+NEON-OBJS-$(CONFIG_MDCT)               += arm/mdct_neon.o               \
+                                          arm/mdct_fixed_neon.o
 NEON-OBJS-$(CONFIG_MPEGVIDEO)          += arm/mpegvideo_neon.o
+NEON-OBJS-$(CONFIG_RDFT)               += arm/rdft_neon.o
 NEON-OBJS-$(CONFIG_RV30_DECODER)       += arm/rv34dsp_neon.o
 NEON-OBJS-$(CONFIG_RV40_DECODER)       += arm/rv34dsp_neon.o            \
-                                          arm/rv40dsp_neon.o            \
-
+                                          arm/rv40dsp_neon.o
 NEON-OBJS-$(CONFIG_VORBIS_DECODER)     += arm/vorbisdsp_neon.o
-
 NEON-OBJS-$(CONFIG_VP3DSP)             += arm/vp3dsp_neon.o
-
-NEON-OBJS-$(CONFIG_VP5_DECODER)        += arm/vp56dsp_neon.o            \
-
-NEON-OBJS-$(CONFIG_VP6_DECODER)        += arm/vp56dsp_neon.o            \
-
+NEON-OBJS-$(CONFIG_VP5_DECODER)        += arm/vp56dsp_neon.o
+NEON-OBJS-$(CONFIG_VP6_DECODER)        += arm/vp56dsp_neon.o
 NEON-OBJS-$(CONFIG_VP8_DECODER)        += arm/vp8dsp_init_neon.o        \
                                           arm/vp8dsp_neon.o
-
-NEON-OBJS                              += arm/dsputil_init_neon.o       \
-                                          arm/dsputil_neon.o            \
-                                          arm/fmtconvert_neon.o         \
-                                          arm/int_neon.o                \
-                                          arm/simple_idct_neon.o        \
diff --git a/libavcodec/arm/dca.h b/libavcodec/arm/dca.h
index 431b62e..af37da8 100644
--- a/libavcodec/arm/dca.h
+++ b/libavcodec/arm/dca.h
@@ -30,9 +30,9 @@
 
 #define decode_blockcodes decode_blockcodes
 static inline int decode_blockcodes(int code1, int code2, int levels,
-                                    int *values)
+                                    int32_t *values)
 {
-    int v0, v1, v2, v3, v4, v5;
+    int32_t v0, v1, v2, v3, v4, v5;
 
     __asm__ ("smmul   %0,  %6,  %10           \n"
              "smmul   %3,  %7,  %10           \n"
diff --git a/libavcodec/arm/dcadsp_init_arm.c b/libavcodec/arm/dcadsp_init_arm.c
index 56568e0..58267a2 100644
--- a/libavcodec/arm/dcadsp_init_arm.c
+++ b/libavcodec/arm/dcadsp_init_arm.c
@@ -24,6 +24,14 @@
 #include "libavutil/attributes.h"
 #include "libavcodec/dcadsp.h"
 
+void ff_dca_lfe_fir_vfp(float *out, const float *in, const float *coefs,
+                        int decifactor, float scale);
+void ff_dca_qmf_32_subbands_vfp(float samples_in[32][8], int sb_act,
+                                SynthFilterContext *synth, FFTContext *imdct,
+                                float synth_buf_ptr[512],
+                                int *synth_buf_offset, float synth_buf2[32],
+                                const float window[512], float *samples_out,
+                                float raXin[32], float scale);
 void ff_dca_lfe_fir_neon(float *out, const float *in, const float *coefs,
                          int decifactor, float scale);
 
@@ -31,6 +39,10 @@
 {
     int cpu_flags = av_get_cpu_flags();
 
+    if (have_vfp(cpu_flags) && !have_vfpv3(cpu_flags)) {
+        s->lfe_fir = ff_dca_lfe_fir_vfp;
+        s->qmf_32_subbands = ff_dca_qmf_32_subbands_vfp;
+    }
     if (have_neon(cpu_flags))
         s->lfe_fir = ff_dca_lfe_fir_neon;
 }
diff --git a/libavcodec/arm/dcadsp_vfp.S b/libavcodec/arm/dcadsp_vfp.S
new file mode 100644
index 0000000..b23ce4a
--- /dev/null
+++ b/libavcodec/arm/dcadsp_vfp.S
@@ -0,0 +1,493 @@
+/*
+ * Copyright (c) 2013 RISC OS Open Ltd
+ * Author: Ben Avison <bavison@riscosopen.org>
+ *
+ * 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
+ */
+
+#include "libavutil/arm/asm.S"
+
+POUT          .req    a1
+PIN           .req    a2
+PCOEF         .req    a3
+DECIFACTOR    .req    a4
+OLDFPSCR      .req    a4
+COUNTER       .req    ip
+
+SCALE32       .req    s28  @ use vector of 4 in place of 9th scalar when decifactor=32 / JMAX=8
+SCALE64       .req    s0   @ spare register in scalar bank when decifactor=64 / JMAX=4
+IN0           .req    s4
+IN1           .req    s5
+IN2           .req    s6
+IN3           .req    s7
+IN4           .req    s0
+IN5           .req    s1
+IN6           .req    s2
+IN7           .req    s3
+COEF0         .req    s8   @ coefficient elements
+COEF1         .req    s9
+COEF2         .req    s10
+COEF3         .req    s11
+COEF4         .req    s12
+COEF5         .req    s13
+COEF6         .req    s14
+COEF7         .req    s15
+ACCUM0        .req    s16  @ double-buffered multiply-accumulate results
+ACCUM4        .req    s20
+POST0         .req    s24  @ do long-latency post-multiply in this vector in parallel
+POST1         .req    s25
+POST2         .req    s26
+POST3         .req    s27
+
+
+.macro inner_loop  decifactor, dir, tail, head
+ .ifc "\dir","up"
+  .set X, 0
+  .set Y, 4
+ .else
+  .set X, 4*JMAX*4 - 4
+  .set Y, -4
+ .endif
+ .ifnc "\head",""
+        vldr    COEF0, [PCOEF, #X + (0*JMAX + 0) * Y]
+        vldr    COEF1, [PCOEF, #X + (1*JMAX + 0) * Y]
+        vldr    COEF2, [PCOEF, #X + (2*JMAX + 0) * Y]
+        vldr    COEF3, [PCOEF, #X + (3*JMAX + 0) * Y]
+ .endif
+ .ifnc "\tail",""
+        vadd.f  POST0, ACCUM0, ACCUM4   @ vector operation
+ .endif
+ .ifnc "\head",""
+        vmul.f  ACCUM0, COEF0, IN0      @ vector = vector * scalar
+        vldr    COEF4, [PCOEF, #X + (0*JMAX + 1) * Y]
+        vldr    COEF5, [PCOEF, #X + (1*JMAX + 1) * Y]
+        vldr    COEF6, [PCOEF, #X + (2*JMAX + 1) * Y]
+ .endif
+ .ifnc "\tail",""
+        vmul.f  POST0, POST0, SCALE\decifactor  @ vector operation (SCALE may be scalar)
+ .endif
+ .ifnc "\head",""
+        vldr    COEF7, [PCOEF, #X + (3*JMAX + 1) * Y]
+   .ifc "\tail",""
+        vmul.f  ACCUM4, COEF4, IN1      @ vector operation
+   .endif
+        vldr    COEF0, [PCOEF, #X + (0*JMAX + 2) * Y]
+        vldr    COEF1, [PCOEF, #X + (1*JMAX + 2) * Y]
+   .ifnc "\tail",""
+        vmul.f  ACCUM4, COEF4, IN1      @ vector operation
+   .endif
+        vldr    COEF2, [PCOEF, #X + (2*JMAX + 2) * Y]
+        vldr    COEF3, [PCOEF, #X + (3*JMAX + 2) * Y]
+ .endif
+ .ifnc "\tail",""
+        vstmia  POUT!, {POST0-POST3}
+ .endif
+ .ifnc "\head",""
+        vmla.f  ACCUM0, COEF0, IN2      @ vector = vector * scalar
+        vldr    COEF4, [PCOEF, #X + (0*JMAX + 3) * Y]
+        vldr    COEF5, [PCOEF, #X + (1*JMAX + 3) * Y]
+        vldr    COEF6, [PCOEF, #X + (2*JMAX + 3) * Y]
+        vldr    COEF7, [PCOEF, #X + (3*JMAX + 3) * Y]
+        vmla.f  ACCUM4, COEF4, IN3      @ vector = vector * scalar
+  .if \decifactor == 32
+        vldr    COEF0, [PCOEF, #X + (0*JMAX + 4) * Y]
+        vldr    COEF1, [PCOEF, #X + (1*JMAX + 4) * Y]
+        vldr    COEF2, [PCOEF, #X + (2*JMAX + 4) * Y]
+        vldr    COEF3, [PCOEF, #X + (3*JMAX + 4) * Y]
+        vmla.f  ACCUM0, COEF0, IN4      @ vector = vector * scalar
+        vldr    COEF4, [PCOEF, #X + (0*JMAX + 5) * Y]
+        vldr    COEF5, [PCOEF, #X + (1*JMAX + 5) * Y]
+        vldr    COEF6, [PCOEF, #X + (2*JMAX + 5) * Y]
+        vldr    COEF7, [PCOEF, #X + (3*JMAX + 5) * Y]
+        vmla.f  ACCUM4, COEF4, IN5      @ vector = vector * scalar
+        vldr    COEF0, [PCOEF, #X + (0*JMAX + 6) * Y]
+        vldr    COEF1, [PCOEF, #X + (1*JMAX + 6) * Y]
+        vldr    COEF2, [PCOEF, #X + (2*JMAX + 6) * Y]
+        vldr    COEF3, [PCOEF, #X + (3*JMAX + 6) * Y]
+        vmla.f  ACCUM0, COEF0, IN6      @ vector = vector * scalar
+        vldr    COEF4, [PCOEF, #X + (0*JMAX + 7) * Y]
+        vldr    COEF5, [PCOEF, #X + (1*JMAX + 7) * Y]
+        vldr    COEF6, [PCOEF, #X + (2*JMAX + 7) * Y]
+        vldr    COEF7, [PCOEF, #X + (3*JMAX + 7) * Y]
+        vmla.f  ACCUM4, COEF4, IN7      @ vector = vector * scalar
+  .endif
+ .endif
+.endm
+
+.macro dca_lfe_fir  decifactor
+ .if \decifactor == 32
+  .set JMAX, 8
+        vpush   {s16-s31}
+        vmov    SCALE32, s0             @ duplicate scalar across vector
+        vldr    IN4, [PIN, #-4*4]
+        vldr    IN5, [PIN, #-5*4]
+        vldr    IN6, [PIN, #-6*4]
+        vldr    IN7, [PIN, #-7*4]
+ .else
+  .set JMAX, 4
+        vpush   {s16-s27}
+ .endif
+
+        mov     COUNTER, #\decifactor/4 - 1
+        inner_loop  \decifactor, up,, head
+1:      add     PCOEF, PCOEF, #4*JMAX*4
+        subs    COUNTER, COUNTER, #1
+        inner_loop  \decifactor, up, tail, head
+        bne     1b
+        inner_loop  \decifactor, up, tail
+
+        mov     COUNTER, #\decifactor/4 - 1
+        inner_loop  \decifactor, down,, head
+1:      sub     PCOEF, PCOEF, #4*JMAX*4
+        subs    COUNTER, COUNTER, #1
+        inner_loop  \decifactor, down, tail, head
+        bne     1b
+        inner_loop  \decifactor, down, tail
+
+ .if \decifactor == 32
+        vpop    {s16-s31}
+ .else
+        vpop    {s16-s27}
+ .endif
+        fmxr    FPSCR, OLDFPSCR
+        bx      lr
+.endm
+
+
+/* void ff_dca_lfe_fir_vfp(float *out, const float *in, const float *coefs,
+ *                         int decifactor, float scale)
+ */
+function ff_dca_lfe_fir_vfp, export=1
+        teq     DECIFACTOR, #32
+        fmrx    OLDFPSCR, FPSCR
+        ldr     ip, =0x03030000         @ RunFast mode, short vectors of length 4, stride 1
+        fmxr    FPSCR, ip
+NOVFP   vldr    s0, [sp]
+        vldr    IN0, [PIN, #-0*4]
+        vldr    IN1, [PIN, #-1*4]
+        vldr    IN2, [PIN, #-2*4]
+        vldr    IN3, [PIN, #-3*4]
+        beq     32f
+64:     dca_lfe_fir  64
+ .ltorg
+32:     dca_lfe_fir  32
+endfunc
+
+        .unreq  POUT
+        .unreq  PIN
+        .unreq  PCOEF
+        .unreq  DECIFACTOR
+        .unreq  OLDFPSCR
+        .unreq  COUNTER
+
+        .unreq  SCALE32
+        .unreq  SCALE64
+        .unreq  IN0
+        .unreq  IN1
+        .unreq  IN2
+        .unreq  IN3
+        .unreq  IN4
+        .unreq  IN5
+        .unreq  IN6
+        .unreq  IN7
+        .unreq  COEF0
+        .unreq  COEF1
+        .unreq  COEF2
+        .unreq  COEF3
+        .unreq  COEF4
+        .unreq  COEF5
+        .unreq  COEF6
+        .unreq  COEF7
+        .unreq  ACCUM0
+        .unreq  ACCUM4
+        .unreq  POST0
+        .unreq  POST1
+        .unreq  POST2
+        .unreq  POST3
+
+
+IN      .req    a1
+SBACT   .req    a2
+OLDFPSCR .req   a3
+IMDCT   .req    a4
+WINDOW  .req    v1
+OUT     .req    v2
+BUF     .req    v3
+SCALEINT .req   v4 @ only used in softfp case
+COUNT   .req    v5
+
+SCALE   .req    s0
+
+/* Stack layout differs in softfp and hardfp cases:
+ *
+ * hardfp
+ *      fp -> 6 arg words saved by caller
+ *            a3,a4,v1-v3,v5,fp,lr on entry (a3 just to pad to 8 bytes)
+ *            s16-s23 on entry
+ *            align 16
+ *     buf -> 8*32*4 bytes buffer
+ *            s0 on entry
+ *      sp -> 3 arg words for callee
+ *
+ * softfp
+ *      fp -> 7 arg words saved by caller
+ *            a4,v1-v5,fp,lr on entry
+ *            s16-s23 on entry
+ *            align 16
+ *     buf -> 8*32*4 bytes buffer
+ *      sp -> 4 arg words for callee
+ */
+
+/* void ff_dca_qmf_32_subbands_vfp(float samples_in[32][8], int sb_act,
+ *                                 SynthFilterContext *synth, FFTContext *imdct,
+ *                                 float (*synth_buf_ptr)[512],
+ *                                 int *synth_buf_offset, float (*synth_buf2)[32],
+ *                                 const float (*window)[512], float *samples_out,
+ *                                 float (*raXin)[32], float scale);
+ */
+function ff_dca_qmf_32_subbands_vfp, export=1
+VFP     push    {a3-a4,v1-v3,v5,fp,lr}
+NOVFP   push    {a4,v1-v5,fp,lr}
+        add     fp, sp, #8*4
+        vpush   {s16-s23}
+        @ The buffer pointed at by raXin isn't big enough for us to do a
+        @ complete matrix transposition as we want to, so allocate an
+        @ alternative buffer from the stack. Align to 4 words for speed.
+        sub     BUF, sp, #8*32*4
+        bic     BUF, BUF, #15
+        mov     sp, BUF
+        ldr     lr, =0x03330000     @ RunFast mode, short vectors of length 4, stride 2
+        fmrx    OLDFPSCR, FPSCR
+        fmxr    FPSCR, lr
+        @ COUNT is used to count down 2 things at once:
+        @ bits 0-4 are the number of word pairs remaining in the output row
+        @ bits 5-31 are the number of words to copy (with possible negation)
+        @   from the source matrix before we start zeroing the remainder
+        mov     COUNT, #(-4 << 5) + 16
+        adds    COUNT, COUNT, SBACT, lsl #5
+        bmi     2f
+1:
+        vldr    s8,  [IN, #(0*8+0)*4]
+        vldr    s10, [IN, #(0*8+1)*4]
+        vldr    s12, [IN, #(0*8+2)*4]
+        vldr    s14, [IN, #(0*8+3)*4]
+        vldr    s16, [IN, #(0*8+4)*4]
+        vldr    s18, [IN, #(0*8+5)*4]
+        vldr    s20, [IN, #(0*8+6)*4]
+        vldr    s22, [IN, #(0*8+7)*4]
+        vneg.f  s8, s8
+        vldr    s9,  [IN, #(1*8+0)*4]
+        vldr    s11, [IN, #(1*8+1)*4]
+        vldr    s13, [IN, #(1*8+2)*4]
+        vldr    s15, [IN, #(1*8+3)*4]
+        vneg.f  s16, s16
+        vldr    s17, [IN, #(1*8+4)*4]
+        vldr    s19, [IN, #(1*8+5)*4]
+        vldr    s21, [IN, #(1*8+6)*4]
+        vldr    s23, [IN, #(1*8+7)*4]
+        vstr    d4,  [BUF, #(0*32+0)*4]
+        vstr    d5,  [BUF, #(1*32+0)*4]
+        vstr    d6,  [BUF, #(2*32+0)*4]
+        vstr    d7,  [BUF, #(3*32+0)*4]
+        vstr    d8,  [BUF, #(4*32+0)*4]
+        vstr    d9,  [BUF, #(5*32+0)*4]
+        vstr    d10, [BUF, #(6*32+0)*4]
+        vstr    d11, [BUF, #(7*32+0)*4]
+        vldr    s9,  [IN, #(3*8+0)*4]
+        vldr    s11, [IN, #(3*8+1)*4]
+        vldr    s13, [IN, #(3*8+2)*4]
+        vldr    s15, [IN, #(3*8+3)*4]
+        vldr    s17, [IN, #(3*8+4)*4]
+        vldr    s19, [IN, #(3*8+5)*4]
+        vldr    s21, [IN, #(3*8+6)*4]
+        vldr    s23, [IN, #(3*8+7)*4]
+        vneg.f  s9, s9
+        vldr    s8,  [IN, #(2*8+0)*4]
+        vldr    s10, [IN, #(2*8+1)*4]
+        vldr    s12, [IN, #(2*8+2)*4]
+        vldr    s14, [IN, #(2*8+3)*4]
+        vneg.f  s17, s17
+        vldr    s16, [IN, #(2*8+4)*4]
+        vldr    s18, [IN, #(2*8+5)*4]
+        vldr    s20, [IN, #(2*8+6)*4]
+        vldr    s22, [IN, #(2*8+7)*4]
+        vstr    d4,  [BUF, #(0*32+2)*4]
+        vstr    d5,  [BUF, #(1*32+2)*4]
+        vstr    d6,  [BUF, #(2*32+2)*4]
+        vstr    d7,  [BUF, #(3*32+2)*4]
+        vstr    d8,  [BUF, #(4*32+2)*4]
+        vstr    d9,  [BUF, #(5*32+2)*4]
+        vstr    d10, [BUF, #(6*32+2)*4]
+        vstr    d11, [BUF, #(7*32+2)*4]
+        add     IN, IN, #4*8*4
+        add     BUF, BUF, #4*4
+        subs    COUNT, COUNT, #(4 << 5) + 2
+        bpl     1b
+2:      @ Now deal with trailing < 4 samples
+        adds    COUNT, COUNT, #3 << 5
+        bmi     4f  @ sb_act was a multiple of 4
+        bics    lr, COUNT, #0x1F
+        bne     3f
+        @ sb_act was n*4+1
+        vldr    s8,  [IN, #(0*8+0)*4]
+        vldr    s10, [IN, #(0*8+1)*4]
+        vldr    s12, [IN, #(0*8+2)*4]
+        vldr    s14, [IN, #(0*8+3)*4]
+        vldr    s16, [IN, #(0*8+4)*4]
+        vldr    s18, [IN, #(0*8+5)*4]
+        vldr    s20, [IN, #(0*8+6)*4]
+        vldr    s22, [IN, #(0*8+7)*4]
+        vneg.f  s8, s8
+        vldr    s9,  zero
+        vldr    s11, zero
+        vldr    s13, zero
+        vldr    s15, zero
+        vneg.f  s16, s16
+        vldr    s17, zero
+        vldr    s19, zero
+        vldr    s21, zero
+        vldr    s23, zero
+        vstr    d4,  [BUF, #(0*32+0)*4]
+        vstr    d5,  [BUF, #(1*32+0)*4]
+        vstr    d6,  [BUF, #(2*32+0)*4]
+        vstr    d7,  [BUF, #(3*32+0)*4]
+        vstr    d8,  [BUF, #(4*32+0)*4]
+        vstr    d9,  [BUF, #(5*32+0)*4]
+        vstr    d10, [BUF, #(6*32+0)*4]
+        vstr    d11, [BUF, #(7*32+0)*4]
+        add     BUF, BUF, #2*4
+        sub     COUNT, COUNT, #1
+        b       4f
+3:      @ sb_act was n*4+2 or n*4+3, so do the first 2
+        vldr    s8,  [IN, #(0*8+0)*4]
+        vldr    s10, [IN, #(0*8+1)*4]
+        vldr    s12, [IN, #(0*8+2)*4]
+        vldr    s14, [IN, #(0*8+3)*4]
+        vldr    s16, [IN, #(0*8+4)*4]
+        vldr    s18, [IN, #(0*8+5)*4]
+        vldr    s20, [IN, #(0*8+6)*4]
+        vldr    s22, [IN, #(0*8+7)*4]
+        vneg.f  s8, s8
+        vldr    s9,  [IN, #(1*8+0)*4]
+        vldr    s11, [IN, #(1*8+1)*4]
+        vldr    s13, [IN, #(1*8+2)*4]
+        vldr    s15, [IN, #(1*8+3)*4]
+        vneg.f  s16, s16
+        vldr    s17, [IN, #(1*8+4)*4]
+        vldr    s19, [IN, #(1*8+5)*4]
+        vldr    s21, [IN, #(1*8+6)*4]
+        vldr    s23, [IN, #(1*8+7)*4]
+        vstr    d4,  [BUF, #(0*32+0)*4]
+        vstr    d5,  [BUF, #(1*32+0)*4]
+        vstr    d6,  [BUF, #(2*32+0)*4]
+        vstr    d7,  [BUF, #(3*32+0)*4]
+        vstr    d8,  [BUF, #(4*32+0)*4]
+        vstr    d9,  [BUF, #(5*32+0)*4]
+        vstr    d10, [BUF, #(6*32+0)*4]
+        vstr    d11, [BUF, #(7*32+0)*4]
+        add     BUF, BUF, #2*4
+        sub     COUNT, COUNT, #(2 << 5) + 1
+        bics    lr, COUNT, #0x1F
+        bne     4f
+        @ sb_act was n*4+3
+        vldr    s8,  [IN, #(2*8+0)*4]
+        vldr    s10, [IN, #(2*8+1)*4]
+        vldr    s12, [IN, #(2*8+2)*4]
+        vldr    s14, [IN, #(2*8+3)*4]
+        vldr    s16, [IN, #(2*8+4)*4]
+        vldr    s18, [IN, #(2*8+5)*4]
+        vldr    s20, [IN, #(2*8+6)*4]
+        vldr    s22, [IN, #(2*8+7)*4]
+        vldr    s9,  zero
+        vldr    s11, zero
+        vldr    s13, zero
+        vldr    s15, zero
+        vldr    s17, zero
+        vldr    s19, zero
+        vldr    s21, zero
+        vldr    s23, zero
+        vstr    d4,  [BUF, #(0*32+0)*4]
+        vstr    d5,  [BUF, #(1*32+0)*4]
+        vstr    d6,  [BUF, #(2*32+0)*4]
+        vstr    d7,  [BUF, #(3*32+0)*4]
+        vstr    d8,  [BUF, #(4*32+0)*4]
+        vstr    d9,  [BUF, #(5*32+0)*4]
+        vstr    d10, [BUF, #(6*32+0)*4]
+        vstr    d11, [BUF, #(7*32+0)*4]
+        add     BUF, BUF, #2*4
+        sub     COUNT, COUNT, #1
+4:      @ Now fill the remainder with 0
+        vldr    s8, zero
+        vldr    s9, zero
+        ands    COUNT, COUNT, #0x1F
+        beq     6f
+5:      vstr    d4, [BUF, #(0*32+0)*4]
+        vstr    d4, [BUF, #(1*32+0)*4]
+        vstr    d4, [BUF, #(2*32+0)*4]
+        vstr    d4, [BUF, #(3*32+0)*4]
+        vstr    d4, [BUF, #(4*32+0)*4]
+        vstr    d4, [BUF, #(5*32+0)*4]
+        vstr    d4, [BUF, #(6*32+0)*4]
+        vstr    d4, [BUF, #(7*32+0)*4]
+        add     BUF, BUF, #2*4
+        subs    COUNT, COUNT, #1
+        bne     5b
+6:
+        fmxr    FPSCR, OLDFPSCR
+        ldr     WINDOW, [fp, #3*4]
+        ldr     OUT, [fp, #4*4]
+        sub     BUF, BUF, #32*4
+NOVFP   ldr     SCALEINT, [fp, #6*4]
+        mov     COUNT, #8
+VFP     vpush   {SCALE}
+VFP     sub     sp, sp, #3*4
+NOVFP   sub     sp, sp, #4*4
+7:
+VFP     ldr     a1, [fp, #-7*4]     @ imdct
+NOVFP   ldr     a1, [fp, #-8*4]
+        ldmia   fp, {a2-a4}
+VFP     stmia   sp, {WINDOW, OUT, BUF}
+NOVFP   stmia   sp, {WINDOW, OUT, BUF, SCALEINT}
+VFP     vldr    SCALE, [sp, #3*4]
+        bl      X(ff_synth_filter_float_vfp)
+        add     OUT, OUT, #32*4
+        add     BUF, BUF, #32*4
+        subs    COUNT, COUNT, #1
+        bne     7b
+
+A       sub     sp, fp, #(8+8)*4
+T       sub     fp, fp, #(8+8)*4
+T       mov     sp, fp
+        vpop    {s16-s23}
+VFP     pop     {a3-a4,v1-v3,v5,fp,pc}
+NOVFP   pop     {a4,v1-v5,fp,pc}
+endfunc
+
+        .unreq  IN
+        .unreq  SBACT
+        .unreq  OLDFPSCR
+        .unreq  IMDCT
+        .unreq  WINDOW
+        .unreq  OUT
+        .unreq  BUF
+        .unreq  SCALEINT
+        .unreq  COUNT
+
+        .unreq  SCALE
+
+        .align 2
+zero:   .word   0
diff --git a/libavcodec/arm/fft_init_arm.c b/libavcodec/arm/fft_init_arm.c
index 8c98abc..a000ea5 100644
--- a/libavcodec/arm/fft_init_arm.c
+++ b/libavcodec/arm/fft_init_arm.c
@@ -26,12 +26,20 @@
 void ff_fft_permute_neon(FFTContext *s, FFTComplex *z);
 void ff_fft_calc_neon(FFTContext *s, FFTComplex *z);
 
+void ff_imdct_half_vfp(FFTContext *s, FFTSample *output, const FFTSample *input);
+
 void ff_imdct_calc_neon(FFTContext *s, FFTSample *output, const FFTSample *input);
 void ff_imdct_half_neon(FFTContext *s, FFTSample *output, const FFTSample *input);
 void ff_mdct_calc_neon(FFTContext *s, FFTSample *output, const FFTSample *input);
 
 void ff_rdft_calc_neon(struct RDFTContext *s, FFTSample *z);
 
+void ff_synth_filter_float_vfp(FFTContext *imdct,
+                               float *synth_buf_ptr, int *synth_buf_offset,
+                               float synth_buf2[32], const float window[512],
+                               float out[32], const float in[32],
+                               float scale);
+
 void ff_synth_filter_float_neon(FFTContext *imdct,
                                 float *synth_buf_ptr, int *synth_buf_offset,
                                 float synth_buf2[32], const float window[512],
@@ -42,6 +50,13 @@
 {
     int cpu_flags = av_get_cpu_flags();
 
+    if (have_vfp(cpu_flags)) {
+#if CONFIG_MDCT
+        if (!have_vfpv3(cpu_flags))
+            s->imdct_half   = ff_imdct_half_vfp;
+#endif
+    }
+
     if (have_neon(cpu_flags)) {
 #if CONFIG_FFT
         s->fft_permute  = ff_fft_permute_neon;
@@ -71,6 +86,8 @@
 {
     int cpu_flags = av_get_cpu_flags();
 
+    if (have_vfp(cpu_flags) && !have_vfpv3(cpu_flags))
+        s->synth_filter_float = ff_synth_filter_float_vfp;
     if (have_neon(cpu_flags))
         s->synth_filter_float = ff_synth_filter_float_neon;
 }
diff --git a/libavcodec/arm/fft_vfp.S b/libavcodec/arm/fft_vfp.S
new file mode 100644
index 0000000..f1ab37c
--- /dev/null
+++ b/libavcodec/arm/fft_vfp.S
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2013 RISC OS Open Ltd
+ * Author: Ben Avison <bavison@riscosopen.org>
+ *
+ * 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
+ */
+
+#include "libavutil/arm/asm.S"
+
+@ TODO: * FFTs wider than 16
+@       * dispatch code
+
+function fft4_vfp
+        vldr    d0, [a1, #0*2*4]   @ s0,s1   = z[0]
+        vldr    d4, [a1, #1*2*4]   @ s8,s9   = z[1]
+        vldr    d1, [a1, #2*2*4]   @ s2,s3   = z[2]
+        vldr    d5, [a1, #3*2*4]   @ s10,s11 = z[3]
+        @ stall
+        vadd.f  s12, s0, s8        @ i0
+        vadd.f  s13, s1, s9        @ i1
+        vadd.f  s14, s2, s10       @ i2
+        vadd.f  s15, s3, s11       @ i3
+        vsub.f  s8, s0, s8         @ i4
+        vsub.f  s9, s1, s9         @ i5
+        vsub.f  s10, s2, s10       @ i6
+        vsub.f  s11, s3, s11       @ i7
+        @ stall
+        @ stall
+        vadd.f  s0, s12, s14       @ z[0].re
+        vsub.f  s4, s12, s14       @ z[2].re
+        vadd.f  s1, s13, s15       @ z[0].im
+        vsub.f  s5, s13, s15       @ z[2].im
+        vadd.f  s7, s9, s10        @ z[3].im
+        vsub.f  s3, s9, s10        @ z[1].im
+        vadd.f  s2, s8, s11        @ z[1].re
+        vsub.f  s6, s8, s11        @ z[3].re
+        @ stall
+        @ stall
+        vstr    d0, [a1, #0*2*4]
+        vstr    d2, [a1, #2*2*4]
+        @ stall
+        @ stall
+        vstr    d1, [a1, #1*2*4]
+        vstr    d3, [a1, #3*2*4]
+
+        bx      lr
+endfunc
+
+.macro macro_fft8_head
+        @ FFT4
+        vldr    d4, [a1, #0 * 2*4]
+        vldr    d6, [a1, #1 * 2*4]
+        vldr    d5, [a1, #2 * 2*4]
+        vldr    d7, [a1, #3 * 2*4]
+            @ BF
+            vldr    d12, [a1, #4 * 2*4]
+        vadd.f  s16, s8, s12    @ vector op
+            vldr    d14, [a1, #5 * 2*4]
+            vldr    d13, [a1, #6 * 2*4]
+            vldr    d15, [a1, #7 * 2*4]
+        vsub.f  s20, s8, s12    @ vector op
+        vadd.f  s0, s16, s18
+        vsub.f  s2, s16, s18
+        vadd.f  s1, s17, s19
+        vsub.f  s3, s17, s19
+        vadd.f  s7, s21, s22
+        vsub.f  s5, s21, s22
+        vadd.f  s4, s20, s23
+        vsub.f  s6, s20, s23
+            vsub.f  s20, s24, s28   @ vector op
+        vstr    d0, [a1, #0 * 2*4]  @ transfer s0-s7 to s24-s31 via memory
+        vstr    d1, [a1, #1 * 2*4]
+        vldr    s0, cos1pi4
+            vadd.f  s16, s24, s28   @ vector op
+        vstr    d2, [a1, #2 * 2*4]
+        vstr    d3, [a1, #3 * 2*4]
+        vldr    d12, [a1, #0 * 2*4]
+            @ TRANSFORM
+            vmul.f  s20, s20, s0    @ vector x scalar op
+        vldr    d13, [a1, #1 * 2*4]
+        vldr    d14, [a1, #2 * 2*4]
+        vldr    d15, [a1, #3 * 2*4]
+        @ BUTTERFLIES
+        vadd.f  s0, s18, s16
+        vadd.f  s1, s17, s19
+        vsub.f  s2, s17, s19
+        vsub.f  s3, s18, s16
+            vadd.f  s4, s21, s20
+            vsub.f  s5, s21, s20
+            vadd.f  s6, s22, s23
+            vsub.f  s7, s22, s23
+        vadd.f  s8, s0, s24         @ vector op
+        vstr    d0, [a1, #0 * 2*4]  @ transfer s0-s3 to s12-s15 via memory
+        vstr    d1, [a1, #1 * 2*4]
+        vldr    d6, [a1, #0 * 2*4]
+        vldr    d7, [a1, #1 * 2*4]
+            vadd.f  s1, s5, s6
+            vadd.f  s0, s7, s4
+            vsub.f  s2, s5, s6
+            vsub.f  s3, s7, s4
+        vsub.f  s12, s24, s12       @ vector op
+            vsub.f  s5, s29, s1
+            vsub.f  s4, s28, s0
+            vsub.f  s6, s30, s2
+            vsub.f  s7, s31, s3
+            vadd.f  s16, s0, s28    @ vector op
+        vstr    d6, [a1, #4 * 2*4]
+        vstr    d7, [a1, #6 * 2*4]
+        vstr    d4, [a1, #0 * 2*4]
+        vstr    d5, [a1, #2 * 2*4]
+             vstr    d2, [a1, #5 * 2*4]
+             vstr    d3, [a1, #7 * 2*4]
+.endm
+
+.macro macro_fft8_tail
+             vstr    d8, [a1, #1 * 2*4]
+             vstr    d9, [a1, #3 * 2*4]
+.endm
+
+function fft8_vfp
+        ldr     a3, =0x03030000     @ RunFast mode, vector length 4, stride 1
+        fmrx    a2, FPSCR
+        fmxr    FPSCR, a3
+        vpush   {s16-s31}
+
+        macro_fft8_head
+        macro_fft8_tail
+
+        vpop    {s16-s31}
+        fmxr    FPSCR, a2
+        bx      lr
+endfunc
+
+.align 3
+cos1pi4:    @ cos(1*pi/4) = sqrt(2)
+        .float  0.707106769084930419921875
+cos1pi8:    @ cos(1*pi/8) = sqrt(2+sqrt(2))/2
+        .float  0.92387950420379638671875
+cos3pi8:    @ cos(2*pi/8) = sqrt(2-sqrt(2))/2
+        .float  0.3826834261417388916015625
+
+function ff_fft16_vfp, export=1
+        ldr     a3, =0x03030000     @ RunFast mode, vector length 4, stride 1
+        fmrx    a2, FPSCR
+        fmxr    FPSCR, a3
+        vpush   {s16-s31}
+
+        macro_fft8_head
+        @ FFT4(z+8)
+        vldr    d10, [a1, #8 * 2*4]
+        vldr    d12, [a1, #9 * 2*4]
+        vldr    d11, [a1, #10 * 2*4]
+        vldr    d13, [a1, #11 * 2*4]
+        macro_fft8_tail
+        vadd.f  s16, s20, s24   @ vector op
+            @ FFT4(z+12)
+            vldr    d4, [a1, #12 * 2*4]
+            vldr    d6, [a1, #13 * 2*4]
+            vldr    d5, [a1, #14 * 2*4]
+        vsub.f  s20, s20, s24   @ vector op
+            vldr    d7, [a1, #15 * 2*4]
+        vadd.f  s0, s16, s18
+        vsub.f  s4, s16, s18
+        vadd.f  s1, s17, s19
+        vsub.f  s5, s17, s19
+        vadd.f  s7, s21, s22
+        vsub.f  s3, s21, s22
+        vadd.f  s2, s20, s23
+        vsub.f  s6, s20, s23
+            vadd.f  s16, s8, s12    @ vector op
+        vstr    d0, [a1, #8 * 2*4]
+        vstr    d2, [a1, #10 * 2*4]
+        vstr    d1, [a1, #9 * 2*4]
+            vsub.f  s20, s8, s12
+        vstr    d3, [a1, #11 * 2*4]
+        @ TRANSFORM(z[2],z[6],z[10],z[14],cos1pi4,cos1pi4)
+        vldr    d12, [a1, #10 * 2*4]
+            vadd.f  s0, s16, s18
+            vadd.f  s1, s17, s19
+            vsub.f  s6, s16, s18
+            vsub.f  s7, s17, s19
+            vsub.f  s3, s21, s22
+            vadd.f  s2, s20, s23
+            vadd.f  s5, s21, s22
+            vsub.f  s4, s20, s23
+            vstr    d0, [a1, #12 * 2*4]
+        vmov    s0, s6
+          @ TRANSFORM(z[1],z[5],z[9],z[13],cos1pi8,cos3pi8)
+          vldr    d6, [a1, #9 * 2*4]
+            vstr    d1, [a1, #13 * 2*4]
+        vldr    d1, cos1pi4 @ s2 = cos1pi4, s3 = cos1pi8
+            vstr    d2, [a1, #15 * 2*4]
+          vldr    d7, [a1, #13 * 2*4]
+        vadd.f  s4, s25, s24
+        vsub.f  s5, s25, s24
+        vsub.f  s6, s0, s7
+        vadd.f  s7, s0, s7
+          vmul.f  s20, s12, s3  @ vector op
+            @ TRANSFORM(z[3],z[7],z[11],z[15],cos3pi8,cos1pi8)
+            vldr    d4, [a1, #11 * 2*4]
+            vldr    d5, [a1, #15 * 2*4]
+            vldr    s1, cos3pi8
+        vmul.f  s24, s4, s2     @ vector * scalar op
+          vmul.f  s28, s12, s1  @ vector * scalar op
+            vmul.f  s12, s8, s1 @ vector * scalar op
+          vadd.f  s4, s20, s29
+          vsub.f  s5, s21, s28
+          vsub.f  s6, s22, s31
+          vadd.f  s7, s23, s30
+            vmul.f  s8, s8, s3  @ vector * scalar op
+          vldr    d8, [a1, #1 * 2*4]
+          vldr    d9, [a1, #5 * 2*4]
+            vldr    d10, [a1, #3 * 2*4]
+            vldr    d11, [a1, #7 * 2*4]
+        vldr    d14, [a1, #2 * 2*4]
+          vadd.f  s0, s6, s4
+          vadd.f  s1, s5, s7
+          vsub.f  s2, s5, s7
+          vsub.f  s3, s6, s4
+            vadd.f  s4, s12, s9
+            vsub.f  s5, s13, s8
+            vsub.f  s6, s14, s11
+            vadd.f  s7, s15, s10
+          vadd.f  s12, s0, s16  @ vector op
+          vstr    d0, [a1, #1 * 2*4]
+          vstr    d1, [a1, #5 * 2*4]
+          vldr    d4, [a1, #1 * 2*4]
+          vldr    d5, [a1, #5 * 2*4]
+            vadd.f  s0, s6, s4
+            vadd.f  s1, s5, s7
+            vsub.f  s2, s5, s7
+            vsub.f  s3, s6, s4
+          vsub.f  s8, s16, s8   @ vector op
+          vstr    d6, [a1, #1 * 2*4]
+          vstr    d7, [a1, #5 * 2*4]
+        vldr    d15, [a1, #6 * 2*4]
+            vsub.f  s4, s20, s0
+            vsub.f  s5, s21, s1
+            vsub.f  s6, s22, s2
+            vsub.f  s7, s23, s3
+            vadd.f  s20, s0, s20    @ vector op
+          vstr    d4, [a1, #9 * 2*4]
+              @ TRANSFORM_ZERO(z[0],z[4],z[8],z[12])
+              vldr    d6, [a1, #8 * 2*4]
+          vstr    d5, [a1, #13 * 2*4]
+              vldr    d7, [a1, #12 * 2*4]
+          vstr    d2, [a1, #11 * 2*4]
+              vldr    d8, [a1, #0 * 2*4]
+          vstr    d3, [a1, #15 * 2*4]
+              vldr    d9, [a1, #4 * 2*4]
+        vadd.f  s0, s26, s24
+        vadd.f  s1, s25, s27
+        vsub.f  s2, s25, s27
+        vsub.f  s3, s26, s24
+              vadd.f  s4, s14, s12
+              vadd.f  s5, s13, s15
+              vsub.f  s6, s13, s15
+              vsub.f  s7, s14, s12
+        vadd.f  s8, s0, s28 @ vector op
+        vstr    d0, [a1, #3 * 2*4]
+        vstr    d1, [a1, #7 * 2*4]
+        vldr    d6, [a1, #3 * 2*4]
+        vldr    d7, [a1, #7 * 2*4]
+              vsub.f  s0, s16, s4
+              vsub.f  s1, s17, s5
+              vsub.f  s2, s18, s6
+              vsub.f  s3, s19, s7
+        vsub.f  s12, s28, s12       @ vector op
+              vadd.f  s16, s4, s16  @ vector op
+            vstr    d10, [a1, #3 * 2*4]
+            vstr    d11, [a1, #7 * 2*4]
+        vstr    d4, [a1, #2 * 2*4]
+        vstr    d5, [a1, #6 * 2*4]
+              vstr    d0, [a1, #8 * 2*4]
+              vstr    d1, [a1, #12 * 2*4]
+        vstr    d6, [a1, #10 * 2*4]
+        vstr    d7, [a1, #14 * 2*4]
+              vstr    d8, [a1, #0 * 2*4]
+              vstr    d9, [a1, #4 * 2*4]
+
+        vpop    {s16-s31}
+        fmxr    FPSCR, a2
+        bx      lr
+endfunc
diff --git a/libavcodec/arm/fmtconvert_init_arm.c b/libavcodec/arm/fmtconvert_init_arm.c
index 1d99c97..185f1b9 100644
--- a/libavcodec/arm/fmtconvert_init_arm.c
+++ b/libavcodec/arm/fmtconvert_init_arm.c
@@ -25,9 +25,15 @@
 #include "libavcodec/avcodec.h"
 #include "libavcodec/fmtconvert.h"
 
-void ff_int32_to_float_fmul_scalar_neon(float *dst, const int *src,
+void ff_int32_to_float_fmul_scalar_neon(float *dst, const int32_t *src,
                                         float mul, int len);
 
+void ff_int32_to_float_fmul_scalar_vfp(float *dst, const int32_t *src,
+                                       float mul, int len);
+void ff_int32_to_float_fmul_array8_vfp(FmtConvertContext *c, float *dst,
+                                       const int32_t *src, const float *mul,
+                                       int len);
+
 void ff_float_to_int16_neon(int16_t *dst, const float *src, long len);
 void ff_float_to_int16_interleave_neon(int16_t *, const float **, long, int);
 
@@ -38,6 +44,14 @@
     int cpu_flags = av_get_cpu_flags();
 
     if (have_vfp(cpu_flags) && have_armv6(cpu_flags)) {
+        if (!have_vfpv3(cpu_flags)) {
+            // These functions don't use anything armv6 specific in themselves,
+            // but ff_float_to_int16_vfp which is in the same assembly source
+            // file does, thus the whole file requires armv6 to be built.
+            c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_vfp;
+            c->int32_to_float_fmul_array8 = ff_int32_to_float_fmul_array8_vfp;
+        }
+
         c->float_to_int16 = ff_float_to_int16_vfp;
     }
 
diff --git a/libavcodec/arm/fmtconvert_vfp.S b/libavcodec/arm/fmtconvert_vfp.S
index 7b012bc..a6d4ebd 100644
--- a/libavcodec/arm/fmtconvert_vfp.S
+++ b/libavcodec/arm/fmtconvert_vfp.S
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
+ * Copyright (c) 2013 RISC OS Open Ltd <bavison@riscosopen.org>
  *
  * This file is part of FFmpeg.
  *
@@ -76,3 +77,202 @@
         vpop            {d8-d11}
         pop             {r4-r8,pc}
 endfunc
+
+/**
+ * ARM VFP optimised int32 to float conversion.
+ * Assume len is a multiple of 8, destination buffer is at least 4 bytes aligned
+ * (16 bytes alignment is best for BCM2835), little-endian.
+ */
+@ void ff_int32_to_float_fmul_array8_vfp(FmtConvertContext *c, float *dst, const int32_t *src, const float *mul, int len)
+function ff_int32_to_float_fmul_array8_vfp, export=1
+        push    {lr}
+        ldr     a1, [sp, #4]
+        subs    lr, a1, #3*8
+        bcc     50f                        @ too short to pipeline
+        @ Now need to find (len / 8) % 3. The approximation
+        @ x / 24 = (x * 0xAB) >> 12
+        @ is good for x < 4096, which is true for both AC3 and DCA.
+        mov     a1, #0xAB
+        ldr     ip, =0x03070000            @ RunFast mode, short vectors of length 8, stride 1
+        mul     a1, lr, a1
+        vpush   {s16-s31}
+        mov     a1, a1, lsr #12
+        add     a1, a1, a1, lsl #1
+        rsb     a1, a1, lr, lsr #3
+        cmp     a1, #1
+        fmrx    a1, FPSCR
+        fmxr    FPSCR, ip
+        beq     11f
+        blo     10f
+        @ Array is (2 + multiple of 3) x 8 floats long
+        @ drop through...
+        vldmia          a3!, {s16-s23}
+        vldmia          a4!, {s2,s3}
+        vldmia          a3!, {s24-s31}
+        vcvt.f32.s32    s16, s16
+        vcvt.f32.s32    s17, s17
+        vcvt.f32.s32    s18, s18
+        vcvt.f32.s32    s19, s19
+        vcvt.f32.s32    s20, s20
+        vcvt.f32.s32    s21, s21
+        vcvt.f32.s32    s22, s22
+        vcvt.f32.s32    s23, s23
+        vmul.f32        s16, s16, s2
+        @ drop through...
+3:
+        vldmia          a3!, {s8-s15}
+        vldmia          a4!, {s1}
+        vcvt.f32.s32    s24, s24
+        vcvt.f32.s32    s25, s25
+        vcvt.f32.s32    s26, s26
+        vcvt.f32.s32    s27, s27
+        vcvt.f32.s32    s28, s28
+        vcvt.f32.s32    s29, s29
+        vcvt.f32.s32    s30, s30
+        vcvt.f32.s32    s31, s31
+        vmul.f32        s24, s24, s3
+        vstmia          a2!, {s16-s19}
+        vstmia          a2!, {s20-s23}
+2:
+        vldmia          a3!, {s16-s23}
+        vldmia          a4!, {s2}
+        vcvt.f32.s32    s8, s8
+        vcvt.f32.s32    s9, s9
+        vcvt.f32.s32    s10, s10
+        vcvt.f32.s32    s11, s11
+        vcvt.f32.s32    s12, s12
+        vcvt.f32.s32    s13, s13
+        vcvt.f32.s32    s14, s14
+        vcvt.f32.s32    s15, s15
+        vmul.f32        s8, s8, s1
+        vstmia          a2!, {s24-s27}
+        vstmia          a2!, {s28-s31}
+1:
+        vldmia          a3!, {s24-s31}
+        vldmia          a4!, {s3}
+        vcvt.f32.s32    s16, s16
+        vcvt.f32.s32    s17, s17
+        vcvt.f32.s32    s18, s18
+        vcvt.f32.s32    s19, s19
+        vcvt.f32.s32    s20, s20
+        vcvt.f32.s32    s21, s21
+        vcvt.f32.s32    s22, s22
+        vcvt.f32.s32    s23, s23
+        vmul.f32        s16, s16, s2
+        vstmia          a2!, {s8-s11}
+        vstmia          a2!, {s12-s15}
+
+        subs            lr, lr, #8*3
+        bpl             3b
+
+        vcvt.f32.s32    s24, s24
+        vcvt.f32.s32    s25, s25
+        vcvt.f32.s32    s26, s26
+        vcvt.f32.s32    s27, s27
+        vcvt.f32.s32    s28, s28
+        vcvt.f32.s32    s29, s29
+        vcvt.f32.s32    s30, s30
+        vcvt.f32.s32    s31, s31
+        vmul.f32        s24, s24, s3
+        vstmia          a2!, {s16-s19}
+        vstmia          a2!, {s20-s23}
+        vstmia          a2!, {s24-s27}
+        vstmia          a2!, {s28-s31}
+
+        fmxr    FPSCR, a1
+        vpop    {s16-s31}
+        pop     {pc}
+
+10:     @ Array is (multiple of 3) x 8 floats long
+        vldmia          a3!, {s8-s15}
+        vldmia          a4!, {s1,s2}
+        vldmia          a3!, {s16-s23}
+        vcvt.f32.s32    s8, s8
+        vcvt.f32.s32    s9, s9
+        vcvt.f32.s32    s10, s10
+        vcvt.f32.s32    s11, s11
+        vcvt.f32.s32    s12, s12
+        vcvt.f32.s32    s13, s13
+        vcvt.f32.s32    s14, s14
+        vcvt.f32.s32    s15, s15
+        vmul.f32        s8, s8, s1
+        b               1b
+
+11:     @ Array is (1 + multiple of 3) x 8 floats long
+        vldmia          a3!, {s24-s31}
+        vldmia          a4!, {s3}
+        vldmia          a3!, {s8-s15}
+        vldmia          a4!, {s1}
+        vcvt.f32.s32    s24, s24
+        vcvt.f32.s32    s25, s25
+        vcvt.f32.s32    s26, s26
+        vcvt.f32.s32    s27, s27
+        vcvt.f32.s32    s28, s28
+        vcvt.f32.s32    s29, s29
+        vcvt.f32.s32    s30, s30
+        vcvt.f32.s32    s31, s31
+        vmul.f32        s24, s24, s3
+        b               2b
+
+50:
+        ldr     lr, =0x03070000         @ RunFast mode, short vectors of length 8, stride 1
+        fmrx    ip, FPSCR
+        fmxr    FPSCR, lr
+51:
+        vldmia          a3!, {s8-s15}
+        vldmia          a4!, {s0}
+        vcvt.f32.s32    s8, s8
+        vcvt.f32.s32    s9, s9
+        vcvt.f32.s32    s10, s10
+        vcvt.f32.s32    s11, s11
+        vcvt.f32.s32    s12, s12
+        vcvt.f32.s32    s13, s13
+        vcvt.f32.s32    s14, s14
+        vcvt.f32.s32    s15, s15
+        vmul.f32        s8, s8, s0
+        subs            a1, a1, #8
+        vstmia          a2!, {s8-s11}
+        vstmia          a2!, {s12-s15}
+        bne             51b
+
+        fmxr    FPSCR, ip
+        pop     {pc}
+endfunc
+
+/**
+ * ARM VFP optimised int32 to float conversion.
+ * Assume len is a multiple of 8, destination buffer is at least 4 bytes aligned
+ * (16 bytes alignment is best for BCM2835), little-endian.
+ * TODO: could be further optimised by unrolling and interleaving, as above
+ */
+@ void ff_int32_to_float_fmul_scalar_vfp(float *dst, const int32_t *src, float mul, int len)
+function ff_int32_to_float_fmul_scalar_vfp, export=1
+VFP     tmp     .req    a4
+VFP     len     .req    a3
+NOVFP   tmp     .req    a3
+NOVFP   len     .req    a4
+NOVFP   vmov    s0, a3
+        ldr     tmp, =0x03070000           @ RunFast mode, short vectors of length 8, stride 1
+        fmrx    ip, FPSCR
+        fmxr    FPSCR, tmp
+1:
+        vldmia          a2!, {s8-s15}
+        vcvt.f32.s32    s8, s8
+        vcvt.f32.s32    s9, s9
+        vcvt.f32.s32    s10, s10
+        vcvt.f32.s32    s11, s11
+        vcvt.f32.s32    s12, s12
+        vcvt.f32.s32    s13, s13
+        vcvt.f32.s32    s14, s14
+        vcvt.f32.s32    s15, s15
+        vmul.f32        s8, s8, s0
+        subs            len, len, #8
+        vstmia          a1!, {s8-s11}
+        vstmia          a1!, {s12-s15}
+        bne             1b
+
+        fmxr    FPSCR, ip
+        bx      lr
+endfunc
+        .unreq  tmp
+        .unreq  len
diff --git a/libavcodec/arm/h264dsp_armv6.S b/libavcodec/arm/h264dsp_armv6.S
new file mode 100644
index 0000000..93dc69b
--- /dev/null
+++ b/libavcodec/arm/h264dsp_armv6.S
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2013 RISC OS Open Ltd
+ * Author: Ben Avison <bavison@riscosopen.org>
+ *
+ * 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
+ */
+
+#include "libavutil/arm/asm.S"
+
+RESULT  .req    a1
+BUF     .req    a1
+SIZE    .req    a2
+PATTERN .req    a3
+PTR     .req    a4
+DAT0    .req    v1
+DAT1    .req    v2
+DAT2    .req    v3
+DAT3    .req    v4
+TMP0    .req    v5
+TMP1    .req    v6
+TMP2    .req    ip
+TMP3    .req    lr
+
+#define PRELOAD_DISTANCE 4
+
+.macro innerloop4
+        ldr     DAT0, [PTR], #4
+        subs    SIZE, SIZE, #4 @ C flag survives rest of macro
+        sub     TMP0, DAT0, PATTERN, lsr #14
+        bic     TMP0, TMP0, DAT0
+        ands    TMP0, TMP0, PATTERN
+.endm
+
+.macro innerloop16  decrement, do_preload
+        ldmia   PTR!, {DAT0,DAT1,DAT2,DAT3}
+ .ifnc "\do_preload",""
+        pld     [PTR, #PRELOAD_DISTANCE*32]
+ .endif
+ .ifnc "\decrement",""
+        subs    SIZE, SIZE, #\decrement @ C flag survives rest of macro
+ .endif
+        sub     TMP0, DAT0, PATTERN, lsr #14
+        sub     TMP1, DAT1, PATTERN, lsr #14
+        bic     TMP0, TMP0, DAT0
+        bic     TMP1, TMP1, DAT1
+        sub     TMP2, DAT2, PATTERN, lsr #14
+        sub     TMP3, DAT3, PATTERN, lsr #14
+        ands    TMP0, TMP0, PATTERN
+        bic     TMP2, TMP2, DAT2
+        it      eq
+        andseq  TMP1, TMP1, PATTERN
+        bic     TMP3, TMP3, DAT3
+        itt     eq
+        andseq  TMP2, TMP2, PATTERN
+        andseq  TMP3, TMP3, PATTERN
+.endm
+
+/* int ff_h264_find_start_code_candidate_armv6(const uint8_t *buf, int size) */
+function ff_h264_find_start_code_candidate_armv6, export=1
+        push    {v1-v6,lr}
+        mov     PTR, BUF
+        @ Ensure there are at least (PRELOAD_DISTANCE+2) complete cachelines to go
+        @ before using code that does preloads
+        cmp     SIZE, #(PRELOAD_DISTANCE+3)*32 - 1
+        blo     60f
+
+        @ Get to word-alignment, 1 byte at a time
+        tst     PTR, #3
+        beq     2f
+1:      ldrb    DAT0, [PTR], #1
+        sub     SIZE, SIZE, #1
+        teq     DAT0, #0
+        beq     90f
+        tst     PTR, #3
+        bne     1b
+2:      @ Get to 4-word alignment, 1 word at a time
+        ldr     PATTERN, =0x80008000
+        setend  be
+        tst     PTR, #12
+        beq     4f
+3:      innerloop4
+        bne     91f
+        tst     PTR, #12
+        bne     3b
+4:      @ Get to cacheline (8-word) alignment
+        tst     PTR, #16
+        beq     5f
+        innerloop16  16
+        bne     93f
+5:      @ Check complete cachelines, with preloading
+        @ We need to stop when there are still (PRELOAD_DISTANCE+1)
+        @ complete cachelines to go
+        sub     SIZE, SIZE, #(PRELOAD_DISTANCE+2)*32
+6:      innerloop16  , do_preload
+        bne     93f
+        innerloop16  32
+        bne     93f
+        bcs     6b
+        @ Preload trailing part-cacheline, if any
+        tst     SIZE, #31
+        beq     7f
+        pld     [PTR, #(PRELOAD_DISTANCE+1)*32]
+        @ Check remaining data without doing any more preloads. First
+        @ do in chunks of 4 words:
+7:      adds    SIZE, SIZE, #(PRELOAD_DISTANCE+2)*32 - 16
+        bmi     9f
+8:      innerloop16  16
+        bne     93f
+        bcs     8b
+        @ Then in words:
+9:      adds    SIZE, SIZE, #16 - 4
+        bmi     11f
+10:     innerloop4
+        bne     91f
+        bcs     10b
+11:     setend  le
+        @ Check second byte of final halfword
+        ldrb    DAT0, [PTR, #-1]
+        teq     DAT0, #0
+        beq     90f
+        @ Check any remaining bytes
+        tst     SIZE, #3
+        beq     13f
+12:     ldrb    DAT0, [PTR], #1
+        sub     SIZE, SIZE, #1
+        teq     DAT0, #0
+        beq     90f
+        tst     SIZE, #3
+        bne     12b
+        @ No candidate found
+13:     sub     RESULT, PTR, BUF
+        b       99f
+
+60:     @ Small buffer - simply check by looping over bytes
+        subs    SIZE, SIZE, #1
+        bcc     99f
+61:     ldrb    DAT0, [PTR], #1
+        subs    SIZE, SIZE, #1
+        teq     DAT0, #0
+        beq     90f
+        bcs     61b
+        @ No candidate found
+        sub     RESULT, PTR, BUF
+        b       99f
+
+90:     @ Found a candidate at the preceding byte
+        sub     RESULT, PTR, BUF
+        sub     RESULT, RESULT, #1
+        b       99f
+
+91:     @ Found a candidate somewhere in the preceding 4 bytes
+        sub     RESULT, PTR, BUF
+        sub     RESULT, RESULT, #4
+        sub     TMP0, DAT0, #0x20000
+        bics    TMP0, TMP0, DAT0
+        itt     pl
+        ldrbpl  DAT0, [PTR, #-3]
+        addpl   RESULT, RESULT, #2
+        bpl     92f
+        teq     RESULT, #0
+        beq     98f @ don't look back a byte if found at first byte in buffer
+        ldrb    DAT0, [PTR, #-5]
+92:     teq     DAT0, #0
+        it      eq
+        subeq   RESULT, RESULT, #1
+        b       98f
+
+93:     @ Found a candidate somewhere in the preceding 16 bytes
+        sub     RESULT, PTR, BUF
+        sub     RESULT, RESULT, #16
+        teq     TMP0, #0
+        beq     95f @ not in first 4 bytes
+        sub     TMP0, DAT0, #0x20000
+        bics    TMP0, TMP0, DAT0
+        itt     pl
+        ldrbpl  DAT0, [PTR, #-15]
+        addpl   RESULT, RESULT, #2
+        bpl     94f
+        teq     RESULT, #0
+        beq     98f @ don't look back a byte if found at first byte in buffer
+        ldrb    DAT0, [PTR, #-17]
+94:     teq     DAT0, #0
+        it      eq
+        subeq   RESULT, RESULT, #1
+        b       98f
+95:     add     RESULT, RESULT, #4
+        teq     TMP1, #0
+        beq     96f @ not in next 4 bytes
+        sub     TMP1, DAT1, #0x20000
+        bics    TMP1, TMP1, DAT1
+        itee    mi
+        ldrbmi  DAT0, [PTR, #-13]
+        ldrbpl  DAT0, [PTR, #-11]
+        addpl   RESULT, RESULT, #2
+        teq     DAT0, #0
+        it      eq
+        subeq   RESULT, RESULT, #1
+        b       98f
+96:     add     RESULT, RESULT, #4
+        teq     TMP2, #0
+        beq     97f @ not in next 4 bytes
+        sub     TMP2, DAT2, #0x20000
+        bics    TMP2, TMP2, DAT2
+        itee    mi
+        ldrbmi  DAT0, [PTR, #-9]
+        ldrbpl  DAT0, [PTR, #-7]
+        addpl   RESULT, RESULT, #2
+        teq     DAT0, #0
+        it      eq
+        subeq   RESULT, RESULT, #1
+        b       98f
+97:     add     RESULT, RESULT, #4
+        sub     TMP3, DAT3, #0x20000
+        bics    TMP3, TMP3, DAT3
+        itee    mi
+        ldrbmi  DAT0, [PTR, #-5]
+        ldrbpl  DAT0, [PTR, #-3]
+        addpl   RESULT, RESULT, #2
+        teq     DAT0, #0
+        it      eq
+        subeq   RESULT, RESULT, #1
+        @ drop through to 98f
+98:     setend  le
+99:     pop     {v1-v6,pc}
+.endfunc
+
+        .unreq  RESULT
+        .unreq  BUF
+        .unreq  SIZE
+        .unreq  PATTERN
+        .unreq  PTR
+        .unreq  DAT0
+        .unreq  DAT1
+        .unreq  DAT2
+        .unreq  DAT3
+        .unreq  TMP0
+        .unreq  TMP1
+        .unreq  TMP2
+        .unreq  TMP3
diff --git a/libavcodec/arm/h264dsp_init_arm.c b/libavcodec/arm/h264dsp_init_arm.c
index 785b604..2cafbaf 100644
--- a/libavcodec/arm/h264dsp_init_arm.c
+++ b/libavcodec/arm/h264dsp_init_arm.c
@@ -24,6 +24,8 @@
 #include "libavutil/arm/cpu.h"
 #include "libavcodec/h264dsp.h"
 
+int ff_h264_find_start_code_candidate_armv6(const uint8_t *buf, int size);
+
 void ff_h264_v_loop_filter_luma_neon(uint8_t *pix, int stride, int alpha,
                                      int beta, int8_t *tc0);
 void ff_h264_h_loop_filter_luma_neon(uint8_t *pix, int stride, int alpha,
@@ -68,8 +70,8 @@
                              int16_t *block, int stride,
                              const uint8_t nnzc[6*8]);
 
-static av_cold void ff_h264dsp_init_neon(H264DSPContext *c, const int bit_depth,
-                                         const int chroma_format_idc)
+static av_cold void h264dsp_init_neon(H264DSPContext *c, const int bit_depth,
+                                      const int chroma_format_idc)
 {
 #if HAVE_NEON
     if (bit_depth == 8) {
@@ -106,6 +108,8 @@
 {
     int cpu_flags = av_get_cpu_flags();
 
+    if (have_armv6(cpu_flags))
+        c->h264_find_start_code_candidate = ff_h264_find_start_code_candidate_armv6;
     if (have_neon(cpu_flags))
-        ff_h264dsp_init_neon(c, bit_depth, chroma_format_idc);
+        h264dsp_init_neon(c, bit_depth, chroma_format_idc);
 }
diff --git a/libavcodec/arm/h264pred_init_arm.c b/libavcodec/arm/h264pred_init_arm.c
index 5ec39ce..1562f0b 100644
--- a/libavcodec/arm/h264pred_init_arm.c
+++ b/libavcodec/arm/h264pred_init_arm.c
@@ -45,9 +45,9 @@
 void ff_pred8x8_l00_dc_neon(uint8_t *src, ptrdiff_t stride);
 void ff_pred8x8_0l0_dc_neon(uint8_t *src, ptrdiff_t stride);
 
-static av_cold void ff_h264_pred_init_neon(H264PredContext *h, int codec_id,
-                                           const int bit_depth,
-                                           const int chroma_format_idc)
+static av_cold void h264_pred_init_neon(H264PredContext *h, int codec_id,
+                                        const int bit_depth,
+                                        const int chroma_format_idc)
 {
 #if HAVE_NEON
     const int high_depth = bit_depth > 8;
@@ -88,5 +88,5 @@
     int cpu_flags = av_get_cpu_flags();
 
     if (have_neon(cpu_flags))
-        ff_h264_pred_init_neon(h, codec_id, bit_depth, chroma_format_idc);
+        h264_pred_init_neon(h, codec_id, bit_depth, chroma_format_idc);
 }
diff --git a/libavcodec/arm/int_neon.S b/libavcodec/arm/int_neon.S
index 6b28a97..dea1ad5 100644
--- a/libavcodec/arm/int_neon.S
+++ b/libavcodec/arm/int_neon.S
@@ -1,6 +1,6 @@
 /*
  * ARM NEON optimised integer operations
- * Copyright (c) 2009 Kostya Shishkov
+ * Copyright (c) 2009 Konstantin Shishkov
  *
  * This file is part of FFmpeg.
  *
diff --git a/libavcodec/arm/mdct_vfp.S b/libavcodec/arm/mdct_vfp.S
new file mode 100644
index 0000000..ee3984c
--- /dev/null
+++ b/libavcodec/arm/mdct_vfp.S
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2013 RISC OS Open Ltd
+ * Author: Ben Avison <bavison@riscosopen.org>
+ *
+ * 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
+ */
+
+#include "libavutil/arm/asm.S"
+
+CONTEXT .req    a1
+ORIGOUT .req    a2
+IN      .req    a3
+OUT     .req    v1
+REVTAB  .req    v2
+TCOS    .req    v3
+TSIN    .req    v4
+OLDFPSCR .req   v5
+J0      .req    a2
+J1      .req    a4
+J2      .req    ip
+J3      .req    lr
+
+.macro prerotation_innerloop
+ .set trig_lo, k
+ .set trig_hi, n4 - k - 2
+ .set in_lo, trig_lo * 2
+ .set in_hi, trig_hi * 2
+        vldr    d8, [TCOS, #trig_lo*4]          @ s16,s17
+        vldr    d9, [TCOS, #trig_hi*4]          @ s18,s19
+        vldr    s0, [IN, #in_hi*4 + 12]
+        vldr    s1, [IN, #in_hi*4 + 4]
+        vldr    s2, [IN, #in_lo*4 + 12]
+        vldr    s3, [IN, #in_lo*4 + 4]
+        vmul.f  s8, s0, s16                     @ vector operation
+        vldr    d10, [TSIN, #trig_lo*4]         @ s20,s21
+        vldr    d11, [TSIN, #trig_hi*4]         @ s22,s23
+        vldr    s4, [IN, #in_lo*4]
+        vldr    s5, [IN, #in_lo*4 + 8]
+        vldr    s6, [IN, #in_hi*4]
+        vldr    s7, [IN, #in_hi*4 + 8]
+        ldr     J0, [REVTAB, #trig_lo*2]
+        vmul.f  s12, s0, s20                    @ vector operation
+        ldr     J2, [REVTAB, #trig_hi*2]
+        mov     J1, J0, lsr #16
+        and     J0, J0, #255                    @ halfword value will be < n4
+        vmls.f  s8, s4, s20                     @ vector operation
+        mov     J3, J2, lsr #16
+        and     J2, J2, #255                    @ halfword value will be < n4
+        add     J0, OUT, J0, lsl #3
+        vmla.f  s12, s4, s16                    @ vector operation
+        add     J1, OUT, J1, lsl #3
+        add     J2, OUT, J2, lsl #3
+        add     J3, OUT, J3, lsl #3
+        vstr    s8, [J0]
+        vstr    s9, [J1]
+        vstr    s10, [J2]
+        vstr    s11, [J3]
+        vstr    s12, [J0, #4]
+        vstr    s13, [J1, #4]
+        vstr    s14, [J2, #4]
+        vstr    s15, [J3, #4]
+ .set k, k + 2
+.endm
+
+.macro postrotation_innerloop tail, head
+ .set trig_lo_head, n8 - k - 2
+ .set trig_hi_head, n8 + k
+ .set out_lo_head, trig_lo_head * 2
+ .set out_hi_head, trig_hi_head * 2
+ .set trig_lo_tail, n8 - (k - 2) - 2
+ .set trig_hi_tail, n8 + (k - 2)
+ .set out_lo_tail, trig_lo_tail * 2
+ .set out_hi_tail, trig_hi_tail * 2
+ .if (k & 2) == 0
+  TCOS_D0_HEAD .req d10 @ s20,s21
+  TCOS_D1_HEAD .req d11 @ s22,s23
+  TCOS_S0_TAIL .req s24
+ .else
+  TCOS_D0_HEAD .req d12 @ s24,s25
+  TCOS_D1_HEAD .req d13 @ s26,s27
+  TCOS_S0_TAIL .req s20
+ .endif
+ .ifnc "\tail",""
+        vmls.f  s8, s0, TCOS_S0_TAIL        @ vector operation
+ .endif
+ .ifnc "\head",""
+        vldr    d8, [TSIN, #trig_lo_head*4] @ s16,s17
+        vldr    d9, [TSIN, #trig_hi_head*4] @ s18,s19
+        vldr    TCOS_D0_HEAD, [TCOS, #trig_lo_head*4]
+ .endif
+ .ifnc "\tail",""
+        vmla.f  s12, s4, TCOS_S0_TAIL       @ vector operation
+ .endif
+ .ifnc "\head",""
+        vldr    s0, [OUT, #out_lo_head*4]
+        vldr    s1, [OUT, #out_lo_head*4 + 8]
+        vldr    s2, [OUT, #out_hi_head*4]
+        vldr    s3, [OUT, #out_hi_head*4 + 8]
+        vldr    s4, [OUT, #out_lo_head*4 + 4]
+        vldr    s5, [OUT, #out_lo_head*4 + 12]
+        vldr    s6, [OUT, #out_hi_head*4 + 4]
+        vldr    s7, [OUT, #out_hi_head*4 + 12]
+ .endif
+ .ifnc "\tail",""
+        vstr    s8, [OUT, #out_lo_tail*4]
+        vstr    s9, [OUT, #out_lo_tail*4 + 8]
+        vstr    s10, [OUT, #out_hi_tail*4]
+        vstr    s11, [OUT, #out_hi_tail*4 + 8]
+ .endif
+ .ifnc "\head",""
+        vmul.f  s8, s4, s16                 @ vector operation
+ .endif
+ .ifnc "\tail",""
+        vstr    s12, [OUT, #out_hi_tail*4 + 12]
+        vstr    s13, [OUT, #out_hi_tail*4 + 4]
+        vstr    s14, [OUT, #out_lo_tail*4 + 12]
+        vstr    s15, [OUT, #out_lo_tail*4 + 4]
+ .endif
+ .ifnc "\head",""
+        vmul.f  s12, s0, s16                @ vector operation
+        vldr    TCOS_D1_HEAD, [TCOS, #trig_hi_head*4]
+ .endif
+ .unreq TCOS_D0_HEAD
+ .unreq TCOS_D1_HEAD
+ .unreq TCOS_S0_TAIL
+ .ifnc "\head",""
+  .set k, k + 2
+ .endif
+.endm
+
+
+/* void ff_imdct_half_vfp(FFTContext *s,
+ *                        FFTSample *output,
+ *                        const FFTSample *input)
+ */
+function ff_imdct_half_vfp, export=1
+        ldr     ip, [CONTEXT, #5*4]         @ mdct_bits
+        teq     ip, #6
+        it      ne
+        bne     X(ff_imdct_half_c)          @ only case currently accelerated is the one used by DCA
+
+ .set n, 1<<6
+ .set n2, n/2
+ .set n4, n/4
+ .set n8, n/8
+
+        push    {v1-v5,lr}
+        vpush   {s16-s27}
+        fmrx    OLDFPSCR, FPSCR
+        ldr     lr, =0x03030000             @ RunFast mode, short vectors of length 4, stride 1
+        fmxr    FPSCR, lr
+        mov     OUT, ORIGOUT
+        ldr     REVTAB, [CONTEXT, #2*4]
+        ldr     TCOS, [CONTEXT, #6*4]
+        ldr     TSIN, [CONTEXT, #7*4]
+
+ .set k, 0
+ .rept n8/2
+        prerotation_innerloop
+ .endr
+
+        fmxr    FPSCR, OLDFPSCR
+        mov     a1, OUT
+        bl      X(ff_fft16_vfp)
+        ldr     lr, =0x03030000             @ RunFast mode, short vectors of length 4, stride 1
+        fmxr    FPSCR, lr
+
+ .set k, 0
+        postrotation_innerloop , head
+ .rept n8/2 - 1
+        postrotation_innerloop tail, head
+ .endr
+        postrotation_innerloop tail
+
+        fmxr    FPSCR, OLDFPSCR
+        vpop    {s16-s27}
+        pop     {v1-v5,pc}
+endfunc
+
+        .unreq  CONTEXT
+        .unreq  ORIGOUT
+        .unreq  IN
+        .unreq  OUT
+        .unreq  REVTAB
+        .unreq  TCOS
+        .unreq  TSIN
+        .unreq  OLDFPSCR
+        .unreq  J0
+        .unreq  J1
+        .unreq  J2
+        .unreq  J3
diff --git a/libavcodec/arm/rv40dsp_init_arm.c b/libavcodec/arm/rv40dsp_init_arm.c
index fec3702..3bf9ac7 100644
--- a/libavcodec/arm/rv40dsp_init_arm.c
+++ b/libavcodec/arm/rv40dsp_init_arm.c
@@ -70,7 +70,7 @@
                                      int filter_q1, int alpha, int beta,
                                      int lim_p0q0, int lim_q1, int lim_p1);
 
-static av_cold void ff_rv40dsp_init_neon(RV34DSPContext *c)
+static av_cold void rv40dsp_init_neon(RV34DSPContext *c)
 {
     c->put_pixels_tab[0][ 1] = ff_put_rv40_qpel16_mc10_neon;
     c->put_pixels_tab[0][ 3] = ff_put_rv40_qpel16_mc30_neon;
@@ -144,5 +144,5 @@
     int cpu_flags = av_get_cpu_flags();
 
     if (have_neon(cpu_flags))
-        ff_rv40dsp_init_neon(c);
+        rv40dsp_init_neon(c);
 }
diff --git a/libavcodec/arm/simple_idct_arm.S b/libavcodec/arm/simple_idct_arm.S
index dd1c815..50d20c9 100644
--- a/libavcodec/arm/simple_idct_arm.S
+++ b/libavcodec/arm/simple_idct_arm.S
@@ -83,7 +83,7 @@
         orrs r5, r5, r7          @ R5=R4 | R3 | R2 | R7
         beq __almost_empty_row
 
-__b_evaluation:
+@@ __b_evaluation:
         @@ at this point, R0=block (temp),  R1(free), R2=ROWr32[1], R3=ROWr32[2], R4=ROWr32[3],
         @@     R5=(temp), R6=ROWr16[0], R7=ROWr16[1], R8-R11 free,
         @@     R12=__const_ptr_, R14=&block[n]
@@ -159,7 +159,7 @@
         @@     R5=b2, R6=ROWr16[0], R7=b3, R8 (free), R9 (free), R10 (free), R11 (free),
         @@     R12=__const_ptr_, R14=&block[n]
 
-__a_evaluation:
+@@ __a_evaluation:
         @@ a0 = (W4 * row[0]) + (1 << (ROW_SHIFT - 1));
         @@ a1 = a0 + W6 * row[2];
         @@ a2 = a0 - W6 * row[2];
@@ -295,7 +295,7 @@
         add r14, r0, #14        @ R14=&block[7], better start from the last col, and decrease the value until col=0, i.e. R14=block.
 __col_loop:
 
-__b_evaluation2:
+@@ __b_evaluation2:
         @@ at this point, R0=block (temp),  R1-R11 (free)
         @@     R12=__const_ptr_, R14=&block[n]
         @@ proceed with b0-b3 first, followed by a0-a3
@@ -357,12 +357,12 @@
         it    ne
         mlane r1, r10, r4, r1    @ R1-=W5*ROWr16[7x8]=b1
         @@ R4 is free now
-__end_b_evaluation2:
+@@ __end_b_evaluation2:
         @@ at this point, R0=b0,  R1=b1, R2 (free), R3 (free), R4 (free),
         @@     R5=b2, R6 (free), R7=b3, R8 (free), R9 (free), R10 (free), R11 (free),
         @@     R12=__const_ptr_, R14=&block[n]
 
-__a_evaluation2:
+@@ __a_evaluation2:
         @@ a0 = (W4 * col[8x0]) + (1 << (COL_SHIFT - 1));
         @@ a1 = a0 + W6 * row[2];
         @@ a2 = a0 - W6 * row[2];
@@ -414,7 +414,7 @@
         itt   ne
         subne r2, r2, r10        @ R2-=W2*ROWr16[6] (a1)
         addne r3, r3, r10        @ R3+=W2*ROWr16[6] (a2)
-__end_a_evaluation2:
+@@ __end_a_evaluation2:
         @@ at this point, R0=b0,  R1=b1, R2=a1, R3=a2, R4=a3,
         @@     R5=b2, R6=a0, R7=b3, R8 (free), R9 (free), R10 (free), R11 (free),
         @@     R12=__const_ptr_, R14=&block[n]
@@ -452,7 +452,7 @@
         strh r8, [r14, #96]
         strh r9, [r14, #112]
 
-__end_col_loop:
+@@ __end_col_loop:
         @@ at this point, R0-R11 (free)
         @@     R12=__const_ptr_, R14=&block[n]
         ldr r0, [sp, #0]         @ R0=block
@@ -463,7 +463,7 @@
 
 
 
-__end_simple_idct_arm:
+@@ __end_simple_idct_arm:
         @@ restore registers to previous status!
         add sp, sp, #8 @@ the local variables!
         ldmfd sp!, {r4-r11, r15} @@ update PC with LR content.
diff --git a/libavcodec/arm/synth_filter_vfp.S b/libavcodec/arm/synth_filter_vfp.S
new file mode 100644
index 0000000..0bf3ef1
--- /dev/null
+++ b/libavcodec/arm/synth_filter_vfp.S
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2013 RISC OS Open Ltd
+ * Author: Ben Avison <bavison@riscosopen.org>
+ *
+ * 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
+ */
+
+#include "libavutil/arm/asm.S"
+
+IMDCT         .req    r0
+ORIG_P_SB     .req    r1
+P_SB_OFF      .req    r2
+I             .req    r0
+P_SB2_UP      .req    r1
+OLDFPSCR      .req    r2
+P_SB2_DN      .req    r3
+P_WIN_DN      .req    r4
+P_OUT_DN      .req    r5
+P_SB          .req    r6
+J_WRAP        .req    r7
+P_WIN_UP      .req    r12
+P_OUT_UP      .req    r14
+
+SCALE         .req    s0
+SBUF_DAT_REV0 .req    s4
+SBUF_DAT_REV1 .req    s5
+SBUF_DAT_REV2 .req    s6
+SBUF_DAT_REV3 .req    s7
+VA0           .req    s8
+VA3           .req    s11
+VB0           .req    s12
+VB3           .req    s15
+VC0           .req    s8
+VC3           .req    s11
+VD0           .req    s12
+VD3           .req    s15
+SBUF_DAT0     .req    s16
+SBUF_DAT1     .req    s17
+SBUF_DAT2     .req    s18
+SBUF_DAT3     .req    s19
+SBUF_DAT_ALT0 .req    s20
+SBUF_DAT_ALT1 .req    s21
+SBUF_DAT_ALT2 .req    s22
+SBUF_DAT_ALT3 .req    s23
+WIN_DN_DAT0   .req    s24
+WIN_UP_DAT0   .req    s28
+
+
+.macro inner_loop  half, tail, head
+ .if (OFFSET & (64*4)) == 0                @ even numbered call
+        SBUF_DAT_THIS0 .req SBUF_DAT0
+        SBUF_DAT_THIS1 .req SBUF_DAT1
+        SBUF_DAT_THIS2 .req SBUF_DAT2
+        SBUF_DAT_THIS3 .req SBUF_DAT3
+  .ifnc "\head",""
+        vldr    d8, [P_SB, #OFFSET]        @ d8 = SBUF_DAT
+        vldr    d9, [P_SB, #OFFSET+8]
+  .endif
+ .else
+        SBUF_DAT_THIS0 .req SBUF_DAT_ALT0
+        SBUF_DAT_THIS1 .req SBUF_DAT_ALT1
+        SBUF_DAT_THIS2 .req SBUF_DAT_ALT2
+        SBUF_DAT_THIS3 .req SBUF_DAT_ALT3
+  .ifnc "\head",""
+        vldr    d10, [P_SB, #OFFSET]       @ d10 = SBUF_DAT_ALT
+        vldr    d11, [P_SB, #OFFSET+8]
+  .endif
+ .endif
+ .ifnc "\tail",""
+  .ifc "\half","ab"
+        vmls.f  VA0, SBUF_DAT_REV0, WIN_DN_DAT0  @ all operands treated as vectors
+  .else
+        vmla.f  VD0, SBUF_DAT_REV0, WIN_DN_DAT0  @ all operands treated as vectors
+  .endif
+ .endif
+ .ifnc "\head",""
+        vldr    d14, [P_WIN_UP, #OFFSET]   @ d14 = WIN_UP_DAT
+        vldr    d15, [P_WIN_UP, #OFFSET+8]
+        vldr    d12, [P_WIN_DN, #OFFSET]   @ d12 = WIN_DN_DAT
+        vldr    d13, [P_WIN_DN, #OFFSET+8]
+        vmov    SBUF_DAT_REV3, SBUF_DAT_THIS0
+        vmov    SBUF_DAT_REV2, SBUF_DAT_THIS1
+        vmov    SBUF_DAT_REV1, SBUF_DAT_THIS2
+        vmov    SBUF_DAT_REV0, SBUF_DAT_THIS3
+  .ifc "\half","ab"
+        vmla.f  VB0, SBUF_DAT_THIS0, WIN_UP_DAT0
+  .else
+        vmla.f  VC0, SBUF_DAT_THIS0, WIN_UP_DAT0
+  .endif
+        teq     J_WRAP, #J
+        bne     2f             @ strongly predictable, so better than cond exec in this case
+        sub     P_SB, P_SB, #512*4
+2:
+  .set J, J - 64
+  .set OFFSET, OFFSET + 64*4
+ .endif
+        .unreq  SBUF_DAT_THIS0
+        .unreq  SBUF_DAT_THIS1
+        .unreq  SBUF_DAT_THIS2
+        .unreq  SBUF_DAT_THIS3
+.endm
+
+
+/* void ff_synth_filter_float_vfp(FFTContext *imdct,
+ *                                float *synth_buf_ptr, int *synth_buf_offset,
+ *                                float synth_buf2[32], const float window[512],
+ *                                float out[32], const float in[32], float scale)
+ */
+function ff_synth_filter_float_vfp, export=1
+        push    {r3-r7,lr}
+        vpush   {s16-s31}
+        ldr     lr, [P_SB_OFF]
+        add     a2, ORIG_P_SB, lr, LSL #2 @ calculate synth_buf to pass to imdct_half
+        mov     P_SB, a2                  @ and keep a copy for ourselves
+        bic     J_WRAP, lr, #63           @ mangled to make testing for wrap easier in inner loop
+        sub     lr, lr, #32
+        and     lr, lr, #512-32
+        str     lr, [P_SB_OFF]            @ rotate offset, modulo buffer size, ready for next call
+        ldr     a3, [sp, #(16+6+2)*4]     @ fetch in from stack, to pass to imdct_half
+VFP     vmov    s16, SCALE                @ imdct_half is free to corrupt s0, but it contains one of our arguments in hardfp case
+        bl      X(ff_imdct_half_vfp)
+VFP     vmov    SCALE, s16
+
+        fmrx    OLDFPSCR, FPSCR
+        ldr     lr, =0x03030000           @ RunFast mode, short vectors of length 4, stride 1
+        fmxr    FPSCR, lr
+        ldr     P_SB2_DN, [sp, #16*4]
+        ldr     P_WIN_DN, [sp, #(16+6+0)*4]
+        ldr     P_OUT_DN, [sp, #(16+6+1)*4]
+NOVFP   vldr    SCALE, [sp, #(16+6+3)*4]
+
+#define IMM_OFF_SKEW 956                   /* also valid immediate constant when you add 16*4 */
+        add     P_SB, P_SB, #IMM_OFF_SKEW  @ so we can use -ve offsets to use full immediate offset range
+        add     P_SB2_UP, P_SB2_DN, #16*4
+        add     P_WIN_UP, P_WIN_DN, #16*4+IMM_OFF_SKEW
+        add     P_OUT_UP, P_OUT_DN, #16*4
+        add     P_SB2_DN, P_SB2_DN, #16*4
+        add     P_WIN_DN, P_WIN_DN, #12*4+IMM_OFF_SKEW
+        add     P_OUT_DN, P_OUT_DN, #16*4
+        mov     I, #4
+1:
+        vldmia  P_SB2_UP!, {VB0-VB3}
+        vldmdb  P_SB2_DN!, {VA0-VA3}
+ .set J, 512 - 64
+ .set OFFSET, -IMM_OFF_SKEW
+        inner_loop  ab,, head
+ .rept 7
+        inner_loop  ab, tail, head
+ .endr
+        inner_loop  ab, tail
+        add     P_WIN_UP, P_WIN_UP, #4*4
+        sub     P_WIN_DN, P_WIN_DN, #4*4
+        vmul.f  VB0, VB0, SCALE      @ SCALE treated as scalar
+        add     P_SB, P_SB, #(512+4)*4
+        subs    I, I, #1
+        vmul.f  VA0, VA0, SCALE
+        vstmia  P_OUT_UP!, {VB0-VB3}
+        vstmdb  P_OUT_DN!, {VA0-VA3}
+        bne     1b
+
+        add     P_SB2_DN, P_SB2_DN, #(16+28-12)*4
+        sub     P_SB2_UP, P_SB2_UP, #(16+16)*4
+        add     P_WIN_DN, P_WIN_DN, #(32+16+28-12)*4
+        mov     I, #4
+1:
+        vldr.d  d4, zero             @ d4 = VC0
+        vldr.d  d5, zero
+        vldr.d  d6, zero             @ d6 = VD0
+        vldr.d  d7, zero
+ .set J, 512 - 64
+ .set OFFSET, -IMM_OFF_SKEW
+        inner_loop  cd,, head
+ .rept 7
+        inner_loop  cd, tail, head
+ .endr
+        inner_loop  cd, tail
+        add     P_WIN_UP, P_WIN_UP, #4*4
+        sub     P_WIN_DN, P_WIN_DN, #4*4
+        add     P_SB, P_SB, #(512+4)*4
+        subs    I, I, #1
+        vstmia  P_SB2_UP!, {VC0-VC3}
+        vstmdb  P_SB2_DN!, {VD0-VD3}
+        bne     1b
+
+        fmxr    FPSCR, OLDFPSCR
+        vpop    {s16-s31}
+        pop     {r3-r7,pc}
+endfunc
+
+        .unreq  IMDCT
+        .unreq  ORIG_P_SB
+        .unreq  P_SB_OFF
+        .unreq  I
+        .unreq  P_SB2_UP
+        .unreq  OLDFPSCR
+        .unreq  P_SB2_DN
+        .unreq  P_WIN_DN
+        .unreq  P_OUT_DN
+        .unreq  P_SB
+        .unreq  J_WRAP
+        .unreq  P_WIN_UP
+        .unreq  P_OUT_UP
+
+        .unreq  SCALE
+        .unreq  SBUF_DAT_REV0
+        .unreq  SBUF_DAT_REV1
+        .unreq  SBUF_DAT_REV2
+        .unreq  SBUF_DAT_REV3
+        .unreq  VA0
+        .unreq  VA3
+        .unreq  VB0
+        .unreq  VB3
+        .unreq  VC0
+        .unreq  VC3
+        .unreq  VD0
+        .unreq  VD3
+        .unreq  SBUF_DAT0
+        .unreq  SBUF_DAT1
+        .unreq  SBUF_DAT2
+        .unreq  SBUF_DAT3
+        .unreq  SBUF_DAT_ALT0
+        .unreq  SBUF_DAT_ALT1
+        .unreq  SBUF_DAT_ALT2
+        .unreq  SBUF_DAT_ALT3
+        .unreq  WIN_DN_DAT0
+        .unreq  WIN_UP_DAT0
+
+        .align  3
+zero:   .word   0, 0
diff --git a/libavcodec/ass.c b/libavcodec/ass.c
index b263c63..6fe18f5 100644
--- a/libavcodec/ass.c
+++ b/libavcodec/ass.c
@@ -54,13 +54,13 @@
 int ff_ass_subtitle_header_default(AVCodecContext *avctx)
 {
     return ff_ass_subtitle_header(avctx, ASS_DEFAULT_FONT,
-                                         ASS_DEFAULT_FONT_SIZE,
-                                         ASS_DEFAULT_COLOR,
-                                         ASS_DEFAULT_BACK_COLOR,
-                                         ASS_DEFAULT_BOLD,
-                                         ASS_DEFAULT_ITALIC,
-                                         ASS_DEFAULT_UNDERLINE,
-                                         ASS_DEFAULT_ALIGNMENT);
+                               ASS_DEFAULT_FONT_SIZE,
+                               ASS_DEFAULT_COLOR,
+                               ASS_DEFAULT_BACK_COLOR,
+                               ASS_DEFAULT_BOLD,
+                               ASS_DEFAULT_ITALIC,
+                               ASS_DEFAULT_UNDERLINE,
+                               ASS_DEFAULT_ALIGNMENT);
 }
 
 static void insert_ts(AVBPrint *buf, int ts)
diff --git a/libavcodec/asvdec.c b/libavcodec/asvdec.c
index 7dca22b..eb29e08 100644
--- a/libavcodec/asvdec.c
+++ b/libavcodec/asvdec.c
@@ -28,7 +28,6 @@
 
 #include "asv.h"
 #include "avcodec.h"
-#include "put_bits.h"
 #include "internal.h"
 #include "mathops.h"
 #include "mpeg12data.h"
diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c
index a9e98f8..2a46a05 100644
--- a/libavcodec/atrac3.c
+++ b/libavcodec/atrac3.c
@@ -36,6 +36,7 @@
 #include <stddef.h>
 #include <stdio.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/float_dsp.h"
 #include "libavutil/libm.h"
 #include "avcodec.h"
@@ -664,8 +665,8 @@
 
     snd->num_components = decode_tonal_components(gb, snd->components,
                                                   snd->bands_coded);
-    if (snd->num_components == -1)
-        return -1;
+    if (snd->num_components < 0)
+        return snd->num_components;
 
     num_subbands = decode_spectrum(gb, snd->spectrum);
 
@@ -838,7 +839,7 @@
     return avctx->block_align;
 }
 
-static void atrac3_init_static_data(void)
+static av_cold void atrac3_init_static_data(void)
 {
     int i;
 
@@ -922,11 +923,6 @@
         return AVERROR(EINVAL);
     }
 
-    if (q->coding_mode == JOINT_STEREO && avctx->channels < 2) {
-        av_log(avctx, AV_LOG_ERROR, "Invalid coding mode\n");
-        return AVERROR_INVALIDDATA;
-    }
-
     /* Check the extradata */
 
     if (version != 4) {
@@ -949,9 +945,13 @@
 
     if (q->coding_mode == STEREO)
         av_log(avctx, AV_LOG_DEBUG, "Normal stereo detected.\n");
-    else if (q->coding_mode == JOINT_STEREO)
+    else if (q->coding_mode == JOINT_STEREO) {
+        if (avctx->channels != 2) {
+            av_log(avctx, AV_LOG_ERROR, "Invalid coding mode\n");
+            return AVERROR_INVALIDDATA;
+        }
         av_log(avctx, AV_LOG_DEBUG, "Joint stereo detected.\n");
-    else {
+    } else {
         av_log(avctx, AV_LOG_ERROR, "Unknown channel coding mode %x!\n",
                q->coding_mode);
         return AVERROR_INVALIDDATA;
diff --git a/libavcodec/audio_frame_queue.c b/libavcodec/audio_frame_queue.c
index ba6e225..1220345 100644
--- a/libavcodec/audio_frame_queue.c
+++ b/libavcodec/audio_frame_queue.c
@@ -19,12 +19,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
 #include "audio_frame_queue.h"
 #include "internal.h"
 #include "libavutil/avassert.h"
 
-void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq)
+av_cold void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq)
 {
     afq->avctx = avctx;
     afq->remaining_delay   = avctx->delay;
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index c6ad077..21ecde0 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -23,11 +23,13 @@
 
 /**
  * @file
- * external API header
+ * @ingroup libavc
+ * Libavcodec external API header
  */
 
 #include <errno.h>
 #include "libavutil/samplefmt.h"
+#include "libavutil/attributes.h"
 #include "libavutil/avutil.h"
 #include "libavutil/buffer.h"
 #include "libavutil/cpu.h"
@@ -270,6 +272,10 @@
     AV_CODEC_ID_CLLC,
     AV_CODEC_ID_MSS2,
     AV_CODEC_ID_VP9,
+    AV_CODEC_ID_AIC,
+    AV_CODEC_ID_ESCAPE130_DEPRECATED,
+    AV_CODEC_ID_G2M_DEPRECATED,
+
     AV_CODEC_ID_BRENDER_PIX= MKBETAG('B','P','I','X'),
     AV_CODEC_ID_Y41P       = MKBETAG('Y','4','1','P'),
     AV_CODEC_ID_ESCAPE130  = MKBETAG('E','1','3','0'),
@@ -294,6 +300,7 @@
     AV_CODEC_ID_MVC2       = MKBETAG('M','V','C','2'),
     AV_CODEC_ID_SNOW       = MKBETAG('S','N','O','W'),
     AV_CODEC_ID_WEBP       = MKBETAG('W','E','B','P'),
+    AV_CODEC_ID_SMVJPEG    = MKBETAG('S','M','V','J'),
 
     /* various PCM "codecs" */
     AV_CODEC_ID_FIRST_AUDIO = 0x10000,     ///< A dummy id pointing at the start of audio codecs
@@ -363,6 +370,8 @@
     AV_CODEC_ID_VIMA       = MKBETAG('V','I','M','A'),
     AV_CODEC_ID_ADPCM_AFC  = MKBETAG('A','F','C',' '),
     AV_CODEC_ID_ADPCM_IMA_OKI = MKBETAG('O','K','I',' '),
+    AV_CODEC_ID_ADPCM_DTK  = MKBETAG('D','T','K',' '),
+    AV_CODEC_ID_ADPCM_IMA_RAD = MKBETAG('R','A','D',' '),
 
     /* AMR */
     AV_CODEC_ID_AMR_NB = 0x12000,
@@ -411,7 +420,9 @@
     AV_CODEC_ID_MLP,
     AV_CODEC_ID_GSM_MS, /* as found in WAV */
     AV_CODEC_ID_ATRAC3,
+#if FF_API_VOXWARE
     AV_CODEC_ID_VOXWARE,
+#endif
     AV_CODEC_ID_APE,
     AV_CODEC_ID_NELLYMOSER,
     AV_CODEC_ID_MUSEPACK8,
@@ -443,6 +454,7 @@
     AV_CODEC_ID_OPUS_DEPRECATED,
     AV_CODEC_ID_COMFORT_NOISE,
     AV_CODEC_ID_TAK_DEPRECATED,
+    AV_CODEC_ID_METASOUND,
     AV_CODEC_ID_FFWAVESYNTH = MKBETAG('F','F','W','S'),
     AV_CODEC_ID_SONIC       = MKBETAG('S','O','N','C'),
     AV_CODEC_ID_SONIC_LS    = MKBETAG('S','O','N','L'),
@@ -620,26 +632,6 @@
     AVCOL_TRC_NB             , ///< Not part of ABI
 };
 
-enum AVColorSpace{
-    AVCOL_SPC_RGB         = 0,
-    AVCOL_SPC_BT709       = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
-    AVCOL_SPC_UNSPECIFIED = 2,
-    AVCOL_SPC_FCC         = 4,
-    AVCOL_SPC_BT470BG     = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
-    AVCOL_SPC_SMPTE170M   = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
-    AVCOL_SPC_SMPTE240M   = 7,
-    AVCOL_SPC_YCOCG       = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
-    AVCOL_SPC_NB             , ///< Not part of ABI
-};
-#define AVCOL_SPC_YCGCO AVCOL_SPC_YCOCG
-
-enum AVColorRange{
-    AVCOL_RANGE_UNSPECIFIED = 0,
-    AVCOL_RANGE_MPEG        = 1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges
-    AVCOL_RANGE_JPEG        = 2, ///< the normal     2^n-1   "JPEG" YUV ranges
-    AVCOL_RANGE_NB             , ///< Not part of ABI
-};
-
 /**
  *  X   X      3 4 X      X are luma samples,
  *             1 2        1-6 are possible chroma positions
@@ -774,10 +766,12 @@
  * This can be used to prevent truncation of the last audio samples.
  */
 #define CODEC_CAP_SMALL_LAST_FRAME 0x0040
+#if FF_API_CAP_VDPAU
 /**
  * Codec can export data for HW decoding (VDPAU).
  */
 #define CODEC_CAP_HWACCEL_VDPAU    0x0080
+#endif
 /**
  * Codec can output multiple frames per AVPacket
  * Normally demuxers return one frame at a time, demuxers which do not do
@@ -1002,6 +996,17 @@
      * by data.
      */
     AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
+
+    /**
+     * The optional first identifier line of a WebVTT cue.
+     */
+    AV_PKT_DATA_WEBVTT_IDENTIFIER,
+
+    /**
+     * The optional settings (rendering instructions) that immediately
+     * follow the timestamp specifier of a WebVTT cue.
+     */
+    AV_PKT_DATA_WEBVTT_SETTINGS,
 };
 
 /**
@@ -1237,7 +1242,7 @@
      * rv10: additional flags
      * mpeg4: global headers (they can be in the bitstream or here)
      * The allocated memory should be FF_INPUT_BUFFER_PADDING_SIZE bytes larger
-     * than extradata_size to avoid prolems if it is read with the bitstream reader.
+     * than extradata_size to avoid problems if it is read with the bitstream reader.
      * The bytewise contents of extradata must not depend on the architecture or CPU endianness.
      * - encoding: Set/allocated/freed by libavcodec.
      * - decoding: Set/allocated/freed by user.
@@ -1914,7 +1919,7 @@
      * - decoding: Set by user.
      * @deprecated Deprecated in favor of request_channel_layout.
      */
-    int request_channels;
+    attribute_deprecated int request_channels;
 #endif
 
     /**
@@ -2047,8 +2052,10 @@
     /**
      * This callback is called at the beginning of each frame to get data
      * buffer(s) for it. There may be one contiguous buffer for all the data or
-     * there may be a buffer per each data plane or anything in between. Each
-     * buffer must be reference-counted using the AVBuffer API.
+     * there may be a buffer per each data plane or anything in between. What
+     * this means is, you may set however many entries in buf[] you feel necessary.
+     * Each buffer must be reference-counted using the AVBuffer API (see description
+     * of buf[] below).
      *
      * The following fields will be set in the frame before this callback is
      * called:
@@ -2069,8 +2076,11 @@
      *     extended_data must be allocated with av_malloc() and will be freed in
      *     av_frame_unref().
      *   * otherwise exended_data must point to data
-     * - buf[] must contain references to the buffers that contain the frame
-     *   data.
+     * - buf[] must contain one or more pointers to AVBufferRef structures. Each of
+     *   the frame's data and extended_data pointers must be contained in these. That
+     *   is, one AVBufferRef for each allocated chunk of memory, not necessarily one
+     *   AVBufferRef per data[] entry. See: av_buffer_create(), av_buffer_alloc(),
+     *   and av_buffer_ref().
      * - extended_buf and nb_extended_buf must be allocated with av_malloc() by
      *   this callback and filled with the extra buffers if there are more
      *   buffers than buf[] can hold. extended_buf will be freed in
@@ -2557,12 +2567,16 @@
      */
     int bits_per_raw_sample;
 
+#if FF_API_LOWRES
     /**
      * low resolution decoding, 1-> 1/2 size, 2->1/4 size
      * - encoding: unused
      * - decoding: Set by user.
+     * Code outside libavcodec should access this field using:
+     * av_codec_{get,set}_lowres(avctx)
      */
      int lowres;
+#endif
 
     /**
      * the picture in the bitstream
@@ -2671,6 +2685,8 @@
 #define FF_PROFILE_AAC_HE_V2 28
 #define FF_PROFILE_AAC_LD   22
 #define FF_PROFILE_AAC_ELD  38
+#define FF_PROFILE_MPEG2_AAC_LOW 128
+#define FF_PROFILE_MPEG2_AAC_HE  131
 
 #define FF_PROFILE_DTS         20
 #define FF_PROFILE_DTS_ES      30
@@ -2799,7 +2815,7 @@
      * Code outside libavcodec should access this field using:
      * av_codec_{get,set}_pkt_timebase(avctx)
      * - encoding unused.
-     * - decodimg set by user
+     * - decoding set by user.
      */
     AVRational pkt_timebase;
 
@@ -2812,6 +2828,17 @@
      */
     const AVCodecDescriptor *codec_descriptor;
 
+#if !FF_API_LOWRES
+    /**
+     * low resolution decoding, 1-> 1/2 size, 2->1/4 size
+     * - encoding: unused
+     * - decoding: Set by user.
+     * Code outside libavcodec should access this field using:
+     * av_codec_{get,set}_lowres(avctx)
+     */
+     int lowres;
+#endif
+
     /**
      * Current statistics for PTS correction.
      * - decoding: maintained and used by libavcodec, not intended to be used by user apps
@@ -2839,6 +2866,7 @@
 #define FF_SUB_CHARENC_MODE_DO_NOTHING  -1  ///< do nothing (demuxer outputs a stream supposed to be already in UTF-8, or the codec is bitmap for instance)
 #define FF_SUB_CHARENC_MODE_AUTOMATIC    0  ///< libavcodec will select the mode itself
 #define FF_SUB_CHARENC_MODE_PRE_DECODER  1  ///< the AVPacket data needs to be recoded to UTF-8 before being fed to the decoder, requires iconv
+
 } AVCodecContext;
 
 AVRational av_codec_get_pkt_timebase         (const AVCodecContext *avctx);
@@ -2847,6 +2875,9 @@
 const AVCodecDescriptor *av_codec_get_codec_descriptor(const AVCodecContext *avctx);
 void                     av_codec_set_codec_descriptor(AVCodecContext *avctx, const AVCodecDescriptor *desc);
 
+int  av_codec_get_lowres(const AVCodecContext *avctx);
+void av_codec_set_lowres(AVCodecContext *avctx, int val);
+
 /**
  * AVProfile.
  */
@@ -3052,11 +3083,13 @@
  */
 
 /**
- * four components are given, that's all.
- * the last component is alpha
+ * Picture data structure.
+ *
+ * Up to four components can be stored into it, the last component is
+ * alpha.
  */
 typedef struct AVPicture {
-    uint8_t *data[AV_NUM_DATA_POINTERS];
+    uint8_t *data[AV_NUM_DATA_POINTERS];    ///< pointers to the image data planes
     int linesize[AV_NUM_DATA_POINTERS];     ///< number of bytes per line
 } AVPicture;
 
@@ -3256,7 +3289,7 @@
  * can use this AVCodecContext to decode/encode video/audio data.
  *
  * @param dest target codec context, should be initialized with
- *             avcodec_alloc_context3(), but otherwise uninitialized
+ *             avcodec_alloc_context3(NULL), but otherwise uninitialized
  * @param src source codec context
  * @return AVERROR() on error (e.g. memory allocation error), 0 on success
  */
@@ -3464,6 +3497,13 @@
 int av_copy_packet(AVPacket *dst, AVPacket *src);
 
 /**
+ * Copy packet side data
+ *
+ * @return 0 on success, negative AVERROR on fail
+ */
+int av_copy_packet_side_data(AVPacket *dst, AVPacket *src);
+
+/**
  * Free a packet.
  *
  * @param pkt packet to free
@@ -3509,6 +3549,66 @@
 
 
 /**
+ * Convenience function to free all the side data stored.
+ * All the other fields stay untouched.
+ *
+ * @param pkt packet
+ */
+void av_packet_free_side_data(AVPacket *pkt);
+
+/**
+ * Setup a new reference to the data described by a given packet
+ *
+ * If src is reference-counted, setup dst as a new reference to the
+ * buffer in src. Otherwise allocate a new buffer in dst and copy the
+ * data from src into it.
+ *
+ * All the other fields are copied from src.
+ *
+ * @see av_packet_unref
+ *
+ * @param dst Destination packet
+ * @param src Source packet
+ *
+ * @return 0 on success, a negative AVERROR on error.
+ */
+int av_packet_ref(AVPacket *dst, AVPacket *src);
+
+/**
+ * Wipe the packet.
+ *
+ * Unreference the buffer referenced by the packet and reset the
+ * remaining packet fields to their default values.
+ *
+ * @param pkt The packet to be unreferenced.
+ */
+void av_packet_unref(AVPacket *pkt);
+
+/**
+ * Move every field in src to dst and reset src.
+ *
+ * @see av_packet_unref
+ *
+ * @param src Source packet, will be reset
+ * @param dst Destination packet
+ */
+void av_packet_move_ref(AVPacket *dst, AVPacket *src);
+
+/**
+ * Copy only "properties" fields from src to dst.
+ *
+ * Properties for the purpose of this function are all the fields
+ * beside those related to the packet data (buf, data, size)
+ *
+ * @param dst Destination packet
+ * @param src Source packet
+ *
+ * @return 0 on success AVERROR on failure.
+ *
+ */
+int av_packet_copy_props(AVPacket *dst, const AVPacket *src);
+
+/**
  * @}
  */
 
@@ -3578,6 +3678,28 @@
 void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
                                int linesize_align[AV_NUM_DATA_POINTERS]);
 
+/**
+ * Converts AVChromaLocation to swscale x/y chroma position.
+ *
+ * The positions represent the chroma (0,0) position in a coordinates system
+ * with luma (0,0) representing the origin and luma(1,1) representing 256,256
+ *
+ * @param xpos  horizontal chroma sample position
+ * @param ypos  vertical   chroma sample position
+ */
+int avcodec_enum_to_chroma_pos(int *xpos, int *ypos, enum AVChromaLocation pos);
+
+/**
+ * Converts swscale x/y chroma position to AVChromaLocation.
+ *
+ * The positions represent the chroma (0,0) position in a coordinates system
+ * with luma (0,0) representing the origin and luma(1,1) representing 256,256
+ *
+ * @param xpos  horizontal chroma sample position
+ * @param ypos  vertical   chroma sample position
+ */
+enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos);
+
 #if FF_API_OLD_DECODE_AUDIO
 /**
  * Wrapper function which calls avcodec_decode_audio4.
@@ -3756,6 +3878,13 @@
  * @{
  */
 
+enum AVPictureStructure {
+    AV_PICTURE_STRUCTURE_UNKNOWN,      //< unknown
+    AV_PICTURE_STRUCTURE_TOP_FIELD,    //< coded as top field
+    AV_PICTURE_STRUCTURE_BOTTOM_FIELD, //< coded as bottom field
+    AV_PICTURE_STRUCTURE_FRAME,        //< coded as frame
+};
+
 typedef struct AVCodecParserContext {
     void *priv_data;
     struct AVCodecParser *parser;
@@ -3890,6 +4019,26 @@
      * For all other types, this is in units of AVCodecContext.time_base.
      */
     int duration;
+
+    enum AVFieldOrder field_order;
+
+    /**
+     * Indicate whether a picture is coded as a frame, top field or bottom field.
+     *
+     * For example, H.264 field_pic_flag equal to 0 corresponds to
+     * AV_PICTURE_STRUCTURE_FRAME. An H.264 picture with field_pic_flag
+     * equal to 1 and bottom_field_flag equal to 0 corresponds to
+     * AV_PICTURE_STRUCTURE_TOP_FIELD.
+     */
+    enum AVPictureStructure picture_structure;
+
+    /**
+     * Picture number incremented in presentation or output order.
+     * This field may be reinitialized at the first picture of a new sequence.
+     *
+     * For example, this corresponds to H.264 PicOrderCnt.
+     */
+    int output_picture_number;
 } AVCodecParserContext;
 
 typedef struct AVCodecParser {
@@ -4221,15 +4370,18 @@
  */
 
 /**
- * Allocate memory for a picture.  Call avpicture_free() to free it.
+ * Allocate memory for the pixels of a picture and setup the AVPicture
+ * fields for it.
  *
- * @see avpicture_fill()
+ * Call avpicture_free() to free it.
  *
- * @param picture the picture to be filled in
- * @param pix_fmt the format of the picture
- * @param width the width of the picture
- * @param height the height of the picture
- * @return zero if successful, a negative value if not
+ * @param picture            the picture structure to be filled in
+ * @param pix_fmt            the pixel format of the picture
+ * @param width              the width of the picture
+ * @param height             the height of the picture
+ * @return zero if successful, a negative error code otherwise
+ *
+ * @see av_image_alloc(), avpicture_fill()
  */
 int avpicture_alloc(AVPicture *picture, enum AVPixelFormat pix_fmt, int width, int height);
 
@@ -4243,8 +4395,25 @@
 void avpicture_free(AVPicture *picture);
 
 /**
- * Fill in the AVPicture fields, always assume a linesize alignment of
- * 1.
+ * Setup the picture fields based on the specified image parameters
+ * and the provided image data buffer.
+ *
+ * The picture fields are filled in by using the image data buffer
+ * pointed to by ptr.
+ *
+ * If ptr is NULL, the function will fill only the picture linesize
+ * array and return the required size for the image buffer.
+ *
+ * To allocate an image buffer and fill the picture data in one call,
+ * use avpicture_alloc().
+ *
+ * @param picture       the picture to be filled in
+ * @param ptr           buffer where the image data is stored, or NULL
+ * @param pix_fmt       the pixel format of the image
+ * @param width         the width of the image in pixels
+ * @param height        the height of the image in pixels
+ * @return the size in bytes required for src, a negative error code
+ * in case of failure
  *
  * @see av_image_fill_arrays()
  */
@@ -4252,19 +4421,36 @@
                    enum AVPixelFormat pix_fmt, int width, int height);
 
 /**
- * Copy pixel data from an AVPicture into a buffer, always assume a
- * linesize alignment of 1.
+ * Copy pixel data from an AVPicture into a buffer.
+ *
+ * avpicture_get_size() can be used to compute the required size for
+ * the buffer to fill.
+ *
+ * @param src        source picture with filled data
+ * @param pix_fmt    picture pixel format
+ * @param width      picture width
+ * @param height     picture height
+ * @param dest       destination buffer
+ * @param dest_size  destination buffer size in bytes
+ * @return the number of bytes written to dest, or a negative value
+ * (error code) on error, for example if the destination buffer is not
+ * big enough
  *
  * @see av_image_copy_to_buffer()
  */
-int avpicture_layout(const AVPicture* src, enum AVPixelFormat pix_fmt,
+int avpicture_layout(const AVPicture *src, enum AVPixelFormat pix_fmt,
                      int width, int height,
                      unsigned char *dest, int dest_size);
 
 /**
  * Calculate the size in bytes that a picture of the given width and height
  * would occupy if stored in the given picture format.
- * Always assume a linesize alignment of 1.
+ *
+ * @param pix_fmt    picture pixel format
+ * @param width      picture width
+ * @param height     picture height
+ * @return the computed picture buffer size or a negative error code
+ * in case of error
  *
  * @see av_image_get_buffer_size().
  */
@@ -4425,7 +4611,7 @@
                                             enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr);
 
 attribute_deprecated
-#if AV_HAVE_INCOMPATIBLE_FORK_ABI
+#if AV_HAVE_INCOMPATIBLE_LIBAV_ABI
 enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat *pix_fmt_list,
                                               enum AVPixelFormat src_pix_fmt,
                                               int has_alpha, int *loss_ptr);
@@ -4555,14 +4741,78 @@
     struct AVBitStreamFilter *next;
 } AVBitStreamFilter;
 
+/**
+ * Register a bitstream filter.
+ *
+ * The filter will be accessible to the application code through
+ * av_bitstream_filter_next() or can be directly initialized with
+ * av_bitstream_filter_init().
+ *
+ * @see avcodec_register_all()
+ */
 void av_register_bitstream_filter(AVBitStreamFilter *bsf);
+
+/**
+ * Create and initialize a bitstream filter context given a bitstream
+ * filter name.
+ *
+ * The returned context must be freed with av_bitstream_filter_close().
+ *
+ * @param name    the name of the bitstream filter
+ * @return a bitstream filter context if a matching filter was found
+ * and successfully initialized, NULL otherwise
+ */
 AVBitStreamFilterContext *av_bitstream_filter_init(const char *name);
+
+/**
+ * Filter bitstream.
+ *
+ * This function filters the buffer buf with size buf_size, and places the
+ * filtered buffer in the buffer pointed to by poutbuf.
+ *
+ * The output buffer must be freed by the caller.
+ *
+ * @param bsfc            bitstream filter context created by av_bitstream_filter_init()
+ * @param avctx           AVCodecContext accessed by the filter, may be NULL.
+ *                        If specified, this must point to the encoder context of the
+ *                        output stream the packet is sent to.
+ * @param args            arguments which specify the filter configuration, may be NULL
+ * @param poutbuf         pointer which is updated to point to the filtered buffer
+ * @param poutbuf_size    pointer which is updated to the filtered buffer size in bytes
+ * @param buf             buffer containing the data to filter
+ * @param buf_size        size in bytes of buf
+ * @param keyframe        set to non-zero if the buffer to filter corresponds to a key-frame packet data
+ * @return >= 0 in case of success, or a negative error code in case of failure
+ *
+ * If the return value is positive, an output buffer is allocated and
+ * is availble in *poutbuf, and is distinct from the input buffer.
+ *
+ * If the return value is 0, the output buffer is not allocated and
+ * should be considered identical to the input buffer, or in case
+ * *poutbuf was set it points to the input buffer (not necessarily to
+ * its starting address).
+ */
 int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc,
                                AVCodecContext *avctx, const char *args,
                                uint8_t **poutbuf, int *poutbuf_size,
                                const uint8_t *buf, int buf_size, int keyframe);
+
+/**
+ * Release bitstream filter context.
+ *
+ * @param bsf the bitstream filter context created with
+ * av_bitstream_filter_init(), can be NULL
+ */
 void av_bitstream_filter_close(AVBitStreamFilterContext *bsf);
 
+/**
+ * If f is NULL, return the first registered bitstream filter,
+ * if f is non-NULL, return the next registered bitstream filter
+ * after f, or NULL if f is the last one.
+ *
+ * This function can be used to iterate over all registered bitstream
+ * filters.
+ */
 AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f);
 
 /* memory */
@@ -4590,7 +4840,7 @@
 
 /**
  * Same behaviour av_fast_malloc but the buffer has additional
- * FF_INPUT_BUFFER_PADDING_SIZE at the end which will will always be 0.
+ * FF_INPUT_BUFFER_PADDING_SIZE at the end which will always be 0.
  *
  * In addition the whole buffer will initially and after resizes
  * be 0-initialized so that no uninitialized data will ever appear.
diff --git a/libavcodec/avfft.c b/libavcodec/avfft.c
index 9e0ddaa..26b3d4b 100644
--- a/libavcodec/avfft.c
+++ b/libavcodec/avfft.c
@@ -16,6 +16,7 @@
  * 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"
@@ -44,7 +45,7 @@
     s->fft_calc(s, z);
 }
 
-void av_fft_end(FFTContext *s)
+av_cold void av_fft_end(FFTContext *s)
 {
     if (s) {
         ff_fft_end(s);
@@ -79,7 +80,7 @@
     s->mdct_calc(s, output, input);
 }
 
-void av_mdct_end(FFTContext *s)
+av_cold void av_mdct_end(FFTContext *s)
 {
     if (s) {
         ff_mdct_end(s);
@@ -106,7 +107,7 @@
     s->rdft_calc(s, data);
 }
 
-void av_rdft_end(RDFTContext *s)
+av_cold void av_rdft_end(RDFTContext *s)
 {
     if (s) {
         ff_rdft_end(s);
@@ -133,7 +134,7 @@
     s->dct_calc(s, data);
 }
 
-void av_dct_end(DCTContext *s)
+av_cold void av_dct_end(DCTContext *s)
 {
     if (s) {
         ff_dct_end(s);
diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
index 651036e..7196c31 100644
--- a/libavcodec/avpacket.c
+++ b/libavcodec/avpacket.c
@@ -23,21 +23,14 @@
 
 #include "libavutil/avassert.h"
 #include "libavutil/common.h"
+#include "libavutil/internal.h"
 #include "libavutil/mem.h"
 #include "avcodec.h"
 #include "bytestream.h"
 #include "internal.h"
 
-void ff_packet_free_side_data(AVPacket *pkt)
-{
-    int i;
-    for (i = 0; i < pkt->side_data_elems; i++)
-        av_free(pkt->side_data[i].data);
-    av_freep(&pkt->side_data);
-    pkt->side_data_elems = 0;
-}
-
 #if FF_API_DESTRUCT_PACKET
+
 void av_destruct_packet(AVPacket *pkt)
 {
     av_free(pkt->data);
@@ -63,32 +56,44 @@
     pkt->flags                = 0;
     pkt->stream_index         = 0;
 #if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
     pkt->destruct             = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
     pkt->buf                  = NULL;
     pkt->side_data            = NULL;
     pkt->side_data_elems      = 0;
 }
 
-int av_new_packet(AVPacket *pkt, int size)
+static int packet_alloc(AVBufferRef **buf, int size)
 {
-    AVBufferRef *buf = NULL;
-
     if ((unsigned)size >= (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE)
         return AVERROR(EINVAL);
 
-    av_buffer_realloc(&buf, size + FF_INPUT_BUFFER_PADDING_SIZE);
-    if (!buf)
+    av_buffer_realloc(buf, size + FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!*buf)
         return AVERROR(ENOMEM);
 
-    memset(buf->data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+    memset((*buf)->data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+
+    return 0;
+}
+
+int av_new_packet(AVPacket *pkt, int size)
+{
+    AVBufferRef *buf = NULL;
+    int ret = packet_alloc(&buf, size);
+    if (ret < 0)
+        return ret;
 
     av_init_packet(pkt);
     pkt->buf      = buf;
     pkt->data     = buf->data;
     pkt->size     = size;
 #if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
     pkt->destruct = dummy_destruct_packet;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
     return 0;
@@ -123,7 +128,9 @@
             return AVERROR(ENOMEM);
         memcpy(pkt->buf->data, pkt->data, FFMIN(pkt->size, pkt->size + grow_by));
 #if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
         pkt->destruct = dummy_destruct_packet;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
     }
     pkt->data  = pkt->buf->data;
@@ -146,7 +153,9 @@
     pkt->data = data;
     pkt->size = size;
 #if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
     pkt->destruct = dummy_destruct_packet;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
     return 0;
@@ -180,7 +189,7 @@
     } while (0)
 
 /* Makes duplicates of data, side_data, but does not copy any other fields */
-static int copy_packet_data(AVPacket *pkt, AVPacket *src)
+static int copy_packet_data(AVPacket *pkt, AVPacket *src, int dup)
 {
     pkt->data      = NULL;
     pkt->side_data = NULL;
@@ -194,17 +203,31 @@
         DUP_DATA(pkt->data, src->data, pkt->size, 1, ALLOC_BUF);
     }
 #if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
     pkt->destruct = dummy_destruct_packet;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
+    if (pkt->side_data_elems && dup)
+        pkt->side_data = src->side_data;
+    if (pkt->side_data_elems && !dup) {
+        return av_copy_packet_side_data(pkt, src);
+    }
+    return 0;
 
-    if (pkt->side_data_elems) {
+failed_alloc:
+    av_destruct_packet(pkt);
+    return AVERROR(ENOMEM);
+}
+
+int av_copy_packet_side_data(AVPacket *pkt, AVPacket *src)
+{
+    if (src->side_data_elems) {
         int i;
-
         DUP_DATA(pkt->side_data, src->side_data,
-                pkt->side_data_elems * sizeof(*pkt->side_data), 0, ALLOC_MALLOC);
+                src->side_data_elems * sizeof(*src->side_data), 0, ALLOC_MALLOC);
         memset(pkt->side_data, 0,
-                pkt->side_data_elems * sizeof(*pkt->side_data));
-        for (i = 0; i < pkt->side_data_elems; i++) {
+                src->side_data_elems * sizeof(*src->side_data));
+        for (i = 0; i < src->side_data_elems; i++) {
             DUP_DATA(pkt->side_data[i].data, src->side_data[i].data,
                     src->side_data[i].size, 1, ALLOC_MALLOC);
             pkt->side_data[i].size = src->side_data[i].size;
@@ -222,13 +245,15 @@
 {
     AVPacket tmp_pkt;
 
+FF_DISABLE_DEPRECATION_WARNINGS
     if (!pkt->buf && pkt->data
 #if FF_API_DESTRUCT_PACKET
         && !pkt->destruct
 #endif
         ) {
+FF_ENABLE_DEPRECATION_WARNINGS
         tmp_pkt = *pkt;
-        return copy_packet_data(pkt, &tmp_pkt);
+        return copy_packet_data(pkt, &tmp_pkt, 1);
     }
     return 0;
 }
@@ -236,14 +261,22 @@
 int av_copy_packet(AVPacket *dst, AVPacket *src)
 {
     *dst = *src;
-    return copy_packet_data(dst, src);
+    return copy_packet_data(dst, src, 0);
+}
+
+void av_packet_free_side_data(AVPacket *pkt)
+{
+    int i;
+    for (i = 0; i < pkt->side_data_elems; i++)
+        av_free(pkt->side_data[i].data);
+    av_freep(&pkt->side_data);
+    pkt->side_data_elems = 0;
 }
 
 void av_free_packet(AVPacket *pkt)
 {
     if (pkt) {
-        int i;
-
+FF_DISABLE_DEPRECATION_WARNINGS
         if (pkt->buf)
             av_buffer_unref(&pkt->buf);
 #if FF_API_DESTRUCT_PACKET
@@ -251,13 +284,11 @@
             pkt->destruct(pkt);
         pkt->destruct = NULL;
 #endif
+FF_ENABLE_DEPRECATION_WARNINGS
         pkt->data            = NULL;
         pkt->size            = 0;
 
-        for (i = 0; i < pkt->side_data_elems; i++)
-            av_free(pkt->side_data[i].data);
-        av_freep(&pkt->side_data);
-        pkt->side_data_elems = 0;
+        av_packet_free_side_data(pkt);
     }
 }
 
@@ -321,7 +352,9 @@
         pkt->buf = buf;
         pkt->data = p = buf->data;
 #if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
         pkt->destruct = dummy_destruct_packet;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
         pkt->size = size - FF_INPUT_BUFFER_PADDING_SIZE;
         bytestream_put_buffer(&p, old.data, old.size);
@@ -344,7 +377,7 @@
 int av_packet_split_side_data(AVPacket *pkt){
     if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == FF_MERGE_MARKER){
         int i;
-        unsigned int size;
+        unsigned int size, orig_pktsize = pkt->size;
         uint8_t *p;
 
         p = pkt->data + pkt->size - 8 - 5;
@@ -377,6 +410,13 @@
             p-= size+5;
         }
         pkt->size -= 8;
+        /* FFMIN() prevents overflow in case the packet wasn't allocated with
+         * proper padding.
+         * If the side data is smaller than the buffer padding size, the
+         * remaining bytes should have already been filled with zeros by the
+         * original packet allocation anyway. */
+        memset(pkt->data + pkt->size, 0,
+               FFMIN(orig_pktsize - pkt->size, FF_INPUT_BUFFER_PADDING_SIZE));
         pkt->side_data_elems = i+1;
         return 1;
     }
@@ -398,3 +438,71 @@
     }
     return AVERROR(ENOENT);
 }
+
+int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
+{
+    int i;
+
+    dst->pts                  = src->pts;
+    dst->dts                  = src->dts;
+    dst->pos                  = src->pos;
+    dst->duration             = src->duration;
+    dst->convergence_duration = src->convergence_duration;
+    dst->flags                = src->flags;
+    dst->stream_index         = src->stream_index;
+    dst->side_data_elems      = src->side_data_elems;
+
+    for (i = 0; i < src->side_data_elems; i++) {
+         enum AVPacketSideDataType type = src->side_data[i].type;
+         int size          = src->side_data[i].size;
+         uint8_t *src_data = src->side_data[i].data;
+         uint8_t *dst_data = av_packet_new_side_data(dst, type, size);
+
+        if (!dst_data) {
+            av_packet_free_side_data(dst);
+            return AVERROR(ENOMEM);
+        }
+        memcpy(dst_data, src_data, size);
+    }
+
+    return 0;
+}
+
+void av_packet_unref(AVPacket *pkt)
+{
+    av_packet_free_side_data(pkt);
+    av_buffer_unref(&pkt->buf);
+    av_init_packet(pkt);
+    pkt->data = NULL;
+    pkt->size = 0;
+}
+
+int av_packet_ref(AVPacket *dst, AVPacket *src)
+{
+    int ret;
+
+    ret = av_packet_copy_props(dst, src);
+    if (ret < 0)
+        return ret;
+
+    if (!src->buf) {
+        ret = packet_alloc(&dst->buf, src->size);
+        if (ret < 0)
+            goto fail;
+        memcpy(dst->buf->data, src->data, src->size);
+    } else
+        dst->buf = av_buffer_ref(src->buf);
+
+    dst->size = src->size;
+    dst->data = dst->buf->data;
+    return 0;
+fail:
+    av_packet_free_side_data(dst);
+    return ret;
+}
+
+void av_packet_move_ref(AVPacket *dst, AVPacket *src)
+{
+    *dst = *src;
+    av_init_packet(src);
+}
diff --git a/libavcodec/bgmc.c b/libavcodec/bgmc.c
index f48ac2e..1a6817b 100644
--- a/libavcodec/bgmc.c
+++ b/libavcodec/bgmc.c
@@ -1,6 +1,6 @@
 /*
  * Block Gilbert-Moore decoder
- * Copyright (c) 2010 Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
+ * Copyright (c) 2010 Thilo Borgmann <thilo.borgmann _at_ mail.de>
  *
  * This file is part of FFmpeg.
  *
@@ -22,9 +22,10 @@
 /**
  * @file
  * Block Gilbert-Moore decoder as used by MPEG-4 ALS
- * @author Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
+ * @author Thilo Borgmann <thilo.borgmann _at_ mail.de>
  */
 
+#include "libavutil/attributes.h"
 #include "bgmc.h"
 
 #define FREQ_BITS  14                      // bits used by frequency counters
@@ -456,7 +457,8 @@
 
 
 /** Initialize the lookup table arrays */
-int ff_bgmc_init(AVCodecContext *avctx, uint8_t **cf_lut, int **cf_lut_status)
+av_cold int ff_bgmc_init(AVCodecContext *avctx,
+                         uint8_t **cf_lut, int **cf_lut_status)
 {
     *cf_lut        = av_malloc(sizeof(**cf_lut)        * LUT_BUFF * 16 * LUT_SIZE);
     *cf_lut_status = av_malloc(sizeof(**cf_lut_status) * LUT_BUFF);
@@ -475,7 +477,7 @@
 
 
 /** Release the lookup table arrays */
-void ff_bgmc_end(uint8_t **cf_lut, int **cf_lut_status)
+av_cold void ff_bgmc_end(uint8_t **cf_lut, int **cf_lut_status)
 {
     av_freep(cf_lut);
     av_freep(cf_lut_status);
@@ -483,8 +485,8 @@
 
 
 /** Initialize decoding and reads the first value */
-void ff_bgmc_decode_init(GetBitContext *gb, unsigned int *h, unsigned int *l,
-                         unsigned int *v)
+void ff_bgmc_decode_init(GetBitContext *gb, unsigned int *h,
+                         unsigned int *l, unsigned int *v)
 {
     *h = TOP_VALUE;
     *l = 0;
diff --git a/libavcodec/bgmc.h b/libavcodec/bgmc.h
index 9e386fd..4893736 100644
--- a/libavcodec/bgmc.h
+++ b/libavcodec/bgmc.h
@@ -1,6 +1,6 @@
 /*
  * Block Gilbert-Moore decoder
- * Copyright (c) 2010 Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
+ * Copyright (c) 2010 Thilo Borgmann <thilo.borgmann _at_ mail.de>
  *
  * This file is part of FFmpeg.
  *
@@ -22,7 +22,7 @@
 /**
  * @file
  * Block Gilbert-Moore decoder header
- * @author Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
+ * @author Thilo Borgmann <thilo.borgmann _at_ mail.de>
  */
 
 
diff --git a/libavcodec/bink.c b/libavcodec/bink.c
index 9bab4b9..dec5f09 100644
--- a/libavcodec/bink.c
+++ b/libavcodec/bink.c
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/internal.h"
 #include "avcodec.h"
@@ -142,7 +143,7 @@
 };
 
 /**
- * Initialize length length in all bundles.
+ * Initialize length in all bundles.
  *
  * @param c     decoder context
  * @param width plane width
@@ -528,14 +529,14 @@
     return ret;
 }
 
-static void binkb_init_bundle(BinkContext *c, int bundle_num)
+static av_cold void binkb_init_bundle(BinkContext *c, int bundle_num)
 {
     c->bundle[bundle_num].cur_dec =
     c->bundle[bundle_num].cur_ptr = c->bundle[bundle_num].data;
     c->bundle[bundle_num].len = 13;
 }
 
-static void binkb_init_bundles(BinkContext *c)
+static av_cold void binkb_init_bundles(BinkContext *c)
 {
     int i;
     for (i = 0; i < BINKB_NB_SRC; i++)
diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
index ef5569a..6d94c99 100644
--- a/libavcodec/binkaudio.c
+++ b/libavcodec/binkaudio.c
@@ -36,10 +36,9 @@
 #include "rdft.h"
 #include "fmtconvert.h"
 #include "internal.h"
+#include "wma.h"
 #include "libavutil/intfloat.h"
 
-extern const uint16_t ff_wma_critical_freqs[25];
-
 static float quant_table[96];
 
 #define MAX_CHANNELS 2
diff --git a/libavcodec/binkdata.h b/libavcodec/binkdata.h
index b9dc1f2..57619be 100644
--- a/libavcodec/binkdata.h
+++ b/libavcodec/binkdata.h
@@ -1,6 +1,6 @@
 /*
  * Bink video decoder
- * Copyright (C) 2009 Kostya Shishkov
+ * Copyright (C) 2009 Konstantin Shishkov
  *
  * This file is part of FFmpeg.
  *
diff --git a/libavcodec/binkdsp.c b/libavcodec/binkdsp.c
index c751743..a23f9c7 100644
--- a/libavcodec/binkdsp.c
+++ b/libavcodec/binkdsp.c
@@ -1,6 +1,6 @@
 /*
  * Bink DSP routines
- * Copyright (c) 2009 Kostya Shishkov
+ * Copyright (c) 2009 Konstantin Shishkov
  *
  * This file is part of FFmpeg.
  *
@@ -24,6 +24,7 @@
  * Bink DSP routines
  */
 
+#include "libavutil/attributes.h"
 #include "dsputil.h"
 #include "binkdsp.h"
 
@@ -128,7 +129,7 @@
     }
 }
 
-void ff_binkdsp_init(BinkDSPContext *c)
+av_cold void ff_binkdsp_init(BinkDSPContext *c)
 {
     c->idct_add    = bink_idct_add_c;
     c->idct_put    = bink_idct_put_c;
diff --git a/libavcodec/binkdsp.h b/libavcodec/binkdsp.h
index 4968413..4c1f73f 100644
--- a/libavcodec/binkdsp.h
+++ b/libavcodec/binkdsp.h
@@ -1,6 +1,6 @@
 /*
  * Bink DSP routines
- * Copyright (c) 2009 Kostya Shishkov
+ * Copyright (c) 2009 Konstantin Shishkov
  *
  * This file is part of Libav.
  *
diff --git a/libavcodec/bintext.h b/libavcodec/bintext.h
index ea834a0..21428ba 100644
--- a/libavcodec/bintext.h
+++ b/libavcodec/bintext.h
@@ -28,7 +28,7 @@
 #define AVCODEC_BINTEXT_H
 
 /* flag values passed between avformat and avcodec;
- * while these are identical to the XBIN flags, they are are also used
+ * while these are identical to the XBIN flags, they are also used
  * for the BINTEXT and IDF decoders.
  */
 #define BINTEXT_PALETTE  0x1
diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c
index 7e297b9..299ee23 100644
--- a/libavcodec/bitstream.c
+++ b/libavcodec/bitstream.c
@@ -28,6 +28,7 @@
  * bitstream api.
  */
 
+#include "libavutil/atomic.h"
 #include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "mathops.h"
@@ -45,81 +46,84 @@
 
 void avpriv_align_put_bits(PutBitContext *s)
 {
-    put_bits(s,s->bit_left & 7,0);
+    put_bits(s, s->bit_left & 7, 0);
 }
 
-void avpriv_put_string(PutBitContext *pb, const char *string, int terminate_string)
+void avpriv_put_string(PutBitContext *pb, const char *string,
+                       int terminate_string)
 {
-    while(*string){
+    while (*string) {
         put_bits(pb, 8, *string);
         string++;
     }
-    if(terminate_string)
+    if (terminate_string)
         put_bits(pb, 8, 0);
 }
 
 void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
 {
-    int words= length>>4;
-    int bits= length&15;
+    int words = length >> 4;
+    int bits  = length & 15;
     int i;
 
-    if(length==0) return;
+    if (length == 0)
+        return;
 
-    if(CONFIG_SMALL || words < 16 || put_bits_count(pb)&7){
-        for(i=0; i<words; i++) put_bits(pb, 16, AV_RB16(src + 2*i));
-    }else{
-        for(i=0; put_bits_count(pb)&31; i++)
+    if (CONFIG_SMALL || words < 16 || put_bits_count(pb) & 7) {
+        for (i = 0; i < words; i++)
+            put_bits(pb, 16, AV_RB16(src + 2 * i));
+    } else {
+        for (i = 0; put_bits_count(pb) & 31; i++)
             put_bits(pb, 8, src[i]);
         flush_put_bits(pb);
-        memcpy(put_bits_ptr(pb), src+i, 2*words-i);
-        skip_put_bytes(pb, 2*words-i);
+        memcpy(put_bits_ptr(pb), src + i, 2 * words - i);
+        skip_put_bytes(pb, 2 * words - i);
     }
 
-    put_bits(pb, bits, AV_RB16(src + 2*words)>>(16-bits));
+    put_bits(pb, bits, AV_RB16(src + 2 * words) >> (16 - bits));
 }
 
 /* VLC decoding */
 
-#define GET_DATA(v, table, i, wrap, size) \
-{\
-    const uint8_t *ptr = (const uint8_t *)table + i * wrap;\
-    switch(size) {\
-    case 1:\
-        v = *(const uint8_t *)ptr;\
-        break;\
-    case 2:\
-        v = *(const uint16_t *)ptr;\
-        break;\
-    default:\
-        v = *(const uint32_t *)ptr;\
-        break;\
-    }\
+#define GET_DATA(v, table, i, wrap, size)                   \
+{                                                           \
+    const uint8_t *ptr = (const uint8_t *)table + i * wrap; \
+    switch(size) {                                          \
+    case 1:                                                 \
+        v = *(const uint8_t *)ptr;                          \
+        break;                                              \
+    case 2:                                                 \
+        v = *(const uint16_t *)ptr;                         \
+        break;                                              \
+    default:                                                \
+        v = *(const uint32_t *)ptr;                         \
+        break;                                              \
+    }                                                       \
 }
 
 
 static int alloc_table(VLC *vlc, int size, int use_static)
 {
-    int index;
-    index = vlc->table_size;
+    int index = vlc->table_size;
+
     vlc->table_size += size;
     if (vlc->table_size > vlc->table_allocated) {
-        if(use_static)
+        if (use_static)
             abort(); // cannot do anything, init_vlc() is used with too little memory
         vlc->table_allocated += (1 << vlc->bits);
-        vlc->table = av_realloc_f(vlc->table,
-                                  vlc->table_allocated, sizeof(VLC_TYPE) * 2);
+        vlc->table = av_realloc_f(vlc->table, vlc->table_allocated, sizeof(VLC_TYPE) * 2);
         if (!vlc->table)
-            return -1;
+            return AVERROR(ENOMEM);
     }
     return index;
 }
 
-static av_always_inline uint32_t bitswap_32(uint32_t x) {
-    return (uint32_t)ff_reverse[x&0xFF]<<24
-         | (uint32_t)ff_reverse[(x>>8)&0xFF]<<16
-         | (uint32_t)ff_reverse[(x>>16)&0xFF]<<8
-         | (uint32_t)ff_reverse[x>>24];
+static av_always_inline uint32_t bitswap_32(uint32_t x)
+{
+    return (uint32_t)ff_reverse[ x        & 0xFF] << 24 |
+           (uint32_t)ff_reverse[(x >> 8)  & 0xFF] << 16 |
+           (uint32_t)ff_reverse[(x >> 16) & 0xFF] << 8  |
+           (uint32_t)ff_reverse[ x >> 24];
 }
 
 typedef struct {
@@ -132,10 +136,9 @@
 
 static int compare_vlcspec(const void *a, const void *b)
 {
-    const VLCcode *sa=a, *sb=b;
+    const VLCcode *sa = a, *sb = b;
     return (sa->code >> 1) - (sb->code >> 1);
 }
-
 /**
  * Build VLC decoding tables suitable for use with get_vlc().
  *
@@ -164,7 +167,7 @@
     table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_NEW_STATIC);
     av_dlog(NULL, "new table index=%d size=%d\n", table_index, table_size);
     if (table_index < 0)
-        return -1;
+        return table_index;
     table = &vlc->table[table_index];
 
     for (i = 0; i < table_size; i++) {
@@ -174,8 +177,8 @@
 
     /* first pass: map codes and compute auxiliary table sizes */
     for (i = 0; i < nb_codes; i++) {
-        n = codes[i].bits;
-        code = codes[i].code;
+        n      = codes[i].bits;
+        code   = codes[i].code;
         symbol = codes[i].symbol;
         av_dlog(NULL, "i=%d n=%d code=0x%x\n", i, n, code);
         if (n <= table_nb_bits) {
@@ -191,7 +194,7 @@
                 av_dlog(NULL, "%4x: code=%d n=%d\n", j, i, n);
                 if (table[j][1] /*bits*/ != 0) {
                     av_log(NULL, AV_LOG_ERROR, "incorrect codes\n");
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 table[j][1] = n; //bits
                 table[j][0] = symbol;
@@ -222,7 +225,7 @@
                     j, codes[i].bits + table_nb_bits);
             index = build_table(vlc, subtable_bits, k-i, codes+i, flags);
             if (index < 0)
-                return -1;
+                return index;
             /* note: realloc has been done, so reload tables */
             table = &vlc->table[table_index];
             table[j][0] = index; //code
@@ -260,71 +263,67 @@
    with av_free_static(), 0 if ff_free_vlc() will be used.
 */
 int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes,
-             const void *bits, int bits_wrap, int bits_size,
-             const void *codes, int codes_wrap, int codes_size,
-             const void *symbols, int symbols_wrap, int symbols_size,
-             int flags)
+                       const void *bits, int bits_wrap, int bits_size,
+                       const void *codes, int codes_wrap, int codes_size,
+                       const void *symbols, int symbols_wrap, int symbols_size,
+                       int flags)
 {
     VLCcode *buf;
     int i, j, ret;
+    VLCcode localbuf[1500]; // the maximum currently needed is 1296 by rv34
+    void *state;
 
     vlc->bits = nb_bits;
-    if(flags & INIT_VLC_USE_NEW_STATIC){
-        VLC dyn_vlc = *vlc;
-
-        if (vlc->table_size)
-            return 0;
-
-        ret = ff_init_vlc_sparse(&dyn_vlc, nb_bits, nb_codes,
-                                 bits, bits_wrap, bits_size,
-                                 codes, codes_wrap, codes_size,
-                                 symbols, symbols_wrap, symbols_size,
-                                 flags & ~INIT_VLC_USE_NEW_STATIC);
-        av_assert0(ret >= 0);
-        av_assert0(dyn_vlc.table_size <= vlc->table_allocated);
-        if(dyn_vlc.table_size < vlc->table_allocated)
-            av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", dyn_vlc.table_size, vlc->table_allocated);
-        memcpy(vlc->table, dyn_vlc.table, dyn_vlc.table_size * sizeof(*vlc->table));
-        vlc->table_size = dyn_vlc.table_size;
-        ff_free_vlc(&dyn_vlc);
-        return 0;
-    }else {
-        vlc->table = NULL;
+    if (flags & INIT_VLC_USE_NEW_STATIC) {
+        while (state = avpriv_atomic_ptr_cas(&vlc->init_state, NULL, vlc)) {
+            if (state == vlc + 1) {
+                av_assert0(vlc->table_size && vlc->table_size == vlc->table_allocated);
+                return 0;
+            }
+        }
+        av_assert0(!vlc->table_size);
+        av_assert0(nb_codes + 1 <= FF_ARRAY_ELEMS(localbuf));
+        buf = localbuf;
+    } else {
+        vlc->table           = NULL;
         vlc->table_allocated = 0;
-        vlc->table_size = 0;
+        vlc->table_size      = 0;
+
+        buf = av_malloc((nb_codes + 1) * sizeof(VLCcode));
+        if (!buf)
+            return AVERROR(ENOMEM);
     }
 
-    av_dlog(NULL, "build table nb_codes=%d\n", nb_codes);
-
-    buf = av_malloc((nb_codes+1)*sizeof(VLCcode));
 
     av_assert0(symbols_size <= 2 || !symbols);
     j = 0;
 #define COPY(condition)\
-    for (i = 0; i < nb_codes; i++) {\
-        GET_DATA(buf[j].bits, bits, i, bits_wrap, bits_size);\
-        if (!(condition))\
-            continue;\
-        if (buf[j].bits > 3*nb_bits || buf[j].bits>32) {\
-            av_log(NULL, AV_LOG_ERROR, "Too long VLC in init_vlc\n");\
-            av_free(buf);\
-            return -1;\
-        }\
-        GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size);\
-        if (buf[j].code >= (1LL<<buf[j].bits)) {\
-            av_log(NULL, AV_LOG_ERROR, "Invalid code in init_vlc\n");\
-            av_free(buf);\
-            return -1;\
-        }\
-        if (flags & INIT_VLC_LE)\
-            buf[j].code = bitswap_32(buf[j].code);\
-        else\
-            buf[j].code <<= 32 - buf[j].bits;\
-        if (symbols)\
-            GET_DATA(buf[j].symbol, symbols, i, symbols_wrap, symbols_size)\
-        else\
-            buf[j].symbol = i;\
-        j++;\
+    for (i = 0; i < nb_codes; i++) {                                        \
+        GET_DATA(buf[j].bits, bits, i, bits_wrap, bits_size);               \
+        if (!(condition))                                                   \
+            continue;                                                       \
+        if (buf[j].bits > 3*nb_bits || buf[j].bits>32) {                    \
+            av_log(NULL, AV_LOG_ERROR, "Too long VLC (%d) in init_vlc\n", buf[j].bits);\
+            if (!(flags & INIT_VLC_USE_NEW_STATIC))                         \
+                av_free(buf);                                               \
+            return -1;                                                      \
+        }                                                                   \
+        GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size);            \
+        if (buf[j].code >= (1LL<<buf[j].bits)) {                            \
+            av_log(NULL, AV_LOG_ERROR, "Invalid code in init_vlc\n");       \
+            if (!(flags & INIT_VLC_USE_NEW_STATIC))                         \
+                av_free(buf);                                               \
+            return -1;                                                      \
+        }                                                                   \
+        if (flags & INIT_VLC_LE)                                            \
+            buf[j].code = bitswap_32(buf[j].code);                          \
+        else                                                                \
+            buf[j].code <<= 32 - buf[j].bits;                               \
+        if (symbols)                                                        \
+            GET_DATA(buf[j].symbol, symbols, i, symbols_wrap, symbols_size) \
+        else                                                                \
+            buf[j].symbol = i;                                              \
+        j++;                                                                \
     }
     COPY(buf[j].bits > nb_bits);
     // qsort is the slowest part of init_vlc, and could probably be improved or avoided
@@ -334,10 +333,18 @@
 
     ret = build_table(vlc, nb_bits, nb_codes, buf, flags);
 
-    av_free(buf);
-    if (ret < 0) {
-        av_freep(&vlc->table);
-        return -1;
+    if (flags & INIT_VLC_USE_NEW_STATIC) {
+        if(vlc->table_size != vlc->table_allocated)
+            av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated);
+        state = avpriv_atomic_ptr_cas(&vlc->init_state, vlc, vlc+1);
+        av_assert0(state == vlc);
+        av_assert0(ret >= 0);
+    } else {
+        av_free(buf);
+        if (ret < 0) {
+            av_freep(&vlc->table);
+            return ret;
+        }
     }
     return 0;
 }
diff --git a/libavcodec/bitstream_filter.c b/libavcodec/bitstream_filter.c
index 328a9f6..3ee582f 100644
--- a/libavcodec/bitstream_filter.c
+++ b/libavcodec/bitstream_filter.c
@@ -21,37 +21,49 @@
 #include <string.h>
 
 #include "avcodec.h"
+#include "libavutil/atomic.h"
 #include "libavutil/mem.h"
 
-static AVBitStreamFilter *first_bitstream_filter= NULL;
+static AVBitStreamFilter *first_bitstream_filter = NULL;
 
-AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f){
-    if(f) return f->next;
-    else  return first_bitstream_filter;
+AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f)
+{
+    if (f)
+        return f->next;
+    else
+        return first_bitstream_filter;
 }
 
-void av_register_bitstream_filter(AVBitStreamFilter *bsf){
-    bsf->next = first_bitstream_filter;
-    first_bitstream_filter= bsf;
+void av_register_bitstream_filter(AVBitStreamFilter *bsf)
+{
+    do {
+        bsf->next = first_bitstream_filter;
+    } while(bsf->next != avpriv_atomic_ptr_cas((void * volatile *)&first_bitstream_filter, bsf->next, bsf));
 }
 
-AVBitStreamFilterContext *av_bitstream_filter_init(const char *name){
-    AVBitStreamFilter *bsf= first_bitstream_filter;
+AVBitStreamFilterContext *av_bitstream_filter_init(const char *name)
+{
+    AVBitStreamFilter *bsf = first_bitstream_filter;
 
-    while(bsf){
-        if(!strcmp(name, bsf->name)){
-            AVBitStreamFilterContext *bsfc= av_mallocz(sizeof(AVBitStreamFilterContext));
-            bsfc->filter= bsf;
-            bsfc->priv_data = bsf->priv_data_size ? av_mallocz(bsf->priv_data_size) : NULL;
+    while (bsf) {
+        if (!strcmp(name, bsf->name)) {
+            AVBitStreamFilterContext *bsfc =
+                av_mallocz(sizeof(AVBitStreamFilterContext));
+            bsfc->filter    = bsf;
+            bsfc->priv_data =
+                bsf->priv_data_size ? av_mallocz(bsf->priv_data_size) : NULL;
             return bsfc;
         }
-        bsf= bsf->next;
+        bsf = bsf->next;
     }
     return NULL;
 }
 
-void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc){
-    if(bsfc->filter->close)
+void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc)
+{
+    if (!bsfc)
+        return;
+    if (bsfc->filter->close)
         bsfc->filter->close(bsfc);
     av_freep(&bsfc->priv_data);
     av_parser_close(bsfc->parser);
@@ -60,9 +72,11 @@
 
 int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc,
                                AVCodecContext *avctx, const char *args,
-                     uint8_t **poutbuf, int *poutbuf_size,
-                     const uint8_t *buf, int buf_size, int keyframe){
-    *poutbuf= (uint8_t *) buf;
-    *poutbuf_size= buf_size;
-    return bsfc->filter->filter(bsfc, avctx, args, poutbuf, poutbuf_size, buf, buf_size, keyframe);
+                               uint8_t **poutbuf, int *poutbuf_size,
+                               const uint8_t *buf, int buf_size, int keyframe)
+{
+    *poutbuf      = (uint8_t *)buf;
+    *poutbuf_size = buf_size;
+    return bsfc->filter->filter(bsfc, avctx, args, poutbuf, poutbuf_size,
+                                buf, buf_size, keyframe);
 }
diff --git a/libavcodec/bmp.c b/libavcodec/bmp.c
index a3bb1a7..51459e5 100644
--- a/libavcodec/bmp.c
+++ b/libavcodec/bmp.c
@@ -244,7 +244,7 @@
         // OS/2 bitmap, 3 bytes per palette entry
         if ((hsize-ihsize-14) < (colors << 2)) {
             if ((hsize-ihsize-14) < colors * 3) {
-                av_log(avctx, AV_LOG_ERROR, "palette doesnt fit in packet\n");
+                av_log(avctx, AV_LOG_ERROR, "palette doesn't fit in packet\n");
                 return AVERROR_INVALIDDATA;
             }
             for (i = 0; i < colors; i++)
@@ -256,7 +256,7 @@
         buf = buf0 + hsize;
     }
     if (comp == BMP_RLE4 || comp == BMP_RLE8) {
-        if (height < 0) {
+        if (comp == BMP_RLE8 && height < 0) {
             p->data[0]    +=  p->linesize[0] * (avctx->height - 1);
             p->linesize[0] = -p->linesize[0];
         }
diff --git a/libavcodec/bytestream.h b/libavcodec/bytestream.h
index af7f75b..f245859 100644
--- a/libavcodec/bytestream.h
+++ b/libavcodec/bytestream.h
@@ -26,6 +26,7 @@
 #include <stdint.h>
 #include <string.h>
 
+#include "libavutil/avassert.h"
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 
@@ -131,6 +132,7 @@
                                               const uint8_t *buf,
                                               int buf_size)
 {
+    av_assert0(buf_size >= 0);
     g->buffer       = buf;
     g->buffer_start = buf;
     g->buffer_end   = buf + buf_size;
@@ -140,6 +142,7 @@
                                                      uint8_t *buf,
                                                      int buf_size)
 {
+    av_assert0(buf_size >= 0);
     p->buffer       = buf;
     p->buffer_start = buf;
     p->buffer_end   = buf + buf_size;
diff --git a/libavcodec/cabac_functions.h b/libavcodec/cabac_functions.h
index ee70fcf..8a7275d 100644
--- a/libavcodec/cabac_functions.h
+++ b/libavcodec/cabac_functions.h
@@ -111,6 +111,7 @@
     return get_cabac_inline(c,state);
 }
 
+#ifndef get_cabac_bypass
 static int av_unused get_cabac_bypass(CABACContext *c){
     int range;
     c->low += c->low;
@@ -126,7 +127,7 @@
         return 1;
     }
 }
-
+#endif
 
 #ifndef get_cabac_bypass_sign
 static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){
diff --git a/libavcodec/cavsdata.h b/libavcodec/cavsdata.h
deleted file mode 100644
index 67fae3c..0000000
--- a/libavcodec/cavsdata.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
- * Copyright (c) 2006  Stefan Gehrer <stefan.gehrer@gmx.de>
- *
- * 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
- */
-
-#ifndef AVCODEC_CAVSDATA_H
-#define AVCODEC_CAVSDATA_H
-
-#include "cavs.h"
-
-const uint8_t ff_cavs_partition_flags[30] = {
-  0,                                 //I_8X8
-  0,                                 //P_SKIP
-  0,                                 //P_16X16
-                      SPLITH,        //P_16X8
-                             SPLITV, //P_8X16
-                      SPLITH|SPLITV, //P_8X8
-                      SPLITH|SPLITV, //B_SKIP
-                      SPLITH|SPLITV, //B_DIRECT
-  0,                                 //B_FWD_16X16
-  0,                                 //B_BWD_16X16
-  0,                                 //B_SYM_16X16
-  FWD0|FWD1          |SPLITH,
-  FWD0|FWD1                 |SPLITV,
-  BWD0|BWD1          |SPLITH,
-  BWD0|BWD1                 |SPLITV,
-  FWD0|BWD1          |SPLITH,
-  FWD0|BWD1                 |SPLITV,
-  BWD0|FWD1          |SPLITH,
-  BWD0|FWD1                 |SPLITV,
-  FWD0|FWD1     |SYM1|SPLITH,
-  FWD0|FWD1     |SYM1       |SPLITV,
-  BWD0|FWD1     |SYM1|SPLITH,
-  BWD0|FWD1     |SYM1       |SPLITV,
-  FWD0|FWD1|SYM0     |SPLITH,
-  FWD0|FWD1|SYM0            |SPLITV,
-  FWD0|BWD1|SYM0     |SPLITH,
-  FWD0|BWD1|SYM0            |SPLITV,
-  FWD0|FWD1|SYM0|SYM1|SPLITH,
-  FWD0|FWD1|SYM0|SYM1       |SPLITV,
-                      SPLITH|SPLITV, //B_8X8 = 29
-};
-
-/** mark block as "no prediction from this direction"
-    e.g. forward motion vector in BWD partition */
-const cavs_vector ff_cavs_dir_mv   = {0,0,1,REF_DIR};
-
-/** mark block as using intra prediction */
-const cavs_vector ff_cavs_intra_mv = {0,0,1,REF_INTRA};
-
-#endif /* AVCODEC_CAVSDATA_H */
diff --git a/libavcodec/cavsdsp.c b/libavcodec/cavsdsp.c
index 653b112..61283c2 100644
--- a/libavcodec/cavsdsp.c
+++ b/libavcodec/cavsdsp.c
@@ -421,77 +421,77 @@
 }\
 
 #define CAVS_MC(OPNAME, SIZE) \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc10_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc10_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
 {\
     OPNAME ## cavs_filt ## SIZE ## _h_qpel_l(dst, src, stride, stride);\
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc20_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc20_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
 {\
     OPNAME ## cavs_filt ## SIZE ## _h_hpel(dst, src, stride, stride);\
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc30_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc30_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
 {\
     OPNAME ## cavs_filt ## SIZE ## _h_qpel_r(dst, src, stride, stride);\
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc01_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc01_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
 {\
     OPNAME ## cavs_filt ## SIZE ## _v_qpel_l(dst, src, stride, stride);\
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc02_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc02_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
 {\
     OPNAME ## cavs_filt ## SIZE ## _v_hpel(dst, src, stride, stride);\
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc03_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc03_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
 {\
     OPNAME ## cavs_filt ## SIZE ## _v_qpel_r(dst, src, stride, stride);\
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc22_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc22_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
 {\
   OPNAME ## cavs_filt ## SIZE ## _hv_jj(dst, src, NULL, stride, stride); \
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc11_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc11_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
 {\
   OPNAME ## cavs_filt ## SIZE ## _hv_egpr(dst, src, src, stride, stride); \
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc13_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc13_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
 {\
   OPNAME ## cavs_filt ## SIZE ## _hv_egpr(dst, src, src+stride, stride, stride); \
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc31_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc31_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
 {\
   OPNAME ## cavs_filt ## SIZE ## _hv_egpr(dst, src, src+1, stride, stride); \
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc33_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc33_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
 {\
   OPNAME ## cavs_filt ## SIZE ## _hv_egpr(dst, src, src+stride+1,stride, stride); \
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc21_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc21_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
 {\
   OPNAME ## cavs_filt ## SIZE ## _hv_ff(dst, src, src+stride+1,stride, stride); \
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc12_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc12_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
 {\
   OPNAME ## cavs_filt ## SIZE ## _hv_ii(dst, src, src+stride+1,stride, stride); \
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc32_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc32_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
 {\
   OPNAME ## cavs_filt ## SIZE ## _hv_kk(dst, src, src+stride+1,stride, stride); \
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc23_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc23_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
 {\
   OPNAME ## cavs_filt ## SIZE ## _hv_qq(dst, src, src+stride+1,stride, stride); \
 }\
@@ -527,29 +527,29 @@
 CAVS_MC(avg_, 8)
 CAVS_MC(avg_, 16)
 
-#define ff_put_cavs_qpel8_mc00_c  ff_put_pixels8x8_c
-#define ff_avg_cavs_qpel8_mc00_c  ff_avg_pixels8x8_c
-#define ff_put_cavs_qpel16_mc00_c ff_put_pixels16x16_c
-#define ff_avg_cavs_qpel16_mc00_c ff_avg_pixels16x16_c
+#define put_cavs_qpel8_mc00_c  ff_put_pixels8x8_c
+#define avg_cavs_qpel8_mc00_c  ff_avg_pixels8x8_c
+#define put_cavs_qpel16_mc00_c ff_put_pixels16x16_c
+#define avg_cavs_qpel16_mc00_c ff_avg_pixels16x16_c
 
 av_cold void ff_cavsdsp_init(CAVSDSPContext* c, AVCodecContext *avctx) {
 #define dspfunc(PFX, IDX, NUM) \
-    c->PFX ## _pixels_tab[IDX][ 0] = ff_ ## PFX ## NUM ## _mc00_c; \
-    c->PFX ## _pixels_tab[IDX][ 1] = ff_ ## PFX ## NUM ## _mc10_c; \
-    c->PFX ## _pixels_tab[IDX][ 2] = ff_ ## PFX ## NUM ## _mc20_c; \
-    c->PFX ## _pixels_tab[IDX][ 3] = ff_ ## PFX ## NUM ## _mc30_c; \
-    c->PFX ## _pixels_tab[IDX][ 4] = ff_ ## PFX ## NUM ## _mc01_c; \
-    c->PFX ## _pixels_tab[IDX][ 5] = ff_ ## PFX ## NUM ## _mc11_c; \
-    c->PFX ## _pixels_tab[IDX][ 6] = ff_ ## PFX ## NUM ## _mc21_c; \
-    c->PFX ## _pixels_tab[IDX][ 7] = ff_ ## PFX ## NUM ## _mc31_c; \
-    c->PFX ## _pixels_tab[IDX][ 8] = ff_ ## PFX ## NUM ## _mc02_c; \
-    c->PFX ## _pixels_tab[IDX][ 9] = ff_ ## PFX ## NUM ## _mc12_c; \
-    c->PFX ## _pixels_tab[IDX][10] = ff_ ## PFX ## NUM ## _mc22_c; \
-    c->PFX ## _pixels_tab[IDX][11] = ff_ ## PFX ## NUM ## _mc32_c; \
-    c->PFX ## _pixels_tab[IDX][12] = ff_ ## PFX ## NUM ## _mc03_c; \
-    c->PFX ## _pixels_tab[IDX][13] = ff_ ## PFX ## NUM ## _mc13_c; \
-    c->PFX ## _pixels_tab[IDX][14] = ff_ ## PFX ## NUM ## _mc23_c; \
-    c->PFX ## _pixels_tab[IDX][15] = ff_ ## PFX ## NUM ## _mc33_c
+    c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_c; \
+    c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_c; \
+    c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_c; \
+    c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_c; \
+    c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_c; \
+    c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_c; \
+    c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_c; \
+    c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_c; \
+    c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_c; \
+    c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_c; \
+    c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_c; \
+    c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_c; \
+    c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_c; \
+    c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_c; \
+    c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_c; \
+    c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_c
     dspfunc(put_cavs_qpel, 0, 16);
     dspfunc(put_cavs_qpel, 1, 8);
     dspfunc(avg_cavs_qpel, 0, 16);
diff --git a/libavcodec/cdgraphics.c b/libavcodec/cdgraphics.c
index d22e9f6..d292317 100644
--- a/libavcodec/cdgraphics.c
+++ b/libavcodec/cdgraphics.c
@@ -265,7 +265,7 @@
     int buf_size       = avpkt->size;
     int ret;
     uint8_t command, inst;
-    uint8_t cdg_data[CDG_DATA_SIZE];
+    uint8_t cdg_data[CDG_DATA_SIZE] = {0};
     AVFrame *frame = data;
     CDGraphicsContext *cc = avctx->priv_data;
 
@@ -289,7 +289,9 @@
     inst    = bytestream_get_byte(&buf);
     inst    &= CDG_MASK;
     buf += 2;  /// skipping 2 unneeded bytes
-    bytestream_get_buffer(&buf, cdg_data, buf_size - CDG_HEADER_SIZE);
+
+    if (buf_size > CDG_HEADER_SIZE)
+        bytestream_get_buffer(&buf, cdg_data, buf_size - CDG_HEADER_SIZE);
 
     if ((command & CDG_MASK) == CDG_COMMAND) {
         switch (inst) {
diff --git a/libavcodec/cdxl.c b/libavcodec/cdxl.c
index 8c9e400..468b294 100644
--- a/libavcodec/cdxl.c
+++ b/libavcodec/cdxl.c
@@ -19,6 +19,14 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+/**
+ * @file
+ * Commodore CDXL video decoder
+ * @author Paul B Mahol
+ */
+
+#define UNCHECKED_BITSTREAM_READER 1
+
 #include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
diff --git a/libavcodec/cljr.c b/libavcodec/cljr.c
index 2120864..cf004b4 100644
--- a/libavcodec/cljr.c
+++ b/libavcodec/cljr.c
@@ -168,7 +168,7 @@
     { NULL },
 };
 
-static const AVClass class = {
+static const AVClass cljr_class = {
     .class_name = "cljr encoder",
     .item_name  = av_default_item_name,
     .option     = options,
@@ -185,6 +185,6 @@
     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P,
                                                    AV_PIX_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"),
-    .priv_class     = &class,
+    .priv_class     = &cljr_class,
 };
 #endif
diff --git a/libavcodec/cllc.c b/libavcodec/cllc.c
index 6378c79..ab8d46a 100644
--- a/libavcodec/cllc.c
+++ b/libavcodec/cllc.c
@@ -1,7 +1,7 @@
 /*
  * Canopus Lossless Codec decoder
  *
- * Copyright (c) 2012 Derek Buitenhuis
+ * Copyright (c) 2012-2013 Derek Buitenhuis
  *
  * This file is part of FFmpeg.
  *
@@ -136,14 +136,13 @@
 
     CLOSE_READER(bits, gb);
 
-    dst         -= 4 * ctx->avctx->width;
-    top_left[0]  = dst[0];
+    top_left[0]  = outbuf[0];
 
     /* Only stash components if they are not transparent */
     if (top_left[0]) {
-        top_left[1] = dst[1];
-        top_left[2] = dst[2];
-        top_left[3] = dst[3];
+        top_left[1] = outbuf[1];
+        top_left[2] = outbuf[2];
+        top_left[3] = outbuf[3];
     }
 
     return 0;
@@ -174,7 +173,35 @@
     CLOSE_READER(bits, gb);
 
     /* Stash the first pixel */
-    *top_left = dst[-3 * ctx->avctx->width];
+    *top_left = outbuf[0];
+
+    return 0;
+}
+
+static int read_yuv_component_line(CLLCContext *ctx, GetBitContext *gb,
+                                   int *top_left, VLC *vlc, uint8_t *outbuf,
+                                   int is_chroma)
+{
+    int pred, code;
+    int i;
+
+    OPEN_READER(bits, gb);
+
+    pred = *top_left;
+
+    /* Simultaneously read and restore the line */
+    for (i = 0; i < ctx->avctx->width >> is_chroma; i++) {
+        UPDATE_CACHE(bits, gb);
+        GET_VLC(code, bits, gb, vlc->table, 7, 2);
+
+        pred     += code;
+        outbuf[i] = pred;
+    }
+
+    CLOSE_READER(bits, gb);
+
+    /* Stash the first pixel */
+    *top_left = outbuf[0];
 
     return 0;
 }
@@ -267,6 +294,61 @@
     return 0;
 }
 
+static int decode_yuv_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
+{
+    AVCodecContext *avctx = ctx->avctx;
+    uint8_t block;
+    uint8_t *dst[3];
+    int pred[3];
+    int ret;
+    int i, j;
+    VLC vlc[2];
+
+    pred[0] = 0x80;
+    pred[1] = 0x80;
+    pred[2] = 0x80;
+
+    dst[0] = pic->data[0];
+    dst[1] = pic->data[1];
+    dst[2] = pic->data[2];
+
+    skip_bits(gb, 8);
+
+    block = get_bits(gb, 8);
+    if (block) {
+        avpriv_request_sample(ctx->avctx, "Blocked YUV");
+        return AVERROR_PATCHWELCOME;
+    }
+
+    /* Read in code table for luma and chroma */
+    for (i = 0; i < 2; i++) {
+        ret = read_code_table(ctx, gb, &vlc[i]);
+        if (ret < 0) {
+            for (j = 0; j <= i; j++)
+                ff_free_vlc(&vlc[j]);
+
+            av_log(ctx->avctx, AV_LOG_ERROR,
+                   "Could not read code table %d.\n", i);
+            return ret;
+        }
+    }
+
+    /* Read in and restore every line */
+    for (i = 0; i < avctx->height; i++) {
+        read_yuv_component_line(ctx, gb, &pred[0], &vlc[0], dst[0], 0); /* Y */
+        read_yuv_component_line(ctx, gb, &pred[1], &vlc[1], dst[1], 1); /* U */
+        read_yuv_component_line(ctx, gb, &pred[2], &vlc[1], dst[2], 1); /* V */
+
+        for (j = 0; j < 3; j++)
+            dst[j] += pic->linesize[j];
+    }
+
+    for (i = 0; i < 2; i++)
+        ff_free_vlc(&vlc[i]);
+
+    return 0;
+}
+
 static int cllc_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_picture_ptr, AVPacket *avpkt)
 {
@@ -324,6 +406,18 @@
     av_log(avctx, AV_LOG_DEBUG, "Frame coding type: %d\n", coding_type);
 
     switch (coding_type) {
+    case 0:
+        avctx->pix_fmt             = AV_PIX_FMT_YUV422P;
+        avctx->bits_per_raw_sample = 8;
+
+        if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
+            return ret;
+
+        ret = decode_yuv_frame(ctx, &gb, pic);
+        if (ret < 0)
+            return ret;
+
+        break;
     case 1:
     case 2:
         avctx->pix_fmt             = AV_PIX_FMT_RGB24;
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index c973025..ff468f6 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -74,7 +74,7 @@
         .id        = AV_CODEC_ID_RV20,
         .type      = AVMEDIA_TYPE_VIDEO,
         .name      = "rv20",
-        .long_name = NULL_IF_CONFIG_SMALL("RealVideo 1.0"),
+        .long_name = NULL_IF_CONFIG_SMALL("RealVideo 2.0"),
         .props     = AV_CODEC_PROP_LOSSY,
     },
     {
@@ -1248,6 +1248,13 @@
         .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
     },
     {
+        .id        = AV_CODEC_ID_AIC,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "aic",
+        .long_name = NULL_IF_CONFIG_SMALL("Apple Intermediate Codec"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+    },
+    {
         .id        = AV_CODEC_ID_Y41P,
         .type      = AVMEDIA_TYPE_VIDEO,
         .name      = "y41p",
@@ -1284,12 +1291,6 @@
         .props     = AV_CODEC_PROP_INTRA_ONLY,
     },
     {
-        .id        = AV_CODEC_ID_G2M,
-        .type      = AVMEDIA_TYPE_VIDEO,
-        .name      = "g2m",
-        .long_name = NULL_IF_CONFIG_SMALL("GoToMeeting"),
-    },
-    {
         .id        = AV_CODEC_ID_AVUI,
         .type      = AVMEDIA_TYPE_VIDEO,
         .name      = "avui",
@@ -1371,6 +1372,20 @@
         .long_name = NULL_IF_CONFIG_SMALL("BRender PIX image"),
         .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
     },
+    {
+        .id        = AV_CODEC_ID_SMVJPEG,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "smv",
+        .long_name = NULL_IF_CONFIG_SMALL("Sigmatel Motion Video"),
+    },
+
+    {
+        .id        = AV_CODEC_ID_G2M,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "g2m",
+        .long_name = NULL_IF_CONFIG_SMALL("Go2Meeting"),
+        .props     = AV_CODEC_PROP_LOSSY,
+    },
 
     /* various PCM "codecs" */
     {
@@ -1581,7 +1596,7 @@
         .type      = AVMEDIA_TYPE_AUDIO,
         .name      = "s302m",
         .long_name = NULL_IF_CONFIG_SMALL("SMPTE 302M"),
-        .props     = AV_CODEC_PROP_LOSSY,
+        .props     = AV_CODEC_PROP_LOSSLESS,
     },
     {
         .id        = AV_CODEC_ID_PCM_S8_PLANAR,
@@ -1816,6 +1831,20 @@
         .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Dialogic OKI"),
         .props     = AV_CODEC_PROP_LOSSY,
     },
+    {
+        .id        = AV_CODEC_ID_ADPCM_DTK,
+        .type      = AVMEDIA_TYPE_AUDIO,
+        .name      = "adpcm_dtk",
+        .long_name = NULL_IF_CONFIG_SMALL("ADPCM Nintendo Gamecube DTK"),
+        .props     = AV_CODEC_PROP_LOSSY,
+    },
+    {
+        .id        = AV_CODEC_ID_ADPCM_IMA_RAD,
+        .type      = AVMEDIA_TYPE_AUDIO,
+        .name      = "adpcm_ima_rad",
+        .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Radical"),
+        .props     = AV_CODEC_PROP_LOSSY,
+    },
 
     /* AMR */
     {
@@ -2103,6 +2132,7 @@
         .long_name = NULL_IF_CONFIG_SMALL("Atrac 3 (Adaptive TRansform Acoustic Coding 3)"),
         .props     = AV_CODEC_PROP_LOSSY,
     },
+#if FF_API_VOXWARE
     {
         .id        = AV_CODEC_ID_VOXWARE,
         .type      = AVMEDIA_TYPE_AUDIO,
@@ -2110,6 +2140,7 @@
         .long_name = NULL_IF_CONFIG_SMALL("Voxware RT29 Metasound"),
         .props     = AV_CODEC_PROP_LOSSY,
     },
+#endif
     {
         .id        = AV_CODEC_ID_APE,
         .type      = AVMEDIA_TYPE_AUDIO,
@@ -2360,6 +2391,13 @@
         .props     = AV_CODEC_PROP_LOSSLESS,
     },
     {
+        .id        = AV_CODEC_ID_METASOUND,
+        .type      = AVMEDIA_TYPE_AUDIO,
+        .name      = "metasound",
+        .long_name = NULL_IF_CONFIG_SMALL("Voxware MetaSound"),
+        .props     = AV_CODEC_PROP_LOSSY,
+    },
+    {
         .id        = AV_CODEC_ID_EVRC,
         .type      = AVMEDIA_TYPE_AUDIO,
         .name      = "evrc",
diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c
index 8265c0fb..4fa7f89 100644
--- a/libavcodec/dcadec.c
+++ b/libavcodec/dcadec.c
@@ -36,7 +36,6 @@
 #include "avcodec.h"
 #include "fft.h"
 #include "get_bits.h"
-#include "put_bits.h"
 #include "dcadata.h"
 #include "dcahuff.h"
 #include "dca.h"
@@ -969,7 +968,13 @@
                        "Invalid channel mode %d\n", am);
                 return AVERROR_INVALIDDATA;
             }
-            for (j = base_channel; j < FFMIN(s->prim_channels, FF_ARRAY_ELEMS(dca_default_coeffs[am])); j++) {
+            if (s->prim_channels > FF_ARRAY_ELEMS(dca_default_coeffs[0])) {
+                avpriv_request_sample(s->avctx, "Downmixing %d channels",
+                                      s->prim_channels);
+                return AVERROR_PATCHWELCOME;
+            }
+
+            for (j = base_channel; j < s->prim_channels; j++) {
                 s->downmix_coef[j][0] = dca_default_coeffs[am][j][0];
                 s->downmix_coef[j][1] = dca_default_coeffs[am][j][1];
             }
@@ -1107,10 +1112,8 @@
                             float scale)
 {
     const float *prCoeff;
-    int i;
 
     int sb_act = s->subband_activity[chans];
-    int subindex;
 
     scale *= sqrt(1 / 8.0);
 
@@ -1120,25 +1123,11 @@
     else                        /* Perfect reconstruction */
         prCoeff = fir_32bands_perfect;
 
-    for (i = sb_act; i < 32; i++)
-        s->raXin[i] = 0.0;
-
-    /* Reconstructed channel sample index */
-    for (subindex = 0; subindex < 8; subindex++) {
-        /* Load in one sample from each subband and clear inactive subbands */
-        for (i = 0; i < sb_act; i++) {
-            unsigned sign = (i - 1) & 2;
-            uint32_t v    = AV_RN32A(&samples_in[i][subindex]) ^ sign << 30;
-            AV_WN32A(&s->raXin[i], v);
-        }
-
-        s->synth.synth_filter_float(&s->imdct,
-                                    s->subband_fir_hist[chans],
-                                    &s->hist_index[chans],
-                                    s->subband_fir_noidea[chans], prCoeff,
-                                    samples_out, s->raXin, scale);
-        samples_out += 32;
-    }
+    s->dcadsp.qmf_32_subbands(samples_in, sb_act, &s->synth, &s->imdct,
+                              s->subband_fir_hist[chans],
+                              &s->hist_index[chans],
+                              s->subband_fir_noidea[chans], prCoeff,
+                              samples_out, s->raXin, scale);
 }
 
 static void lfe_interpolation_fir(DCAContext *s, int decimation_select,
@@ -1258,7 +1247,7 @@
 #ifndef decode_blockcodes
 /* Very compact version of the block code decoder that does not use table
  * look-up but is slightly slower */
-static int decode_blockcode(int code, int levels, int *values)
+static int decode_blockcode(int code, int levels, int32_t *values)
 {
     int i;
     int offset = (levels - 1) >> 1;
@@ -1272,7 +1261,7 @@
     return code;
 }
 
-static int decode_blockcodes(int code1, int code2, int levels, int *values)
+static int decode_blockcodes(int code1, int code2, int levels, int32_t *values)
 {
     return decode_blockcode(code1, levels, values) |
            decode_blockcode(code2, levels, values + 4);
@@ -1301,7 +1290,7 @@
 
     /* FIXME */
     float (*subband_samples)[DCA_SUBBANDS][8] = s->subband_samples[block_index];
-    LOCAL_ALIGNED_16(int, block, [8]);
+    LOCAL_ALIGNED_16(int32_t, block, [8 * DCA_SUBBANDS]);
 
     /*
      * Audio data
@@ -1314,6 +1303,8 @@
         quant_step_table = lossy_quant_d;
 
     for (k = base_channel; k < s->prim_channels; k++) {
+        float rscale[DCA_SUBBANDS];
+
         if (get_bits_left(&s->gb) < 0)
             return AVERROR_INVALIDDATA;
 
@@ -1336,11 +1327,12 @@
              * Extract bits from the bit stream
              */
             if (!abits) {
-                memset(subband_samples[k][l], 0, 8 * sizeof(subband_samples[0][0][0]));
+                rscale[l] = 0;
+                memset(block + 8 * l, 0, 8 * sizeof(block[0]));
             } else {
                 /* Deal with transients */
                 int sfi = s->transition_mode[k][l] && subsubframe >= s->transition_mode[k][l];
-                float rscale = quant_step_size * s->scale_factor[k][l][sfi] *
+                rscale[l] = quant_step_size * s->scale_factor[k][l][sfi] *
                                s->scalefactor_adj[k][sel];
 
                 if (abits >= 11 || !dca_smpl_bitalloc[abits].vlc[sel].table) {
@@ -1354,7 +1346,7 @@
                         block_code1 = get_bits(&s->gb, size);
                         block_code2 = get_bits(&s->gb, size);
                         err = decode_blockcodes(block_code1, block_code2,
-                                                levels, block);
+                                                levels, block + 8 * l);
                         if (err) {
                             av_log(s->avctx, AV_LOG_ERROR,
                                    "ERROR: block code look-up failed\n");
@@ -1363,19 +1355,23 @@
                     } else {
                         /* no coding */
                         for (m = 0; m < 8; m++)
-                            block[m] = get_sbits(&s->gb, abits - 3);
+                            block[8 * l + m] = get_sbits(&s->gb, abits - 3);
                     }
                 } else {
                     /* Huffman coded */
                     for (m = 0; m < 8; m++)
-                        block[m] = get_bitalloc(&s->gb,
+                        block[8 * l + m] = get_bitalloc(&s->gb,
                                                 &dca_smpl_bitalloc[abits], sel);
                 }
 
-                s->fmt_conv.int32_to_float_fmul_scalar(subband_samples[k][l],
-                                                       block, rscale, 8);
             }
+        }
 
+        s->fmt_conv.int32_to_float_fmul_array8(&s->fmt_conv, subband_samples[k][0],
+                                               block, rscale, 8 * s->vq_start_subband[k]);
+
+        for (l = 0; l < s->vq_start_subband[k]; l++) {
+            int m;
             /*
              * Inverse ADPCM if in prediction mode
              */
@@ -1423,6 +1419,7 @@
 #endif
         } else {
             av_log(s->avctx, AV_LOG_ERROR, "Didn't get subframe DSYNC\n");
+            return AVERROR_INVALIDDATA;
         }
     }
 
diff --git a/libavcodec/dcadsp.c b/libavcodec/dcadsp.c
index dd4994d..abeba24 100644
--- a/libavcodec/dcadsp.c
+++ b/libavcodec/dcadsp.c
@@ -20,6 +20,8 @@
  */
 
 #include "config.h"
+#include "libavutil/attributes.h"
+#include "libavutil/intreadwrite.h"
 #include "dcadsp.h"
 
 static void dca_lfe_fir_c(float *out, const float *in, const float *coefs,
@@ -44,8 +46,37 @@
     }
 }
 
-void ff_dcadsp_init(DCADSPContext *s)
+static void dca_qmf_32_subbands(float samples_in[32][8], int sb_act,
+                                SynthFilterContext *synth, FFTContext *imdct,
+                                float synth_buf_ptr[512],
+                                int *synth_buf_offset, float synth_buf2[32],
+                                const float window[512], float *samples_out,
+                                float raXin[32], float scale)
+{
+    int i;
+    int subindex;
+
+    for (i = sb_act; i < 32; i++)
+        raXin[i] = 0.0;
+
+    /* Reconstructed channel sample index */
+    for (subindex = 0; subindex < 8; subindex++) {
+        /* Load in one sample from each subband and clear inactive subbands */
+        for (i = 0; i < sb_act; i++) {
+            unsigned sign = (i - 1) & 2;
+            uint32_t v    = AV_RN32A(&samples_in[i][subindex]) ^ sign << 30;
+            AV_WN32A(&raXin[i], v);
+        }
+
+        synth->synth_filter_float(imdct, synth_buf_ptr, synth_buf_offset,
+                                  synth_buf2, window, samples_out, raXin, scale);
+        samples_out += 32;
+    }
+}
+
+av_cold void ff_dcadsp_init(DCADSPContext *s)
 {
     s->lfe_fir = dca_lfe_fir_c;
+    s->qmf_32_subbands = dca_qmf_32_subbands;
     if (ARCH_ARM) ff_dcadsp_init_arm(s);
 }
diff --git a/libavcodec/dcadsp.h b/libavcodec/dcadsp.h
index bb157f7..d86c1f3 100644
--- a/libavcodec/dcadsp.h
+++ b/libavcodec/dcadsp.h
@@ -19,9 +19,18 @@
 #ifndef AVCODEC_DCADSP_H
 #define AVCODEC_DCADSP_H
 
+#include "avfft.h"
+#include "synth_filter.h"
+
 typedef struct DCADSPContext {
     void (*lfe_fir)(float *out, const float *in, const float *coefs,
                     int decifactor, float scale);
+    void (*qmf_32_subbands)(float samples_in[32][8], int sb_act,
+                            SynthFilterContext *synth, FFTContext *imdct,
+                            float synth_buf_ptr[512],
+                            int *synth_buf_offset, float synth_buf2[32],
+                            const float window[512], float *samples_out,
+                            float raXin[32], float scale);
 } DCADSPContext;
 
 void ff_dcadsp_init(DCADSPContext *s);
diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c
index 4799ef4..439be47 100644
--- a/libavcodec/dcaenc.c
+++ b/libavcodec/dcaenc.c
@@ -1,6 +1,6 @@
 /*
  * DCA encoder
- * Copyright (C) 2008 Alexander E. Patrakov
+ * Copyright (C) 2008-2012 Alexander E. Patrakov
  *               2010 Benjamin Larsson
  *               2011 Xiang Wang
  *
@@ -21,211 +21,683 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/avassert.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
-#include "libavutil/avassert.h"
 #include "avcodec.h"
+#include "dca.h"
+#include "dcadata.h"
+#include "dcaenc.h"
 #include "internal.h"
 #include "put_bits.h"
-#include "dcaenc.h"
-#include "dcadata.h"
-#include "dca.h"
-
-#undef NDEBUG
 
 #define MAX_CHANNELS 6
-#define DCA_SUBBANDS_32 32
-#define DCA_MAX_FRAME_SIZE 16383
+#define DCA_MAX_FRAME_SIZE 16384
 #define DCA_HEADER_SIZE 13
+#define DCA_LFE_SAMPLES 8
 
-#define DCA_SUBBANDS 32 ///< Subband activity count
-#define QUANTIZER_BITS 16
+#define DCA_SUBBANDS 32
 #define SUBFRAMES 1
-#define SUBSUBFRAMES 4
-#define PCM_SAMPLES (SUBFRAMES*SUBSUBFRAMES*8)
-#define LFE_BITS 8
-#define LFE_INTERPOLATION 64
-#define LFE_PRESENT 2
-#define LFE_MISSING 0
+#define SUBSUBFRAMES 2
+#define SUBBAND_SAMPLES (SUBFRAMES * SUBSUBFRAMES * 8)
+#define AUBANDS 25
 
-static const int8_t dca_lfe_index[] = {
-    1,2,2,2,2,3,2,3,2,3,2,3,1,3,2,3
-};
-
-static const int8_t dca_channel_reorder_lfe[][9] = {
-    { 0, -1, -1, -1, -1, -1, -1, -1, -1 },
-    { 0,  1, -1, -1, -1, -1, -1, -1, -1 },
-    { 0,  1, -1, -1, -1, -1, -1, -1, -1 },
-    { 0,  1, -1, -1, -1, -1, -1, -1, -1 },
-    { 0,  1, -1, -1, -1, -1, -1, -1, -1 },
-    { 1,  2,  0, -1, -1, -1, -1, -1, -1 },
-    { 0,  1, -1,  2, -1, -1, -1, -1, -1 },
-    { 1,  2,  0, -1,  3, -1, -1, -1, -1 },
-    { 0,  1, -1,  2,  3, -1, -1, -1, -1 },
-    { 1,  2,  0, -1,  3,  4, -1, -1, -1 },
-    { 2,  3, -1,  0,  1,  4,  5, -1, -1 },
-    { 1,  2,  0, -1,  3,  4,  5, -1, -1 },
-    { 0, -1,  4,  5,  2,  3,  1, -1, -1 },
-    { 3,  4,  1, -1,  0,  2,  5,  6, -1 },
-    { 2,  3, -1,  5,  7,  0,  1,  4,  6 },
-    { 3,  4,  1, -1,  0,  2,  5,  7,  6 },
-};
-
-static const int8_t dca_channel_reorder_nolfe[][9] = {
-    { 0, -1, -1, -1, -1, -1, -1, -1, -1 },
-    { 0,  1, -1, -1, -1, -1, -1, -1, -1 },
-    { 0,  1, -1, -1, -1, -1, -1, -1, -1 },
-    { 0,  1, -1, -1, -1, -1, -1, -1, -1 },
-    { 0,  1, -1, -1, -1, -1, -1, -1, -1 },
-    { 1,  2,  0, -1, -1, -1, -1, -1, -1 },
-    { 0,  1,  2, -1, -1, -1, -1, -1, -1 },
-    { 1,  2,  0,  3, -1, -1, -1, -1, -1 },
-    { 0,  1,  2,  3, -1, -1, -1, -1, -1 },
-    { 1,  2,  0,  3,  4, -1, -1, -1, -1 },
-    { 2,  3,  0,  1,  4,  5, -1, -1, -1 },
-    { 1,  2,  0,  3,  4,  5, -1, -1, -1 },
-    { 0,  4,  5,  2,  3,  1, -1, -1, -1 },
-    { 3,  4,  1,  0,  2,  5,  6, -1, -1 },
-    { 2,  3,  5,  7,  0,  1,  4,  6, -1 },
-    { 3,  4,  1,  0,  2,  5,  7,  6, -1 },
-};
-
-typedef struct {
+typedef struct DCAContext {
     PutBitContext pb;
-    int32_t history[MAX_CHANNELS][512]; /* This is a circular buffer */
-    int start[MAX_CHANNELS];
     int frame_size;
-    int prim_channels;
+    int frame_bits;
+    int fullband_channels;
+    int channels;
     int lfe_channel;
-    int sample_rate_code;
-    int scale_factor[MAX_CHANNELS][DCA_SUBBANDS_32];
+    int samplerate_index;
+    int bitrate_index;
+    int channel_config;
+    const int32_t *band_interpolation;
+    const int32_t *band_spectrum;
     int lfe_scale_factor;
-    int lfe_data[SUBFRAMES*SUBSUBFRAMES*4];
+    softfloat lfe_quant;
+    int32_t lfe_peak_cb;
 
-    int a_mode;                         ///< audio channels arrangement
-    int num_channel;
-    int lfe_state;
-    int lfe_offset;
-    const int8_t *channel_order_tab;    ///< channel reordering table, lfe and non lfe
-
-    int32_t pcm[FFMAX(LFE_INTERPOLATION, DCA_SUBBANDS_32)];
-    int32_t subband[PCM_SAMPLES][MAX_CHANNELS][DCA_SUBBANDS_32]; /* [sample][channel][subband] */
+    int32_t history[512][MAX_CHANNELS]; /* This is a circular buffer */
+    int32_t subband[SUBBAND_SAMPLES][DCA_SUBBANDS][MAX_CHANNELS];
+    int32_t quantized[SUBBAND_SAMPLES][DCA_SUBBANDS][MAX_CHANNELS];
+    int32_t peak_cb[DCA_SUBBANDS][MAX_CHANNELS];
+    int32_t downsampled_lfe[DCA_LFE_SAMPLES];
+    int32_t masking_curve_cb[SUBSUBFRAMES][256];
+    int abits[DCA_SUBBANDS][MAX_CHANNELS];
+    int scale_factor[DCA_SUBBANDS][MAX_CHANNELS];
+    softfloat quant[DCA_SUBBANDS][MAX_CHANNELS];
+    int32_t eff_masking_curve_cb[256];
+    int32_t band_masking_cb[32];
+    int32_t worst_quantization_noise;
+    int32_t worst_noise_ever;
+    int consumed_bits;
 } DCAContext;
 
-static int32_t cos_table[128];
+static int32_t cos_table[2048];
+static int32_t band_interpolation[2][512];
+static int32_t band_spectrum[2][8];
+static int32_t auf[9][AUBANDS][256];
+static int32_t cb_to_add[256];
+static int32_t cb_to_level[2048];
+static int32_t lfe_fir_64i[512];
+
+/* Transfer function of outer and middle ear, Hz -> dB */
+static double hom(double f)
+{
+    double f1 = f / 1000;
+
+    return -3.64 * pow(f1, -0.8)
+           + 6.8 * exp(-0.6 * (f1 - 3.4) * (f1 - 3.4))
+           - 6.0 * exp(-0.15 * (f1 - 8.7) * (f1 - 8.7))
+           - 0.0006 * (f1 * f1) * (f1 * f1);
+}
+
+static double gammafilter(int i, double f)
+{
+    double h = (f - fc[i]) / erb[i];
+
+    h = 1 + h * h;
+    h = 1 / (h * h);
+    return 20 * log10(h);
+}
+
+static int encode_init(AVCodecContext *avctx)
+{
+    DCAContext *c = avctx->priv_data;
+    uint64_t layout = avctx->channel_layout;
+    int i, min_frame_bits;
+
+    c->fullband_channels = c->channels = avctx->channels;
+    c->lfe_channel = (avctx->channels == 3 || avctx->channels == 6);
+    c->band_interpolation = band_interpolation[1];
+    c->band_spectrum = band_spectrum[1];
+    c->worst_quantization_noise = -2047;
+    c->worst_noise_ever = -2047;
+
+    if (!layout) {
+        av_log(avctx, AV_LOG_WARNING, "No channel layout specified. The "
+                                      "encoder will guess the layout, but it "
+                                      "might be incorrect.\n");
+        layout = av_get_default_channel_layout(avctx->channels);
+    }
+    switch (layout) {
+    case AV_CH_LAYOUT_MONO:         c->channel_config = 0; break;
+    case AV_CH_LAYOUT_STEREO:       c->channel_config = 2; break;
+    case AV_CH_LAYOUT_2_2:          c->channel_config = 8; break;
+    case AV_CH_LAYOUT_5POINT0:      c->channel_config = 9; break;
+    case AV_CH_LAYOUT_5POINT1:      c->channel_config = 9; break;
+    default:
+        av_log(avctx, AV_LOG_ERROR, "Unsupported channel layout!\n");
+        return AVERROR_PATCHWELCOME;
+    }
+
+    if (c->lfe_channel)
+        c->fullband_channels--;
+
+    for (i = 0; i < 9; i++) {
+        if (sample_rates[i] == avctx->sample_rate)
+            break;
+    }
+    if (i == 9)
+        return AVERROR(EINVAL);
+    c->samplerate_index = i;
+
+    if (avctx->bit_rate < 32000 || avctx->bit_rate > 3840000) {
+        av_log(avctx, AV_LOG_ERROR, "Bit rate %i not supported.", avctx->bit_rate);
+        return AVERROR(EINVAL);
+    }
+    for (i = 0; dca_bit_rates[i] < avctx->bit_rate; i++)
+        ;
+    c->bitrate_index = i;
+    avctx->bit_rate = dca_bit_rates[i];
+    c->frame_bits = FFALIGN((avctx->bit_rate * 512 + avctx->sample_rate - 1) / avctx->sample_rate, 32);
+    min_frame_bits = 132 + (493 + 28 * 32) * c->fullband_channels + c->lfe_channel * 72;
+    if (c->frame_bits < min_frame_bits || c->frame_bits > (DCA_MAX_FRAME_SIZE << 3))
+        return AVERROR(EINVAL);
+
+    c->frame_size = (c->frame_bits + 7) / 8;
+
+    avctx->frame_size = 32 * SUBBAND_SAMPLES;
+
+    if (!cos_table[0]) {
+        int j, k;
+
+        for (i = 0; i < 2048; i++) {
+            cos_table[i]   = (int32_t)(0x7fffffff * cos(M_PI * i / 1024));
+            cb_to_level[i] = (int32_t)(0x7fffffff * pow(10, -0.005 * i));
+        }
+
+        /* FIXME: probably incorrect */
+        for (i = 0; i < 256; i++) {
+            lfe_fir_64i[i] = (int32_t)(0x01ffffff * lfe_fir_64[i]);
+            lfe_fir_64i[511 - i] = (int32_t)(0x01ffffff * lfe_fir_64[i]);
+        }
+
+        for (i = 0; i < 512; i++) {
+            band_interpolation[0][i] = (int32_t)(0x1000000000ULL * fir_32bands_perfect[i]);
+            band_interpolation[1][i] = (int32_t)(0x1000000000ULL * fir_32bands_nonperfect[i]);
+        }
+
+        for (i = 0; i < 9; i++) {
+            for (j = 0; j < AUBANDS; j++) {
+                for (k = 0; k < 256; k++) {
+                    double freq = sample_rates[i] * (k + 0.5) / 512;
+
+                    auf[i][j][k] = (int32_t)(10 * (hom(freq) + gammafilter(j, freq)));
+                }
+            }
+        }
+
+        for (i = 0; i < 256; i++) {
+            double add = 1 + pow(10, -0.01 * i);
+            cb_to_add[i] = (int32_t)(100 * log10(add));
+        }
+        for (j = 0; j < 8; j++) {
+            double accum = 0;
+            for (i = 0; i < 512; i++) {
+                double reconst = fir_32bands_perfect[i] * ((i & 64) ? (-1) : 1);
+                accum += reconst * cos(2 * M_PI * (i + 0.5 - 256) * (j + 0.5) / 512);
+            }
+            band_spectrum[0][j] = (int32_t)(200 * log10(accum));
+        }
+        for (j = 0; j < 8; j++) {
+            double accum = 0;
+            for (i = 0; i < 512; i++) {
+                double reconst = fir_32bands_nonperfect[i] * ((i & 64) ? (-1) : 1);
+                accum += reconst * cos(2 * M_PI * (i + 0.5 - 256) * (j + 0.5) / 512);
+            }
+            band_spectrum[1][j] = (int32_t)(200 * log10(accum));
+        }
+    }
+    return 0;
+}
+
+static inline int32_t cos_t(int x)
+{
+    return cos_table[x & 2047];
+}
+
+static inline int32_t sin_t(int x)
+{
+    return cos_t(x - 512);
+}
+
+static inline int32_t half32(int32_t a)
+{
+    return (a + 1) >> 1;
+}
 
 static inline int32_t mul32(int32_t a, int32_t b)
 {
-    int64_t r = (int64_t) a * b;
-    /* round the result before truncating - improves accuracy */
-    return (r + 0x80000000) >> 32;
+    int64_t r = (int64_t)a * b + 0x80000000ULL;
+    return r >> 32;
 }
 
-/* Integer version of the cosine modulated Pseudo QMF */
-
-static void qmf_init(void)
+static void subband_transform(DCAContext *c, const int32_t *input)
 {
-    int i;
-    int32_t c[17], s[17];
-    s[0] = 0;           /* sin(index * PI / 64) * 0x7fffffff */
-    c[0] = 0x7fffffff;  /* cos(index * PI / 64) * 0x7fffffff */
+    int ch, subs, i, k, j;
 
-    for (i = 1; i <= 16; i++) {
-        s[i] = 2 * (mul32(c[i - 1], 105372028)  + mul32(s[i - 1], 2144896908));
-        c[i] = 2 * (mul32(c[i - 1], 2144896908) - mul32(s[i - 1], 105372028));
-    }
+    for (ch = 0; ch < c->fullband_channels; ch++) {
+        /* History is copied because it is also needed for PSY */
+        int32_t hist[512];
+        int hist_start = 0;
 
-    for (i = 0; i < 16; i++) {
-        cos_table[i      ]  =  c[i]      >> 3; /* avoid output overflow */
-        cos_table[i +  16]  =  s[16 - i] >> 3;
-        cos_table[i +  32]  = -s[i]      >> 3;
-        cos_table[i +  48]  = -c[16 - i] >> 3;
-        cos_table[i +  64]  = -c[i]      >> 3;
-        cos_table[i +  80]  = -s[16 - i] >> 3;
-        cos_table[i +  96]  =  s[i]      >> 3;
-        cos_table[i + 112]  =  c[16 - i] >> 3;
+        for (i = 0; i < 512; i++)
+            hist[i] = c->history[i][ch];
+
+        for (subs = 0; subs < SUBBAND_SAMPLES; subs++) {
+            int32_t accum[64];
+            int32_t resp;
+            int band;
+
+            /* Calculate the convolutions at once */
+            for (i = 0; i < 64; i++)
+                accum[i] = 0;
+
+            for (k = 0, i = hist_start, j = 0;
+                    i < 512; k = (k + 1) & 63, i++, j++)
+                accum[k] += mul32(hist[i], c->band_interpolation[j]);
+            for (i = 0; i < hist_start; k = (k + 1) & 63, i++, j++)
+                accum[k] += mul32(hist[i], c->band_interpolation[j]);
+
+            for (k = 16; k < 32; k++)
+                accum[k] = accum[k] - accum[31 - k];
+            for (k = 32; k < 48; k++)
+                accum[k] = accum[k] + accum[95 - k];
+
+            for (band = 0; band < 32; band++) {
+                resp = 0;
+                for (i = 16; i < 48; i++) {
+                    int s = (2 * band + 1) * (2 * (i + 16) + 1);
+                    resp += mul32(accum[i], cos_t(s << 3)) >> 3;
+                }
+
+                c->subband[subs][band][ch] = ((band + 1) & 2) ? -resp : resp;
+            }
+
+            /* Copy in 32 new samples from input */
+            for (i = 0; i < 32; i++)
+                hist[i + hist_start] = input[(subs * 32 + i) * c->channels + ch];
+            hist_start = (hist_start + 32) & 511;
+        }
     }
 }
 
-static int32_t band_delta_factor(int band, int sample_num)
+static void lfe_downsample(DCAContext *c, const int32_t *input)
 {
-    int index = band * (2 * sample_num + 1);
-    if (band == 0)
-        return 0x07ffffff;
-    else
-        return cos_table[index & 127];
-}
-
-static void add_new_samples(DCAContext *c, const int32_t *in,
-                            int count, int channel)
-{
-    int i;
-
-    /* Place new samples into the history buffer */
-    for (i = 0; i < count; i++) {
-        c->history[channel][c->start[channel] + i] = in[i];
-        av_assert0(c->start[channel] + i < 512);
-    }
-    c->start[channel] += count;
-    if (c->start[channel] == 512)
-        c->start[channel] = 0;
-    av_assert0(c->start[channel] < 512);
-}
-
-static void qmf_decompose(DCAContext *c, int32_t in[32], int32_t out[32],
-                          int channel)
-{
-    int band, i, j, k;
-    int32_t resp;
-    int32_t accum[DCA_SUBBANDS_32] = {0};
-
-    add_new_samples(c, in, DCA_SUBBANDS_32, channel);
-
-    /* Calculate the dot product of the signal with the (possibly inverted)
-       reference decoder's response to this vector:
-       (0.0, 0.0, ..., 0.0, -1.0, 1.0, 0.0, ..., 0.0)
-       so that -1.0 cancels 1.0 from the previous step */
-
-    for (k = 48, j = 0, i = c->start[channel]; i < 512; k++, j++, i++)
-        accum[(k & 32) ? (31 - (k & 31)) : (k & 31)] += mul32(c->history[channel][i], UnQMF[j]);
-    for (i = 0; i < c->start[channel]; k++, j++, i++)
-        accum[(k & 32) ? (31 - (k & 31)) : (k & 31)] += mul32(c->history[channel][i], UnQMF[j]);
-
-    resp = 0;
-    /* TODO: implement FFT instead of this naive calculation */
-    for (band = 0; band < DCA_SUBBANDS_32; band++) {
-        for (j = 0; j < 32; j++)
-            resp += mul32(accum[j], band_delta_factor(band, j));
-
-        out[band] = (band & 2) ? (-resp) : resp;
-    }
-}
-
-static int32_t lfe_fir_64i[512];
-static int lfe_downsample(DCAContext *c, int32_t in[LFE_INTERPOLATION])
-{
-    int i, j;
-    int channel = c->prim_channels;
-    int32_t accum = 0;
-
-    add_new_samples(c, in, LFE_INTERPOLATION, channel);
-    for (i = c->start[channel], j = 0; i < 512; i++, j++)
-        accum += mul32(c->history[channel][i], lfe_fir_64i[j]);
-    for (i = 0; i < c->start[channel]; i++, j++)
-        accum += mul32(c->history[channel][i], lfe_fir_64i[j]);
-    return accum;
-}
-
-static void init_lfe_fir(void)
-{
-    static int initialized = 0;
-    int i;
-    if (initialized)
-        return;
+    /* FIXME: make 128x LFE downsampling possible */
+    int i, j, lfes;
+    int32_t hist[512];
+    int32_t accum;
+    int hist_start = 0;
 
     for (i = 0; i < 512; i++)
-        lfe_fir_64i[i] = lfe_fir_64[i] * (1 << 25); //float -> int32_t
-    initialized = 1;
+        hist[i] = c->history[i][c->channels - 1];
+
+    for (lfes = 0; lfes < DCA_LFE_SAMPLES; lfes++) {
+        /* Calculate the convolution */
+        accum = 0;
+
+        for (i = hist_start, j = 0; i < 512; i++, j++)
+            accum += mul32(hist[i], lfe_fir_64i[j]);
+        for (i = 0; i < hist_start; i++, j++)
+            accum += mul32(hist[i], lfe_fir_64i[j]);
+
+        c->downsampled_lfe[lfes] = accum;
+
+        /* Copy in 64 new samples from input */
+        for (i = 0; i < 64; i++)
+            hist[i + hist_start] = input[(lfes * 64 + i) * c->channels + c->channels - 1];
+
+        hist_start = (hist_start + 64) & 511;
+    }
+}
+
+typedef struct {
+    int32_t re;
+    int32_t im;
+} cplx32;
+
+static void fft(const int32_t in[2 * 256], cplx32 out[256])
+{
+    cplx32 buf[256], rin[256], rout[256];
+    int i, j, k, l;
+
+    /* do two transforms in parallel */
+    for (i = 0; i < 256; i++) {
+        /* Apply the Hann window */
+        rin[i].re = mul32(in[2 * i], 0x3fffffff - (cos_t(8 * i + 2) >> 1));
+        rin[i].im = mul32(in[2 * i + 1], 0x3fffffff - (cos_t(8 * i + 6) >> 1));
+    }
+    /* pre-rotation */
+    for (i = 0; i < 256; i++) {
+        buf[i].re = mul32(cos_t(4 * i + 2), rin[i].re)
+                  - mul32(sin_t(4 * i + 2), rin[i].im);
+        buf[i].im = mul32(cos_t(4 * i + 2), rin[i].im)
+                  + mul32(sin_t(4 * i + 2), rin[i].re);
+    }
+
+    for (j = 256, l = 1; j != 1; j >>= 1, l <<= 1) {
+        for (k = 0; k < 256; k += j) {
+            for (i = k; i < k + j / 2; i++) {
+                cplx32 sum, diff;
+                int t = 8 * l * i;
+
+                sum.re = buf[i].re + buf[i + j / 2].re;
+                sum.im = buf[i].im + buf[i + j / 2].im;
+
+                diff.re = buf[i].re - buf[i + j / 2].re;
+                diff.im = buf[i].im - buf[i + j / 2].im;
+
+                buf[i].re = half32(sum.re);
+                buf[i].im = half32(sum.im);
+
+                buf[i + j / 2].re = mul32(diff.re, cos_t(t))
+                                  - mul32(diff.im, sin_t(t));
+                buf[i + j / 2].im = mul32(diff.im, cos_t(t))
+                                  + mul32(diff.re, sin_t(t));
+            }
+        }
+    }
+    /* post-rotation */
+    for (i = 0; i < 256; i++) {
+        int b = ff_reverse[i];
+        rout[i].re = mul32(buf[b].re, cos_t(4 * i))
+                   - mul32(buf[b].im, sin_t(4 * i));
+        rout[i].im = mul32(buf[b].im, cos_t(4 * i))
+                   + mul32(buf[b].re, sin_t(4 * i));
+    }
+    for (i = 0; i < 256; i++) {
+        /* separate the results of the two transforms */
+        cplx32 o1, o2;
+
+        o1.re =  rout[i].re - rout[255 - i].re;
+        o1.im =  rout[i].im + rout[255 - i].im;
+
+        o2.re =  rout[i].im - rout[255 - i].im;
+        o2.im = -rout[i].re - rout[255 - i].re;
+
+        /* combine them into one long transform */
+        out[i].re = mul32( o1.re + o2.re, cos_t(2 * i + 1))
+                  + mul32( o1.im - o2.im, sin_t(2 * i + 1));
+        out[i].im = mul32( o1.im + o2.im, cos_t(2 * i + 1))
+                  + mul32(-o1.re + o2.re, sin_t(2 * i + 1));
+    }
+}
+
+static int32_t get_cb(int32_t in)
+{
+    int i, res;
+
+    res = 0;
+    if (in < 0)
+        in = -in;
+    for (i = 1024; i > 0; i >>= 1) {
+        if (cb_to_level[i + res] >= in)
+            res += i;
+    }
+    return -res;
+}
+
+static int32_t add_cb(int32_t a, int32_t b)
+{
+    if (a < b)
+        FFSWAP(int32_t, a, b);
+
+    if (a - b >= 256)
+        return a;
+    return a + cb_to_add[a - b];
+}
+
+static void adjust_jnd(int samplerate_index,
+                       const int32_t in[512], int32_t out_cb[256])
+{
+    int32_t power[256];
+    cplx32 out[256];
+    int32_t out_cb_unnorm[256];
+    int32_t denom;
+    const int32_t ca_cb = -1114;
+    const int32_t cs_cb = 928;
+    int i, j;
+
+    fft(in, out);
+
+    for (j = 0; j < 256; j++) {
+        power[j] = add_cb(get_cb(out[j].re), get_cb(out[j].im));
+        out_cb_unnorm[j] = -2047; /* and can only grow */
+    }
+
+    for (i = 0; i < AUBANDS; i++) {
+        denom = ca_cb; /* and can only grow */
+        for (j = 0; j < 256; j++)
+            denom = add_cb(denom, power[j] + auf[samplerate_index][i][j]);
+        for (j = 0; j < 256; j++)
+            out_cb_unnorm[j] = add_cb(out_cb_unnorm[j],
+                    -denom + auf[samplerate_index][i][j]);
+    }
+
+    for (j = 0; j < 256; j++)
+        out_cb[j] = add_cb(out_cb[j], -out_cb_unnorm[j] - ca_cb - cs_cb);
+}
+
+typedef void (*walk_band_t)(DCAContext *c, int band1, int band2, int f,
+                            int32_t spectrum1, int32_t spectrum2, int channel,
+                            int32_t * arg);
+
+static void walk_band_low(DCAContext *c, int band, int channel,
+                          walk_band_t walk, int32_t *arg)
+{
+    int f;
+
+    if (band == 0) {
+        for (f = 0; f < 4; f++)
+            walk(c, 0, 0, f, 0, -2047, channel, arg);
+    } else {
+        for (f = 0; f < 8; f++)
+            walk(c, band, band - 1, 8 * band - 4 + f,
+                    c->band_spectrum[7 - f], c->band_spectrum[f], channel, arg);
+    }
+}
+
+static void walk_band_high(DCAContext *c, int band, int channel,
+                           walk_band_t walk, int32_t *arg)
+{
+    int f;
+
+    if (band == 31) {
+        for (f = 0; f < 4; f++)
+            walk(c, 31, 31, 256 - 4 + f, 0, -2047, channel, arg);
+    } else {
+        for (f = 0; f < 8; f++)
+            walk(c, band, band + 1, 8 * band + 4 + f,
+                    c->band_spectrum[f], c->band_spectrum[7 - f], channel, arg);
+    }
+}
+
+static void update_band_masking(DCAContext *c, int band1, int band2,
+                                int f, int32_t spectrum1, int32_t spectrum2,
+                                int channel, int32_t * arg)
+{
+    int32_t value = c->eff_masking_curve_cb[f] - spectrum1;
+
+    if (value < c->band_masking_cb[band1])
+        c->band_masking_cb[band1] = value;
+}
+
+static void calc_masking(DCAContext *c, const int32_t *input)
+{
+    int i, k, band, ch, ssf;
+    int32_t data[512];
+
+    for (i = 0; i < 256; i++)
+        for (ssf = 0; ssf < SUBSUBFRAMES; ssf++)
+            c->masking_curve_cb[ssf][i] = -2047;
+
+    for (ssf = 0; ssf < SUBSUBFRAMES; ssf++)
+        for (ch = 0; ch < c->fullband_channels; ch++) {
+            for (i = 0, k = 128 + 256 * ssf; k < 512; i++, k++)
+                data[i] = c->history[k][ch];
+            for (k -= 512; i < 512; i++, k++)
+                data[i] = input[k * c->channels + ch];
+            adjust_jnd(c->samplerate_index, data, c->masking_curve_cb[ssf]);
+        }
+    for (i = 0; i < 256; i++) {
+        int32_t m = 2048;
+
+        for (ssf = 0; ssf < SUBSUBFRAMES; ssf++)
+            if (c->masking_curve_cb[ssf][i] < m)
+                m = c->masking_curve_cb[ssf][i];
+        c->eff_masking_curve_cb[i] = m;
+    }
+
+    for (band = 0; band < 32; band++) {
+        c->band_masking_cb[band] = 2048;
+        walk_band_low(c, band, 0, update_band_masking, NULL);
+        walk_band_high(c, band, 0, update_band_masking, NULL);
+    }
+}
+
+static void find_peaks(DCAContext *c)
+{
+    int band, ch;
+
+    for (band = 0; band < 32; band++)
+        for (ch = 0; ch < c->fullband_channels; ch++) {
+            int sample;
+            int32_t m = 0;
+
+            for (sample = 0; sample < SUBBAND_SAMPLES; sample++) {
+                int32_t s = abs(c->subband[sample][band][ch]);
+                if (m < s)
+                    m = s;
+            }
+            c->peak_cb[band][ch] = get_cb(m);
+        }
+
+    if (c->lfe_channel) {
+        int sample;
+        int32_t m = 0;
+
+        for (sample = 0; sample < DCA_LFE_SAMPLES; sample++)
+            if (m < abs(c->downsampled_lfe[sample]))
+                m = abs(c->downsampled_lfe[sample]);
+        c->lfe_peak_cb = get_cb(m);
+    }
+}
+
+static const int snr_fudge = 128;
+#define USED_1ABITS 1
+#define USED_NABITS 2
+#define USED_26ABITS 4
+
+static int init_quantization_noise(DCAContext *c, int noise)
+{
+    int ch, band, ret = 0;
+
+    c->consumed_bits = 132 + 493 * c->fullband_channels;
+    if (c->lfe_channel)
+        c->consumed_bits += 72;
+
+    /* attempt to guess the bit distribution based on the prevoius frame */
+    for (ch = 0; ch < c->fullband_channels; ch++) {
+        for (band = 0; band < 32; band++) {
+            int snr_cb = c->peak_cb[band][ch] - c->band_masking_cb[band] - noise;
+
+            if (snr_cb >= 1312) {
+                c->abits[band][ch] = 26;
+                ret |= USED_26ABITS;
+            } else if (snr_cb >= 222) {
+                c->abits[band][ch] = 8 + mul32(snr_cb - 222, 69000000);
+                ret |= USED_NABITS;
+            } else if (snr_cb >= 0) {
+                c->abits[band][ch] = 2 + mul32(snr_cb, 106000000);
+                ret |= USED_NABITS;
+            } else {
+                c->abits[band][ch] = 1;
+                ret |= USED_1ABITS;
+            }
+        }
+    }
+
+    for (band = 0; band < 32; band++)
+        for (ch = 0; ch < c->fullband_channels; ch++) {
+            c->consumed_bits += bit_consumption[c->abits[band][ch]];
+        }
+
+    return ret;
+}
+
+static void assign_bits(DCAContext *c)
+{
+    /* Find the bounds where the binary search should work */
+    int low, high, down;
+    int used_abits = 0;
+
+    init_quantization_noise(c, c->worst_quantization_noise);
+    low = high = c->worst_quantization_noise;
+    if (c->consumed_bits > c->frame_bits) {
+        while (c->consumed_bits > c->frame_bits) {
+            av_assert0(used_abits != USED_1ABITS);
+            low = high;
+            high += snr_fudge;
+            used_abits = init_quantization_noise(c, high);
+        }
+    } else {
+        while (c->consumed_bits <= c->frame_bits) {
+            high = low;
+            if (used_abits == USED_26ABITS)
+                goto out; /* The requested bitrate is too high, pad with zeros */
+            low -= snr_fudge;
+            used_abits = init_quantization_noise(c, low);
+        }
+    }
+
+    /* Now do a binary search between low and high to see what fits */
+    for (down = snr_fudge >> 1; down; down >>= 1) {
+        init_quantization_noise(c, high - down);
+        if (c->consumed_bits <= c->frame_bits)
+            high -= down;
+    }
+    init_quantization_noise(c, high);
+out:
+    c->worst_quantization_noise = high;
+    if (high > c->worst_noise_ever)
+        c->worst_noise_ever = high;
+}
+
+static void shift_history(DCAContext *c, const int32_t *input)
+{
+    int k, ch;
+
+    for (k = 0; k < 512; k++)
+        for (ch = 0; ch < c->channels; ch++)
+            c->history[k][ch] = input[k * c->channels + ch];
+}
+
+static int32_t quantize_value(int32_t value, softfloat quant)
+{
+    int32_t offset = 1 << (quant.e - 1);
+
+    value = mul32(value, quant.m) + offset;
+    value = value >> quant.e;
+    return value;
+}
+
+static int calc_one_scale(int32_t peak_cb, int abits, softfloat *quant)
+{
+    int32_t peak;
+    int our_nscale, try_remove;
+    softfloat our_quant;
+
+    av_assert0(peak_cb <= 0);
+    av_assert0(peak_cb >= -2047);
+
+    our_nscale = 127;
+    peak = cb_to_level[-peak_cb];
+
+    for (try_remove = 64; try_remove > 0; try_remove >>= 1) {
+        if (scalefactor_inv[our_nscale - try_remove].e + stepsize_inv[abits].e <= 17)
+            continue;
+        our_quant.m = mul32(scalefactor_inv[our_nscale - try_remove].m, stepsize_inv[abits].m);
+        our_quant.e = scalefactor_inv[our_nscale - try_remove].e + stepsize_inv[abits].e - 17;
+        if ((quant_levels[abits] - 1) / 2 < quantize_value(peak, our_quant))
+            continue;
+        our_nscale -= try_remove;
+    }
+
+    if (our_nscale >= 125)
+        our_nscale = 124;
+
+    quant->m = mul32(scalefactor_inv[our_nscale].m, stepsize_inv[abits].m);
+    quant->e = scalefactor_inv[our_nscale].e + stepsize_inv[abits].e - 17;
+    av_assert0((quant_levels[abits] - 1) / 2 >= quantize_value(peak, *quant));
+
+    return our_nscale;
+}
+
+static void calc_scales(DCAContext *c)
+{
+    int band, ch;
+
+    for (band = 0; band < 32; band++)
+        for (ch = 0; ch < c->fullband_channels; ch++)
+            c->scale_factor[band][ch] = calc_one_scale(c->peak_cb[band][ch],
+                                                       c->abits[band][ch],
+                                                       &c->quant[band][ch]);
+
+    if (c->lfe_channel)
+        c->lfe_scale_factor = calc_one_scale(c->lfe_peak_cb, 11, &c->lfe_quant);
+}
+
+static void quantize_all(DCAContext *c)
+{
+    int sample, band, ch;
+
+    for (sample = 0; sample < SUBBAND_SAMPLES; sample++)
+        for (band = 0; band < 32; band++)
+            for (ch = 0; ch < c->fullband_channels; ch++)
+                c->quantized[sample][band][ch] = quantize_value(c->subband[sample][band][ch], c->quant[band][ch]);
 }
 
 static void put_frame_header(DCAContext *c)
@@ -244,19 +716,19 @@
     put_bits(&c->pb, 1, 0);
 
     /* Number of PCM sample blocks */
-    put_bits(&c->pb, 7, PCM_SAMPLES-1);
+    put_bits(&c->pb, 7, SUBBAND_SAMPLES - 1);
 
     /* Primary frame byte size */
-    put_bits(&c->pb, 14, c->frame_size-1);
+    put_bits(&c->pb, 14, c->frame_size - 1);
 
-    /* Audio channel arrangement: L + R (stereo) */
-    put_bits(&c->pb, 6, c->num_channel);
+    /* Audio channel arrangement */
+    put_bits(&c->pb, 6, c->channel_config);
 
     /* Core audio sampling frequency */
-    put_bits(&c->pb, 4, c->sample_rate_code);
+    put_bits(&c->pb, 4, bitstream_sfreq[c->samplerate_index]);
 
-    /* Transmission bit rate: 1411.2 kbps */
-    put_bits(&c->pb, 5, 0x16); /* FIXME: magic number */
+    /* Transmission bit rate */
+    put_bits(&c->pb, 5, c->bitrate_index);
 
     /* Embedded down mix: disabled */
     put_bits(&c->pb, 1, 0);
@@ -282,8 +754,8 @@
     /* Audio sync word insertion flag: after each sub-frame */
     put_bits(&c->pb, 1, 0);
 
-    /* Low frequency effects flag: not present or interpolation factor=64 */
-    put_bits(&c->pb, 2, c->lfe_state);
+    /* Low frequency effects flag: not present or 64x subsampling */
+    put_bits(&c->pb, 2, c->lfe_channel ? 2 : 0);
 
     /* Predictor history switch flag: on */
     put_bits(&c->pb, 1, 1);
@@ -321,82 +793,68 @@
     put_bits(&c->pb, 4, SUBFRAMES - 1);
 
     /* Number of primary audio channels */
-    put_bits(&c->pb, 3, c->prim_channels - 1);
+    put_bits(&c->pb, 3, c->fullband_channels - 1);
 
     /* Subband activity count */
-    for (ch = 0; ch < c->prim_channels; ch++)
+    for (ch = 0; ch < c->fullband_channels; ch++)
         put_bits(&c->pb, 5, DCA_SUBBANDS - 2);
 
     /* High frequency VQ start subband */
-    for (ch = 0; ch < c->prim_channels; ch++)
+    for (ch = 0; ch < c->fullband_channels; ch++)
         put_bits(&c->pb, 5, DCA_SUBBANDS - 1);
 
     /* Joint intensity coding index: 0, 0 */
-    for (ch = 0; ch < c->prim_channels; ch++)
+    for (ch = 0; ch < c->fullband_channels; ch++)
         put_bits(&c->pb, 3, 0);
 
     /* Transient mode codebook: A4, A4 (arbitrary) */
-    for (ch = 0; ch < c->prim_channels; ch++)
+    for (ch = 0; ch < c->fullband_channels; ch++)
         put_bits(&c->pb, 2, 0);
 
     /* Scale factor code book: 7 bit linear, 7-bit sqrt table (for each channel) */
-    for (ch = 0; ch < c->prim_channels; ch++)
+    for (ch = 0; ch < c->fullband_channels; ch++)
         put_bits(&c->pb, 3, 6);
 
     /* Bit allocation quantizer select: linear 5-bit */
-    for (ch = 0; ch < c->prim_channels; ch++)
+    for (ch = 0; ch < c->fullband_channels; ch++)
         put_bits(&c->pb, 3, 6);
 
     /* Quantization index codebook select: dummy data
        to avoid transmission of scale factor adjustment */
-
     for (i = 1; i < 11; i++)
-        for (ch = 0; ch < c->prim_channels; ch++)
+        for (ch = 0; ch < c->fullband_channels; ch++)
             put_bits(&c->pb, bitlen[i], thr[i]);
 
     /* Scale factor adjustment index: not transmitted */
+    /* Audio header CRC check word: not transmitted */
 }
 
-/**
- * 8-23 bits quantization
- * @param sample
- * @param bits
- */
-static inline uint32_t quantize(int32_t sample, int bits)
+static void put_subframe_samples(DCAContext *c, int ss, int band, int ch)
 {
-    av_assert0(sample <    1 << (bits - 1));
-    av_assert0(sample >= -(1 << (bits - 1)));
-    return sample & ((1 << bits) - 1);
-}
-
-static inline int find_scale_factor7(int64_t max_value, int bits)
-{
-    int i = 0, j = 128, q;
-    max_value = ((max_value << 15) / lossy_quant[bits + 3]) >> (bits - 1);
-    while (i < j) {
-        q = (i + j) >> 1;
-        if (max_value < scale_factor_quant7[q])
-            j = q;
-        else
-            i = q + 1;
+    if (c->abits[band][ch] <= 7) {
+        int sum, i, j;
+        for (i = 0; i < 8; i += 4) {
+            sum = 0;
+            for (j = 3; j >= 0; j--) {
+                sum *= quant_levels[c->abits[band][ch]];
+                sum += c->quantized[ss * 8 + i + j][band][ch];
+                sum += (quant_levels[c->abits[band][ch]] - 1) / 2;
+            }
+            put_bits(&c->pb, bit_consumption[c->abits[band][ch]] / 4, sum);
+        }
+    } else {
+        int i;
+        for (i = 0; i < 8; i++) {
+            int bits = bit_consumption[c->abits[band][ch]] / 16;
+            int32_t mask = (1 << bits) - 1;
+            put_bits(&c->pb, bits, c->quantized[ss * 8 + i][band][ch] & mask);
+        }
     }
-    av_assert1(i < 128);
-    return i;
 }
 
-static inline void put_sample7(DCAContext *c, int64_t sample, int bits,
-                               int scale_factor)
+static void put_subframe(DCAContext *c, int subframe)
 {
-    sample = (sample << 15) / ((int64_t) lossy_quant[bits + 3] * scale_factor_quant7[scale_factor]);
-    put_bits(&c->pb, bits, quantize((int) sample, bits));
-}
-
-static void put_subframe(DCAContext *c,
-                         int32_t subband_data[8 * SUBSUBFRAMES][MAX_CHANNELS][32],
-                         int subframe)
-{
-    int i, sub, ss, ch, max_value;
-    int32_t *lfe_data = c->lfe_data + 4 * SUBSUBFRAMES * subframe;
+    int i, band, ss, ch;
 
     /* Subsubframes count */
     put_bits(&c->pb, 2, SUBSUBFRAMES -1);
@@ -405,44 +863,27 @@
     put_bits(&c->pb, 3, 0);
 
     /* Prediction mode: no ADPCM, in each channel and subband */
-    for (ch = 0; ch < c->prim_channels; ch++)
-        for (sub = 0; sub < DCA_SUBBANDS; sub++)
+    for (ch = 0; ch < c->fullband_channels; ch++)
+        for (band = 0; band < DCA_SUBBANDS; band++)
             put_bits(&c->pb, 1, 0);
 
     /* Prediction VQ addres: not transmitted */
     /* Bit allocation index */
-    for (ch = 0; ch < c->prim_channels; ch++)
-        for (sub = 0; sub < DCA_SUBBANDS; sub++)
-            put_bits(&c->pb, 5, QUANTIZER_BITS+3);
+    for (ch = 0; ch < c->fullband_channels; ch++)
+        for (band = 0; band < DCA_SUBBANDS; band++)
+            put_bits(&c->pb, 5, c->abits[band][ch]);
 
     if (SUBSUBFRAMES > 1) {
         /* Transition mode: none for each channel and subband */
-        for (ch = 0; ch < c->prim_channels; ch++)
-            for (sub = 0; sub < DCA_SUBBANDS; sub++)
+        for (ch = 0; ch < c->fullband_channels; ch++)
+            for (band = 0; band < DCA_SUBBANDS; band++)
                 put_bits(&c->pb, 1, 0); /* codebook A4 */
     }
 
-    /* Determine scale_factor */
-    for (ch = 0; ch < c->prim_channels; ch++)
-        for (sub = 0; sub < DCA_SUBBANDS; sub++) {
-            max_value = 0;
-            for (i = 0; i < 8 * SUBSUBFRAMES; i++)
-                max_value = FFMAX(max_value, FFABS(subband_data[i][ch][sub]));
-            c->scale_factor[ch][sub] = find_scale_factor7(max_value, QUANTIZER_BITS);
-        }
-
-    if (c->lfe_channel) {
-        max_value = 0;
-        for (i = 0; i < 4 * SUBSUBFRAMES; i++)
-            max_value = FFMAX(max_value, FFABS(lfe_data[i]));
-        c->lfe_scale_factor = find_scale_factor7(max_value, LFE_BITS);
-    }
-
-    /* Scale factors: the same for each channel and subband,
-       encoded according to Table D.1.2 */
-    for (ch = 0; ch < c->prim_channels; ch++)
-        for (sub = 0; sub < DCA_SUBBANDS; sub++)
-            put_bits(&c->pb, 7, c->scale_factor[ch][sub]);
+    /* Scale factors */
+    for (ch = 0; ch < c->fullband_channels; ch++)
+        for (band = 0; band < DCA_SUBBANDS; band++)
+            put_bits(&c->pb, 7, c->scale_factor[band][ch]);
 
     /* Joint subband scale factor codebook select: not transmitted */
     /* Scale factors for joint subband coding: not transmitted */
@@ -451,152 +892,83 @@
     /* Stde information CRC check word: not transmitted */
     /* VQ encoded high frequency subbands: not transmitted */
 
-    /* LFE data */
+    /* LFE data: 8 samples and scalefactor */
     if (c->lfe_channel) {
-        for (i = 0; i < 4 * SUBSUBFRAMES; i++)
-            put_sample7(c, lfe_data[i], LFE_BITS, c->lfe_scale_factor);
+        for (i = 0; i < DCA_LFE_SAMPLES; i++)
+            put_bits(&c->pb, 8, quantize_value(c->downsampled_lfe[i], c->lfe_quant) & 0xff);
         put_bits(&c->pb, 8, c->lfe_scale_factor);
     }
 
     /* Audio data (subsubframes) */
-
     for (ss = 0; ss < SUBSUBFRAMES ; ss++)
-        for (ch = 0; ch < c->prim_channels; ch++)
-            for (sub = 0; sub < DCA_SUBBANDS; sub++)
-                for (i = 0; i < 8; i++)
-                    put_sample7(c, subband_data[ss * 8 + i][ch][sub], QUANTIZER_BITS, c->scale_factor[ch][sub]);
+        for (ch = 0; ch < c->fullband_channels; ch++)
+            for (band = 0; band < DCA_SUBBANDS; band++)
+                    put_subframe_samples(c, ss, band, ch);
 
     /* DSYNC */
     put_bits(&c->pb, 16, 0xffff);
 }
 
-static void put_frame(DCAContext *c,
-                      int32_t subband_data[PCM_SAMPLES][MAX_CHANNELS][32],
-                      uint8_t *frame)
-{
-    int i;
-    init_put_bits(&c->pb, frame + DCA_HEADER_SIZE, DCA_MAX_FRAME_SIZE-DCA_HEADER_SIZE);
-
-    put_primary_audio_header(c);
-    for (i = 0; i < SUBFRAMES; i++)
-        put_subframe(c, &subband_data[SUBSUBFRAMES * 8 * i], i);
-
-    flush_put_bits(&c->pb);
-    c->frame_size = (put_bits_count(&c->pb) >> 3) + DCA_HEADER_SIZE;
-
-    init_put_bits(&c->pb, frame, DCA_HEADER_SIZE);
-    put_frame_header(c);
-    flush_put_bits(&c->pb);
-}
-
 static int encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
                         const AVFrame *frame, int *got_packet_ptr)
 {
-    int i, k, channel;
     DCAContext *c = avctx->priv_data;
-    const int16_t *samples;
-    int ret, real_channel = 0;
+    const int32_t *samples;
+    int ret, i;
 
-    if ((ret = ff_alloc_packet2(avctx, avpkt, DCA_MAX_FRAME_SIZE + DCA_HEADER_SIZE)) < 0)
+    if ((ret = ff_alloc_packet2(avctx, avpkt, c->frame_size )) < 0)
         return ret;
 
-    samples = (const int16_t *)frame->data[0];
-    for (i = 0; i < PCM_SAMPLES; i ++) { /* i is the decimated sample number */
-        for (channel = 0; channel < c->prim_channels + 1; channel++) {
-            real_channel = c->channel_order_tab[channel];
-            if (real_channel >= 0) {
-                /* Get 32 PCM samples */
-                for (k = 0; k < 32; k++) { /* k is the sample number in a 32-sample block */
-                    c->pcm[k] = samples[avctx->channels * (32 * i + k) + channel] << 16;
-                }
-                /* Put subband samples into the proper place */
-                qmf_decompose(c, c->pcm, &c->subband[i][real_channel][0], real_channel);
-            }
-        }
-    }
+    samples = (const int32_t *)frame->data[0];
 
-    if (c->lfe_channel) {
-        for (i = 0; i < PCM_SAMPLES / 2; i++) {
-            for (k = 0; k < LFE_INTERPOLATION; k++) /* k is the sample number in a 32-sample block */
-                c->pcm[k] = samples[avctx->channels * (LFE_INTERPOLATION*i+k) + c->lfe_offset] << 16;
-            c->lfe_data[i] = lfe_downsample(c, c->pcm);
-        }
-    }
+    subband_transform(c, samples);
+    if (c->lfe_channel)
+        lfe_downsample(c, samples);
 
-    put_frame(c, c->subband, avpkt->data);
+    calc_masking(c, samples);
+    find_peaks(c);
+    assign_bits(c);
+    calc_scales(c);
+    quantize_all(c);
+    shift_history(c, samples);
 
-    avpkt->size     = c->frame_size;
+    init_put_bits(&c->pb, avpkt->data, avpkt->size);
+    put_frame_header(c);
+    put_primary_audio_header(c);
+    for (i = 0; i < SUBFRAMES; i++)
+        put_subframe(c, i);
+
+    flush_put_bits(&c->pb);
+
+    avpkt->pts      = frame->pts;
+    avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples);
+    avpkt->size     = c->frame_size + 1;
     *got_packet_ptr = 1;
     return 0;
 }
 
-static int encode_init(AVCodecContext *avctx)
-{
-    DCAContext *c = avctx->priv_data;
-    int i;
-    uint64_t layout = avctx->channel_layout;
-
-    c->prim_channels = avctx->channels;
-    c->lfe_channel   = (avctx->channels == 3 || avctx->channels == 6);
-
-    if (!layout) {
-        av_log(avctx, AV_LOG_WARNING, "No channel layout specified. The "
-                                      "encoder will guess the layout, but it "
-                                      "might be incorrect.\n");
-        layout = av_get_default_channel_layout(avctx->channels);
-    }
-    switch (layout) {
-    case AV_CH_LAYOUT_STEREO:       c->a_mode = 2; c->num_channel = 2; break;
-    case AV_CH_LAYOUT_5POINT0:      c->a_mode = 9; c->num_channel = 9; break;
-    case AV_CH_LAYOUT_5POINT1:      c->a_mode = 9; c->num_channel = 9; break;
-    case AV_CH_LAYOUT_5POINT0_BACK: c->a_mode = 9; c->num_channel = 9; break;
-    case AV_CH_LAYOUT_5POINT1_BACK: c->a_mode = 9; c->num_channel = 9; break;
-    default:
-    av_log(avctx, AV_LOG_ERROR,
-           "Only stereo, 5.0, 5.1 channel layouts supported at the moment!\n");
-    return AVERROR_PATCHWELCOME;
-    }
-
-    if (c->lfe_channel) {
-        init_lfe_fir();
-        c->prim_channels--;
-        c->channel_order_tab = dca_channel_reorder_lfe[c->a_mode];
-        c->lfe_state         = LFE_PRESENT;
-        c->lfe_offset        = dca_lfe_index[c->a_mode];
-    } else {
-        c->channel_order_tab = dca_channel_reorder_nolfe[c->a_mode];
-        c->lfe_state         = LFE_MISSING;
-    }
-
-    for (i = 0; i < 16; i++) {
-        if (avpriv_dca_sample_rates[i] && (avpriv_dca_sample_rates[i] == avctx->sample_rate))
-            break;
-    }
-    if (i == 16) {
-        av_log(avctx, AV_LOG_ERROR, "Sample rate %iHz not supported, only ", avctx->sample_rate);
-        for (i = 0; i < 16; i++)
-            av_log(avctx, AV_LOG_ERROR, "%d, ", avpriv_dca_sample_rates[i]);
-        av_log(avctx, AV_LOG_ERROR, "supported.\n");
-        return -1;
-    }
-    c->sample_rate_code = i;
-
-    avctx->frame_size = 32 * PCM_SAMPLES;
-
-    if (!cos_table[127])
-        qmf_init();
-    return 0;
-}
+static const AVCodecDefault defaults[] = {
+    { "b",          "1411200" },
+    { NULL },
+};
 
 AVCodec ff_dca_encoder = {
-    .name           = "dca",
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_DTS,
-    .priv_data_size = sizeof(DCAContext),
-    .init           = encode_init,
-    .encode2        = encode_frame,
-    .capabilities   = CODEC_CAP_EXPERIMENTAL,
-    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
-                                                     AV_SAMPLE_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"),
+    .name                  = "dca",
+    .type                  = AVMEDIA_TYPE_AUDIO,
+    .id                    = AV_CODEC_ID_DTS,
+    .priv_data_size        = sizeof(DCAContext),
+    .init                  = encode_init,
+    .encode2               = encode_frame,
+    .capabilities          = CODEC_CAP_EXPERIMENTAL,
+    .sample_fmts           = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32,
+                                                            AV_SAMPLE_FMT_NONE },
+    .long_name             = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"),
+    .supported_samplerates = sample_rates,
+    .channel_layouts       = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
+                                                  AV_CH_LAYOUT_STEREO,
+                                                  AV_CH_LAYOUT_2_2,
+                                                  AV_CH_LAYOUT_5POINT0,
+                                                  AV_CH_LAYOUT_5POINT1,
+                                                  0 },
+    .defaults              = defaults,
 };
diff --git a/libavcodec/dcaenc.h b/libavcodec/dcaenc.h
index 121e5da..20f557b 100644
--- a/libavcodec/dcaenc.h
+++ b/libavcodec/dcaenc.h
@@ -1,6 +1,6 @@
 /*
  * DCA encoder tables
- * Copyright (C) 2008 Alexander E. Patrakov
+ * Copyright (C) 2008-2012 Alexander E. Patrakov
  *
  * This file is part of FFmpeg.
  *
@@ -24,523 +24,90 @@
 
 #include <stdint.h>
 
-/* This is a scaled version of the response of the reference decoder to
-   this vector of subband samples: ( 1.0 0.0 0.0 ... 0.0 )
-   */
+typedef struct {
+    int32_t m;
+    int32_t e;
+} softfloat;
 
-static const int32_t UnQMF[512] = {
-    7,
-    4,
-    -961,
-    -2844,
-    -8024,
-    -18978,
-    -32081,
-    -15635,
-    -16582,
-    -18359,
-    -17180,
-    -14868,
-    -11664,
-    -8051,
-    -4477,
-    -1327,
-    -1670,
-    -6019,
-    -11590,
-    -18030,
-    -24762,
-    -30965,
-    -35947,
-    -36145,
-    -37223,
-    -86311,
-    -57024,
-    -27215,
-    -11274,
-    -4684,
-    42,
-    108,
-    188,
-    250,
-    -1007,
-    -596,
-    -2289,
-    -12218,
-    -27191,
-    -124367,
-    -184256,
-    -250538,
-    -323499,
-    -397784,
-    -468855,
-    -532072,
-    -583000,
-    -618041,
-    -777916,
-    -783868,
-    -765968,
-    -724740,
-    -662468,
-    -583058,
-    -490548,
-    -401623,
-    -296090,
-    -73154,
-    -36711,
-    -7766,
-    -2363,
-    -4905,
-    2388,
-    2681,
-    5651,
-    4086,
-    71110,
-    139742,
-    188067,
-    151237,
-    101355,
-    309917,
-    343690,
-    358839,
-    357555,
-    334606,
-    289625,
-    224152,
-    142063,
-    48725,
-    74996,
-    238425,
-    411666,
-    584160,
-    744276,
-    880730,
-    983272,
-    1041933,
-    1054396,
-    789531,
-    851022,
-    864032,
-    675431,
-    418134,
-    35762,
-    66911,
-    103502,
-    136403,
-    -55147,
-    -245269,
-    -499595,
-    -808470,
-    -1136858,
-    -2010912,
-    -2581654,
-    -3151901,
-    -3696328,
-    -4196599,
-    -4633761,
-    -4993229,
-    -5262495,
-    -5436311,
-    -477650,
-    -901314,
-    -1308090,
-    -1677468,
-    -1985525,
-    -2212848,
-    -2341196,
-    -2373915,
-    -2269552,
-    -2620489,
-    -2173858,
-    -1629954,
-    -946595,
-    -193499,
-    1119459,
-    1138657,
-    1335311,
-    1126544,
-    2765033,
-    3139603,
-    3414913,
-    3599213,
-    3676363,
-    3448981,
-    3328726,
-    3111551,
-    2810887,
-    2428657,
-    1973684,
-    1457278,
-    893848,
-    300995,
-    -292521,
-    -867621,
-    -1404936,
-    -1871278,
-    -2229831,
-    -2440932,
-    -2462684,
-    -2255006,
-    -1768898,
-    -1079574,
-    82115,
-    1660302,
-    3660715,
-    6123610,
-    8329598,
-    11888744,
-    15722147,
-    19737089,
-    25647773,
-    31039399,
-    36868007,
-    43124253,
-    49737161,
-    56495958,
-    63668945,
-    71039511,
-    78540240,
-    86089058,
-    93600041,
-    100981151,
-    108136061,
-    114970055,
-    121718321,
-    127566038,
-    132774642,
-    137247294,
-    140894737,
-    143635018,
-    145395599,
-    146114032,
-    145742999,
-    144211606,
-    141594341,
-    137808404,
-    132914122,
-    126912246,
-    120243281,
-    112155281,
-    103338368,
-    93904953,
-    83439152,
-    72921548,
-    62192990,
-    51434918,
-    40894003,
-    30786726,
-    21384955,
-    12939112,
-    5718193,
-    -5790,
-    -3959261,
-    -5870978,
-    -5475538,
-    -2517061,
-    3247310,
-    12042937,
-    24076729,
-    39531397,
-    58562863,
-    81297002,
-    107826748,
-    138209187,
-    172464115,
-    210569037,
-    252468018,
-    298045453,
-    347168648,
-    399634888,
-    455137189,
-    513586535,
-    574537650,
-    637645129,
-    702597163,
-    768856566,
-    836022040,
-    903618096,
-    971159680,
-    1038137214,
-    1103987353,
-    1168195035,
-    1230223053,
-    1289539180,
-    1345620373,
-    1397957958,
-    1446063657,
-    1489474689,
-    1527740502,
-    1560502307,
-    1587383079,
-    1608071145,
-    1622301248,
-    1629859340,
-    1630584888,
-    1624373875,
-    1611178348,
-    1591018893,
-    1563948667,
-    1530105004,
-    1489673227,
-    1442904075,
-    1390107674,
-    1331590427,
-    1267779478,
-    1199115126,
-    1126053392,
-    1049146257,
-    968928307,
-    885965976,
-    800851610,
-    714186243,
-    626590147,
-    538672486,
-    451042824,
-    364299927,
-    279026812,
-    195785029,
-    115109565,
-    37503924,
-    -36564551,
-    -106668063,
-    -172421668,
-    -233487283,
-    -289575706,
-    -340448569,
-    -385919511,
-    -425854915,
-    -460174578,
-    -488840702,
-    -511893328,
-    -529405118,
-    -541489888,
-    -548312207,
-    -550036471,
-    -547005316,
-    -539436808,
-    -527630488,
-    -512084785,
-    -492941605,
-    -470665204,
-    -445668379,
-    -418328829,
-    -389072810,
-    -358293846,
-    -326396227,
-    -293769619,
-    -260792276,
-    -227825056,
-    -195208961,
-    -163262121,
-    -132280748,
-    -102533727,
-    -74230062,
-    -47600637,
-    -22817785,
-    -25786,
-    20662895,
-    39167253,
-    55438413,
-    69453741,
-    81242430,
-    90795329,
-    98213465,
-    103540643,
-    106917392,
-    108861938,
-    108539682,
-    106780704,
-    103722568,
-    99043289,
-    93608686,
-    87266209,
-    80212203,
-    72590022,
-    64603428,
-    56362402,
-    48032218,
-    39749162,
-    31638971,
-    23814664,
-    16376190,
-    9409836,
-    2988017,
-    -2822356,
-    -7976595,
-    -12454837,
-    -16241147,
-    -19331944,
-    -21735011,
-    -23468284,
-    -24559822,
-    -25042936,
-    -25035583,
-    -24429587,
-    -23346408,
-    -21860411,
-    -20015718,
-    -17025330,
-    -14968728,
-    -12487138,
-    -9656319,
-    -7846681,
-    -5197816,
-    -2621904,
-    -144953,
-    2144746,
-    3990570,
-    5845884,
-    7454650,
-    8820394,
-    9929891,
-    10784445,
-    11390921,
-    11762056,
-    11916017,
-    12261189,
-    12117604,
-    11815303,
-    11374622,
-    10815301,
-    10157241,
-    9418799,
-    8629399,
-    7780776,
-    7303680,
-    6353499,
-    5392738,
-    4457895,
-    3543062,
-    1305978,
-    1402521,
-    1084092,
-    965652,
-    -151008,
-    -666667,
-    -1032157,
-    -1231475,
-    -1319043,
-    -1006023,
-    -915720,
-    -773426,
-    -612377,
-    -445864,
-    -291068,
-    -161337,
-    -66484,
-    -11725,
-    133453,
-    388184,
-    615856,
-    804033,
-    942377,
-    1022911,
-    1041247,
-    995854,
-    891376,
-    572246,
-    457992,
-    316365,
-    172738,
-    43037,
-    -117662,
-    -98542,
-    -70279,
-    -41458,
-    -535790,
-    -959038,
-    -1364456,
-    -1502265,
-    -1568530,
-    -2378681,
-    -2701111,
-    -2976407,
-    -3182552,
-    -3314415,
-    -3366600,
-    -3337701,
-    -3232252,
-    -3054999,
-    1984841,
-    1925903,
-    1817377,
-    1669153,
-    1490069,
-    1292040,
-    1086223,
-    890983,
-    699163,
-    201358,
-    266971,
-    296990,
-    198419,
-    91119,
-    4737,
-    5936,
-    2553,
-    2060,
-    -3828,
-    -1664,
-    -4917,
-    -20796,
-    -36822,
-    -131247,
-    -154923,
-    -162055,
-    -161354,
-    -148762,
-    -125754,
-    -94473,
-    -57821,
-    -19096,
-    15172,
-    43004,
-    65624,
-    81354,
-    89325,
-    89524,
-    82766,
-    71075,
-    55128,
-    13686,
-    6921,
-    1449,
-    420,
-    785,
-    -215,
-    -179,
-    -113,
-    -49,
-    6002,
-    16007,
-    42978,
-    100662,
-    171472,
-    83975,
-    93702,
-    108813,
-    111893,
-    110272,
-    103914,
-    93973,
-    81606,
-    68041,
-    -54058,
-    -60695,
-    -65277,
-    -67224,
-    -66213,
-    -62082,
-    -55574,
-    -42988,
-    -35272,
-    -63735,
-    -33501,
-    -12671,
-    -4038,
-    -1232,
-    5,
-    7
+static const int sample_rates[] = {
+    8000, 16000, 32000, 11025, 22050, 44100, 12000, 24000, 48000, 0,
+};
+
+static const uint8_t bitstream_sfreq[] = { 1, 2, 3, 6, 7, 8, 11, 12, 13 };
+
+/* Auditory filter center frequencies and bandwidths, in Hz.
+ * The last two are made up, because there is no scientific data.
+ */
+static uint16_t fc[] = {
+    50, 150, 250, 350, 450, 570, 700, 840, 1000, 1170, 1370, 1600, 1850, 2150,
+    2500, 2900, 3400, 4000, 4800, 5800, 7000, 8500, 10500, 13500, 17000
+};
+
+static uint16_t erb[] = {
+    80, 100, 100, 100, 110, 120, 140, 150, 160, 190, 210, 240, 280,
+    320, 380, 450, 550, 700, 900, 1100, 1300, 1800, 2500, 3500, 4500
+};
+
+static const softfloat stepsize_inv[27] = {
+    {0, 0}, {1342177360, 21}, {2147483647, 21}, {1342177360, 20},
+    {1819901661, 20}, {2147483647, 20}, {1278263843, 19}, {1579032492, 19},
+    {1412817763, 18}, {1220162327, 17}, {1118482133, 16}, {1917391412, 16},
+    {1766017772, 15}, {1525212826, 14}, {1290553940, 13}, {2097179000, 13},
+    {1677683200, 12}, {1497972244, 11}, {1310893147, 10}, {1165354136, 9},
+    {1748031204, 9}, {1542092044, 8}, {1636178017, 7}, {1636178017, 6},
+    {1636178017, 5}, {1636178017, 4}, {1636178017, 3},
+};
+
+static const softfloat scalefactor_inv[128] = {
+    {2147483647, 1}, {2147483647, 1}, {2147483647, 2}, {2147483647, 2},
+    {2147483647, 2}, {2147483647, 2}, {1431655765, 2}, {1431655765, 2},
+    {1431655765, 2}, {2147483647, 3}, {2147483647, 3}, {1717986918, 3},
+    {1431655765, 3}, {1227133513, 3}, {1227133513, 3}, {2147483647, 4},
+    {1717986918, 4}, {1561806289, 4}, {1431655765, 4}, {1227133513, 4},
+    {2147483647, 5}, {1908874353, 5}, {1717986918, 5}, {1493901668, 5},
+    {1321528398, 5}, {1145324612, 5}, {2021161080, 6}, {1808407282, 6},
+    {1561806289, 6}, {1374389534, 6}, {1227133513, 6}, {2147483647, 7},
+    {1908874353, 7}, {1676084798, 7}, {1477838209, 7}, {1296593900, 7},
+    {1145324612, 7}, {2021161080, 8}, {1773405851, 8}, {1561806289, 8},
+    {1374389534, 8}, {1216273924, 8}, {2139127680, 9}, {1882725390, 9},
+    {1660893697, 9}, {1462116526, 9}, {1287484341, 9}, {1135859119, 9},
+    {1999112050, 10}, {1762037865, 10}, {1552982525, 10}, {1367551775, 10},
+    {1205604855, 10}, {2124660150, 11}, {1871509153, 11}, {1648443220, 11},
+    {1452459217, 11}, {1279990253, 11}, {1127704233, 11}, {1987368509, 12},
+    {1750814693, 12}, {1542632939, 12}, {1359099663, 12}, {1197398995, 12},
+    {2109880792, 13}, {1858853132, 13}, {1638006149, 13}, {1443165385, 13},
+    {1271479187, 13}, {1120235993, 13}, {1973767086, 14}, {1739045674, 14},
+    {1532153461, 14}, {1349922194, 14}, {1189384493, 14}, {2095804865, 15},
+    {1846464029, 15}, {1626872524, 15}, {1433347133, 15}, {1262853884, 15},
+    {1112619678, 15}, {1960569045, 16}, {1727349015, 16}, {1521881227, 16},
+    {1340842289, 16}, {1181357555, 16}, {2081669156, 17}, {1834047752, 17},
+    {1615889229, 17}, {1423675973, 17}, {1254322457, 17}, {1105123583, 17},
+    {1947330755, 18}, {1715693602, 18}, {1511607799, 18}, {1331801790, 18},
+    {1173384427, 18}, {2067616532, 19}, {1821667648, 19}, {1604980024, 19},
+    {1414066955, 19}, {1245861410, 19}, {1097665748, 19}, {1934193616, 20},
+    {1704119624, 20}, {1501412075, 20}, {1322817107, 20}, {1165466323, 20},
+    {2053666205, 21}, {1809379407, 21}, {1594151671, 21}, {1404526328, 21},
+    {1237455941, 21}, {1090259329, 21}, {1921143210, 22}, {1692621231, 22},
+    {1491281857, 22}, {1313892269, 22}, {1157603482, 22}, {2039810470, 23},
+    {1797172644, 23}, {1583396912, 23}, {1395050052, 23}, {1229107276, 23},
+    {1082903494, 23}, {1082903494, 23}, {1082903494, 23}, {1082903494, 23},
+};
+
+/* manually derived from
+ * Table B.5: Selection of quantization levels and codebooks
+ * FIXME: will become invalid when Huffman codes are introduced.
+ */
+static const int bit_consumption[27] = {
+    -8, 28, 40, 48, 52, 60, 68, 76, 80, 96,
+    112, 128, 144, 160, 176, 192, 208, 224, 240, 256,
+    272, 288, 304, 320, 336, 352, 368,
+};
+
+/* Table B.5: Selection of quantization levels and codebooks */
+static const int quant_levels[27] = {
+    1, 3, 5, 7, 9, 13, 17, 25, 32, 64,
+    128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536,
+    131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608,
 };
 
 #endif /* AVCODEC_DCAENC_H */
diff --git a/libavcodec/dct.c b/libavcodec/dct.c
index e2ac0a8..b1ee06a 100644
--- a/libavcodec/dct.c
+++ b/libavcodec/dct.c
@@ -40,7 +40,7 @@
 /* cos((M_PI * x / (2 * n)) */
 #define COS(s, n, x) (s->costab[x])
 
-static void ff_dst_calc_I_c(DCTContext *ctx, FFTSample *data)
+static void dst_calc_I_c(DCTContext *ctx, FFTSample *data)
 {
     int n = 1 << ctx->nbits;
     int i;
@@ -70,7 +70,7 @@
     data[n - 1] = 0;
 }
 
-static void ff_dct_calc_I_c(DCTContext *ctx, FFTSample *data)
+static void dct_calc_I_c(DCTContext *ctx, FFTSample *data)
 {
     int n = 1 << ctx->nbits;
     int i;
@@ -100,7 +100,7 @@
         data[i] = data[i - 2] - data[i];
 }
 
-static void ff_dct_calc_III_c(DCTContext *ctx, FFTSample *data)
+static void dct_calc_III_c(DCTContext *ctx, FFTSample *data)
 {
     int n = 1 << ctx->nbits;
     int i;
@@ -133,7 +133,7 @@
     }
 }
 
-static void ff_dct_calc_II_c(DCTContext *ctx, FFTSample *data)
+static void dct_calc_II_c(DCTContext *ctx, FFTSample *data)
 {
     int n = 1 << ctx->nbits;
     int i;
@@ -201,10 +201,10 @@
             s->csc2[i] = 0.5 / sin((M_PI / (2 * n) * (2 * i + 1)));
 
         switch (inverse) {
-        case DCT_I  : s->dct_calc = ff_dct_calc_I_c;   break;
-        case DCT_II : s->dct_calc = ff_dct_calc_II_c;  break;
-        case DCT_III: s->dct_calc = ff_dct_calc_III_c; break;
-        case DST_I  : s->dct_calc = ff_dst_calc_I_c;   break;
+        case DCT_I  : s->dct_calc = dct_calc_I_c;   break;
+        case DCT_II : s->dct_calc = dct_calc_II_c;  break;
+        case DCT_III: s->dct_calc = dct_calc_III_c; break;
+        case DST_I  : s->dct_calc = dst_calc_I_c;   break;
         }
     }
 
diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c
index 6a095b2..bba7626 100644
--- a/libavcodec/dfa.c
+++ b/libavcodec/dfa.c
@@ -254,6 +254,9 @@
             y        += skip_lines;
             segments = bytestream2_get_le16(gb);
         }
+
+        if (frame_end <= frame)
+            return AVERROR_INVALIDDATA;
         if (segments & 0x8000) {
             frame[width - 1] = segments & 0xFF;
             segments = bytestream2_get_le16(gb);
diff --git a/libavcodec/dirac_dwt.c b/libavcodec/dirac_dwt.c
index a2848f0..bbd8ec7 100644
--- a/libavcodec/dirac_dwt.c
+++ b/libavcodec/dirac_dwt.c
@@ -569,17 +569,3 @@
     }
 }
 
-int ff_spatial_idwt2(IDWTELEM *buffer, int width, int height, int stride,
-                     enum dwt_type type, int decomposition_count, IDWTELEM *temp)
-{
-    DWTContext d;
-    int y;
-
-    if (ff_spatial_idwt_init2(&d, buffer, width, height, stride, type, decomposition_count, temp))
-        return -1;
-
-    for (y = 0; y < d.height; y += 4)
-        ff_spatial_idwt_slice2(&d, y);
-
-    return 0;
-}
diff --git a/libavcodec/dirac_dwt.h b/libavcodec/dirac_dwt.h
index 9514e95..25c13d1 100644
--- a/libavcodec/dirac_dwt.h
+++ b/libavcodec/dirac_dwt.h
@@ -80,9 +80,6 @@
                           int stride, enum dwt_type type, int decomposition_count,
                           IDWTELEM *temp);
 
-int ff_spatial_idwt2(IDWTELEM *buffer, int width, int height, int stride,
-                     enum dwt_type type, int decomposition_count, IDWTELEM *temp);
-
 void ff_spatial_idwt_slice2(DWTContext *d, int y);
 
 // shared stuff for simd optimiztions
diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c
index 81d2b65..7468280 100644
--- a/libavcodec/diracdec.c
+++ b/libavcodec/diracdec.c
@@ -567,7 +567,7 @@
     if (!b->length)
         return;
 
-    init_get_bits(&gb, b->coeff_data, b->length*8);
+    init_get_bits8(&gb, b->coeff_data, b->length);
 
     if (is_arith)
         ff_dirac_init_arith_decoder(&c, &gb, b->length);
diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c
index 11bed00..e96369b 100644
--- a/libavcodec/dnxhddec.c
+++ b/libavcodec/dnxhddec.c
@@ -22,9 +22,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-//#define TRACE
-//#define DEBUG
-
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
 #include "get_bits.h"
diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c
index 4b6ce2f..6bfd88a 100644
--- a/libavcodec/dnxhdenc.c
+++ b/libavcodec/dnxhdenc.c
@@ -23,9 +23,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-//#define DEBUG
 #define RC_VARIANCE 1 // use variance or ssd for fast rc
 
+#include "libavutil/attributes.h"
 #include "libavutil/internal.h"
 #include "libavutil/opt.h"
 #include "avcodec.h"
@@ -43,7 +43,7 @@
 {NULL}
 };
 
-static const AVClass class = {
+static const AVClass dnxhd_class = {
     .class_name = "dnxhd",
     .item_name  = av_default_item_name,
     .option     = options,
@@ -115,7 +115,7 @@
     return last_non_zero;
 }
 
-static int dnxhd_init_vlc(DNXHDEncContext *ctx)
+static av_cold int dnxhd_init_vlc(DNXHDEncContext *ctx)
 {
     int i, j, level, run;
     int max_level = 1<<(ctx->cid_table->bit_depth+2);
@@ -170,7 +170,7 @@
     return -1;
 }
 
-static int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias)
+static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias)
 {
     // init first elem to 1 to avoid div by 0 in convert_matrix
     uint16_t weight_matrix[64] = {1,}; // convert_matrix needs uint16_t*
@@ -234,7 +234,7 @@
     return -1;
 }
 
-static int dnxhd_init_rc(DNXHDEncContext *ctx)
+static av_cold int dnxhd_init_rc(DNXHDEncContext *ctx)
 {
     FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_rc, 8160*ctx->m.avctx->qmax*sizeof(RCEntry), fail);
     if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD)
@@ -248,7 +248,7 @@
     return -1;
 }
 
-static int dnxhd_encode_init(AVCodecContext *avctx)
+static av_cold int dnxhd_encode_init(AVCodecContext *avctx)
 {
     DNXHDEncContext *ctx = avctx->priv_data;
     int i, index, bit_depth;
@@ -353,7 +353,7 @@
 static int dnxhd_write_header(AVCodecContext *avctx, uint8_t *buf)
 {
     DNXHDEncContext *ctx = avctx->priv_data;
-    const uint8_t header_prefix[5] = { 0x00,0x00,0x02,0x80,0x01 };
+    static const uint8_t header_prefix[5] = { 0x00,0x00,0x02,0x80,0x01 };
 
     memset(buf, 0, 640);
 
@@ -1002,7 +1002,7 @@
     return 0;
 }
 
-static int dnxhd_encode_end(AVCodecContext *avctx)
+static av_cold int dnxhd_encode_end(AVCodecContext *avctx)
 {
     DNXHDEncContext *ctx = avctx->priv_data;
     int max_level = 1<<(ctx->cid_table->bit_depth+2);
@@ -1049,6 +1049,6 @@
                                                   AV_PIX_FMT_YUV422P10,
                                                   AV_PIX_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("VC3/DNxHD"),
-    .priv_class     = &class,
+    .priv_class     = &dnxhd_class,
     .defaults       = dnxhd_defaults,
 };
diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c
index 2fd5bdc..a910eac5 100644
--- a/libavcodec/dpx.c
+++ b/libavcodec/dpx.c
@@ -244,11 +244,9 @@
     case 16:
         elements *= 2;
     case 8:
-        for (x = 0; x < avctx->height; x++) {
-            memcpy(ptr[0], buf, elements*avctx->width);
-            ptr[0] += p->linesize[0];
-            buf += elements*avctx->width;
-        }
+        av_image_copy_plane(ptr[0], p->linesize[0],
+                            buf, elements * avctx->width,
+                            elements * avctx->width, avctx->height);
         break;
     }
 
diff --git a/libavcodec/dpxenc.c b/libavcodec/dpxenc.c
index f210bbc..c3e4398 100644
--- a/libavcodec/dpxenc.c
+++ b/libavcodec/dpxenc.c
@@ -26,7 +26,6 @@
 #include "internal.h"
 
 typedef struct DPXContext {
-    AVFrame picture;
     int big_endian;
     int bits_per_component;
     int descriptor;
@@ -36,44 +35,27 @@
 static av_cold int encode_init(AVCodecContext *avctx)
 {
     DPXContext *s = avctx->priv_data;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
 
-    avctx->coded_frame = &s->picture;
-    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
-    avctx->coded_frame->key_frame = 1;
-
-    s->big_endian         = 1;
-    s->bits_per_component = 8;
-    s->descriptor         = 50; /* RGB */
-    s->planar             = 0;
+    s->big_endian         = !!(desc->flags & AV_PIX_FMT_FLAG_BE);
+    s->bits_per_component = desc->comp[0].depth_minus1 + 1;
+    s->descriptor         = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) ? 51 : 50;
+    s->planar             = !!(desc->flags & AV_PIX_FMT_FLAG_PLANAR);
 
     switch (avctx->pix_fmt) {
+    case AV_PIX_FMT_GBRP10BE:
+    case AV_PIX_FMT_GBRP10LE:
+    case AV_PIX_FMT_GBRP12BE:
+    case AV_PIX_FMT_GBRP12LE:
     case AV_PIX_FMT_RGB24:
-        break;
+    case AV_PIX_FMT_RGBA64BE:
+    case AV_PIX_FMT_RGBA64LE:
     case AV_PIX_FMT_RGBA:
-        s->descriptor = 51; /* RGBA */
         break;
     case AV_PIX_FMT_RGB48LE:
-        s->big_endian = 0;
     case AV_PIX_FMT_RGB48BE:
-        s->bits_per_component = avctx->bits_per_raw_sample ? avctx->bits_per_raw_sample : 16;
-        break;
-    case AV_PIX_FMT_RGBA64LE:
-        s->big_endian = 0;
-    case AV_PIX_FMT_RGBA64BE:
-        s->descriptor = 51;
-        s->bits_per_component = 16;
-        break;
-    case AV_PIX_FMT_GBRP10LE:
-        s->big_endian = 0;
-    case AV_PIX_FMT_GBRP10BE:
-        s->bits_per_component = 10;
-        s->planar = 1;
-        break;
-    case AV_PIX_FMT_GBRP12LE:
-        s->big_endian = 0;
-    case AV_PIX_FMT_GBRP12BE:
-        s->bits_per_component = 12;
-        s->planar = 1;
+        if (avctx->bits_per_raw_sample)
+            s->bits_per_component = avctx->bits_per_raw_sample;
         break;
     default:
         av_log(avctx, AV_LOG_INFO, "unsupported pixel format\n");
@@ -132,11 +114,11 @@
             if (s->big_endian) {
                 value = (AV_RB16(src[0] + 2*x) << 12)
                       | (AV_RB16(src[1] + 2*x) << 2)
-                      | (AV_RB16(src[2] + 2*x) << 22);
+                      | ((unsigned)AV_RB16(src[2] + 2*x) << 22);
             } else {
                 value = (AV_RL16(src[0] + 2*x) << 12)
                       | (AV_RL16(src[1] + 2*x) << 2)
-                      | (AV_RL16(src[2] + 2*x) << 22);
+                      | ((unsigned)AV_RL16(src[2] + 2*x) << 22);
             }
             write32(dst, value);
             dst += 4;
@@ -252,23 +234,18 @@
 }
 
 AVCodec ff_dpx_encoder = {
-    .name = "dpx",
-    .type = AVMEDIA_TYPE_VIDEO,
-    .id   = AV_CODEC_ID_DPX,
+    .name           = "dpx",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_DPX,
     .priv_data_size = sizeof(DPXContext),
-    .init   = encode_init,
-    .encode2 = encode_frame,
-    .pix_fmts = (const enum AVPixelFormat[]){
-        AV_PIX_FMT_RGB24,
-        AV_PIX_FMT_RGBA,
-        AV_PIX_FMT_RGB48LE,
-        AV_PIX_FMT_RGB48BE,
-        AV_PIX_FMT_RGBA64LE,
-        AV_PIX_FMT_RGBA64BE,
-        AV_PIX_FMT_GBRP10LE,
-        AV_PIX_FMT_GBRP10BE,
-        AV_PIX_FMT_GBRP12LE,
-        AV_PIX_FMT_GBRP12BE,
+    .init           = encode_init,
+    .encode2        = encode_frame,
+    .pix_fmts       = (const enum AVPixelFormat[]){
+        AV_PIX_FMT_RGB24,    AV_PIX_FMT_RGBA,
+        AV_PIX_FMT_RGB48LE,  AV_PIX_FMT_RGB48BE,
+        AV_PIX_FMT_RGBA64LE, AV_PIX_FMT_RGBA64BE,
+        AV_PIX_FMT_GBRP10LE, AV_PIX_FMT_GBRP10BE,
+        AV_PIX_FMT_GBRP12LE, AV_PIX_FMT_GBRP12BE,
         AV_PIX_FMT_NONE},
-    .long_name = NULL_IF_CONFIG_SMALL("DPX image"),
+    .long_name     = NULL_IF_CONFIG_SMALL("DPX image"),
 };
diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c
index f0e8f02..55c2742 100644
--- a/libavcodec/dsicinav.c
+++ b/libavcodec/dsicinav.c
@@ -127,27 +127,30 @@
     return 0;
 }
 
-static void cin_apply_delta_data(const unsigned char *src, unsigned char *dst, int size)
+static void cin_apply_delta_data(const unsigned char *src, unsigned char *dst,
+                                 int size)
 {
     while (size--)
         *dst++ += *src++;
 }
 
-static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
+static int cin_decode_huffman(const unsigned char *src, int src_size,
+                              unsigned char *dst, int dst_size)
 {
     int b, huff_code = 0;
     unsigned char huff_code_table[15];
-    unsigned char *dst_cur = dst;
-    unsigned char *dst_end = dst + dst_size;
+    unsigned char *dst_cur       = dst;
+    unsigned char *dst_end       = dst + dst_size;
     const unsigned char *src_end = src + src_size;
 
-    memcpy(huff_code_table, src, 15); src += 15;
+    memcpy(huff_code_table, src, 15);
+    src += 15;
 
     while (src < src_end) {
         huff_code = *src++;
         if ((huff_code >> 4) == 15) {
-            b = huff_code << 4;
-            huff_code = *src++;
+            b          = huff_code << 4;
+            huff_code  = *src++;
             *dst_cur++ = b | (huff_code >> 4);
         } else
             *dst_cur++ = huff_code_table[huff_code >> 4];
@@ -166,11 +169,12 @@
     return dst_cur - dst;
 }
 
-static int cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
+static int cin_decode_lzss(const unsigned char *src, int src_size,
+                           unsigned char *dst, int dst_size)
 {
     uint16_t cmd;
     int i, sz, offset, code;
-    unsigned char *dst_end = dst + dst_size, *dst_start = dst;
+    unsigned char *dst_end       = dst + dst_size, *dst_start = dst;
     const unsigned char *src_end = src + src_size;
 
     while (src < src_end && dst < dst_end) {
@@ -179,13 +183,15 @@
             if (code & (1 << i)) {
                 *dst++ = *src++;
             } else {
-                cmd = AV_RL16(src); src += 2;
+                cmd    = AV_RL16(src);
+                src   += 2;
                 offset = cmd >> 4;
-                if ((int) (dst - dst_start) < offset + 1)
+                if ((int)(dst - dst_start) < offset + 1)
                     return AVERROR_INVALIDDATA;
                 sz = (cmd & 0xF) + 2;
-                /* don't use memcpy/memmove here as the decoding routine (ab)uses */
-                /* buffer overlappings to repeat bytes in the destination */
+                /* don't use memcpy/memmove here as the decoding routine
+                 * (ab)uses buffer overlappings to repeat bytes in the
+                 * destination */
                 sz = FFMIN(sz, dst_end - dst);
                 while (sz--) {
                     *dst = *(dst - offset - 1);
@@ -198,10 +204,11 @@
     return 0;
 }
 
-static int cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
+static int cin_decode_rle(const unsigned char *src, int src_size,
+                           unsigned char *dst, int dst_size)
 {
     int len, code;
-    unsigned char *dst_end = dst + dst_size;
+    unsigned char *dst_end       = dst + dst_size;
     const unsigned char *src_end = src + src_size;
 
     while (src + 1 < src_end && dst < dst_end) {
@@ -215,7 +222,7 @@
                 av_log(NULL, AV_LOG_ERROR, "RLE overread\n");
                 return AVERROR_INVALIDDATA;
             }
-            memcpy(dst, src, FFMIN(len, dst_end - dst));
+            memcpy(dst, src, FFMIN3(len, dst_end - dst, src_end - src));
             src += len;
         }
         dst += len;
@@ -227,15 +234,16 @@
                                  void *data, int *got_frame,
                                  AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
+    const uint8_t *buf   = avpkt->data;
+    int buf_size         = avpkt->size;
     CinVideoContext *cin = avctx->priv_data;
-    int i, y, palette_type, palette_colors_count, bitmap_frame_type, bitmap_frame_size, res = 0;
+    int i, y, palette_type, palette_colors_count,
+        bitmap_frame_type, bitmap_frame_size, res = 0;
 
-    palette_type = buf[0];
-    palette_colors_count = AV_RL16(buf+1);
-    bitmap_frame_type = buf[3];
-    buf += 4;
+    palette_type         = buf[0];
+    palette_colors_count = AV_RL16(buf + 1);
+    bitmap_frame_type    = buf[3];
+    buf                 += 4;
 
     bitmap_frame_size = buf_size - 4;
 
@@ -246,46 +254,48 @@
         if (palette_colors_count > 256)
             return AVERROR_INVALIDDATA;
         for (i = 0; i < palette_colors_count; ++i) {
-            cin->palette[i] = 0xFFU << 24 | bytestream_get_le24(&buf);
+            cin->palette[i]    = 0xFFU << 24 | bytestream_get_le24(&buf);
             bitmap_frame_size -= 3;
         }
     } else {
         for (i = 0; i < palette_colors_count; ++i) {
-            cin->palette[buf[0]] = 0xFFU << 24 | AV_RL24(buf+1);
-            buf += 4;
-            bitmap_frame_size -= 4;
+            cin->palette[buf[0]] = 0xFFU << 24 | AV_RL24(buf + 1);
+            buf                 += 4;
+            bitmap_frame_size   -= 4;
         }
     }
 
-    /* note: the decoding routines below assumes that surface.width = surface.pitch */
+    /* note: the decoding routines below assumes that
+     * surface.width = surface.pitch */
     switch (bitmap_frame_type) {
     case 9:
         cin_decode_rle(buf, bitmap_frame_size,
-          cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
+                       cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
         break;
     case 34:
         cin_decode_rle(buf, bitmap_frame_size,
-          cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
+                       cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
         cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
-          cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
+                             cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
         break;
     case 35:
         bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size,
-          cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
+                           cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
         cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
-          cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
+                       cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
         break;
     case 36:
         bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size,
-          cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
+                                               cin->bitmap_table[CIN_INT_BMP],
+                                               cin->bitmap_size);
         cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
-          cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
+                       cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
         cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
-          cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
+                             cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
         break;
     case 37:
         cin_decode_huffman(buf, bitmap_frame_size,
-          cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
+                           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
         break;
     case 38:
         res = cin_decode_lzss(buf, bitmap_frame_size,
@@ -301,7 +311,7 @@
         if (res < 0)
             return res;
         cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
-          cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
+                             cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
         break;
     }
 
@@ -312,10 +322,11 @@
     cin->frame.palette_has_changed = 1;
     for (y = 0; y < cin->avctx->height; ++y)
         memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0],
-          cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width,
-          cin->avctx->width);
+               cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width,
+               cin->avctx->width);
 
-    FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_table[CIN_PRE_BMP]);
+    FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP],
+                      cin->bitmap_table[CIN_PRE_BMP]);
 
     if ((res = av_frame_ref(data, &cin->frame)) < 0)
         return res;
@@ -352,9 +363,9 @@
 static int cinaudio_decode_frame(AVCodecContext *avctx, void *data,
                                  int *got_frame_ptr, AVPacket *avpkt)
 {
-    AVFrame *frame     = data;
-    const uint8_t *buf = avpkt->data;
-    CinAudioContext *cin = avctx->priv_data;
+    AVFrame *frame         = data;
+    const uint8_t *buf     = avpkt->data;
+    CinAudioContext *cin   = avctx->priv_data;
     const uint8_t *buf_end = buf + avpkt->size;
     int16_t *samples;
     int delta, ret;
@@ -368,13 +379,13 @@
     delta = cin->delta;
     if (cin->initial_decode_frame) {
         cin->initial_decode_frame = 0;
-        delta = sign_extend(AV_RL16(buf), 16);
-        buf += 2;
-        *samples++ = delta;
+        delta                     = sign_extend(AV_RL16(buf), 16);
+        buf                      += 2;
+        *samples++                = delta;
     }
     while (buf < buf_end) {
-        delta += cinaudio_delta16_table[*buf++];
-        delta = av_clip_int16(delta);
+        delta     += cinaudio_delta16_table[*buf++];
+        delta      = av_clip_int16(delta);
         *samples++ = delta;
     }
     cin->delta = delta;
@@ -384,7 +395,6 @@
     return avpkt->size;
 }
 
-
 AVCodec ff_dsicinvideo_decoder = {
     .name           = "dsicinvideo",
     .type           = AVMEDIA_TYPE_VIDEO,
diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c
index d1e466a..b434589 100644
--- a/libavcodec/dsputil.c
+++ b/libavcodec/dsputil.c
@@ -27,6 +27,7 @@
  * DSP utils
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/internal.h"
 #include "avcodec.h"
@@ -107,7 +108,9 @@
 
 static const uint8_t idct_sse2_row_perm[8] = {0, 4, 1, 5, 2, 6, 3, 7};
 
-void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable){
+av_cold void ff_init_scantable(uint8_t *permutation, ScanTable *st,
+                               const uint8_t *src_scantable)
+{
     int i;
     int end;
 
@@ -128,8 +131,8 @@
     }
 }
 
-void ff_init_scantable_permutation(uint8_t *idct_permutation,
-                                   int idct_permutation_type)
+av_cold void ff_init_scantable_permutation(uint8_t *idct_permutation,
+                                           int idct_permutation_type)
 {
     int i;
 
@@ -2598,12 +2601,12 @@
     } while (len > 0);
 }
 
-static void ff_jref_idct_put(uint8_t *dest, int line_size, int16_t *block)
+static void jref_idct_put(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_j_rev_dct (block);
     put_pixels_clamped_c(block, dest, line_size);
 }
-static void ff_jref_idct_add(uint8_t *dest, int line_size, int16_t *block)
+static void jref_idct_add(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_j_rev_dct (block);
     add_pixels_clamped_c(block, dest, line_size);
@@ -2719,8 +2722,8 @@
             c->idct_permutation_type = FF_NO_IDCT_PERM;
         } else {
         if(avctx->idct_algo==FF_IDCT_INT){
-            c->idct_put= ff_jref_idct_put;
-            c->idct_add= ff_jref_idct_add;
+            c->idct_put= jref_idct_put;
+            c->idct_add= jref_idct_add;
             c->idct    = ff_j_rev_dct;
             c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM;
         }else if(avctx->idct_algo==FF_IDCT_FAAN){
diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h
index 07a95af..4381caa 100644
--- a/libavcodec/dsputil.h
+++ b/libavcodec/dsputil.h
@@ -34,9 +34,6 @@
 #include "avcodec.h"
 #include "rnd_avg.h"
 
-
-//#define DEBUG
-
 /* encoding scans */
 extern const uint8_t ff_alternate_horizontal_scan[64];
 extern const uint8_t ff_alternate_vertical_scan[64];
diff --git a/libavcodec/dv.c b/libavcodec/dv.c
index 39a87a9..5a62bf2 100644
--- a/libavcodec/dv.c
+++ b/libavcodec/dv.c
@@ -351,11 +351,6 @@
 static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5;
 static const int mb_area_start[5] = { 1, 6, 21, 43, 64 };
 
-static inline int put_bits_left(PutBitContext* s)
-{
-    return (s->buf_end - s->buf) * 8 - put_bits_count(s);
-}
-
 #if CONFIG_SMALL
 /* Converts run and level (where level != 0) pair into VLC, returning bit size */
 static av_always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc)
@@ -556,7 +551,7 @@
 
           if (level + 15 > 30U) {
               bi->sign[i] = (level >> 31) & 1;
-              /* weight it and and shift down into range, adding for rounding */
+              /* weight it and shift down into range, adding for rounding */
               /* the extra division by a factor of 2^4 reverses the 8x expansion of the DCT
                  AND the 2x doubling of the weights */
               level = (FFABS(level) * weight[i] + (1 << (dv_weight_bits+3))) >> (dv_weight_bits+4);
diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c
index 6cc40b7..19c31dc 100644
--- a/libavcodec/dvdsubdec.c
+++ b/libavcodec/dvdsubdec.c
@@ -21,13 +21,12 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "dsputil.h"
+#include "libavutil/attributes.h"
 #include "libavutil/colorspace.h"
 #include "libavutil/opt.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/avstring.h"
 
-//#define DEBUG
-
 typedef struct DVDSubContext
 {
   AVClass *class;
@@ -565,7 +564,7 @@
     return 1;
 }
 
-static int dvdsub_init(AVCodecContext *avctx)
+static av_cold int dvdsub_init(AVCodecContext *avctx)
 {
     DVDSubContext *ctx = avctx->priv_data;
     int ret;
@@ -592,7 +591,7 @@
     { "palette", "set the global palette", OFFSET(palette_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VD },
     { NULL }
 };
-static const AVClass class = {
+static const AVClass dvdsub_class = {
     .class_name = "dvdsubdec",
     .item_name  = av_default_item_name,
     .option     = options,
@@ -607,5 +606,5 @@
     .init           = dvdsub_init,
     .decode         = dvdsub_decode,
     .long_name      = NULL_IF_CONFIG_SMALL("DVD subtitles"),
-    .priv_class     = &class,
+    .priv_class     = &dvdsub_class,
 };
diff --git a/libavcodec/dxa.c b/libavcodec/dxa.c
index 2286f33..36fef90 100644
--- a/libavcodec/dxa.c
+++ b/libavcodec/dxa.c
@@ -39,7 +39,7 @@
  * Decoder context
  */
 typedef struct DxaDecContext {
-    AVFrame prev;
+    AVFrame *prev;
 
     int dsize;
     uint8_t *decomp_buf;
@@ -71,6 +71,11 @@
             case 4: // motion compensation
                 x = (*mv) >> 4;    if(x & 8) x = 8 - x;
                 y = (*mv++) & 0xF; if(y & 8) y = 8 - y;
+                if (i < -x || avctx->width  - i - 4 < x ||
+                    j < -y || avctx->height - j - 4 < y) {
+                    av_log(avctx, AV_LOG_ERROR, "MV %d %d out of bounds\n", x,y);
+                    return AVERROR_INVALIDDATA;
+                }
                 tmp2 += x + y*stride;
             case 0: // skip
             case 5: // skip in method 12
@@ -128,6 +133,11 @@
                     case 0x80: // motion compensation
                         x = (*mv) >> 4;    if(x & 8) x = 8 - x;
                         y = (*mv++) & 0xF; if(y & 8) y = 8 - y;
+                        if (i + 2*(k & 1) < -x || avctx->width  - i - 2*(k & 1) - 2 < x ||
+                            j +   (k & 2) < -y || avctx->height - j -   (k & 2) - 2 < y) {
+                            av_log(avctx, AV_LOG_ERROR, "MV %d %d out of bounds\n", x,y);
+                            return AVERROR_INVALIDDATA;
+                        }
                         tmp2 += x + y*stride;
                     case 0x00: // skip
                         tmp[d + 0         ] = tmp2[0];
@@ -219,7 +229,7 @@
 
     outptr = frame->data[0];
     srcptr = c->decomp_buf;
-    tmpptr = c->prev.data[0];
+    tmpptr = c->prev->data[0];
     stride = frame->linesize[0];
 
     if (bytestream2_get_le32(&gb) == MKTAG('N','U','L','L'))
@@ -236,12 +246,16 @@
             return AVERROR_UNKNOWN;
         }
     }
+
+    if (avctx->debug & FF_DEBUG_PICT_INFO)
+        av_log(avctx, AV_LOG_DEBUG, "compr:%2d, dsize:%d\n", compr, (int)dsize);
+
     switch(compr){
     case -1:
         frame->key_frame = 0;
         frame->pict_type = AV_PICTURE_TYPE_P;
-        if(c->prev.data[0])
-            memcpy(frame->data[0], c->prev.data[0], frame->linesize[0] * avctx->height);
+        if (c->prev->data[0])
+            memcpy(frame->data[0], c->prev->data[0], frame->linesize[0] * avctx->height);
         else{ // Should happen only when first frame is 'NULL'
             memset(frame->data[0], 0, frame->linesize[0] * avctx->height);
             frame->key_frame = 1;
@@ -249,13 +263,26 @@
         }
         break;
     case 2:
-    case 3:
     case 4:
+        frame->key_frame = 1;
+        frame->pict_type = AV_PICTURE_TYPE_I;
+        for (j = 0; j < avctx->height; j++) {
+                memcpy(outptr, srcptr, avctx->width);
+            outptr += stride;
+            srcptr += avctx->width;
+        }
+        break;
+    case 3:
     case 5:
-        frame->key_frame = !(compr & 1);
-        frame->pict_type = (compr & 1) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
-        for(j = 0; j < avctx->height; j++){
-            if((compr & 1) && tmpptr){
+        if (!tmpptr) {
+            av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
+            if (!(avctx->flags2 & CODEC_FLAG2_SHOW_ALL))
+                return AVERROR_INVALIDDATA;
+        }
+        frame->key_frame = 0;
+        frame->pict_type = AV_PICTURE_TYPE_P;
+        for (j = 0; j < avctx->height; j++) {
+            if(tmpptr){
                 for(i = 0; i < avctx->width; i++)
                     outptr[i] = srcptr[i] ^ tmpptr[i];
                 tmpptr += stride;
@@ -269,19 +296,19 @@
     case 13:
         frame->key_frame = 0;
         frame->pict_type = AV_PICTURE_TYPE_P;
-        if (!c->prev.data[0]) {
+        if (!c->prev->data[0]) {
             av_log(avctx, AV_LOG_ERROR, "Missing reference frame\n");
             return AVERROR_INVALIDDATA;
         }
-        decode_13(avctx, c, frame->data[0], frame->linesize[0], srcptr, c->prev.data[0]);
+        decode_13(avctx, c, frame->data[0], frame->linesize[0], srcptr, c->prev->data[0]);
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "Unknown/unsupported compression type %d\n", compr);
         return AVERROR_INVALIDDATA;
     }
 
-    av_frame_unref(&c->prev);
-    if ((ret = av_frame_ref(&c->prev, frame)) < 0)
+    av_frame_unref(c->prev);
+    if ((ret = av_frame_ref(c->prev, frame)) < 0)
         return ret;
 
     *got_frame = 1;
@@ -296,11 +323,14 @@
 
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
-    avcodec_get_frame_defaults(&c->prev);
+    c->prev = av_frame_alloc();
+    if (!c->prev)
+        return AVERROR(ENOMEM);
 
     c->dsize = avctx->width * avctx->height * 2;
     c->decomp_buf = av_malloc(c->dsize);
     if (!c->decomp_buf) {
+        av_frame_free(&c->prev);
         av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
         return AVERROR(ENOMEM);
     }
@@ -313,7 +343,7 @@
     DxaDecContext * const c = avctx->priv_data;
 
     av_freep(&c->decomp_buf);
-    av_frame_unref(&c->prev);
+    av_frame_free(&c->prev);
 
     return 0;
 }
diff --git a/libavcodec/dxtory.c b/libavcodec/dxtory.c
index 28e66ba..17d0bbb 100644
--- a/libavcodec/dxtory.c
+++ b/libavcodec/dxtory.c
@@ -20,44 +20,31 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#define BITSTREAM_READER_LE
 #include "avcodec.h"
+#include "bytestream.h"
+#include "get_bits.h"
 #include "internal.h"
+#include "unary.h"
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 
-static av_cold int decode_init(AVCodecContext *avctx)
-{
-    avctx->pix_fmt     = AV_PIX_FMT_YUV420P;
-
-    return 0;
-}
-
-static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
-                        AVPacket *avpkt)
+static int dxtory_decode_v1(AVCodecContext *avctx, AVFrame *pic,
+                            const uint8_t *src, int src_size)
 {
     int h, w;
-    AVFrame *pic = data;
-    const uint8_t *src = avpkt->data;
     uint8_t *Y1, *Y2, *U, *V;
     int ret;
 
-    if (avpkt->size < avctx->width * avctx->height * 3 / 2 + 16) {
+    if (src_size < avctx->width * avctx->height * 3 / 2) {
         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
         return AVERROR_INVALIDDATA;
     }
 
+    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
         return ret;
 
-    pic->pict_type = AV_PICTURE_TYPE_I;
-    pic->key_frame = 1;
-
-    if (AV_RL32(src) != 0x01000002) {
-        avpriv_request_sample(avctx, "Frame header %X", AV_RL32(src));
-        return AVERROR_PATCHWELCOME;
-    }
-    src += 16;
-
     Y1 = pic->data[0];
     Y2 = pic->data[0] + pic->linesize[0];
     U  = pic->data[1];
@@ -76,6 +63,154 @@
         V  += pic->linesize[2];
     }
 
+    return 0;
+}
+
+static const uint8_t def_lru[8] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xFF };
+
+static inline uint8_t decode_sym(GetBitContext *gb, uint8_t lru[8])
+{
+    uint8_t c, val;
+
+    c = get_unary(gb, 0, 8);
+    if (!c) {
+        val = get_bits(gb, 8);
+        memmove(lru + 1, lru, sizeof(*lru) * (8 - 1));
+    } else {
+        val = lru[c - 1];
+        memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
+    }
+    lru[0] = val;
+
+    return val;
+}
+
+static int dx2_decode_slice(GetBitContext *gb, int width, int height,
+                            uint8_t *Y, uint8_t *U, uint8_t *V,
+                            int ystride, int ustride, int vstride)
+{
+    int x, y, i;
+    uint8_t lru[3][8];
+
+    for (i = 0; i < 3; i++)
+        memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
+
+    for (y = 0; y < height; y+=2) {
+        for (x = 0; x < width; x += 2) {
+            Y[x + 0 + 0 * ystride] = decode_sym(gb, lru[0]);
+            Y[x + 1 + 0 * ystride] = decode_sym(gb, lru[0]);
+            Y[x + 0 + 1 * ystride] = decode_sym(gb, lru[0]);
+            Y[x + 1 + 1 * ystride] = decode_sym(gb, lru[0]);
+            U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80;
+            V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80;
+        }
+
+        Y += ystride << 1;
+        U += ustride;
+        V += vstride;
+    }
+
+    return 0;
+}
+
+static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic,
+                            const uint8_t *src, int src_size)
+{
+    GetByteContext gb;
+    GetBitContext  gb2;
+    int nslices, slice, slice_height;
+    uint32_t off, slice_size;
+    uint8_t *Y, *U, *V;
+    int ret;
+
+    bytestream2_init(&gb, src, src_size);
+    nslices = bytestream2_get_le16(&gb);
+    off = FFALIGN(nslices * 4 + 2, 16);
+    if (src_size < off) {
+        av_log(avctx, AV_LOG_ERROR, "no slice data\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (!nslices || avctx->height % nslices) {
+        avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
+                              avctx->width, avctx->height);
+        return AVERROR(ENOSYS);
+    }
+
+    slice_height = avctx->height / nslices;
+    if ((avctx->width & 1) || (slice_height & 1)) {
+        avpriv_request_sample(avctx, "slice dimensions %dx%d",
+                              avctx->width, slice_height);
+    }
+
+    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
+        return ret;
+
+    Y = pic->data[0];
+    U = pic->data[1];
+    V = pic->data[2];
+
+    for (slice = 0; slice < nslices; slice++) {
+        slice_size = bytestream2_get_le32(&gb);
+        if (slice_size > src_size - off) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "invalid slice size %d (only %d bytes left)\n",
+                   slice_size, src_size - off);
+            return AVERROR_INVALIDDATA;
+        }
+        if (slice_size <= 16) {
+            av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n", slice_size);
+            return AVERROR_INVALIDDATA;
+        }
+
+        if (AV_RL32(src + off) != slice_size - 16) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "Slice sizes mismatch: got %d instead of %d\n",
+                   AV_RL32(src + off), slice_size - 16);
+        }
+        init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);
+        dx2_decode_slice(&gb2, avctx->width, slice_height, Y, U, V,
+                         pic->linesize[0], pic->linesize[1], pic->linesize[2]);
+
+        Y += pic->linesize[0] *  slice_height;
+        U += pic->linesize[1] * (slice_height >> 1);
+        V += pic->linesize[2] * (slice_height >> 1);
+        off += slice_size;
+    }
+
+    return 0;
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+                        AVPacket *avpkt)
+{
+    AVFrame *pic = data;
+    const uint8_t *src = avpkt->data;
+    int ret;
+
+    if (avpkt->size < 16) {
+        av_log(avctx, AV_LOG_ERROR, "packet too small\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    switch (AV_RB32(src)) {
+    case 0x02000001:
+        ret = dxtory_decode_v1(avctx, pic, src + 16, avpkt->size - 16);
+        break;
+    case 0x02000009:
+        ret = dxtory_decode_v2(avctx, pic, src + 16, avpkt->size - 16);
+        break;
+    default:
+        avpriv_request_sample(avctx, "Frame header %X", AV_RB32(src));
+        return AVERROR_PATCHWELCOME;
+    }
+
+    if (ret)
+        return ret;
+
+    pic->pict_type = AV_PICTURE_TYPE_I;
+    pic->key_frame = 1;
     *got_frame = 1;
 
     return avpkt->size;
@@ -86,7 +221,6 @@
     .long_name      = NULL_IF_CONFIG_SMALL("Dxtory"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_DXTORY,
-    .init           = decode_init,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
 };
diff --git a/libavcodec/eac3enc.c b/libavcodec/eac3enc.c
index bb9ef4f..bca60bb 100644
--- a/libavcodec/eac3enc.c
+++ b/libavcodec/eac3enc.c
@@ -25,6 +25,8 @@
  */
 
 #define CONFIG_AC3ENC_FLOAT 1
+
+#include "libavutil/attributes.h"
 #include "ac3enc.h"
 #include "eac3enc.h"
 #include "eac3_data.h"
@@ -47,7 +49,7 @@
 static int8_t eac3_frame_expstr_index_tab[3][4][4][4][4][4];
 
 
-void ff_eac3_exponent_init(void)
+av_cold void ff_eac3_exponent_init(void)
 {
     int i;
 
diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c
index 58cdea6..b6bf86d 100644
--- a/libavcodec/eamad.c
+++ b/libavcodec/eamad.c
@@ -257,6 +257,11 @@
     calc_quant_matrix(s, buf[13]);
     buf += 16;
 
+    if (width < 16 || height < 16) {
+        av_log(avctx, AV_LOG_ERROR, "Dimensions too small\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     if (avctx->width != width || avctx->height != height) {
         if((width * height)/2048*7 > buf_end-buf)
             return AVERROR_INVALIDDATA;
diff --git a/libavcodec/eatgq.c b/libavcodec/eatgq.c
index cf93c06..3db6f84 100644
--- a/libavcodec/eatgq.c
+++ b/libavcodec/eatgq.c
@@ -157,7 +157,7 @@
     mode = bytestream2_get_byte(&s->gb);
     if (mode > 12) {
         GetBitContext gb;
-        init_get_bits(&gb, s->gb.buffer, FFMIN(bytestream2_get_bytes_left(&s->gb), mode) * 8);
+        init_get_bits8(&gb, s->gb.buffer, FFMIN(bytestream2_get_bytes_left(&s->gb), mode));
         for (i = 0; i < 6; i++)
             tgq_decode_block(s, s->block[i], &gb);
         tgq_idct_put_mb(s, s->block, frame, mb_x, mb_y);
diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c
index c9f5e1f..9c3b505 100644
--- a/libavcodec/error_resilience.c
+++ b/libavcodec/error_resilience.c
@@ -860,6 +860,21 @@
                           (s->avctx->skip_top + s->avctx->skip_bottom)) {
         return;
     }
+    for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
+        int status = s->error_status_table[mb_x + (s->mb_height - 1) * s->mb_stride];
+        if (status != 0x7F)
+            break;
+    }
+
+    if (   mb_x == s->mb_width
+        && s->avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO
+        && (s->avctx->height&16)
+        && s->error_count == 3 * s->mb_width * (s->avctx->skip_top + s->avctx->skip_bottom + 1)
+    ) {
+        av_log(s->avctx, AV_LOG_DEBUG, "ignoring last missing slice\n");
+        return;
+    }
+
     if (s->last_pic) {
         if (s->last_pic->f.width  != s->cur_pic->f.width  ||
             s->last_pic->f.height != s->cur_pic->f.height ||
diff --git a/libavcodec/escape124.c b/libavcodec/escape124.c
index 3c83e58..0879b3e 100644
--- a/libavcodec/escape124.c
+++ b/libavcodec/escape124.c
@@ -200,7 +200,6 @@
                                   void *data, int *got_frame,
                                   AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     Escape124Context *s = avctx->priv_data;
     AVFrame *frame = data;
@@ -218,7 +217,8 @@
 
     int ret;
 
-    init_get_bits(&gb, buf, buf_size * 8);
+    if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
+        return ret;
 
     // This call also guards the potential depth reads for the
     // codebook unpacking.
@@ -234,7 +234,7 @@
         if (!s->frame.data[0])
             return AVERROR_INVALIDDATA;
 
-        av_log(NULL, AV_LOG_DEBUG, "Skipping frame\n");
+        av_log(avctx, AV_LOG_DEBUG, "Skipping frame\n");
 
         *got_frame = 1;
         if ((ret = av_frame_ref(frame, &s->frame)) < 0)
@@ -352,7 +352,7 @@
         skip--;
     }
 
-    av_log(NULL, AV_LOG_DEBUG,
+    av_log(avctx, AV_LOG_DEBUG,
            "Escape sizes: %i, %i, %i\n",
            frame_size, buf_size, get_bits_count(&gb) / 8);
 
diff --git a/libavcodec/escape130.c b/libavcodec/escape130.c
index d24af79..eb6a26e 100644
--- a/libavcodec/escape130.c
+++ b/libavcodec/escape130.c
@@ -1,5 +1,5 @@
 /*
- * Escape 130 Video Decoder
+ * Escape 130 video decoder
  * Copyright (C) 2008 Eli Friedman (eli.friedman <at> gmail.com)
  *
  * This file is part of FFmpeg.
@@ -19,35 +19,134 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
+#include "libavutil/mem.h"
 #include "avcodec.h"
-
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
 #include "internal.h"
 
-
 typedef struct Escape130Context {
-    AVFrame frame;
-    uint8_t *bases;
+    uint8_t *old_y_avg;
+
+    uint8_t *new_y, *old_y;
+    uint8_t *new_u, *old_u;
+    uint8_t *new_v, *old_v;
+
+    uint8_t *buf1, *buf2;
+    int     linesize[3];
 } Escape130Context;
 
-/**
- * Initialize the decoder
- * @param avctx decoder context
- * @return 0 success, negative on error
- */
+static const uint8_t offset_table[] = { 2, 4, 10, 20 };
+static const int8_t sign_table[64][4] = {
+    {  0,  0,  0,  0 },
+    { -1,  1,  0,  0 },
+    {  1, -1,  0,  0 },
+    { -1,  0,  1,  0 },
+    { -1,  1,  1,  0 },
+    {  0, -1,  1,  0 },
+    {  1, -1,  1,  0 },
+    { -1, -1,  1,  0 },
+    {  1,  0, -1,  0 },
+    {  0,  1, -1,  0 },
+    {  1,  1, -1,  0 },
+    { -1,  1, -1,  0 },
+    {  1, -1, -1,  0 },
+    { -1,  0,  0,  1 },
+    { -1,  1,  0,  1 },
+    {  0, -1,  0,  1 },
+
+    {  0,  0,  0,  0 },
+    {  1, -1,  0,  1 },
+    { -1, -1,  0,  1 },
+    { -1,  0,  1,  1 },
+    { -1,  1,  1,  1 },
+    {  0, -1,  1,  1 },
+    {  1, -1,  1,  1 },
+    { -1, -1,  1,  1 },
+    {  0,  0, -1,  1 },
+    {  1,  0, -1,  1 },
+    { -1,  0, -1,  1 },
+    {  0,  1, -1,  1 },
+    {  1,  1, -1,  1 },
+    { -1,  1, -1,  1 },
+    {  0, -1, -1,  1 },
+    {  1, -1, -1,  1 },
+
+    {  0,  0,  0,  0 },
+    { -1, -1, -1,  1 },
+    {  1,  0,  0, -1 },
+    {  0,  1,  0, -1 },
+    {  1,  1,  0, -1 },
+    { -1,  1,  0, -1 },
+    {  1, -1,  0, -1 },
+    {  0,  0,  1, -1 },
+    {  1,  0,  1, -1 },
+    { -1,  0,  1, -1 },
+    {  0,  1,  1, -1 },
+    {  1,  1,  1, -1 },
+    { -1,  1,  1, -1 },
+    {  0, -1,  1, -1 },
+    {  1, -1,  1, -1 },
+    { -1, -1,  1, -1 },
+
+    {  0,  0,  0,  0 },
+    {  1,  0, -1, -1 },
+    {  0,  1, -1, -1 },
+    {  1,  1, -1, -1 },
+    { -1,  1, -1, -1 },
+    {  1, -1, -1, -1 }
+};
+
+static const int8_t luma_adjust[] = { -4, -3, -2, -1, 1, 2, 3, 4 };
+
+static const int8_t chroma_adjust[2][8] = {
+    { 1, 1, 0, -1, -1, -1,  0,  1 },
+    { 0, 1, 1,  1,  0, -1, -1, -1 }
+};
+
+static const uint8_t chroma_vals[] = {
+     20,  28,  36,  44,  52,  60,  68,  76,
+     84,  92, 100, 106, 112, 116, 120, 124,
+    128, 132, 136, 140, 144, 150, 156, 164,
+    172, 180, 188, 196, 204, 212, 220, 228
+};
+
 static av_cold int escape130_decode_init(AVCodecContext *avctx)
 {
     Escape130Context *s = avctx->priv_data;
     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
-    avcodec_get_frame_defaults(&s->frame);
 
-    if((avctx->width&1) || (avctx->height&1)){
-        av_log(avctx, AV_LOG_ERROR, "Dimensions are not a multiple of the block size\n");
-        return AVERROR(EINVAL);
+    if ((avctx->width & 1) || (avctx->height & 1)) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Dimensions should be a multiple of two.\n");
+        return AVERROR_INVALIDDATA;
     }
 
-    s->bases= av_malloc(avctx->width * avctx->height /4);
+    s->old_y_avg = av_malloc(avctx->width * avctx->height / 4);
+    s->buf1      = av_malloc(avctx->width * avctx->height * 3 / 2);
+    s->buf2      = av_malloc(avctx->width * avctx->height * 3 / 2);
+    if (!s->old_y_avg || !s->buf1 || !s->buf2) {
+        av_freep(&s->old_y_avg);
+        av_freep(&s->buf1);
+        av_freep(&s->buf2);
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    s->linesize[0] = avctx->width;
+    s->linesize[1] =
+    s->linesize[2] = avctx->width / 2;
+
+    s->new_y = s->buf1;
+    s->new_u = s->new_y + avctx->width * avctx->height;
+    s->new_v = s->new_u + avctx->width * avctx->height / 4;
+    s->old_y = s->buf2;
+    s->old_u = s->old_y + avctx->width * avctx->height;
+    s->old_v = s->old_u + avctx->width * avctx->height / 4;
+    memset(s->old_y, 0,    avctx->width * avctx->height);
+    memset(s->old_u, 0x10, avctx->width * avctx->height / 4);
+    memset(s->old_v, 0x10, avctx->width * avctx->height / 4);
 
     return 0;
 }
@@ -56,17 +155,17 @@
 {
     Escape130Context *s = avctx->priv_data;
 
-    av_frame_unref(&s->frame);
-
-    av_freep(&s->bases);
+    av_freep(&s->old_y_avg);
+    av_freep(&s->buf1);
+    av_freep(&s->buf2);
 
     return 0;
 }
 
-static unsigned decode_skip_count(GetBitContext* gb) {
-    unsigned value;
-    // This function reads a maximum of 27 bits,
-    // which is within the padding space
+static int decode_skip_count(GetBitContext* gb)
+{
+    int value;
+
     if (get_bits_left(gb) < 1+3)
         return -1;
 
@@ -89,165 +188,88 @@
     return -1;
 }
 
-/**
- * Decode a single frame
- * @param avctx decoder context
- * @param data decoded frame
- * @param got_frame have decoded frame
- * @param buf input buffer
- * @param buf_size input buffer size
- * @return 0 success, -1 on error
- */
-static int escape130_decode_frame(AVCodecContext *avctx,
-                                  void *data, int *got_frame,
-                                  AVPacket *avpkt)
+static int escape130_decode_frame(AVCodecContext *avctx, void *data,
+                                  int *got_frame, AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
+    int buf_size        = avpkt->size;
     Escape130Context *s = avctx->priv_data;
-
+    AVFrame *pic        = data;
     GetBitContext gb;
-    unsigned i;
     int ret;
 
     uint8_t *old_y, *old_cb, *old_cr,
             *new_y, *new_cb, *new_cr;
+    uint8_t *dstY, *dstU, *dstV;
     unsigned old_y_stride, old_cb_stride, old_cr_stride,
              new_y_stride, new_cb_stride, new_cr_stride;
     unsigned total_blocks = avctx->width * avctx->height / 4,
-             block_index, row_index = 0;
-    unsigned y[4] = {0}, cb = 16, cr = 16;
-    unsigned skip = -1;
-    unsigned y_base = 0;
-    uint8_t *yb= s->bases;
+             block_index, block_x = 0;
+    unsigned y[4] = { 0 }, cb = 0x10, cr = 0x10;
+    int skip = -1, y_avg = 0, i, j;
+    uint8_t *ya = s->old_y_avg;
 
-    AVFrame *frame = data;
+    // first 16 bytes are header; no useful information in here
+    if (buf_size <= 16) {
+        av_log(avctx, AV_LOG_ERROR, "Insufficient frame data\n");
+        return AVERROR_INVALIDDATA;
+    }
 
-    init_get_bits(&gb, buf, buf_size * 8);
-
-    if (get_bits_left(&gb) < 128)
-        return -1;
-
-    // Header; no useful information in here
-    skip_bits_long(&gb, 128);
-
-    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
+    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
         return ret;
 
-    new_y = frame->data[0];
-    new_cb = frame->data[1];
-    new_cr = frame->data[2];
-    new_y_stride = frame->linesize[0];
-    new_cb_stride = frame->linesize[1];
-    new_cr_stride = frame->linesize[2];
-    old_y = s->frame.data[0];
-    old_cb = s->frame.data[1];
-    old_cr = s->frame.data[2];
-    old_y_stride = s->frame.linesize[0];
-    old_cb_stride = s->frame.linesize[1];
-    old_cr_stride = s->frame.linesize[2];
+    if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
+        return ret;
+    skip_bits_long(&gb, 16 * 8);
 
-    av_log(avctx, AV_LOG_DEBUG,
-           "Strides: %i, %i\n",
-           new_y_stride, new_cb_stride);
+    new_y  = s->new_y;
+    new_cb = s->new_u;
+    new_cr = s->new_v;
+    new_y_stride  = s->linesize[0];
+    new_cb_stride = s->linesize[1];
+    new_cr_stride = s->linesize[2];
+    old_y  = s->old_y;
+    old_cb = s->old_u;
+    old_cr = s->old_v;
+    old_y_stride  = s->linesize[0];
+    old_cb_stride = s->linesize[1];
+    old_cr_stride = s->linesize[2];
 
     for (block_index = 0; block_index < total_blocks; block_index++) {
         // Note that this call will make us skip the rest of the blocks
-        // if the frame prematurely ends
+        // if the frame ends prematurely.
         if (skip == -1)
             skip = decode_skip_count(&gb);
+        if (skip == -1) {
+            av_log(avctx, AV_LOG_ERROR, "Error decoding skip value\n");
+            return AVERROR_INVALIDDATA;
+        }
 
         if (skip) {
-            if (old_y) {
-                y[0] = old_y[0] / 4;
-                y[1] = old_y[1] / 4;
-                y[2] = old_y[old_y_stride] / 4;
-                y[3] = old_y[old_y_stride+1] / 4;
-                y_base= yb[0];
-                cb = old_cb[0] / 8;
-                cr = old_cr[0] / 8;
-            } else {
-                y_base=y[0] = y[1] = y[2] = y[3] = 0;
-                cb = cr = 16;
-            }
+            y[0] = old_y[0];
+            y[1] = old_y[1];
+            y[2] = old_y[old_y_stride];
+            y[3] = old_y[old_y_stride + 1];
+            y_avg = ya[0];
+            cb = old_cb[0];
+            cr = old_cr[0];
         } else {
             if (get_bits1(&gb)) {
-                static const uint8_t offset_table[] = {2, 4, 10, 20};
-                static const int8_t sign_table[64][4] =
-                    { {0, 0, 0, 0},
-                      {-1, 1, 0, 0},
-                      {1, -1, 0, 0},
-                      {-1, 0, 1, 0},
-                      {-1, 1, 1, 0},
-                      {0, -1, 1, 0},
-                      {1, -1, 1, 0},
-                      {-1, -1, 1, 0},
-                      {1, 0, -1, 0},
-                      {0, 1, -1, 0},
-                      {1, 1, -1, 0},
-                      {-1, 1, -1, 0},
-                      {1, -1, -1, 0},
-                      {-1, 0, 0, 1},
-                      {-1, 1, 0, 1},
-                      {0, -1, 0, 1},
-
-                      {0, 0, 0, 0},
-                      {1, -1, 0, 1},
-                      {-1, -1, 0, 1},
-                      {-1, 0, 1, 1},
-                      {-1, 1, 1, 1},
-                      {0, -1, 1, 1},
-                      {1, -1, 1, 1},
-                      {-1, -1, 1, 1},
-                      {0, 0, -1, 1},
-                      {1, 0, -1, 1},
-                      {-1, 0, -1, 1},
-                      {0, 1, -1, 1},
-                      {1, 1, -1, 1},
-                      {-1, 1, -1, 1},
-                      {0, -1, -1, 1},
-                      {1, -1, -1, 1},
-
-                      {0, 0, 0, 0},
-                      {-1, -1, -1, 1},
-                      {1, 0, 0, -1},
-                      {0, 1, 0, -1},
-                      {1, 1, 0, -1},
-                      {-1, 1, 0, -1},
-                      {1, -1, 0, -1},
-                      {0, 0, 1, -1},
-                      {1, 0, 1, -1},
-                      {-1, 0, 1, -1},
-                      {0, 1, 1, -1},
-                      {1, 1, 1, -1},
-                      {-1, 1, 1, -1},
-                      {0, -1, 1, -1},
-                      {1, -1, 1, -1},
-                      {-1, -1, 1, -1},
-
-                      {0, 0, 0, 0},
-                      {1, 0, -1, -1},
-                      {0, 1, -1, -1},
-                      {1, 1, -1, -1},
-                      {-1, 1, -1, -1},
-                      {1, -1, -1, -1} };
-                unsigned sign_selector = get_bits(&gb, 6);
+                unsigned sign_selector       = get_bits(&gb, 6);
                 unsigned difference_selector = get_bits(&gb, 2);
-                y_base = 2 * get_bits(&gb, 5);
+                y_avg = 2 * get_bits(&gb, 5);
                 for (i = 0; i < 4; i++) {
-                    y[i] = av_clip((int)y_base + offset_table[difference_selector] *
-                                            sign_table[sign_selector][i], 0, 63);
+                    y[i] = av_clip(y_avg + offset_table[difference_selector] *
+                                   sign_table[sign_selector][i], 0, 63);
                 }
             } else if (get_bits1(&gb)) {
                 if (get_bits1(&gb)) {
-                    y_base = get_bits(&gb, 6);
+                    y_avg = get_bits(&gb, 6);
                 } else {
                     unsigned adjust_index = get_bits(&gb, 3);
-                    static const int8_t adjust[] = {-4, -3, -2, -1, 1, 2, 3, 4};
-                    y_base = (y_base + adjust[adjust_index]) & 63;
+                    y_avg = (y_avg + luma_adjust[adjust_index]) & 63;
                 }
                 for (i = 0; i < 4; i++)
-                    y[i] = y_base;
+                    y[i] = y_avg;
             }
 
             if (get_bits1(&gb)) {
@@ -256,56 +278,75 @@
                     cr = get_bits(&gb, 5);
                 } else {
                     unsigned adjust_index = get_bits(&gb, 3);
-                    static const int8_t adjust[2][8] =
-                        {  { 1, 1, 0, -1, -1, -1,  0,  1 },
-                           { 0, 1, 1,  1,  0, -1, -1, -1 } };
-                    cb = (cb + adjust[0][adjust_index]) & 31;
-                    cr = (cr + adjust[1][adjust_index]) & 31;
+                    cb = (cb + chroma_adjust[0][adjust_index]) & 31;
+                    cr = (cr + chroma_adjust[1][adjust_index]) & 31;
                 }
             }
         }
-        *yb++= y_base;
+        *ya++ = y_avg;
 
-        new_y[0] = y[0] * 4;
-        new_y[1] = y[1] * 4;
-        new_y[new_y_stride] = y[2] * 4;
-        new_y[new_y_stride + 1] = y[3] * 4;
-        *new_cb = cb * 8;
-        *new_cr = cr * 8;
+        new_y[0]                = y[0];
+        new_y[1]                = y[1];
+        new_y[new_y_stride]     = y[2];
+        new_y[new_y_stride + 1] = y[3];
+        *new_cb = cb;
+        *new_cr = cr;
 
-        if (old_y)
-            old_y += 2, old_cb++, old_cr++;
-        new_y += 2, new_cb++, new_cr++;
-        row_index++;
-        if (avctx->width / 2 == row_index) {
-            row_index = 0;
-            if (old_y) {
-                old_y  += old_y_stride * 2  - avctx->width;
-                old_cb += old_cb_stride - avctx->width / 2;
-                old_cr += old_cr_stride - avctx->width / 2;
-            }
+        old_y += 2;
+        old_cb++;
+        old_cr++;
+        new_y += 2;
+        new_cb++;
+        new_cr++;
+        block_x++;
+        if (block_x * 2 == avctx->width) {
+            block_x = 0;
+            old_y  += old_y_stride * 2  - avctx->width;
+            old_cb += old_cb_stride     - avctx->width / 2;
+            old_cr += old_cr_stride     - avctx->width / 2;
             new_y  += new_y_stride * 2  - avctx->width;
-            new_cb += new_cb_stride - avctx->width / 2;
-            new_cr += new_cr_stride - avctx->width / 2;
+            new_cb += new_cb_stride     - avctx->width / 2;
+            new_cr += new_cr_stride     - avctx->width / 2;
         }
 
         skip--;
     }
 
-    av_log(avctx, AV_LOG_DEBUG,
-           "Escape sizes: %i, %i\n",
-           buf_size, get_bits_count(&gb) / 8);
+    new_y  = s->new_y;
+    new_cb = s->new_u;
+    new_cr = s->new_v;
+    dstY   = pic->data[0];
+    dstU   = pic->data[1];
+    dstV   = pic->data[2];
+    for (j = 0; j < avctx->height; j++) {
+        for (i = 0; i < avctx->width; i++)
+            dstY[i] = new_y[i] << 2;
+        dstY  += pic->linesize[0];
+        new_y += new_y_stride;
+    }
+    for (j = 0; j < avctx->height / 2; j++) {
+        for (i = 0; i < avctx->width / 2; i++) {
+            dstU[i] = chroma_vals[new_cb[i]];
+            dstV[i] = chroma_vals[new_cr[i]];
+        }
+        dstU   += pic->linesize[1];
+        dstV   += pic->linesize[2];
+        new_cb += new_cb_stride;
+        new_cr += new_cr_stride;
+    }
 
-    av_frame_unref(&s->frame);
-    if ((ret = av_frame_ref(&s->frame, frame)) < 0)
-        return ret;
+    av_dlog(avctx, "Frame data: provided %d bytes, used %d bytes\n",
+            buf_size, get_bits_count(&gb) >> 3);
+
+    FFSWAP(uint8_t*, s->old_y, s->new_y);
+    FFSWAP(uint8_t*, s->old_u, s->new_u);
+    FFSWAP(uint8_t*, s->old_v, s->new_v);
 
     *got_frame = 1;
 
     return buf_size;
 }
 
-
 AVCodec ff_escape130_decoder = {
     .name           = "escape130",
     .type           = AVMEDIA_TYPE_VIDEO,
diff --git a/libavcodec/evrcdec.c b/libavcodec/evrcdec.c
index f0e594f..f104e33 100644
--- a/libavcodec/evrcdec.c
+++ b/libavcodec/evrcdec.c
@@ -374,7 +374,7 @@
     int offset, i, coef_idx;
     int16_t t;
 
-    offset = lrintf(fabs(delay));
+    offset = lrintf(delay);
 
     t = (offset - delay + 0.5) * 8.0 + 0.5;
     if (t == 8) {
diff --git a/libavcodec/exif.c b/libavcodec/exif.c
new file mode 100644
index 0000000..ec524a5
--- /dev/null
+++ b/libavcodec/exif.c
@@ -0,0 +1,130 @@
+/*
+ * EXIF metadata parser
+ * Copyright (c) 2013 Thilo Borgmann <thilo.borgmann _at_ mail.de>
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * EXIF metadata parser
+ * @author Thilo Borgmann <thilo.borgmann _at_ mail.de>
+ */
+
+#include "exif.h"
+
+
+static const char *exif_get_tag_name(uint16_t id)
+{
+    int i;
+
+    for (i = 0; i < FF_ARRAY_ELEMS(tag_list); i++) {
+        if (tag_list[i].id == id)
+            return tag_list[i].name;
+    }
+
+    return NULL;
+}
+
+
+static int exif_add_metadata(AVCodecContext *avctx, int count, int type,
+                             const char *name, const char *sep,
+                             GetByteContext *gb, int le,
+                             AVDictionary **metadata)
+{
+    switch(type) {
+    case TIFF_DOUBLE   : return ff_tadd_doubles_metadata(count, name, sep, gb, le, metadata);
+    case TIFF_SHORT    : return ff_tadd_shorts_metadata(count, name, sep, gb, le, metadata);
+    case TIFF_BYTE     :
+    case TIFF_UNDEFINED:
+    case TIFF_STRING   : return ff_tadd_string_metadata(count, name, gb, le, metadata);
+    case TIFF_SRATIONAL:
+    case TIFF_RATIONAL : return ff_tadd_rational_metadata(count, name, sep, gb, le, metadata);
+    case TIFF_SLONG    :
+    case TIFF_LONG     : return ff_tadd_long_metadata(count, name, sep, gb, le, metadata);
+    default:
+        avpriv_request_sample(avctx, "TIFF tag type (%u)", type);
+        return 0;
+    };
+}
+
+
+static int exif_decode_tag(AVCodecContext *avctx, GetByteContext *gbytes, int le,
+                           int depth, AVDictionary **metadata)
+{
+    int ret, cur_pos;
+    unsigned id, count;
+    enum TiffTypes type;
+
+    if (depth > 2) {
+        return 0;
+    }
+
+    ff_tread_tag(gbytes, le, &id, &type, &count, &cur_pos);
+
+    // read count values and add it metadata
+    // store metadata or proceed with next IFD
+    ret = ff_tis_ifd(id);
+    if (ret) {
+        ret = ff_exif_decode_ifd(avctx, gbytes, le, depth + 1, metadata);
+    } else {
+        const char *name = exif_get_tag_name(id);
+        char *use_name   = (char*) name;
+
+        if (!use_name) {
+            use_name = av_malloc(7);
+            if (!use_name) {
+                return AVERROR(ENOMEM);
+            }
+            snprintf(use_name, 7, "0x%04X", id);
+        }
+
+        ret = exif_add_metadata(avctx, count, type, use_name, NULL,
+                                gbytes, le, metadata);
+
+        if (!name) {
+            av_freep(&use_name);
+        }
+    }
+
+    bytestream2_seek(gbytes, cur_pos, SEEK_SET);
+
+    return ret;
+}
+
+
+int ff_exif_decode_ifd(AVCodecContext *avctx, GetByteContext *gbytes, int le,
+                       int depth, AVDictionary **metadata)
+{
+    int i, ret;
+    int entries;
+
+    entries = ff_tget_short(gbytes, le);
+
+    if (bytestream2_get_bytes_left(gbytes) < entries * 12) {
+        return AVERROR_INVALIDDATA;
+    }
+
+    for (i = 0; i < entries; i++) {
+        if ((ret = exif_decode_tag(avctx, gbytes, le, depth, metadata)) < 0) {
+            return ret;
+        }
+    }
+
+    // return next IDF offset or 0x000000000 or a value < 0 for failure
+    return ff_tget_long(gbytes, le);
+}
diff --git a/libavcodec/exif.h b/libavcodec/exif.h
new file mode 100644
index 0000000..71fe829
--- /dev/null
+++ b/libavcodec/exif.h
@@ -0,0 +1,170 @@
+/*
+ * EXIF metadata parser
+ * Copyright (c) 2013 Thilo Borgmann <thilo.borgmann _at_ mail.de>
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * EXIF metadata parser
+ * @author Thilo Borgmann <thilo.borgmann _at_ mail.de>
+ */
+
+#ifndef AVCODEC_EXIF_H
+#define AVCODEC_EXIF_H
+
+#include "avcodec.h"
+#include "bytestream.h"
+#include "tiff.h"
+
+#define EXIF_MAX_IFD_RECURSION 2
+#define EXIF_TAG_NAME_LENGTH   32
+
+struct exif_tag {
+    char      name[EXIF_TAG_NAME_LENGTH];
+    uint16_t  id;
+};
+
+static const struct exif_tag tag_list[] = { // JEITA CP-3451 EXIF specification:
+    {"GPSVersionID",               0x00}, // <- Table 12 GPS Attribute Information
+    {"GPSLatitudeRef",             0x01},
+    {"GPSLatitude",                0x02},
+    {"GPSLongitudeRef",            0x03},
+    {"GPSLongitude",               0x04},
+    {"GPSAltitudeRef",             0x05},
+    {"GPSAltitude",                0x06},
+    {"GPSTimeStamp",               0x07},
+    {"GPSSatellites",              0x08},
+    {"GPSStatus",                  0x09},
+    {"GPSMeasureMode",             0x0A},
+    {"GPSDOP",                     0x0B},
+    {"GPSSpeedRef",                0x0C},
+    {"GPSSpeed",                   0x0D},
+    {"GPSTrackRef",                0x0E},
+    {"GPSTrack",                   0x0F},
+    {"GPSImgDirectionRef",         0x10},
+    {"GPSImgDirection",            0x11},
+    {"GPSMapDatum",                0x12},
+    {"GPSDestLatitudeRef",         0x13},
+    {"GPSDestLatitude",            0x14},
+    {"GPSDestLongitudeRef",        0x15},
+    {"GPSDestLongitude",           0x16},
+    {"GPSDestBearingRef",          0x17},
+    {"GPSDestBearing",             0x18},
+    {"GPSDestDistanceRef",         0x19},
+    {"GPSDestDistance",            0x1A},
+    {"GPSProcessingMethod",        0x1B},
+    {"GPSAreaInformation",         0x1C},
+    {"GPSDateStamp",               0x1D},
+    {"GPSDifferential",            0x1E},
+    {"ImageWidth",                 0x100}, // <- Table 3 TIFF Rev. 6.0 Attribute Information Used in Exif
+    {"ImageLength",                0x101},
+    {"BitsPerSample",              0x102},
+    {"Compression",                0x103},
+    {"PhotometricInterpretation",  0x106},
+    {"Orientation",                0x112},
+    {"SamplesPerPixel",            0x115},
+    {"PlanarConfiguration",        0x11C},
+    {"YCbCrSubSampling",           0x212},
+    {"YCbCrPositioning",           0x213},
+    {"XResolution",                0x11A},
+    {"YResolution",                0x11B},
+    {"ResolutionUnit",             0x128},
+    {"StripOffsets",               0x111},
+    {"RowsPerStrip",               0x116},
+    {"StripByteCounts",            0x117},
+    {"JPEGInterchangeFormat",      0x201},
+    {"JPEGInterchangeFormatLength",0x202},
+    {"TransferFunction",           0x12D},
+    {"WhitePoint",                 0x13E},
+    {"PrimaryChromaticities",      0x13F},
+    {"YCbCrCoefficients",          0x211},
+    {"ReferenceBlackWhite",        0x214},
+    {"DateTime",                   0x132},
+    {"ImageDescription",           0x10E},
+    {"Make",                       0x10F},
+    {"Model",                      0x110},
+    {"Software",                   0x131},
+    {"Artist",                     0x13B},
+    {"Copyright",                  0x8298},
+    {"ExifVersion",                0x9000}, // <- Table 4 Exif IFD Attribute Information (1)
+    {"FlashpixVersion",            0xA000},
+    {"ColorSpace",                 0xA001},
+    {"ComponentsConfiguration",    0x9101},
+    {"CompressedBitsPerPixel",     0x9102},
+    {"PixelXDimension",            0xA002},
+    {"PixelYDimension",            0xA003},
+    {"MakerNote",                  0x927C},
+    {"UserComment",                0x9286},
+    {"RelatedSoundFile",           0xA004},
+    {"DateTimeOriginal",           0x9003},
+    {"DateTimeDigitized",          0x9004},
+    {"SubSecTime",                 0x9290},
+    {"SubSecTimeOriginal",         0x9291},
+    {"SubSecTimeDigitized",        0x9292},
+    {"ImageUniqueID",              0xA420},
+    {"ExposureTime",               0x829A}, // <- Table 5 Exif IFD Attribute Information (2)
+    {"FNumber",                    0x829D},
+    {"ExposureProgram",            0x8822},
+    {"SpectralSensitivity",        0x8824},
+    {"ISOSpeedRatings",            0x8827},
+    {"OECF",                       0x8828},
+    {"ShutterSpeedValue",          0x9201},
+    {"ApertureValue",              0x9202},
+    {"BrightnessValue",            0x9203},
+    {"ExposureBiasValue",          0x9204},
+    {"MaxApertureValue",           0x9205},
+    {"SubjectDistance",            0x9206},
+    {"MeteringMode",               0x9207},
+    {"LightSource",                0x9208},
+    {"Flash",                      0x9209},
+    {"FocalLength",                0x920A},
+    {"SubjectArea",                0x9214},
+    {"FlashEnergy",                0xA20B},
+    {"SpatialFrequencyResponse",   0xA20C},
+    {"FocalPlaneXResolution",      0xA20E},
+    {"FocalPlaneYResolution",      0xA20F},
+    {"FocalPlaneResolutionUnit",   0xA210},
+    {"SubjectLocation",            0xA214},
+    {"ExposureIndex",              0xA215},
+    {"SensingMethod",              0xA217},
+    {"FileSource",                 0xA300},
+    {"SceneType",                  0xA301},
+    {"CFAPattern",                 0xA302},
+    {"CustomRendered",             0xA401},
+    {"ExposureMode",               0xA402},
+    {"WhiteBalance",               0xA403},
+    {"DigitalZoomRatio",           0xA404},
+    {"FocalLengthIn35mmFilm",      0xA405},
+    {"SceneCaptureType",           0xA406},
+    {"GainControl",                0xA407},
+    {"Contrast",                   0xA408},
+    {"Saturation",                 0xA409},
+    {"Sharpness",                  0xA40A},
+    {"DeviceSettingDescription",   0xA40B},
+    {"SubjectDistanceRange",       0xA40C}
+//    {"InteroperabilityIndex",      0x1}, // <- Table 13 Interoperability IFD Attribute Information
+//    {"",                           0x0}
+};
+
+/** Recursively decodes all IFD's and
+ *  adds included TAGS into the metadata dictionary. */
+int ff_exif_decode_ifd(AVCodecContext *avctx, GetByteContext *gbytes, int le,
+                       int depth, AVDictionary **metadata);
+
+#endif /* AVCODEC_EXIF_H */
diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index af1bee0..cba0c4d 100644
--- a/libavcodec/exr.c
+++ b/libavcodec/exr.c
@@ -778,6 +778,7 @@
         ptr += picture->linesize[0];
     }
 
+    picture->pict_type = AV_PICTURE_TYPE_I;
     *got_frame = 1;
 
     return buf_size;
diff --git a/libavcodec/faxcompr.c b/libavcodec/faxcompr.c
index 86be977..900851b 100644
--- a/libavcodec/faxcompr.c
+++ b/libavcodec/faxcompr.c
@@ -103,13 +103,13 @@
     int i;
     static int initialized = 0;
 
-    if(initialized)
+    if (initialized)
         return;
     ccitt_vlc[0].table = code_table1;
     ccitt_vlc[0].table_allocated = 528;
     ccitt_vlc[1].table = code_table2;
     ccitt_vlc[1].table_allocated = 648;
-    for(i = 0; i < 2; i++){
+    for (i = 0; i < 2; i++) {
         ff_init_vlc_sparse(&ccitt_vlc[i], 9, CCITT_SYMS,
                            ccitt_codes_lens[i], 1, 1,
                            ccitt_codes_bits[i], 1, 1,
@@ -124,32 +124,33 @@
 
 
 static int decode_group3_1d_line(AVCodecContext *avctx, GetBitContext *gb,
-                                 unsigned int pix_left, int *runs, const int *runend)
+                                 unsigned int pix_left, int *runs,
+                                 const int *runend)
 {
-    int mode = 0;
-    unsigned int run=0;
+    int mode         = 0;
+    unsigned int run = 0;
     unsigned int t;
-    for(;;){
-        t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2);
+    for (;;) {
+        t    = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2);
         run += t;
-        if(t < 64){
+        if (t < 64) {
             *runs++ = run;
-            if(runs >= runend){
+            if (runs >= runend) {
                 av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
-            if(pix_left <= run){
-                if(pix_left == run)
+            if (pix_left <= run) {
+                if (pix_left == run)
                     break;
                 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
             pix_left -= run;
-            run = 0;
-            mode = !mode;
-        }else if((int)t == -1){
+            run       = 0;
+            mode      = !mode;
+        } else if ((int)t == -1) {
             av_log(avctx, AV_LOG_ERROR, "Incorrect code\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
     *runs++ = 0;
@@ -157,85 +158,86 @@
 }
 
 static int decode_group3_2d_line(AVCodecContext *avctx, GetBitContext *gb,
-                                 unsigned int width, int *runs, const int *runend, const int *ref)
+                                 unsigned int width, int *runs,
+                                 const int *runend, const int *ref)
 {
-    int mode = 0, saved_run = 0, t;
-    int run_off = *ref++;
-    unsigned int offs=0, run= 0;
+    int mode          = 0, saved_run = 0, t;
+    int run_off       = *ref++;
+    unsigned int offs = 0, run = 0;
 
-    while(offs < width){
+    while (offs < width) {
         int cmode = get_vlc2(gb, ccitt_group3_2d_vlc.table, 9, 1);
-        if(cmode == -1){
+        if (cmode == -1) {
             av_log(avctx, AV_LOG_ERROR, "Incorrect mode VLC\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
-        if(!cmode){//pass mode
-            if(run_off < width)
+        if (!cmode) { //pass mode
+            if (run_off < width)
                 run_off += *ref++;
-            run = run_off - offs;
-            offs= run_off;
-            if(run_off < width)
+            run      = run_off - offs;
+            offs     = run_off;
+            if (run_off < width)
                 run_off += *ref++;
-            if(offs > width){
+            if (offs > width) {
                 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
             saved_run += run;
-        }else if(cmode == 1){//horizontal mode
+        } else if (cmode == 1) { //horizontal mode
             int k;
-            for(k = 0; k < 2; k++){
+            for (k = 0; k < 2; k++) {
                 run = 0;
-                for(;;){
+                for (;;) {
                     t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2);
-                    if(t == -1){
+                    if (t == -1) {
                         av_log(avctx, AV_LOG_ERROR, "Incorrect code\n");
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     }
                     run += t;
-                    if(t < 64)
+                    if (t < 64)
                         break;
                 }
                 *runs++ = run + saved_run;
-                if(runs >= runend){
+                if (runs >= runend) {
                     av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 saved_run = 0;
-                offs += run;
-                if(offs > width || run > width){
+                offs     += run;
+                if (offs > width || run > width) {
                     av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 mode = !mode;
             }
-        }else if(cmode == 9 || cmode == 10){
-            av_log(avctx, AV_LOG_ERROR, "Special modes are not supported (yet)\n");
-            return -1;
-        }else{//vertical mode
-            run = run_off - offs + (cmode - 5);
+        } else if (cmode == 9 || cmode == 10) {
+            avpriv_report_missing_feature(avctx, "Special modes support");
+            return AVERROR_PATCHWELCOME;
+        } else { //vertical mode
+            run      = run_off - offs + (cmode - 5);
             run_off -= *--ref;
-            offs += run;
-            if(offs > width || run > width){
+            offs    += run;
+            if (offs > width || run > width) {
                 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
             *runs++ = run + saved_run;
-            if(runs >= runend){
+            if (runs >= runend) {
                 av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
             saved_run = 0;
-            mode = !mode;
+            mode      = !mode;
         }
         //sync line pointers
-        while(offs < width && run_off <= offs){
+        while (offs < width && run_off <= offs) {
             run_off += *ref++;
             run_off += *ref++;
         }
     }
     *runs++ = saved_run;
     if (saved_run) {
-        if(runs >= runend){
+        if (runs >= runend) {
             av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
             return -1;
         }
@@ -249,14 +251,14 @@
     PutBitContext pb;
     int run, mode = ~0, pix_left = width, run_idx = 0;
 
-    init_put_bits(&pb, dst, size*8);
-    while(pix_left > 0){
-        run = runs[run_idx++];
-        mode = ~mode;
+    init_put_bits(&pb, dst, size * 8);
+    while (pix_left > 0) {
+        run       = runs[run_idx++];
+        mode      = ~mode;
         pix_left -= run;
-        for(; run > 16; run -= 16)
+        for (; run > 16; run -= 16)
             put_sbits(&pb, 16, mode);
-        if(run)
+        if (run)
             put_sbits(&pb, run, mode);
     }
     flush_put_bits(&pb);
@@ -266,16 +268,15 @@
 {
     unsigned int state = -1;
     srcsize -= get_bits_count(gb);
-    while(srcsize-- > 0){
-        state+= state + get_bits1(gb);
-        if((state & 0xFFF) == 1)
+    while (srcsize-- > 0) {
+        state += state + get_bits1(gb);
+        if ((state & 0xFFF) == 1)
             return 0;
     }
     return -1;
 }
 
-int ff_ccitt_unpack(AVCodecContext *avctx,
-                    const uint8_t *src, int srcsize,
+int ff_ccitt_unpack(AVCodecContext *avctx, const uint8_t *src, int srcsize,
                     uint8_t *dst, int height, int stride,
                     enum TiffCompr compr, int opts)
 {
@@ -283,51 +284,57 @@
     GetBitContext gb;
     int *runs, *ref = NULL, *runend;
     int ret;
-    int runsize= avctx->width + 2;
-    int err = 0;
+    int runsize = avctx->width + 2;
     int has_eol;
 
     runs = av_malloc(runsize * sizeof(runs[0]));
     ref  = av_malloc(runsize * sizeof(ref[0]));
-    if (!runs || ! ref) {
-        err = AVERROR(ENOMEM);
+    if (!runs || !ref) {
+        ret = AVERROR(ENOMEM);
         goto fail;
     }
     ref[0] = avctx->width;
     ref[1] = 0;
     ref[2] = 0;
-    init_get_bits(&gb, src, srcsize*8);
+    init_get_bits(&gb, src, srcsize * 8);
     has_eol = show_bits(&gb, 12) == 1 || show_bits(&gb, 16) == 1;
 
-    for(j = 0; j < height; j++){
+    for (j = 0; j < height; j++) {
         runend = runs + runsize;
-        if(compr == TIFF_G4){
-            ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref);
-            if(ret < 0){
-                err = -1;
+        if (compr == TIFF_G4) {
+            ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend,
+                                        ref);
+            if (ret < 0)
                 goto fail;
-            }
-        }else{
+        } else {
             int g3d1 = (compr == TIFF_G3) && !(opts & 1);
-            if(compr!=TIFF_CCITT_RLE && has_eol && find_group3_syncmarker(&gb, srcsize*8) < 0)
+            if (compr != TIFF_CCITT_RLE &&
+                has_eol &&
+                find_group3_syncmarker(&gb, srcsize * 8) < 0)
                 break;
-            if(compr==TIFF_CCITT_RLE || g3d1 || get_bits1(&gb))
-                ret = decode_group3_1d_line(avctx, &gb, avctx->width, runs, runend);
+            if (compr == TIFF_CCITT_RLE || g3d1 || get_bits1(&gb))
+                ret = decode_group3_1d_line(avctx, &gb, avctx->width, runs,
+                                            runend);
             else
-                ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref);
-            if(compr==TIFF_CCITT_RLE)
+                ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs,
+                                            runend, ref);
+            if (compr == TIFF_CCITT_RLE)
                 align_get_bits(&gb);
         }
-        if(ret < 0){
+        if (avctx->err_recognition & AV_EF_EXPLODE && ret < 0)
+            goto fail;
+
+        if (ret < 0) {
             put_line(dst, stride, avctx->width, ref);
-        }else{
+        } else {
             put_line(dst, stride, avctx->width, runs);
-            FFSWAP(int*, runs, ref);
+            FFSWAP(int *, runs, ref);
         }
         dst += stride;
     }
+    ret = 0;
 fail:
     av_free(runs);
     av_free(ref);
-    return err;
+    return ret;
 }
diff --git a/libavcodec/fft-fixed32-test.c b/libavcodec/fft-fixed32-test.c
new file mode 100644
index 0000000..89cd47c
--- /dev/null
+++ b/libavcodec/fft-fixed32-test.c
@@ -0,0 +1,21 @@
+/*
+ * 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 CONFIG_FFT_FLOAT 0
+#define CONFIG_FFT_FIXED_32 1
+#include "fft-test.c"
diff --git a/libavcodec/fft-internal.h b/libavcodec/fft-internal.h
index d66731f..065eecc 100644
--- a/libavcodec/fft-internal.h
+++ b/libavcodec/fft-internal.h
@@ -36,12 +36,29 @@
 
 #else
 
+#define SCALE_FLOAT(a, bits) lrint((a) * (double)(1 << (bits)))
+
+#if CONFIG_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 /* CONFIG_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))
@@ -62,6 +79,8 @@
 #define CMULL(dre, dim, are, aim, bre, bim)     \
     CMULS(dre, dim, are, aim, bre, bim, 0)
 
+#endif /* CONFIG_FFT_FIXED_32 */
+
 #endif /* CONFIG_FFT_FLOAT */
 
 #define ff_imdct_calc_c FFT_NAME(ff_imdct_calc_c)
diff --git a/libavcodec/fft-test.c b/libavcodec/fft-test.c
index 66474ce..9831b2c 100644
--- a/libavcodec/fft-test.c
+++ b/libavcodec/fft-test.c
@@ -54,6 +54,10 @@
 #   define RANGE 1.0
 #   define REF_SCALE(x, bits)  (x)
 #   define FMT "%10.6f"
+#elif CONFIG_FFT_FIXED_32
+#   define RANGE 8388608
+#   define REF_SCALE(x, bits) (x)
+#   define FMT "%6d"
 #else
 #   define RANGE 16384
 #   define REF_SCALE(x, bits) ((x) / (1<<(bits)))
diff --git a/libavcodec/fft.c b/libavcodec/fft.c
index 00c434a..e0cf1f2 100644
--- a/libavcodec/fft.c
+++ b/libavcodec/fft.c
@@ -32,6 +32,10 @@
 #include "fft.h"
 #include "fft-internal.h"
 
+#if CONFIG_FFT_FIXED_32
+#include "fft_table.h"
+#else /* CONFIG_FFT_FIXED_32 */
+
 /* cos(2*pi*x/n) for 0<=x<=n/4, followed by its reverse */
 #if !CONFIG_HARDCODED_TABLES
 COSTABLE(16);
@@ -65,8 +69,10 @@
     FFT_NAME(ff_cos_65536),
 };
 
-static void ff_fft_permute_c(FFTContext *s, FFTComplex *z);
-static void ff_fft_calc_c(FFTContext *s, FFTComplex *z);
+#endif /* CONFIG_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)
 {
@@ -81,7 +87,7 @@
 
 av_cold void ff_init_ff_cos_tabs(int index)
 {
-#if !CONFIG_HARDCODED_TABLES
+#if (!CONFIG_HARDCODED_TABLES) && (!CONFIG_FFT_FIXED_32)
     int i;
     int m = 1<<index;
     double freq = 2*M_PI/m;
@@ -149,17 +155,23 @@
     s->inverse = inverse;
     s->fft_permutation = FF_FFT_PERM_DEFAULT;
 
-    s->fft_permute = ff_fft_permute_c;
-    s->fft_calc    = ff_fft_calc_c;
+    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 CONFIG_FFT_FIXED_32
+    {
+        int n=0;
+        ff_fft_lut_init(fft_offsets_lut, 0, 1 << 16, &n);
+    }
+#else /* CONFIG_FFT_FIXED_32 */
 #if CONFIG_FFT_FLOAT
     if (ARCH_ARM)     ff_fft_init_arm(s);
-    if (HAVE_ALTIVEC) ff_fft_init_altivec(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);
@@ -167,16 +179,17 @@
     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 /* CONFIG_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;
+            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;
@@ -190,7 +203,7 @@
     return -1;
 }
 
-static void ff_fft_permute_c(FFTContext *s, FFTComplex *z)
+static void fft_permute_c(FFTContext *s, FFTComplex *z)
 {
     int j, np;
     const uint16_t *revtab = s->revtab;
@@ -206,6 +219,169 @@
     av_freep(&s->tmp_buf);
 }
 
+#if CONFIG_FFT_FIXED_32
+
+static void fft_calc_c(FFTContext *s, FFTComplex *z) {
+
+    int nbits, i, n, num_transforms, offset, step;
+    int n4, n2, n34;
+    FFTSample tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
+    FFTComplex *tmpz;
+    FFTSample w_re, w_im;
+    FFTSample *w_re_ptr, *w_im_ptr;
+    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 = fft_offsets_lut[n] << 2;
+        tmpz = z + offset;
+
+        tmp1 = tmpz[0].re + tmpz[1].re;
+        tmp5 = tmpz[2].re + tmpz[3].re;
+        tmp2 = tmpz[0].im + tmpz[1].im;
+        tmp6 = tmpz[2].im + tmpz[3].im;
+        tmp3 = tmpz[0].re - tmpz[1].re;
+        tmp8 = tmpz[2].im - tmpz[3].im;
+        tmp4 = tmpz[0].im - tmpz[1].im;
+        tmp7 = tmpz[2].re - 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 = fft_offsets_lut[n] << 3;
+        tmpz = z + offset;
+
+        tmp1 = tmpz[4].re + tmpz[5].re;
+        tmp3 = tmpz[6].re + tmpz[7].re;
+        tmp2 = tmpz[4].im + tmpz[5].im;
+        tmp4 = tmpz[6].im + tmpz[7].im;
+        tmp5 = tmp1 + tmp3;
+        tmp7 = tmp1 - tmp3;
+        tmp6 = tmp2 + tmp4;
+        tmp8 = tmp2 - tmp4;
+
+        tmp1 = tmpz[4].re - tmpz[5].re;
+        tmp2 = tmpz[4].im - tmpz[5].im;
+        tmp3 = tmpz[6].re - tmpz[7].re;
+        tmp4 = tmpz[6].im - 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)*(tmp1 + tmp2);
+        tmp5 = (int32_t)((accu + 0x40000000) >> 31);
+        accu = (int64_t)Q31(M_SQRT1_2)*(tmp3 - tmp4);
+        tmp7 = (int32_t)((accu + 0x40000000) >> 31);
+        accu = (int64_t)Q31(M_SQRT1_2)*(tmp2 - tmp1);
+        tmp6 = (int32_t)((accu + 0x40000000) >> 31);
+        accu = (int64_t)Q31(M_SQRT1_2)*(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++){
+            offset = fft_offsets_lut[n] << nbits;
+            tmpz = z + offset;
+
+            tmp5 = tmpz[ n2].re + tmpz[n34].re;
+            tmp1 = tmpz[ n2].re - tmpz[n34].re;
+            tmp6 = tmpz[ n2].im + tmpz[n34].im;
+            tmp2 = tmpz[ n2].im - 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;
+
+            w_re_ptr = w_tab_sr + step;
+            w_im_ptr = w_tab_sr + MAX_FFT_SIZE/(4*16) - step;
+
+            for (i=1; i<n4; i++){
+                w_re = w_re_ptr[0];
+                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 /* CONFIG_FFT_FIXED_32 */
+
 #define BUTTERFLIES(a0,a1,a2,a3) {\
     BF(t3, t5, t5, t1);\
     BF(a2.re, a0.re, a0.re, t5);\
@@ -347,7 +523,8 @@
     fft2048, fft4096, fft8192, fft16384, fft32768, fft65536,
 };
 
-static void ff_fft_calc_c(FFTContext *s, FFTComplex *z)
+static void fft_calc_c(FFTContext *s, FFTComplex *z)
 {
     fft_dispatch[s->nbits-2](z);
 }
+#endif /* CONFIG_FFT_FIXED_32 */
diff --git a/libavcodec/fft.h b/libavcodec/fft.h
index 9d92b2c..217090c 100644
--- a/libavcodec/fft.h
+++ b/libavcodec/fft.h
@@ -26,6 +26,10 @@
 #define CONFIG_FFT_FLOAT 1
 #endif
 
+#ifndef CONFIG_FFT_FIXED_32
+#define CONFIG_FFT_FIXED_32 0
+#endif
+
 #include <stdint.h>
 #include "config.h"
 #include "libavutil/mem.h"
@@ -40,15 +44,26 @@
 
 #else
 
+#if CONFIG_FFT_FIXED_32
+
+#define Q31(x) (int)((x)*2147483648.0 + 0.5)
+#define FFT_NAME(x) x ## _fixed_32
+
+typedef int32_t FFTSample;
+
+#else /* CONFIG_FFT_FIXED_32 */
+
 #define FFT_NAME(x) x ## _fixed
 
 typedef int16_t FFTSample;
-typedef int     FFTDouble;
+
+#endif /* CONFIG_FFT_FIXED_32 */
 
 typedef struct FFTComplex {
-    int16_t re, im;
+    FFTSample re, im;
 } FFTComplex;
 
+typedef int    FFTDouble;
 typedef struct FFTContext FFTContext;
 
 #endif /* CONFIG_FFT_FLOAT */
@@ -133,14 +148,12 @@
  */
 int ff_fft_init(FFTContext *s, int nbits, int inverse);
 
-#if CONFIG_FFT_FLOAT
-void ff_fft_init_altivec(FFTContext *s);
 void ff_fft_init_x86(FFTContext *s);
 void ff_fft_init_arm(FFTContext *s);
 void ff_fft_init_mips(FFTContext *s);
-#else
+void ff_fft_init_ppc(FFTContext *s);
+
 void ff_fft_fixed_init_arm(FFTContext *s);
-#endif
 
 void ff_fft_end(FFTContext *s);
 
diff --git a/libavcodec/fft_fixed.c b/libavcodec/fft_fixed.c
index 3955efe..153b7d8 100644
--- a/libavcodec/fft_fixed.c
+++ b/libavcodec/fft_fixed.c
@@ -17,4 +17,5 @@
  */
 
 #define CONFIG_FFT_FLOAT 0
+#define CONFIG_FFT_FIXED_32 0
 #include "fft.c"
diff --git a/libavcodec/mips/fft_table.h b/libavcodec/fft_fixed_32.c
similarity index 83%
copy from libavcodec/mips/fft_table.h
copy to libavcodec/fft_fixed_32.c
index dd52eaf..f2954d7 100644
--- a/libavcodec/mips/fft_table.h
+++ b/libavcodec/fft_fixed_32.c
@@ -26,7 +26,9 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * Author:  Stanislav Ocovaj (socovaj@mips.com)
+ * Authors:  Stanislav Ocovaj (socovaj@mips.com)
+ *           Goran Cordasic   (goran@mips.com)
+ *           Djordje Pesut    (djordje@mips.com)
  *
  * This file is part of FFmpeg.
  *
@@ -45,19 +47,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-/**
- * @file
- * definitions and LUT table for MIPS FFT
- */
-#ifndef AVCODEC_MIPS_FFT_TABLE_H
-#define AVCODEC_MIPS_FFT_TABLE_H
-
-#include "libavcodec/fft.h"
-
-#define MAX_LOG2_NFFT 16 //!< Specifies maxiumum allowed fft size
-#define MAX_FFT_SIZE (1 << MAX_LOG2_NFFT)
-
-extern uint16_t fft_offsets_lut[];
-void ff_fft_lut_init(uint16_t *table, int off, int size, int *index);
-
-#endif /* AVCODEC_MIPS_FFT_TABLE_H */
+#define CONFIG_FFT_FLOAT 0
+#define CONFIG_FFT_FIXED_32 1
+#include "fft.c"
diff --git a/libavcodec/fft_float.c b/libavcodec/fft_float.c
index 2149646..011dc45 100644
--- a/libavcodec/fft_float.c
+++ b/libavcodec/fft_float.c
@@ -17,4 +17,5 @@
  */
 
 #define CONFIG_FFT_FLOAT 1
+#define CONFIG_FFT_FIXED_32 0
 #include "fft.c"
diff --git a/libavcodec/fft_init_table.c b/libavcodec/fft_init_table.c
new file mode 100644
index 0000000..7511dbe
--- /dev/null
+++ b/libavcodec/fft_init_table.c
@@ -0,0 +1,200 @@
+/*
+ * 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.
+ *
+ * Authors:  Stanislav Ocovaj (socovaj@mips.com)
+ *           Goran Cordasic   (goran@mips.com)
+ *           Djordje Pesut    (djordje@mips.com)
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * definitions and initialization of LUT table for FFT
+ */
+#include "libavcodec/fft_table.h"
+
+int32_t w_tab_sr[MAX_FFT_SIZE/(4*16)] = {
+    2147483647, 2147481121, 2147473542, 2147460908, 2147443222, 2147420483, 2147392690, 2147359845,
+    2147321946, 2147278995, 2147230991, 2147177934, 2147119825, 2147056664, 2146988450, 2146915184,
+    2146836866, 2146753497, 2146665076, 2146571603, 2146473080, 2146369505, 2146260881, 2146147205,
+    2146028480, 2145904705, 2145775880, 2145642006, 2145503083, 2145359112, 2145210092, 2145056025,
+    2144896910, 2144732748, 2144563539, 2144389283, 2144209982, 2144025635, 2143836244, 2143641807,
+    2143442326, 2143237802, 2143028234, 2142813624, 2142593971, 2142369276, 2142139541, 2141904764,
+    2141664948, 2141420092, 2141170197, 2140915264, 2140655293, 2140390284, 2140120240, 2139845159,
+    2139565043, 2139279892, 2138989708, 2138694490, 2138394240, 2138088958, 2137778644, 2137463301,
+    2137142927, 2136817525, 2136487095, 2136151637, 2135811153, 2135465642, 2135115107, 2134759548,
+    2134398966, 2134033361, 2133662734, 2133287087, 2132906420, 2132520734, 2132130030, 2131734309,
+    2131333572, 2130927819, 2130517052, 2130101272, 2129680480, 2129254676, 2128823862, 2128388038,
+    2127947206, 2127501367, 2127050522, 2126594672, 2126133817, 2125667960, 2125197100, 2124721240,
+    2124240380, 2123754522, 2123263666, 2122767814, 2122266967, 2121761126, 2121250292, 2120734467,
+    2120213651, 2119687847, 2119157054, 2118621275, 2118080511, 2117534762, 2116984031, 2116428319,
+    2115867626, 2115301954, 2114731305, 2114155680, 2113575080, 2112989506, 2112398960, 2111803444,
+    2111202959, 2110597505, 2109987085, 2109371700, 2108751352, 2108126041, 2107495770, 2106860540,
+    2106220352, 2105575208, 2104925109, 2104270057, 2103610054, 2102945101, 2102275199, 2101600350,
+    2100920556, 2100235819, 2099546139, 2098851519, 2098151960, 2097447464, 2096738032, 2096023667,
+    2095304370, 2094580142, 2093850985, 2093116901, 2092377892, 2091633960, 2090885105, 2090131331,
+    2089372638, 2088609029, 2087840505, 2087067068, 2086288720, 2085505463, 2084717298, 2083924228,
+    2083126254, 2082323379, 2081515603, 2080702930, 2079885360, 2079062896, 2078235540, 2077403294,
+    2076566160, 2075724139, 2074877233, 2074025446, 2073168777, 2072307231, 2071440808, 2070569511,
+    2069693342, 2068812302, 2067926394, 2067035621, 2066139983, 2065239484, 2064334124, 2063423908,
+    2062508835, 2061588910, 2060664133, 2059734508, 2058800036, 2057860719, 2056916560, 2055967560,
+    2055013723, 2054055050, 2053091544, 2052123207, 2051150040, 2050172048, 2049189231, 2048201592,
+    2047209133, 2046211857, 2045209767, 2044202863, 2043191150, 2042174628, 2041153301, 2040127172,
+    2039096241, 2038060512, 2037019988, 2035974670, 2034924562, 2033869665, 2032809982, 2031745516,
+    2030676269, 2029602243, 2028523442, 2027439867, 2026351522, 2025258408, 2024160529, 2023057887,
+    2021950484, 2020838323, 2019721407, 2018599739, 2017473321, 2016342155, 2015206245, 2014065592,
+    2012920201, 2011770073, 2010615210, 2009455617, 2008291295, 2007122248, 2005948478, 2004769987,
+    2003586779, 2002398857, 2001206222, 2000008879, 1998806829, 1997600076, 1996388622, 1995172471,
+    1993951625, 1992726087, 1991495860, 1990260946, 1989021350, 1987777073, 1986528118, 1985274489,
+    1984016189, 1982753220, 1981485585, 1980213288, 1978936331, 1977654717, 1976368450, 1975077532,
+    1973781967, 1972481757, 1971176906, 1969867417, 1968553292, 1967234535, 1965911148, 1964583136,
+    1963250501, 1961913246, 1960571375, 1959224890, 1957873796, 1956518093, 1955157788, 1953792881,
+    1952423377, 1951049279, 1949670589, 1948287312, 1946899451, 1945507008, 1944109987, 1942708392,
+    1941302225, 1939891490, 1938476190, 1937056329, 1935631910, 1934202936, 1932769411, 1931331338,
+    1929888720, 1928441561, 1926989864, 1925533633, 1924072871, 1922607581, 1921137767, 1919663432,
+    1918184581, 1916701216, 1915213340, 1913720958, 1912224073, 1910722688, 1909216806, 1907706433,
+    1906191570, 1904672222, 1903148392, 1901620084, 1900087301, 1898550047, 1897008325, 1895462140,
+    1893911494, 1892356392, 1890796837, 1889232832, 1887664383, 1886091491, 1884514161, 1882932397,
+    1881346202, 1879755580, 1878160535, 1876561070, 1874957189, 1873348897, 1871736196, 1870119091,
+    1868497586, 1866871683, 1865241388, 1863606704, 1861967634, 1860324183, 1858676355, 1857024153,
+    1855367581, 1853706643, 1852041343, 1850371686, 1848697674, 1847019312, 1845336604, 1843649553,
+    1841958164, 1840262441, 1838562388, 1836858008, 1835149306, 1833436286, 1831718951, 1829997307,
+    1828271356, 1826541103, 1824806552, 1823067707, 1821324572, 1819577151, 1817825449, 1816069469,
+    1814309216, 1812544694, 1810775906, 1809002858, 1807225553, 1805443995, 1803658189, 1801868139,
+    1800073849, 1798275323, 1796472565, 1794665580, 1792854372, 1791038946, 1789219305, 1787395453,
+    1785567396, 1783735137, 1781898681, 1780058032, 1778213194, 1776364172, 1774510970, 1772653593,
+    1770792044, 1768926328, 1767056450, 1765182414, 1763304224, 1761421885, 1759535401, 1757644777,
+    1755750017, 1753851126, 1751948107, 1750040966, 1748129707, 1746214334, 1744294853, 1742371267,
+    1740443581, 1738511799, 1736575927, 1734635968, 1732691928, 1730743810, 1728791620, 1726835361,
+    1724875040, 1722910659, 1720942225, 1718969740, 1716993211, 1715012642, 1713028037, 1711039401,
+    1709046739, 1707050055, 1705049355, 1703044642, 1701035922, 1699023199, 1697006479, 1694985765,
+    1692961062, 1690932376, 1688899711, 1686863072, 1684822463, 1682777890, 1680729357, 1678676870,
+    1676620432, 1674560049, 1672495725, 1670427466, 1668355276, 1666279161, 1664199124, 1662115172,
+    1660027308, 1657935539, 1655839867, 1653740300, 1651636841, 1649529496, 1647418269, 1645303166,
+    1643184191, 1641061349, 1638934646, 1636804087, 1634669676, 1632531418, 1630389319, 1628243383,
+    1626093616, 1623940023, 1621782608, 1619621377, 1617456335, 1615287487, 1613114838, 1610938393,
+    1608758157, 1606574136, 1604386335, 1602194758, 1599999411, 1597800299, 1595597428, 1593390801,
+    1591180426, 1588966306, 1586748447, 1584526854, 1582301533, 1580072489, 1577839726, 1575603251,
+    1573363068, 1571119183, 1568871601, 1566620327, 1564365367, 1562106725, 1559844408, 1557578421,
+    1555308768, 1553035455, 1550758488, 1548477872, 1546193612, 1543905714, 1541614183, 1539319024,
+    1537020244, 1534717846, 1532411837, 1530102222, 1527789007, 1525472197, 1523151797, 1520827813,
+    1518500250, 1516169114, 1513834411, 1511496145, 1509154322, 1506808949, 1504460029, 1502107570,
+    1499751576, 1497392053, 1495029006, 1492662441, 1490292364, 1487918781, 1485541696, 1483161115,
+    1480777044, 1478389489, 1475998456, 1473603949, 1471205974, 1468804538, 1466399645, 1463991302,
+    1461579514, 1459164286, 1456745625, 1454323536, 1451898025, 1449469098, 1447036760, 1444601017,
+    1442161874, 1439719338, 1437273414, 1434824109, 1432371426, 1429915374, 1427455956, 1424993180,
+    1422527051, 1420057574, 1417584755, 1415108601, 1412629117, 1410146309, 1407660183, 1405170745,
+    1402678000, 1400181954, 1397682613, 1395179984, 1392674072, 1390164882, 1387652422, 1385136696,
+    1382617710, 1380095472, 1377569986, 1375041258, 1372509294, 1369974101, 1367435685, 1364894050,
+    1362349204, 1359801152, 1357249901, 1354695455, 1352137822, 1349577007, 1347013017, 1344445857,
+    1341875533, 1339302052, 1336725419, 1334145641, 1331562723, 1328976672, 1326387494, 1323795195,
+    1321199781, 1318601257, 1315999631, 1313394909, 1310787095, 1308176198, 1305562222, 1302945174,
+    1300325060, 1297701886, 1295075659, 1292446384, 1289814068, 1287178717, 1284540337, 1281898935,
+    1279254516, 1276607086, 1273956653, 1271303222, 1268646800, 1265987392, 1263325005, 1260659646,
+    1257991320, 1255320034, 1252645794, 1249968606, 1247288478, 1244605414, 1241919421, 1239230506,
+    1236538675, 1233843935, 1231146291, 1228445750, 1225742318, 1223036002, 1220326809, 1217614743,
+    1214899813, 1212182024, 1209461382, 1206737894, 1204011567, 1201282407, 1198550419, 1195815612,
+    1193077991, 1190337562, 1187594332, 1184848308, 1182099496, 1179347902, 1176593533, 1173836395,
+    1171076495, 1168313840, 1165548435, 1162780288, 1160009405, 1157235792, 1154459456, 1151680403,
+    1148898640, 1146114174, 1143327011, 1140537158, 1137744621, 1134949406, 1132151521, 1129350972,
+    1126547765, 1123741908, 1120933406, 1118122267, 1115308496, 1112492101, 1109673089, 1106851465,
+    1104027237, 1101200410, 1098370993, 1095538991, 1092704411, 1089867259, 1087027544, 1084185270,
+    1081340445, 1078493076, 1075643169, 1072790730, 1069935768, 1067078288, 1064218296, 1061355801,
+    1058490808, 1055623324, 1052753357, 1049880912, 1047005996, 1044128617, 1041248781, 1038366495,
+    1035481766, 1032594600, 1029705004, 1026812985, 1023918550, 1021021705, 1018122458, 1015220816,
+    1012316784, 1009410370, 1006501581, 1003590424, 1000676905,  997761031,  994842810,  991922248,
+     988999351,  986074127,  983146583,  980216726,  977284562,  974350098,  971413342,  968474300,
+     965532978,  962589385,  959643527,  956695411,  953745043,  950792431,  947837582,  944880503,
+     941921200,  938959681,  935995952,  933030021,  930061894,  927091579,  924119082,  921144411,
+     918167572,  915188572,  912207419,  909224120,  906238681,  903251110,  900261413,  897269597,
+     894275671,  891279640,  888281512,  885281293,  882278992,  879274614,  876268167,  873259659,
+     870249095,  867236484,  864221832,  861205147,  858186435,  855165703,  852142959,  849118210,
+     846091463,  843062726,  840032004,  836999305,  833964638,  830928007,  827889422,  824848888,
+     821806413,  818762005,  815715670,  812667415,  809617249,  806565177,  803511207,  800455346,
+     797397602,  794337982,  791276492,  788213141,  785147934,  782080880,  779011986,  775941259,
+     772868706,  769794334,  766718151,  763640164,  760560380,  757478806,  754395449,  751310318,
+     748223418,  745134758,  742044345,  738952186,  735858287,  732762657,  729665303,  726566232,
+     723465451,  720362968,  717258790,  714152924,  711045377,  707936158,  704825272,  701712728,
+     698598533,  695482694,  692365218,  689246113,  686125387,  683003045,  679879097,  676753549,
+     673626408,  670497682,  667367379,  664235505,  661102068,  657967075,  654830535,  651692453,
+     648552838,  645411696,  642269036,  639124865,  635979190,  632832018,  629683357,  626533215,
+     623381598,  620228514,  617073971,  613917975,  610760536,  607601658,  604441352,  601279623,
+     598116479,  594951927,  591785976,  588618632,  585449903,  582279796,  579108320,  575935480,
+     572761285,  569585743,  566408860,  563230645,  560051104,  556870245,  553688076,  550504604,
+     547319836,  544133781,  540946445,  537757837,  534567963,  531376831,  528184449,  524990824,
+     521795963,  518599875,  515402566,  512204045,  509004318,  505803394,  502601279,  499397982,
+     496193509,  492987869,  489781069,  486573117,  483364019,  480153784,  476942419,  473729932,
+     470516330,  467301622,  464085813,  460868912,  457650927,  454431865,  451211734,  447990541,
+     444768294,  441545000,  438320667,  435095303,  431868915,  428641511,  425413098,  422183684,
+     418953276,  415721883,  412489512,  409256170,  406021865,  402786604,  399550396,  396313247,
+     393075166,  389836160,  386596237,  383355404,  380113669,  376871039,  373627523,  370383128,
+     367137861,  363891730,  360644742,  357396906,  354148230,  350898719,  347648383,  344397230,
+     341145265,  337892498,  334638936,  331384586,  328129457,  324873555,  321616889,  318359466,
+     315101295,  311842381,  308582734,  305322361,  302061269,  298799466,  295536961,  292273760,
+     289009871,  285745302,  282480061,  279214155,  275947592,  272680379,  269412525,  266144038,
+     262874923,  259605191,  256334847,  253063900,  249792358,  246520228,  243247518,  239974235,
+     236700388,  233425984,  230151030,  226875535,  223599506,  220322951,  217045878,  213768293,
+     210490206,  207211624,  203932553,  200653003,  197372981,  194092495,  190811551,  187530159,
+     184248325,  180966058,  177683365,  174400254,  171116733,  167832808,  164548489,  161263783,
+     157978697,  154693240,  151407418,  148121241,  144834714,  141547847,  138260647,  134973122,
+     131685278,  128397125,  125108670,  121819921,  118530885,  115241570,  111951983,  108662134,
+     105372028,  102081675,   98791081,   95500255,   92209205,   88917937,   85626460,   82334782,
+      79042909,   75750851,   72458615,   69166208,   65873638,   62580914,   59288042,   55995030,
+      52701887,   49408620,   46115236,   42821744,   39528151,   36234466,   32940695,   29646846,
+      26352928,   23058947,   19764913,   16470832,   13176712,    9882561,    6588387,    3294197
+};
+
+uint16_t fft_offsets_lut[0x2aab];
+
+void ff_fft_lut_init(uint16_t *table, int off, int size, int *index)
+{
+    if (size < 16) {
+        table[*index] = off >> 2;
+        (*index)++;
+    }
+    else {
+        ff_fft_lut_init(table, off, size>>1, index);
+        ff_fft_lut_init(table, off+(size>>1), size>>2, index);
+        ff_fft_lut_init(table, off+3*(size>>2), size>>2, index);
+    }
+}
diff --git a/libavcodec/mips/fft_table.h b/libavcodec/fft_table.h
similarity index 89%
rename from libavcodec/mips/fft_table.h
rename to libavcodec/fft_table.h
index dd52eaf..687e5b9 100644
--- a/libavcodec/mips/fft_table.h
+++ b/libavcodec/fft_table.h
@@ -26,7 +26,9 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * Author:  Stanislav Ocovaj (socovaj@mips.com)
+ * Authors:  Stanislav Ocovaj (socovaj@mips.com)
+ *           Goran Cordasic   (goran@mips.com)
+ *           Djordje Pesut    (djordje@mips.com)
  *
  * This file is part of FFmpeg.
  *
@@ -47,17 +49,18 @@
 
 /**
  * @file
- * definitions and LUT table for MIPS FFT
+ * definitions and tables for FFT
  */
-#ifndef AVCODEC_MIPS_FFT_TABLE_H
-#define AVCODEC_MIPS_FFT_TABLE_H
+#ifndef AVCODEC_FFT_TABLE_H
+#define AVCODEC_FFT_TABLE_H
 
 #include "libavcodec/fft.h"
 
 #define MAX_LOG2_NFFT 16 //!< Specifies maxiumum allowed fft size
 #define MAX_FFT_SIZE (1 << MAX_LOG2_NFFT)
 
+extern int32_t w_tab_sr[];
 extern uint16_t fft_offsets_lut[];
 void ff_fft_lut_init(uint16_t *table, int off, int size, int *index);
 
-#endif /* AVCODEC_MIPS_FFT_TABLE_H */
+#endif /* AVCODEC_FFT_TABLE_H */
diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c
index 404b0e3..9f3206f 100644
--- a/libavcodec/ffv1.c
+++ b/libavcodec/ffv1.c
@@ -1,7 +1,7 @@
 /*
  * FFV1 codec for libavcodec
  *
- * Copyright (c) 2003-2012 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (c) 2003-2013 Michael Niedermayer <michaelni@gmx.at>
  *
  * This file is part of FFmpeg.
  *
@@ -25,6 +25,7 @@
  * FF Video Codec 1 (a lossless codec)
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "libavutil/crc.h"
 #include "libavutil/opt.h"
@@ -48,8 +49,10 @@
     s->avctx = avctx;
     s->flags = avctx->flags;
 
-    avcodec_get_frame_defaults(&s->picture);
-
+    s->picture.f = avcodec_alloc_frame();
+    s->last_picture.f = av_frame_alloc();
+    if (!s->picture.f || !s->last_picture.f)
+        return AVERROR(ENOMEM);
     ff_dsputil_init(&s->dsp, avctx);
 
     s->width  = avctx->width;
@@ -62,7 +65,7 @@
     return 0;
 }
 
-int ffv1_init_slice_state(FFV1Context *f, FFV1Context *fs)
+av_cold int ffv1_init_slice_state(FFV1Context *f, FFV1Context *fs)
 {
     int j;
 
@@ -96,7 +99,7 @@
     return 0;
 }
 
-int ffv1_init_slices_state(FFV1Context *f)
+av_cold int ffv1_init_slices_state(FFV1Context *f)
 {
     int i, ret;
     for (i = 0; i < f->slice_count; i++) {
@@ -191,7 +194,13 @@
     FFV1Context *s = avctx->priv_data;
     int i, j;
 
-    av_frame_unref(&s->last_picture);
+    if (s->picture.f)
+        ff_thread_release_buffer(avctx, &s->picture);
+    av_frame_free(&s->picture.f);
+
+    if (s->last_picture.f)
+        ff_thread_release_buffer(avctx, &s->last_picture);
+    av_frame_free(&s->last_picture.f);
 
     for (j = 0; j < s->slice_count; j++) {
         FFV1Context *fs = s->slice_context[j];
diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h
index 23633c9..9221cc1 100644
--- a/libavcodec/ffv1.h
+++ b/libavcodec/ffv1.h
@@ -41,6 +41,7 @@
 #include "mathops.h"
 #include "put_bits.h"
 #include "rangecoder.h"
+#include "thread.h"
 
 #ifdef __INTEL_COMPILER
 #undef av_flatten
@@ -82,14 +83,15 @@
     uint64_t rc_stat[256][2];
     uint64_t (*rc_stat2[MAX_QUANT_TABLES])[32][2];
     int version;
-    int minor_version;
+    int micro_version;
     int width, height;
     int chroma_planes;
     int chroma_h_shift, chroma_v_shift;
     int transparency;
     int flags;
     int picture_number;
-    AVFrame picture, last_picture;
+    ThreadFrame picture, last_picture;
+    struct FFV1Context *fsrc;
 
     AVFrame *cur;
     int plane_count;
@@ -106,6 +108,7 @@
     int16_t *sample_buffer;
 
     int ec;
+    int intra;
     int slice_damaged;
     int key_frame_ok;
 
diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
index 21afa1d..658c717 100644
--- a/libavcodec/ffv1dec.c
+++ b/libavcodec/ffv1dec.c
@@ -1,7 +1,7 @@
 /*
  * FFV1 decoder
  *
- * Copyright (c) 2003-2012 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (c) 2003-2013 Michael Niedermayer <michaelni@gmx.at>
  *
  * This file is part of FFmpeg.
  *
@@ -34,7 +34,6 @@
 #include "avcodec.h"
 #include "internal.h"
 #include "get_bits.h"
-#include "put_bits.h"
 #include "rangecoder.h"
 #include "golomb.h"
 #include "mathops.h"
@@ -327,6 +326,42 @@
     int width, height, x, y, ret;
     const int ps      = av_pix_fmt_desc_get(c->pix_fmt)->comp[0].step_minus1 + 1;
     AVFrame * const p = f->cur;
+    int i, si;
+
+    for( si=0; fs != f->slice_context[si]; si ++)
+        ;
+
+    if(f->fsrc && !p->key_frame)
+        ff_thread_await_progress(&f->last_picture, si, 0);
+
+    if(f->fsrc && !p->key_frame) {
+        FFV1Context *fssrc = f->fsrc->slice_context[si];
+        FFV1Context *fsdst = f->slice_context[si];
+        av_assert1(fsdst->plane_count == fssrc->plane_count);
+        av_assert1(fsdst == fs);
+
+        if (!p->key_frame)
+            fsdst->slice_damaged |= fssrc->slice_damaged;
+
+        for (i = 0; i < f->plane_count; i++) {
+            PlaneContext *psrc = &fssrc->plane[i];
+            PlaneContext *pdst = &fsdst->plane[i];
+
+            av_free(pdst->state);
+            av_free(pdst->vlc_state);
+            memcpy(pdst, psrc, sizeof(*pdst));
+            pdst->state = NULL;
+            pdst->vlc_state = NULL;
+
+            if (fssrc->ac) {
+                pdst->state = av_malloc(CONTEXT_SIZE * psrc->context_count);
+                memcpy(pdst->state, psrc->state, CONTEXT_SIZE * psrc->context_count);
+            } else {
+                pdst->vlc_state = av_malloc(sizeof(*pdst->vlc_state) * psrc->context_count);
+                memcpy(pdst->vlc_state, psrc->vlc_state, sizeof(*pdst->vlc_state) * psrc->context_count);
+            }
+        }
+    }
 
     if (f->version > 2) {
         if (ffv1_init_slice_state(f, fs) < 0)
@@ -347,7 +382,7 @@
     y      = fs->slice_y;
 
     if (!fs->ac) {
-        if (f->version == 3 && f->minor_version > 1 || f->version > 3)
+        if (f->version == 3 && f->micro_version > 1 || f->version > 3)
             get_rac(&fs->c, (uint8_t[]) { 129 });
         fs->ac_byte_count = f->version > 2 || (!x && !y) ? fs->c.bytestream - fs->c.bytestream_start - 1 : 0;
         init_get_bits(&fs->gb,
@@ -357,8 +392,8 @@
 
     av_assert1(width && height);
     if (f->colorspace == 0) {
-        const int chroma_width  = -((-width) >> f->chroma_h_shift);
-        const int chroma_height = -((-height) >> f->chroma_v_shift);
+        const int chroma_width  = FF_CEIL_RSHIFT(width,  f->chroma_h_shift);
+        const int chroma_height = FF_CEIL_RSHIFT(height, f->chroma_v_shift);
         const int cx            = x >> f->chroma_h_shift;
         const int cy            = y >> f->chroma_v_shift;
         decode_plane(fs, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0);
@@ -387,6 +422,8 @@
 
     emms_c();
 
+    ff_thread_report_progress(&f->picture, si, 0);
+
     return 0;
 }
 
@@ -448,7 +485,7 @@
     f->version = get_symbol(c, state, 0);
     if (f->version > 2) {
         c->bytestream_end -= 4;
-        f->minor_version = get_symbol(c, state, 0);
+        f->micro_version = get_symbol(c, state, 0);
     }
     f->ac = f->avctx->coder_type = get_symbol(c, state, 0);
     if (f->ac > 1) {
@@ -462,7 +499,7 @@
     f->chroma_h_shift             = get_symbol(c, state, 0);
     f->chroma_v_shift             = get_symbol(c, state, 0);
     f->transparency               = get_rac(c, state);
-    f->plane_count                = 2 + f->transparency;
+    f->plane_count                = 1 + (f->chroma_planes || f->version<4) + f->transparency;
     f->num_h_slices               = 1 + get_symbol(c, state, 0);
     f->num_v_slices               = 1 + get_symbol(c, state, 0);
 
@@ -499,6 +536,8 @@
 
     if (f->version > 2) {
         f->ec = get_symbol(c, state, 0);
+        if (f->micro_version > 2)
+            f->intra = get_symbol(c, state, 0);
     }
 
     if (f->version > 2) {
@@ -511,6 +550,20 @@
         }
     }
 
+    if (f->avctx->debug & FF_DEBUG_PICT_INFO)
+        av_log(f->avctx, AV_LOG_DEBUG,
+               "global: ver:%d.%d, coder:%d, colorspace: %d bpr:%d chroma:%d(%d:%d), alpha:%d slices:%dx%d qtabs:%d ec:%d intra:%d\n",
+               f->version, f->micro_version,
+               f->ac,
+               f->colorspace,
+               f->avctx->bits_per_raw_sample,
+               f->chroma_planes, f->chroma_h_shift, f->chroma_v_shift,
+               f->transparency,
+               f->num_h_slices, f->num_v_slices,
+               f->quant_table_count,
+               f->ec,
+               f->intra
+              );
     return 0;
 }
 
@@ -723,6 +776,8 @@
     if ((ret = ffv1_init_slice_contexts(f)) < 0)
         return ret;
 
+    avctx->internal->allocate_progress = 1;
+
     return 0;
 }
 
@@ -735,10 +790,22 @@
     int i, ret;
     uint8_t keystate = 128;
     const uint8_t *buf_p;
-    AVFrame *const p    = data;
+    AVFrame *p;
 
-    f->cur = p;
+    if (f->last_picture.f)
+        ff_thread_release_buffer(avctx, &f->last_picture);
+    FFSWAP(ThreadFrame, f->picture, f->last_picture);
 
+    f->cur = p = f->picture.f;
+
+    if (f->version < 3 && avctx->field_order > AV_FIELD_PROGRESSIVE) {
+        /* we have interlaced material flagged in container */
+        p->interlaced_frame = 1;
+        if (avctx->field_order == AV_FIELD_TT || avctx->field_order == AV_FIELD_TB)
+            p->top_field_first = 1;
+    }
+
+    f->avctx = avctx;
     ff_init_range_decoder(c, buf, buf_size);
     ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8);
 
@@ -758,13 +825,15 @@
         p->key_frame = 0;
     }
 
-    if ((ret = ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, &f->picture, AV_GET_BUFFER_FLAG_REF)) < 0)
         return ret;
 
     if (avctx->debug & FF_DEBUG_PICT_INFO)
         av_log(avctx, AV_LOG_DEBUG, "ver:%d keyframe:%d coder:%d ec:%d slices:%d bps:%d\n",
                f->version, p->key_frame, f->ac, f->ec, f->slice_count, f->avctx->bits_per_raw_sample);
 
+    ff_thread_finish_setup(avctx);
+
     buf_p = buf + buf_size;
     for (i = f->slice_count - 1; i >= 0; i--) {
         FFV1Context *fs = f->slice_context[i];
@@ -800,6 +869,7 @@
         } else
             fs->c.bytestream_end = (uint8_t *)(buf_p + v);
 
+        fs->avctx = avctx;
         fs->cur = p;
     }
 
@@ -813,37 +883,98 @@
     for (i = f->slice_count - 1; i >= 0; i--) {
         FFV1Context *fs = f->slice_context[i];
         int j;
-        if (fs->slice_damaged && f->last_picture.data[0]) {
+        if (fs->slice_damaged && f->last_picture.f->data[0]) {
             const uint8_t *src[4];
             uint8_t *dst[4];
+            ff_thread_await_progress(&f->last_picture, INT_MAX, 0);
             for (j = 0; j < 4; j++) {
                 int sh = (j==1 || j==2) ? f->chroma_h_shift : 0;
                 int sv = (j==1 || j==2) ? f->chroma_v_shift : 0;
                 dst[j] = p->data[j] + p->linesize[j]*
                          (fs->slice_y>>sv) + (fs->slice_x>>sh);
-                src[j] = f->last_picture.data[j] + f->last_picture.linesize[j]*
+                src[j] = f->last_picture.f->data[j] + f->last_picture.f->linesize[j]*
                          (fs->slice_y>>sv) + (fs->slice_x>>sh);
             }
             av_image_copy(dst, p->linesize, (const uint8_t **)src,
-                          f->last_picture.linesize,
+                          f->last_picture.f->linesize,
                           avctx->pix_fmt,
                           fs->slice_width,
                           fs->slice_height);
         }
     }
+    ff_thread_report_progress(&f->picture, INT_MAX, 0);
 
     f->picture_number++;
 
-    av_frame_unref(&f->last_picture);
-    if ((ret = av_frame_ref(&f->last_picture, p)) < 0)
-        return ret;
+    if (f->last_picture.f)
+        ff_thread_release_buffer(avctx, &f->last_picture);
     f->cur = NULL;
+    if ((ret = av_frame_ref(data, f->picture.f)) < 0)
+        return ret;
 
     *got_frame = 1;
 
     return buf_size;
 }
 
+static int init_thread_copy(AVCodecContext *avctx)
+{
+    FFV1Context *f = avctx->priv_data;
+
+    f->picture.f      = NULL;
+    f->last_picture.f = NULL;
+    f->sample_buffer  = NULL;
+    f->quant_table_count = 0;
+    f->slice_count = 0;
+
+    return 0;
+}
+
+static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
+{
+    FFV1Context *fsrc = src->priv_data;
+    FFV1Context *fdst = dst->priv_data;
+    int i, ret;
+
+    if (dst == src)
+        return 0;
+
+    if (!fdst->picture.f) {
+        memcpy(fdst, fsrc, sizeof(*fdst));
+
+        for (i = 0; i < fdst->quant_table_count; i++) {
+            fdst->initial_states[i] = av_malloc(fdst->context_count[i] * sizeof(*fdst->initial_states[i]));
+            memcpy(fdst->initial_states[i], fsrc->initial_states[i], fdst->context_count[i] * sizeof(*fdst->initial_states[i]));
+        }
+
+        fdst->picture.f      = av_frame_alloc();
+        fdst->last_picture.f = av_frame_alloc();
+
+        if ((ret = ffv1_init_slice_contexts(fdst)) < 0)
+            return ret;
+    }
+
+    av_assert1(fdst->slice_count == fsrc->slice_count);
+
+    fdst->key_frame_ok = fsrc->key_frame_ok;
+
+    ff_thread_release_buffer(dst, &fdst->picture);
+    if (fsrc->picture.f->data[0]) {
+        if ((ret = ff_thread_ref_frame(&fdst->picture, &fsrc->picture)) < 0)
+            return ret;
+    }
+    for (i = 0; i < fdst->slice_count; i++) {
+        FFV1Context *fsdst = fdst->slice_context[i];
+        FFV1Context *fssrc = fsrc->slice_context[i];
+
+        fsdst->slice_damaged = fssrc->slice_damaged;
+    }
+
+    fdst->fsrc = fsrc;
+
+    return 0;
+}
+
 AVCodec ff_ffv1_decoder = {
     .name           = "ffv1",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -852,7 +983,9 @@
     .init           = decode_init,
     .close          = ffv1_close,
     .decode         = decode_frame,
+    .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
+    .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
     .capabilities   = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/ |
-                      CODEC_CAP_SLICE_THREADS,
+                      CODEC_CAP_FRAME_THREADS | CODEC_CAP_SLICE_THREADS,
     .long_name      = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
 };
diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c
index 70fcd65..faf64ca 100644
--- a/libavcodec/ffv1enc.c
+++ b/libavcodec/ffv1enc.c
@@ -1,7 +1,7 @@
 /*
  * FFV1 encoder
  *
- * Copyright (c) 2003-2012 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (c) 2003-2013 Michael Niedermayer <michaelni@gmx.at>
  *
  * This file is part of FFmpeg.
  *
@@ -25,6 +25,7 @@
  * FF Video Codec 1 (a lossless codec) encoder
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "libavutil/crc.h"
 #include "libavutil/opt.h"
@@ -528,14 +529,16 @@
     f->avctx->extradata_size = 10000 + 4 +
                                     (11 * 11 * 5 * 5 * 5 + 11 * 11 * 11) * 32;
     f->avctx->extradata = av_malloc(f->avctx->extradata_size);
+    if (!f->avctx->extradata)
+        return AVERROR(ENOMEM);
     ff_init_range_encoder(c, f->avctx->extradata, f->avctx->extradata_size);
     ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8);
 
     put_symbol(c, state, f->version, 0);
     if (f->version > 2) {
         if (f->version == 3)
-            f->minor_version = 2;
-        put_symbol(c, state, f->minor_version, 0);
+            f->micro_version = 4;
+        put_symbol(c, state, f->micro_version, 0);
     }
 
     put_symbol(c, state, f->ac, 0);
@@ -575,6 +578,7 @@
 
     if (f->version > 2) {
         put_symbol(c, state, f->ec, 0);
+        put_symbol(c, state, f->intra = (f->avctx->gop_size < 2), 0);
     }
 
     f->avctx->extradata_size = ff_rac_terminate(c);
@@ -639,14 +643,15 @@
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
     int i, j, k, m, ret;
 
-    ffv1_common_init(avctx);
+    if ((ret = ffv1_common_init(avctx)) < 0)
+        return ret;
 
     s->version = 0;
 
     if ((avctx->flags & (CODEC_FLAG_PASS1|CODEC_FLAG_PASS2)) || avctx->slices>1)
         s->version = FFMAX(s->version, 2);
 
-    if (avctx->level == 3) {
+    if (avctx->level == 3 || (s->version==2 && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL)) {
         s->version = 3;
     }
 
@@ -716,9 +721,11 @@
     case AV_PIX_FMT_RGB32:
         s->colorspace = 1;
         s->transparency = 1;
+        s->chroma_planes = 1;
         break;
     case AV_PIX_FMT_0RGB32:
         s->colorspace = 1;
+        s->chroma_planes = 1;
         break;
     case AV_PIX_FMT_GBRP9:
         if (!avctx->bits_per_raw_sample)
@@ -792,9 +799,11 @@
     if ((ret = ffv1_allocate_initial_states(s)) < 0)
         return ret;
 
-    avctx->coded_frame = &s->picture;
     if (!s->transparency)
         s->plane_count = 2;
+    if (!s->chroma_planes && s->version > 3)
+        s->plane_count--;
+
     avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift);
     s->picture_number = 0;
 
@@ -895,7 +904,8 @@
                avctx->slices);
         return AVERROR(ENOSYS);
 slices_ok:
-        write_extradata(s);
+        if ((ret = write_extradata(s)) < 0)
+            return ret;
     }
 
     if ((ret = ffv1_init_slice_contexts(s)) < 0)
@@ -937,12 +947,12 @@
         put_symbol(c, state, f->plane[j].quant_table_index, 0);
         av_assert0(f->plane[j].quant_table_index == f->avctx->context_model);
     }
-    if (!f->picture.interlaced_frame)
+    if (!f->picture.f->interlaced_frame)
         put_symbol(c, state, 3, 0);
     else
-        put_symbol(c, state, 1 + !f->picture.top_field_first, 0);
-    put_symbol(c, state, f->picture.sample_aspect_ratio.num, 0);
-    put_symbol(c, state, f->picture.sample_aspect_ratio.den, 0);
+        put_symbol(c, state, 1 + !f->picture.f->top_field_first, 0);
+    put_symbol(c, state, f->picture.f->sample_aspect_ratio.num, 0);
+    put_symbol(c, state, f->picture.f->sample_aspect_ratio.den, 0);
 }
 
 static int encode_slice(AVCodecContext *c, void *arg)
@@ -953,7 +963,7 @@
     int height       = fs->slice_height;
     int x            = fs->slice_x;
     int y            = fs->slice_y;
-    AVFrame *const p = &f->picture;
+    AVFrame *const p = f->picture.f;
     const int ps     = av_pix_fmt_desc_get(c->pix_fmt)->comp[0].step_minus1 + 1;
 
     if (p->key_frame)
@@ -971,8 +981,8 @@
     }
 
     if (f->colorspace == 0) {
-        const int chroma_width  = -((-width) >> f->chroma_h_shift);
-        const int chroma_height = -((-height) >> f->chroma_v_shift);
+        const int chroma_width  = FF_CEIL_RSHIFT(width,  f->chroma_h_shift);
+        const int chroma_height = FF_CEIL_RSHIFT(height, f->chroma_v_shift);
         const int cx            = x >> f->chroma_h_shift;
         const int cy            = y >> f->chroma_v_shift;
 
@@ -1000,7 +1010,7 @@
 {
     FFV1Context *f      = avctx->priv_data;
     RangeCoder *const c = &f->slice_context[0]->c;
-    AVFrame *const p    = &f->picture;
+    AVFrame *const p    = f->picture.f;
     int used_count      = 0;
     uint8_t keystate    = 128;
     uint8_t *buf_p;
@@ -1013,7 +1023,9 @@
     ff_init_range_encoder(c, pkt->data, pkt->size);
     ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8);
 
-    *p           = *pict;
+    av_frame_unref(p);
+    if ((ret = av_frame_ref(p, pict)) < 0)
+        return ret;
     p->pict_type = AV_PICTURE_TYPE_I;
 
     if (avctx->gop_size == 0 || f->picture_number % avctx->gop_size == 0) {
@@ -1131,7 +1143,7 @@
     { NULL }
 };
 
-static const AVClass class = {
+static const AVClass ffv1_class = {
     .class_name = "ffv1 encoder",
     .item_name  = av_default_item_name,
     .option     = options,
@@ -1165,5 +1177,5 @@
     },
     .long_name      = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
     .defaults       = ffv1_defaults,
-    .priv_class     = &class,
+    .priv_class     = &ffv1_class,
 };
diff --git a/libavcodec/file_open.c b/libavcodec/file_open.c
new file mode 100644
index 0000000..494a5d3
--- /dev/null
+++ b/libavcodec/file_open.c
@@ -0,0 +1 @@
+#include "libavutil/file_open.c"
diff --git a/libavcodec/flac.c b/libavcodec/flac.c
index a79a809..3874b6c 100644
--- a/libavcodec/flac.c
+++ b/libavcodec/flac.c
@@ -55,7 +55,7 @@
     /* frame sync code */
     if ((get_bits(gb, 15) & 0x7FFF) != 0x7FFC) {
         av_log(avctx, AV_LOG_ERROR + log_level_offset, "invalid sync code\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* variable block size stream code */
@@ -76,7 +76,7 @@
     } else {
         av_log(avctx, AV_LOG_ERROR + log_level_offset,
                "invalid channel mode: %d\n", fi->ch_mode);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* bits per sample */
@@ -85,7 +85,7 @@
         av_log(avctx, AV_LOG_ERROR + log_level_offset,
                "invalid sample size code (%d)\n",
                bps_code);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     fi->bps = sample_size_table[bps_code];
 
@@ -93,7 +93,7 @@
     if (get_bits1(gb)) {
         av_log(avctx, AV_LOG_ERROR + log_level_offset,
                "broken stream, invalid padding\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* sample or frame count */
@@ -101,14 +101,14 @@
     if (fi->frame_or_sample_num < 0) {
         av_log(avctx, AV_LOG_ERROR + log_level_offset,
                "sample/frame number invalid; utf8 fscked\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* blocksize */
     if (bs_code == 0) {
         av_log(avctx, AV_LOG_ERROR + log_level_offset,
                "reserved blocksize code: 0\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     } else if (bs_code == 6) {
         fi->blocksize = get_bits(gb, 8) + 1;
     } else if (bs_code == 7) {
@@ -130,7 +130,7 @@
         av_log(avctx, AV_LOG_ERROR + log_level_offset,
                "illegal sample rate code %d\n",
                sr_code);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* header CRC-8 check */
@@ -139,7 +139,7 @@
                get_bits_count(gb)/8)) {
         av_log(avctx, AV_LOG_ERROR + log_level_offset,
                "header crc mismatch\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     return 0;
diff --git a/libavcodec/flac_parser.c b/libavcodec/flac_parser.c
index e2c6744..69c2965 100644
--- a/libavcodec/flac_parser.c
+++ b/libavcodec/flac_parser.c
@@ -27,11 +27,12 @@
  * Each time it finds and verifies a CRC-8 header it sees which of the
  * FLAC_MAX_SEQUENTIAL_HEADERS that came before it have a valid CRC-16 footer
  * that ends at the newly found header.
- * Headers are scored by FLAC_HEADER_BASE_SCORE plus the max of it's crc-verified
+ * Headers are scored by FLAC_HEADER_BASE_SCORE plus the max of its crc-verified
  * children, penalized by changes in sample rate, frame number, etc.
  * The parser returns the frame with the highest score.
  **/
 
+#include "libavutil/attributes.h"
 #include "libavutil/crc.h"
 #include "libavutil/fifo.h"
 #include "bytestream.h"
@@ -86,6 +87,8 @@
     int end_padded;                /**< specifies if fifo_buf's end is padded */
     uint8_t *wrap_buf;             /**< general fifo read buffer when wrapped */
     int wrap_buf_allocated_size;   /**< actual allocated size of the buffer   */
+    FLACFrameInfo last_fi;         /**< last decoded frame header info        */
+    int last_fi_valid;             /**< set if last_fi is valid               */
 } FLACParseContext;
 
 static int frame_header_is_valid(AVCodecContext *avctx, const uint8_t *buf,
@@ -266,13 +269,12 @@
     return size;
 }
 
-static int check_header_mismatch(FLACParseContext  *fpc,
-                                 FLACHeaderMarker  *header,
-                                 FLACHeaderMarker  *child,
-                                 int                log_level_offset)
+static int check_header_fi_mismatch(FLACParseContext  *fpc,
+                                    FLACFrameInfo     *header_fi,
+                                    FLACFrameInfo     *child_fi,
+                                    int                log_level_offset)
 {
-    FLACFrameInfo  *header_fi = &header->fi, *child_fi = &child->fi;
-    int deduction = 0, deduction_expected = 0, i;
+    int deduction = 0;
     if (child_fi->samplerate != header_fi->samplerate) {
         deduction += FLAC_HEADER_CHANGED_PENALTY;
         av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
@@ -287,13 +289,25 @@
         /* Changing blocking strategy not allowed per the spec */
         deduction += FLAC_HEADER_BASE_SCORE;
         av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
-                   "blocking strategy change detected in adjacent frames\n");
+               "blocking strategy change detected in adjacent frames\n");
     }
     if (child_fi->channels != header_fi->channels) {
         deduction += FLAC_HEADER_CHANGED_PENALTY;
         av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
-                   "number of channels change detected in adjacent frames\n");
+               "number of channels change detected in adjacent frames\n");
     }
+    return deduction;
+}
+
+static int check_header_mismatch(FLACParseContext  *fpc,
+                                 FLACHeaderMarker  *header,
+                                 FLACHeaderMarker  *child,
+                                 int                log_level_offset)
+{
+    FLACFrameInfo  *header_fi = &header->fi, *child_fi = &child->fi;
+    int deduction, deduction_expected = 0, i;
+    deduction = check_header_fi_mismatch(fpc, header_fi, child_fi,
+                                         log_level_offset);
     /* Check sample and frame numbers. */
     if ((child_fi->frame_or_sample_num - header_fi->frame_or_sample_num
          != header_fi->blocksize) &&
@@ -398,11 +412,18 @@
     FLACHeaderMarker *child;
     int dist = 0;
     int child_score;
-
+    int base_score = FLAC_HEADER_BASE_SCORE;
     if (header->max_score != FLAC_HEADER_NOT_SCORED_YET)
         return header->max_score;
 
-    header->max_score = FLAC_HEADER_BASE_SCORE;
+    /* Modify the base score with changes from the last output header */
+    if (fpc->last_fi_valid) {
+        /* Silence the log since this will be repeated if selected */
+        base_score -= check_header_fi_mismatch(fpc, &fpc->last_fi, &header->fi,
+                                               AV_LOG_DEBUG);
+    }
+
+    header->max_score = base_score;
 
     /* Check and compute the children's scores. */
     child = header->next;
@@ -418,7 +439,7 @@
         if (FLAC_HEADER_BASE_SCORE + child_score > header->max_score) {
             /* Keep the child because the frame scoring is dynamic. */
             header->best_child = child;
-            header->max_score  = FLAC_HEADER_BASE_SCORE + child_score;
+            header->max_score  = base_score + child_score;
         }
         child = child->next;
     }
@@ -429,7 +450,7 @@
 static void score_sequences(FLACParseContext *fpc)
 {
     FLACHeaderMarker *curr;
-    int best_score = FLAC_HEADER_NOT_SCORED_YET;
+    int best_score = 0;//FLAC_HEADER_NOT_SCORED_YET;
     /* First pass to clear all old scores. */
     for (curr = fpc->headers; curr; curr = curr->next)
         curr->max_score = FLAC_HEADER_NOT_SCORED_YET;
@@ -469,6 +490,9 @@
                                         &fpc->wrap_buf_allocated_size);
 
     fpc->best_header_valid = 0;
+    fpc->last_fi_valid = 1;
+    fpc->last_fi = header->fi;
+
     /* Return the negative overread index so the client can compute pos.
        This should be the amount overread to the beginning of the child */
     if (child)
@@ -628,9 +652,12 @@
     }
 
     curr = fpc->headers;
-    for (curr = fpc->headers; curr; curr = curr->next)
-        if (!fpc->best_header || curr->max_score > fpc->best_header->max_score)
+    for (curr = fpc->headers; curr; curr = curr->next) {
+        if (curr->max_score > 0 &&
+            (!fpc->best_header || curr->max_score > fpc->best_header->max_score)) {
             fpc->best_header = curr;
+        }
+    }
 
     if (fpc->best_header) {
         fpc->best_header_valid = 1;
@@ -658,13 +685,15 @@
     return read_end - buf;
 }
 
-static int flac_parse_init(AVCodecParserContext *c)
+static av_cold int flac_parse_init(AVCodecParserContext *c)
 {
     FLACParseContext *fpc = c->priv_data;
     fpc->pc = c;
     /* There will generally be FLAC_MIN_HEADERS buffered in the fifo before
        it drains.  This is allocated early to avoid slow reallocation. */
     fpc->fifo_buf = av_fifo_alloc(FLAC_AVG_FRAME_SIZE * (FLAC_MIN_HEADERS + 3));
+    if (!fpc->fifo_buf)
+        return AVERROR(ENOMEM);
     return 0;
 }
 
diff --git a/libavcodec/flacdata.c b/libavcodec/flacdata.c
index 6fcbe39..1954f32 100644
--- a/libavcodec/flacdata.c
+++ b/libavcodec/flacdata.c
@@ -27,7 +27,7 @@
   8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000,
   0, 0, 0, 0 };
 
-const int16_t ff_flac_blocksize_table[16] = {
+const int32_t ff_flac_blocksize_table[16] = {
      0,    192, 576<<0, 576<<1, 576<<2, 576<<3,      0,      0,
 256<<0, 256<<1, 256<<2, 256<<3, 256<<4, 256<<5, 256<<6, 256<<7
 };
diff --git a/libavcodec/flacdata.h b/libavcodec/flacdata.h
index 96a50b9..e2c1e5d 100644
--- a/libavcodec/flacdata.h
+++ b/libavcodec/flacdata.h
@@ -26,6 +26,6 @@
 
 extern const int ff_flac_sample_rate_table[16];
 
-extern const int16_t ff_flac_blocksize_table[16];
+extern const int32_t ff_flac_blocksize_table[16];
 
 #endif /* AVCODEC_FLACDATA_H */
diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c
index 1bf6dc7..c8301a5 100644
--- a/libavcodec/flacdec.c
+++ b/libavcodec/flacdec.c
@@ -44,6 +44,7 @@
 #include "flac.h"
 #include "flacdata.h"
 #include "flacdsp.h"
+#include "thread.h"
 
 typedef struct FLACContext {
     FLACSTREAMINFO
@@ -408,9 +409,9 @@
     GetBitContext *gb = &s->gb;
     FLACFrameInfo fi;
 
-    if (ff_flac_decode_frame_header(s->avctx, gb, &fi, 0)) {
+    if ((ret = ff_flac_decode_frame_header(s->avctx, gb, &fi, 0)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "invalid frame header\n");
-        return AVERROR_INVALIDDATA;
+        return ret;
     }
 
     if (s->channels && fi.channels != s->channels && s->got_streaminfo) {
@@ -434,7 +435,7 @@
     } else if (s->bps && fi.bps != s->bps) {
         av_log(s->avctx, AV_LOG_ERROR, "switching bps mid-stream is not "
                                        "supported\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (!s->bps) {
@@ -489,6 +490,7 @@
                              int *got_frame_ptr, AVPacket *avpkt)
 {
     AVFrame *frame     = data;
+    ThreadFrame tframe = { .f = data };
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     FLACContext *s = avctx->priv_data;
@@ -521,15 +523,16 @@
 
     /* check for inline header */
     if (AV_RB32(buf) == MKBETAG('f','L','a','C')) {
-        if (!s->got_streaminfo && parse_streaminfo(s, buf, buf_size)) {
+        if (!s->got_streaminfo && (ret = parse_streaminfo(s, buf, buf_size))) {
             av_log(s->avctx, AV_LOG_ERROR, "invalid header\n");
-            return AVERROR_INVALIDDATA;
+            return ret;
         }
         return get_metadata_size(buf, buf_size);
     }
 
     /* decode frame */
-    init_get_bits(&s->gb, buf, buf_size*8);
+    if ((ret = init_get_bits8(&s->gb, buf, buf_size)) < 0)
+        return ret;
     if ((ret = decode_frame(s)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "decode_frame() failed\n");
         return ret;
@@ -546,7 +549,7 @@
 
     /* get output buffer */
     frame->nb_samples = s->blocksize;
-    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
         return ret;
 
     s->dsp.decorrelate[s->ch_mode](frame->data, s->decoded, s->channels,
@@ -566,6 +569,17 @@
     return bytes_read;
 }
 
+static int init_thread_copy(AVCodecContext *avctx)
+{
+    FLACContext *s = avctx->priv_data;
+    s->decoded_buffer = NULL;
+    s->decoded_buffer_size = 0;
+    s->avctx = avctx;
+    if (s->max_blocksize)
+        return allocate_buffers(s);
+    return 0;
+}
+
 static av_cold int flac_decode_close(AVCodecContext *avctx)
 {
     FLACContext *s = avctx->priv_data;
@@ -583,7 +597,8 @@
     .init           = flac_decode_init,
     .close          = flac_decode_close,
     .decode         = flac_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
+    .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
     .long_name      = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
                                                       AV_SAMPLE_FMT_S16P,
diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c
index dc932c6..1e9cc48 100644
--- a/libavcodec/flacenc.c
+++ b/libavcodec/flacenc.c
@@ -1259,7 +1259,7 @@
 
     frame_bytes = encode_frame(s);
 
-    /* fallback to verbatim mode if the compressed frame is larger than it
+    /* Fall back on verbatim mode if the compressed frame is larger than it
        would be if encoded uncompressed. */
     if (frame_bytes < 0 || frame_bytes > s->max_framesize) {
         s->frame.verbatim_only = 1;
diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c
index 9982b5e..f00bf21 100644
--- a/libavcodec/flashsv.c
+++ b/libavcodec/flashsv.c
@@ -387,6 +387,10 @@
                     }
                     s->diff_start  = get_bits(&gb, 8);
                     s->diff_height = get_bits(&gb, 8);
+                    if (s->diff_start + s->diff_height > cur_blk_height) {
+                        av_log(avctx, AV_LOG_ERROR, "Block parameters invalid\n");
+                        return AVERROR_INVALIDDATA;
+                    }
                     av_log(avctx, AV_LOG_DEBUG,
                            "%dx%d diff start %d height %d\n",
                            i, j, s->diff_start, s->diff_height);
diff --git a/libavcodec/flicvideo.c b/libavcodec/flicvideo.c
index 90885fc..a2f9ef9 100644
--- a/libavcodec/flicvideo.c
+++ b/libavcodec/flicvideo.c
@@ -593,7 +593,7 @@
             break;
 
         case FLI_LC:
-            av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-paletised FLC\n");
+            av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-palettized FLC\n");
             bytestream2_skip(&g2, chunk_size - 6);
             break;
 
diff --git a/libavcodec/fmtconvert.c b/libavcodec/fmtconvert.c
index 79e9645..fb4302c 100644
--- a/libavcodec/fmtconvert.c
+++ b/libavcodec/fmtconvert.c
@@ -24,12 +24,23 @@
 #include "fmtconvert.h"
 #include "libavutil/common.h"
 
-static void int32_to_float_fmul_scalar_c(float *dst, const int *src, float mul, int len){
+static void int32_to_float_fmul_scalar_c(float *dst, const int32_t *src,
+                                         float mul, int len)
+{
     int i;
     for(i=0; i<len; i++)
         dst[i] = src[i] * mul;
 }
 
+static void int32_to_float_fmul_array8_c(FmtConvertContext *c, float *dst,
+                                         const int32_t *src, const float *mul,
+                                         int len)
+{
+    int i;
+    for (i = 0; i < len; i += 8)
+        c->int32_to_float_fmul_scalar(&dst[i], &src[i], *mul++, 8);
+}
+
 static av_always_inline int float_to_int16_one(const float *src){
     return av_clip_int16(lrintf(*src));
 }
@@ -79,12 +90,13 @@
 av_cold void ff_fmt_convert_init(FmtConvertContext *c, AVCodecContext *avctx)
 {
     c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_c;
+    c->int32_to_float_fmul_array8 = int32_to_float_fmul_array8_c;
     c->float_to_int16             = float_to_int16_c;
     c->float_to_int16_interleave  = float_to_int16_interleave_c;
     c->float_interleave           = ff_float_interleave_c;
 
     if (ARCH_ARM) ff_fmt_convert_init_arm(c, avctx);
-    if (HAVE_ALTIVEC) ff_fmt_convert_init_altivec(c, avctx);
+    if (ARCH_PPC) ff_fmt_convert_init_ppc(c, avctx);
     if (ARCH_X86) ff_fmt_convert_init_x86(c, avctx);
     if (HAVE_MIPSFPU) ff_fmt_convert_init_mips(c);
 }
diff --git a/libavcodec/fmtconvert.h b/libavcodec/fmtconvert.h
index 3fb9f4e..30abcc3 100644
--- a/libavcodec/fmtconvert.h
+++ b/libavcodec/fmtconvert.h
@@ -35,7 +35,24 @@
      * @param len number of elements to convert.
      *            constraints: multiple of 8
      */
-    void (*int32_to_float_fmul_scalar)(float *dst, const int *src, float mul, int len);
+    void (*int32_to_float_fmul_scalar)(float *dst, const int32_t *src,
+                                       float mul, int len);
+
+    /**
+     * Convert an array of int32_t to float and multiply by a float value from another array,
+     * stepping along the float array once for each 8 integers.
+     * @param c   pointer to FmtConvertContext.
+     * @param dst destination array of float.
+     *            constraints: 16-byte aligned
+     * @param src source array of int32_t.
+     *            constraints: 16-byte aligned
+     * @param mul source array of float multipliers.
+     * @param len number of elements to convert.
+     *            constraints: multiple of 8
+     */
+    void (*int32_to_float_fmul_array8)(struct FmtConvertContext *c,
+                                       float *dst, const int32_t *src,
+                                       const float *mul, int len);
 
     /**
      * Convert an array of float to an array of int16_t.
@@ -90,7 +107,7 @@
 void ff_fmt_convert_init(FmtConvertContext *c, AVCodecContext *avctx);
 
 void ff_fmt_convert_init_arm(FmtConvertContext *c, AVCodecContext *avctx);
-void ff_fmt_convert_init_altivec(FmtConvertContext *c, AVCodecContext *avctx);
+void ff_fmt_convert_init_ppc(FmtConvertContext *c, AVCodecContext *avctx);
 void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx);
 void ff_fmt_convert_init_mips(FmtConvertContext *c);
 
diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c
index b11a54a..b9acefc 100644
--- a/libavcodec/frame_thread_encoder.c
+++ b/libavcodec/frame_thread_encoder.c
@@ -30,9 +30,9 @@
 #if HAVE_PTHREADS
 #include <pthread.h>
 #elif HAVE_W32THREADS
-#include "w32pthreads.h"
+#include "compat/w32pthreads.h"
 #elif HAVE_OS2THREADS
-#include "os2threads.h"
+#include "compat/os2threads.h"
 #endif
 
 #define MAX_THREADS 64
@@ -126,7 +126,7 @@
         return 0;
 
     if(!avctx->thread_count) {
-        avctx->thread_count = ff_get_logical_cpus(avctx);
+        avctx->thread_count = av_cpu_count();
         avctx->thread_count = FFMIN(avctx->thread_count, MAX_THREADS);
     }
 
diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c
index 00a38c6..a1d5a17 100644
--- a/libavcodec/fraps.c
+++ b/libavcodec/fraps.c
@@ -105,7 +105,7 @@
     init_get_bits(&gb, s->tmpbuf, size * 8);
     for (j = 0; j < h; j++) {
         for (i = 0; i < w*step; i += step) {
-            dst[i] = get_vlc2(&gb, vlc.table, 9, 3);
+            dst[i] = get_vlc2(&gb, vlc.table, FF_HUFFMAN_BITS, 3);
             /* lines are stored as deltas between previous lines
              * and we need to add 0x80 to the first lines of chroma planes
              */
@@ -200,6 +200,7 @@
     f->key_frame = 1;
 
     avctx->pix_fmt = version & 1 ? AV_PIX_FMT_BGR24 : AV_PIX_FMT_YUVJ420P;
+    avctx->color_range = version & 1 ? AVCOL_RANGE_UNSPECIFIED : AVCOL_RANGE_JPEG;
 
     if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
         return ret;
diff --git a/libavcodec/g2meet.c b/libavcodec/g2meet.c
new file mode 100644
index 0000000..99d4d1e
--- /dev/null
+++ b/libavcodec/g2meet.c
@@ -0,0 +1,876 @@
+/*
+ * Go2Webinar decoder
+ * Copyright (c) 2012 Konstantin Shishkov
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * Go2Webinar decoder
+ */
+
+#include <zlib.h>
+
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "dsputil.h"
+#include "get_bits.h"
+#include "internal.h"
+#include "mjpeg.h"
+
+enum ChunkType {
+    FRAME_INFO = 0xC8,
+    TILE_DATA,
+    CURSOR_POS,
+    CURSOR_SHAPE,
+    CHUNK_CC,
+    CHUNK_CD
+};
+
+enum Compression {
+    COMPR_EPIC_J_B = 2,
+    COMPR_KEMPF_J_B,
+};
+
+static const uint8_t luma_quant[64] = {
+     8,  6,  5,  8, 12, 20, 26, 31,
+     6,  6,  7, 10, 13, 29, 30, 28,
+     7,  7,  8, 12, 20, 29, 35, 28,
+     7,  9, 11, 15, 26, 44, 40, 31,
+     9, 11, 19, 28, 34, 55, 52, 39,
+    12, 18, 28, 32, 41, 52, 57, 46,
+    25, 32, 39, 44, 52, 61, 60, 51,
+    36, 46, 48, 49, 56, 50, 52, 50
+};
+
+static const uint8_t chroma_quant[64] = {
+     9,  9, 12, 24, 50, 50, 50, 50,
+     9, 11, 13, 33, 50, 50, 50, 50,
+    12, 13, 28, 50, 50, 50, 50, 50,
+    24, 33, 50, 50, 50, 50, 50, 50,
+    50, 50, 50, 50, 50, 50, 50, 50,
+    50, 50, 50, 50, 50, 50, 50, 50,
+    50, 50, 50, 50, 50, 50, 50, 50,
+    50, 50, 50, 50, 50, 50, 50, 50,
+};
+
+typedef struct JPGContext {
+    DSPContext dsp;
+    ScanTable  scantable;
+
+    VLC        dc_vlc[2], ac_vlc[2];
+    int        prev_dc[3];
+    DECLARE_ALIGNED(16, int16_t, block)[6][64];
+
+    uint8_t    *buf;
+} JPGContext;
+
+typedef struct G2MContext {
+    JPGContext jc;
+    int        version;
+
+    int        compression;
+    int        width, height, bpp;
+    int        tile_width, tile_height;
+    int        tiles_x, tiles_y, tile_x, tile_y;
+
+    int        got_header;
+
+    uint8_t    *framebuf;
+    int        framebuf_stride, old_width, old_height;
+
+    uint8_t    *synth_tile, *jpeg_tile;
+    int        tile_stride, old_tile_w, old_tile_h;
+
+    uint8_t    *kempf_buf, *kempf_flags;
+
+    uint8_t    *cursor;
+    int        cursor_stride;
+    int        cursor_fmt;
+    int        cursor_w, cursor_h, cursor_x, cursor_y;
+    int        cursor_hot_x, cursor_hot_y;
+} G2MContext;
+
+static av_cold int build_vlc(VLC *vlc, const uint8_t *bits_table,
+                             const uint8_t *val_table, int nb_codes,
+                             int is_ac)
+{
+    uint8_t  huff_size[256] = { 0 };
+    uint16_t huff_code[256];
+    uint16_t huff_sym[256];
+    int i;
+
+    ff_mjpeg_build_huffman_codes(huff_size, huff_code, bits_table, val_table);
+
+    for (i = 0; i < 256; i++)
+        huff_sym[i] = i + 16 * is_ac;
+
+    if (is_ac)
+        huff_sym[0] = 16 * 256;
+
+    return ff_init_vlc_sparse(vlc, 9, nb_codes, huff_size, 1, 1,
+                              huff_code, 2, 2, huff_sym, 2, 2, 0);
+}
+
+static av_cold int jpg_init(AVCodecContext *avctx, JPGContext *c)
+{
+    int ret;
+
+    ret = build_vlc(&c->dc_vlc[0], avpriv_mjpeg_bits_dc_luminance,
+                    avpriv_mjpeg_val_dc, 12, 0);
+    if (ret)
+        return ret;
+    ret = build_vlc(&c->dc_vlc[1], avpriv_mjpeg_bits_dc_chrominance,
+                    avpriv_mjpeg_val_dc, 12, 0);
+    if (ret)
+        return ret;
+    ret = build_vlc(&c->ac_vlc[0], avpriv_mjpeg_bits_ac_luminance,
+                    avpriv_mjpeg_val_ac_luminance, 251, 1);
+    if (ret)
+        return ret;
+    ret = build_vlc(&c->ac_vlc[1], avpriv_mjpeg_bits_ac_chrominance,
+                    avpriv_mjpeg_val_ac_chrominance, 251, 1);
+    if (ret)
+        return ret;
+
+    ff_dsputil_init(&c->dsp, avctx);
+    ff_init_scantable(c->dsp.idct_permutation, &c->scantable,
+                      ff_zigzag_direct);
+
+    return 0;
+}
+
+static av_cold void jpg_free_context(JPGContext *ctx)
+{
+    int i;
+
+    for (i = 0; i < 2; i++) {
+        ff_free_vlc(&ctx->dc_vlc[i]);
+        ff_free_vlc(&ctx->ac_vlc[i]);
+    }
+
+    av_freep(&ctx->buf);
+}
+
+static void jpg_unescape(const uint8_t *src, int src_size,
+                         uint8_t *dst, int *dst_size)
+{
+    const uint8_t *src_end = src + src_size;
+    uint8_t *dst_start = dst;
+
+    while (src < src_end) {
+        uint8_t x = *src++;
+
+        *dst++ = x;
+
+        if (x == 0xFF && !*src)
+            src++;
+    }
+    *dst_size = dst - dst_start;
+}
+
+static int jpg_decode_block(JPGContext *c, GetBitContext *gb,
+                            int plane, int16_t *block)
+{
+    int dc, val, pos;
+    const int is_chroma = !!plane;
+    const uint8_t *qmat = is_chroma ? chroma_quant : luma_quant;
+
+    c->dsp.clear_block(block);
+    dc = get_vlc2(gb, c->dc_vlc[is_chroma].table, 9, 3);
+    if (dc < 0)
+        return AVERROR_INVALIDDATA;
+    if (dc)
+        dc = get_xbits(gb, dc);
+    dc = dc * qmat[0] + c->prev_dc[plane];
+    block[0] = dc;
+    c->prev_dc[plane] = dc;
+
+    pos = 0;
+    while (pos < 63) {
+        val = get_vlc2(gb, c->ac_vlc[is_chroma].table, 9, 3);
+        if (val < 0)
+            return AVERROR_INVALIDDATA;
+        pos += val >> 4;
+        val &= 0xF;
+        if (pos > 63)
+            return val ? AVERROR_INVALIDDATA : 0;
+        if (val) {
+            int nbits = val;
+
+            val = get_xbits(gb, nbits);
+            val *= qmat[ff_zigzag_direct[pos]];
+            block[c->scantable.permutated[pos]] = val;
+        }
+    }
+    return 0;
+}
+
+static inline void yuv2rgb(uint8_t *out, int Y, int U, int V)
+{
+    out[0] = av_clip_uint8(Y + (             91881 * V + 32768 >> 16));
+    out[1] = av_clip_uint8(Y + (-22554 * U - 46802 * V + 32768 >> 16));
+    out[2] = av_clip_uint8(Y + (116130 * U             + 32768 >> 16));
+}
+
+static int jpg_decode_data(JPGContext *c, int width, int height,
+                           const uint8_t *src, int src_size,
+                           uint8_t *dst, int dst_stride,
+                           const uint8_t *mask, int mask_stride, int num_mbs,
+                           int swapuv)
+{
+    GetBitContext gb;
+    uint8_t *tmp;
+    int mb_w, mb_h, mb_x, mb_y, i, j;
+    int bx, by;
+    int unesc_size;
+    int ret;
+
+    tmp = av_realloc(c->buf, src_size + FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!tmp)
+        return AVERROR(ENOMEM);
+    c->buf = tmp;
+    jpg_unescape(src, src_size, c->buf, &unesc_size);
+    memset(c->buf + unesc_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+    init_get_bits(&gb, c->buf, unesc_size * 8);
+
+    width = FFALIGN(width, 16);
+    mb_w  =  width        >> 4;
+    mb_h  = (height + 15) >> 4;
+
+    if (!num_mbs)
+        num_mbs = mb_w * mb_h;
+
+    for (i = 0; i < 3; i++)
+        c->prev_dc[i] = 1024;
+    bx = by = 0;
+    for (mb_y = 0; mb_y < mb_h; mb_y++) {
+        for (mb_x = 0; mb_x < mb_w; mb_x++) {
+            if (mask && !mask[mb_x]) {
+                bx += 16;
+                continue;
+            }
+            for (j = 0; j < 2; j++) {
+                for (i = 0; i < 2; i++) {
+                    if ((ret = jpg_decode_block(c, &gb, 0,
+                                                c->block[i + j * 2])) != 0)
+                        return ret;
+                    c->dsp.idct(c->block[i + j * 2]);
+                }
+            }
+            for (i = 1; i < 3; i++) {
+                if ((ret = jpg_decode_block(c, &gb, i, c->block[i + 3])) != 0)
+                    return ret;
+                c->dsp.idct(c->block[i + 3]);
+            }
+
+            for (j = 0; j < 16; j++) {
+                uint8_t *out = dst + bx * 3 + (by + j) * dst_stride;
+                for (i = 0; i < 16; i++) {
+                    int Y, U, V;
+
+                    Y = c->block[(j >> 3) * 2 + (i >> 3)][(i & 7) + (j & 7) * 8];
+                    U = c->block[4 ^ swapuv][(i >> 1) + (j >> 1) * 8] - 128;
+                    V = c->block[5 ^ swapuv][(i >> 1) + (j >> 1) * 8] - 128;
+                    yuv2rgb(out + i * 3, Y, U, V);
+                }
+            }
+
+            if (!--num_mbs)
+                return 0;
+            bx += 16;
+        }
+        bx  = 0;
+        by += 16;
+        if (mask)
+            mask += mask_stride;
+    }
+
+    return 0;
+}
+
+static void kempf_restore_buf(const uint8_t *src, int len,
+                              uint8_t *dst, int stride,
+                              const uint8_t *jpeg_tile, int tile_stride,
+                              int width, int height,
+                              const uint8_t *pal, int npal, int tidx)
+{
+    GetBitContext gb;
+    int i, j, nb, col;
+
+    init_get_bits(&gb, src, len * 8);
+
+    if (npal <= 2)       nb = 1;
+    else if (npal <= 4)  nb = 2;
+    else if (npal <= 16) nb = 4;
+    else                 nb = 8;
+
+    for (j = 0; j < height; j++, dst += stride, jpeg_tile += tile_stride) {
+        if (get_bits(&gb, 8))
+            continue;
+        for (i = 0; i < width; i++) {
+            col = get_bits(&gb, nb);
+            if (col != tidx)
+                memcpy(dst + i * 3, pal + col * 3, 3);
+            else
+                memcpy(dst + i * 3, jpeg_tile + i * 3, 3);
+        }
+    }
+}
+
+static int kempf_decode_tile(G2MContext *c, int tile_x, int tile_y,
+                             const uint8_t *src, int src_size)
+{
+    int width, height;
+    int hdr, zsize, npal, tidx = -1, ret;
+    int i, j;
+    const uint8_t *src_end = src + src_size;
+    uint8_t pal[768], transp[3];
+    uLongf dlen = (c->tile_width + 1) * c->tile_height;
+    int sub_type;
+    int nblocks, cblocks, bstride;
+    int bits, bitbuf, coded;
+    uint8_t *dst = c->framebuf + tile_x * c->tile_width * 3 +
+                   tile_y * c->tile_height * c->framebuf_stride;
+
+    if (src_size < 2)
+        return AVERROR_INVALIDDATA;
+
+    width  = FFMIN(c->width  - tile_x * c->tile_width,  c->tile_width);
+    height = FFMIN(c->height - tile_y * c->tile_height, c->tile_height);
+
+    hdr = *src++;
+    sub_type = hdr >> 5;
+    if (sub_type == 0) {
+        int j;
+        memcpy(transp, src, 3);
+        src += 3;
+        for (j = 0; j < height; j++, dst += c->framebuf_stride)
+            for (i = 0; i < width; i++)
+                memcpy(dst + i * 3, transp, 3);
+        return 0;
+    } else if (sub_type == 1) {
+        return jpg_decode_data(&c->jc, width, height, src, src_end - src,
+                               dst, c->framebuf_stride, NULL, 0, 0, 0);
+    }
+
+    if (sub_type != 2) {
+        memcpy(transp, src, 3);
+        src += 3;
+    }
+    npal = *src++ + 1;
+    memcpy(pal, src, npal * 3); src += npal * 3;
+    if (sub_type != 2) {
+        for (i = 0; i < npal; i++) {
+            if (!memcmp(pal + i * 3, transp, 3)) {
+               tidx = i;
+               break;
+            }
+        }
+    }
+
+    if (src_end - src < 2)
+        return 0;
+    zsize = (src[0] << 8) | src[1]; src += 2;
+
+    if (src_end - src < zsize + (sub_type != 2))
+        return AVERROR_INVALIDDATA;
+
+    ret = uncompress(c->kempf_buf, &dlen, src, zsize);
+    if (ret)
+        return AVERROR_INVALIDDATA;
+    src += zsize;
+
+    if (sub_type == 2) {
+        kempf_restore_buf(c->kempf_buf, dlen, dst, c->framebuf_stride,
+                          NULL, 0, width, height, pal, npal, tidx);
+        return 0;
+    }
+
+    nblocks = *src++ + 1;
+    cblocks = 0;
+    bstride = FFALIGN(width, 16) >> 4;
+    // blocks are coded LSB and we need normal bitreader for JPEG data
+    bits = 0;
+    for (i = 0; i < (FFALIGN(height, 16) >> 4); i++) {
+        for (j = 0; j < (FFALIGN(width, 16) >> 4); j++) {
+            if (!bits) {
+                if (src >= src_end)
+                    return AVERROR_INVALIDDATA;
+                bitbuf = *src++;
+                bits   = 8;
+            }
+            coded = bitbuf & 1;
+            bits--;
+            bitbuf >>= 1;
+            cblocks += coded;
+            if (cblocks > nblocks)
+                return AVERROR_INVALIDDATA;
+            c->kempf_flags[j + i * bstride] = coded;
+        }
+    }
+
+    memset(c->jpeg_tile, 0, c->tile_stride * height);
+    jpg_decode_data(&c->jc, width, height, src, src_end - src,
+                    c->jpeg_tile, c->tile_stride,
+                    c->kempf_flags, bstride, nblocks, 0);
+
+    kempf_restore_buf(c->kempf_buf, dlen, dst, c->framebuf_stride,
+                      c->jpeg_tile, c->tile_stride,
+                      width, height, pal, npal, tidx);
+
+    return 0;
+}
+
+static int g2m_init_buffers(G2MContext *c)
+{
+    int aligned_height;
+
+    if (!c->framebuf || c->old_width < c->width || c->old_height < c->height) {
+        c->framebuf_stride = FFALIGN(c->width * 3, 16);
+        aligned_height     = FFALIGN(c->height,    16);
+        av_free(c->framebuf);
+        c->framebuf = av_mallocz(c->framebuf_stride * aligned_height);
+        if (!c->framebuf)
+            return AVERROR(ENOMEM);
+    }
+    if (!c->synth_tile || !c->jpeg_tile ||
+        c->old_tile_w < c->tile_width ||
+        c->old_tile_h < c->tile_height) {
+        c->tile_stride = FFALIGN(c->tile_width * 3, 16);
+        aligned_height = FFALIGN(c->tile_height,    16);
+        av_free(c->synth_tile);
+        av_free(c->jpeg_tile);
+        av_free(c->kempf_buf);
+        av_free(c->kempf_flags);
+        c->synth_tile  = av_mallocz(c->tile_stride      * aligned_height);
+        c->jpeg_tile   = av_mallocz(c->tile_stride      * aligned_height);
+        c->kempf_buf   = av_mallocz((c->tile_width + 1) * aligned_height
+                                    + FF_INPUT_BUFFER_PADDING_SIZE);
+        c->kempf_flags = av_mallocz( c->tile_width      * aligned_height);
+        if (!c->synth_tile || !c->jpeg_tile ||
+            !c->kempf_buf || !c->kempf_flags)
+            return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+static int g2m_load_cursor(AVCodecContext *avctx, G2MContext *c,
+                           GetByteContext *gb)
+{
+    int i, j, k;
+    uint8_t *dst;
+    uint32_t bits;
+    uint32_t cur_size, cursor_w, cursor_h, cursor_stride;
+    uint32_t cursor_hot_x, cursor_hot_y;
+    int cursor_fmt;
+    uint8_t *tmp;
+
+    cur_size      = bytestream2_get_be32(gb);
+    cursor_w      = bytestream2_get_byte(gb);
+    cursor_h      = bytestream2_get_byte(gb);
+    cursor_hot_x  = bytestream2_get_byte(gb);
+    cursor_hot_y  = bytestream2_get_byte(gb);
+    cursor_fmt    = bytestream2_get_byte(gb);
+
+    cursor_stride = cursor_w * 4;
+
+    if (cursor_w < 1 || cursor_w > 256 ||
+        cursor_h < 1 || cursor_h > 256) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid cursor dimensions %dx%d\n",
+               cursor_w, cursor_h);
+        return AVERROR_INVALIDDATA;
+    }
+    if (cursor_hot_x > cursor_w || cursor_hot_y > cursor_h) {
+        av_log(avctx, AV_LOG_WARNING, "Invalid hotspot position %d,%d\n",
+               cursor_hot_x, cursor_hot_y);
+        cursor_hot_x = FFMIN(cursor_hot_x, cursor_w - 1);
+        cursor_hot_y = FFMIN(cursor_hot_y, cursor_h - 1);
+    }
+    if (cur_size - 9 > bytestream2_get_bytes_left(gb) ||
+        c->cursor_w * c->cursor_h / 4 > cur_size) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid cursor data size %d/%d\n",
+               cur_size, bytestream2_get_bytes_left(gb));
+        return AVERROR_INVALIDDATA;
+    }
+    if (cursor_fmt != 1 && cursor_fmt != 32) {
+        avpriv_report_missing_feature(avctx, "Cursor format %d",
+                                      cursor_fmt);
+        return AVERROR_PATCHWELCOME;
+    }
+
+    if (cursor_fmt == 1 && cursor_w % 32) {
+        avpriv_report_missing_feature(avctx, "odd monochrome cursor width %d", cursor_w);
+        return AVERROR_PATCHWELCOME;
+    }
+
+    tmp = av_realloc(c->cursor, cursor_stride * cursor_h);
+    if (!tmp) {
+        av_log(avctx, AV_LOG_ERROR, "Cannot allocate cursor buffer\n");
+        return AVERROR(ENOMEM);
+    }
+
+    c->cursor        = tmp;
+    c->cursor_w      = cursor_w;
+    c->cursor_h      = cursor_h;
+    c->cursor_hot_x  = cursor_hot_x;
+    c->cursor_hot_y  = cursor_hot_y;
+    c->cursor_fmt    = cursor_fmt;
+    c->cursor_stride = cursor_stride;
+
+    dst = c->cursor;
+    switch (c->cursor_fmt) {
+    case 1: // old monochrome
+        for (j = 0; j < c->cursor_h; j++) {
+            for (i = 0; i < c->cursor_w; i += 32) {
+                bits = bytestream2_get_be32(gb);
+                for (k = 0; k < 32; k++) {
+                    dst[0] = !!(bits & 0x80000000);
+                    dst += 4;
+                    bits <<= 1;
+                }
+            }
+        }
+
+        dst = c->cursor;
+        for (j = 0; j < c->cursor_h; j++) {
+            for (i = 0; i < c->cursor_w; i += 32) {
+                bits = bytestream2_get_be32(gb);
+                for (k = 0; k < 32; k++) {
+                    int mask_bit = !!(bits & 0x80000000);
+                    switch (dst[0] * 2 + mask_bit) {
+                    case 0:
+                        dst[0] = 0xFF; dst[1] = 0x00;
+                        dst[2] = 0x00; dst[3] = 0x00;
+                        break;
+                    case 1:
+                        dst[0] = 0xFF; dst[1] = 0xFF;
+                        dst[2] = 0xFF; dst[3] = 0xFF;
+                        break;
+                    default:
+                        dst[0] = 0x00; dst[1] = 0x00;
+                        dst[2] = 0x00; dst[3] = 0x00;
+                    }
+                    dst += 4;
+                    bits <<= 1;
+                }
+            }
+        }
+        break;
+    case 32: // full colour
+        /* skip monochrome version of the cursor and decode RGBA instead */
+        bytestream2_skip(gb, c->cursor_h * (FFALIGN(c->cursor_w, 32) >> 3));
+        for (j = 0; j < c->cursor_h; j++) {
+            for (i = 0; i < c->cursor_w; i++) {
+                int val = bytestream2_get_be32(gb);
+                *dst++ = val >>  0;
+                *dst++ = val >>  8;
+                *dst++ = val >> 16;
+                *dst++ = val >> 24;
+            }
+        }
+        break;
+    default:
+        return AVERROR_PATCHWELCOME;
+    }
+    return 0;
+}
+
+#define APPLY_ALPHA(src, new, alpha) \
+    src = (src * (256 - alpha) + new * alpha) >> 8
+
+static void g2m_paint_cursor(G2MContext *c, uint8_t *dst, int stride)
+{
+    int i, j;
+    int x, y, w, h;
+    const uint8_t *cursor;
+
+    if (!c->cursor)
+        return;
+
+    x = c->cursor_x - c->cursor_hot_x;
+    y = c->cursor_y - c->cursor_hot_y;
+
+    cursor = c->cursor;
+    w      = c->cursor_w;
+    h      = c->cursor_h;
+
+    if (x + w > c->width)
+        w = c->width - x;
+    if (y + h > c->height)
+        h = c->height - y;
+    if (x < 0) {
+        w      +=  x;
+        cursor += -x * 4;
+    } else {
+        dst    +=  x * 3;
+    }
+    if (y < 0) {
+        h      +=  y;
+        cursor += -y * c->cursor_stride;
+    } else {
+        dst    +=  y * stride;
+    }
+    if (w < 0 || h < 0)
+        return;
+
+    for (j = 0; j < h; j++) {
+        for (i = 0; i < w; i++) {
+            uint8_t alpha = cursor[i * 4];
+            APPLY_ALPHA(dst[i * 3 + 0], cursor[i * 4 + 1], alpha);
+            APPLY_ALPHA(dst[i * 3 + 1], cursor[i * 4 + 2], alpha);
+            APPLY_ALPHA(dst[i * 3 + 2], cursor[i * 4 + 3], alpha);
+        }
+        dst    += stride;
+        cursor += c->cursor_stride;
+    }
+}
+
+static int g2m_decode_frame(AVCodecContext *avctx, void *data,
+                            int *got_picture_ptr, AVPacket *avpkt)
+{
+    const uint8_t *buf = avpkt->data;
+    int buf_size = avpkt->size;
+    G2MContext *c = avctx->priv_data;
+    AVFrame *pic = data;
+    GetByteContext bc, tbc;
+    int magic;
+    int got_header = 0;
+    uint32_t chunk_size;
+    int chunk_type;
+    int i;
+    int ret;
+
+    if (buf_size < 12) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Frame should have at least 12 bytes, got %d instead\n",
+               buf_size);
+        return AVERROR_INVALIDDATA;
+    }
+
+    bytestream2_init(&bc, buf, buf_size);
+
+    magic = bytestream2_get_be32(&bc);
+    if ((magic & ~0xF) != MKBETAG('G', '2', 'M', '0') ||
+        (magic & 0xF) < 2 || (magic & 0xF) > 4) {
+        av_log(avctx, AV_LOG_ERROR, "Wrong magic %08X\n", magic);
+        return AVERROR_INVALIDDATA;
+    }
+
+    if ((magic & 0xF) != 4) {
+        av_log(avctx, AV_LOG_ERROR, "G2M2 and G2M3 are not yet supported\n");
+        return AVERROR(ENOSYS);
+    }
+
+    while (bytestream2_get_bytes_left(&bc) > 5) {
+        chunk_size = bytestream2_get_le32(&bc) - 1;
+        chunk_type = bytestream2_get_byte(&bc);
+        if (chunk_size > bytestream2_get_bytes_left(&bc)) {
+            av_log(avctx, AV_LOG_ERROR, "Invalid chunk size %d type %02X\n",
+                   chunk_size, chunk_type);
+            break;
+        }
+        switch (chunk_type) {
+        case FRAME_INFO:
+            c->got_header = 0;
+            if (chunk_size < 21) {
+                av_log(avctx, AV_LOG_ERROR, "Invalid frame info size %d\n",
+                       chunk_size);
+                break;
+            }
+            c->width  = bytestream2_get_be32(&bc);
+            c->height = bytestream2_get_be32(&bc);
+            if (c->width  < 16 || c->width  > avctx->width ||
+                c->height < 16 || c->height > avctx->height) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Invalid frame dimensions %dx%d\n",
+                       c->width, c->height);
+                ret = AVERROR_INVALIDDATA;
+                goto header_fail;
+            }
+            if (c->width != avctx->width || c->height != avctx->height)
+                avcodec_set_dimensions(avctx, c->width, c->height);
+            c->compression = bytestream2_get_be32(&bc);
+            if (c->compression != 2 && c->compression != 3) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Unknown compression method %d\n",
+                       c->compression);
+                return AVERROR_PATCHWELCOME;
+            }
+            c->tile_width  = bytestream2_get_be32(&bc);
+            c->tile_height = bytestream2_get_be32(&bc);
+            if (!c->tile_width || !c->tile_height) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Invalid tile dimensions %dx%d\n",
+                       c->tile_width, c->tile_height);
+                ret = AVERROR_INVALIDDATA;
+                goto header_fail;
+            }
+            c->tiles_x = (c->width  + c->tile_width  - 1) / c->tile_width;
+            c->tiles_y = (c->height + c->tile_height - 1) / c->tile_height;
+            c->bpp = bytestream2_get_byte(&bc);
+            chunk_size -= 21;
+            bytestream2_skip(&bc, chunk_size);
+            if (g2m_init_buffers(c)) {
+                ret = AVERROR(ENOMEM);
+                goto header_fail;
+            }
+            got_header = 1;
+            break;
+        case TILE_DATA:
+            if (!c->tiles_x || !c->tiles_y) {
+                av_log(avctx, AV_LOG_WARNING,
+                       "No frame header - skipping tile\n");
+                bytestream2_skip(&bc, bytestream2_get_bytes_left(&bc));
+                break;
+            }
+            if (chunk_size < 2) {
+                av_log(avctx, AV_LOG_ERROR, "Invalid tile data size %d\n",
+                       chunk_size);
+                break;
+            }
+            c->tile_x = bytestream2_get_byte(&bc);
+            c->tile_y = bytestream2_get_byte(&bc);
+            if (c->tile_x >= c->tiles_x || c->tile_y >= c->tiles_y) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Invalid tile pos %d,%d (in %dx%d grid)\n",
+                       c->tile_x, c->tile_y, c->tiles_x, c->tiles_y);
+                break;
+            }
+            chunk_size -= 2;
+            ret = 0;
+            switch (c->compression) {
+            case COMPR_EPIC_J_B:
+                av_log(avctx, AV_LOG_ERROR,
+                       "ePIC j-b compression is not implemented yet\n");
+                return AVERROR(ENOSYS);
+            case COMPR_KEMPF_J_B:
+                ret = kempf_decode_tile(c, c->tile_x, c->tile_y,
+                                        buf + bytestream2_tell(&bc),
+                                        chunk_size);
+                break;
+            }
+            if (ret && c->framebuf)
+                av_log(avctx, AV_LOG_ERROR, "Error decoding tile %d,%d\n",
+                       c->tile_x, c->tile_y);
+            bytestream2_skip(&bc, chunk_size);
+            break;
+        case CURSOR_POS:
+            if (chunk_size < 5) {
+                av_log(avctx, AV_LOG_ERROR, "Invalid cursor pos size %d\n",
+                       chunk_size);
+                break;
+            }
+            c->cursor_x = bytestream2_get_be16(&bc);
+            c->cursor_y = bytestream2_get_be16(&bc);
+            bytestream2_skip(&bc, chunk_size - 4);
+            break;
+        case CURSOR_SHAPE:
+            if (chunk_size < 8) {
+                av_log(avctx, AV_LOG_ERROR, "Invalid cursor data size %d\n",
+                       chunk_size);
+                break;
+            }
+            bytestream2_init(&tbc, buf + bytestream2_tell(&bc),
+                             chunk_size - 4);
+            g2m_load_cursor(avctx, c, &tbc);
+            bytestream2_skip(&bc, chunk_size);
+            break;
+        case CHUNK_CC:
+        case CHUNK_CD:
+            bytestream2_skip(&bc, chunk_size);
+            break;
+        default:
+            av_log(avctx, AV_LOG_WARNING, "Skipping chunk type %02X\n",
+                   chunk_type);
+            bytestream2_skip(&bc, chunk_size);
+        }
+    }
+    if (got_header)
+        c->got_header = 1;
+
+    if (c->width && c->height && c->framebuf) {
+        if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) {
+            av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+            return ret;
+        }
+
+        pic->key_frame = got_header;
+        pic->pict_type = got_header ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+
+        for (i = 0; i < avctx->height; i++)
+            memcpy(pic->data[0] + i * pic->linesize[0],
+                   c->framebuf  + i * c->framebuf_stride,
+                   c->width * 3);
+        g2m_paint_cursor(c, pic->data[0], pic->linesize[0]);
+
+        *got_picture_ptr = 1;
+    }
+
+    return buf_size;
+header_fail:
+    c->width   = c->height  = 0;
+    c->tiles_x = c->tiles_y = 0;
+    return ret;
+}
+
+static av_cold int g2m_decode_init(AVCodecContext *avctx)
+{
+    G2MContext * const c = avctx->priv_data;
+    int ret;
+
+    if ((ret = jpg_init(avctx, &c->jc)) != 0) {
+        av_log(avctx, AV_LOG_ERROR, "Cannot initialise VLCs\n");
+        jpg_free_context(&c->jc);
+        return AVERROR(ENOMEM);
+    }
+
+    avctx->pix_fmt = AV_PIX_FMT_RGB24;
+
+    return 0;
+}
+
+static av_cold int g2m_decode_end(AVCodecContext *avctx)
+{
+    G2MContext * const c = avctx->priv_data;
+
+    jpg_free_context(&c->jc);
+
+    av_freep(&c->kempf_buf);
+    av_freep(&c->kempf_flags);
+    av_freep(&c->synth_tile);
+    av_freep(&c->jpeg_tile);
+    av_freep(&c->cursor);
+    av_freep(&c->framebuf);
+
+    return 0;
+}
+
+AVCodec ff_g2m_decoder = {
+    .name           = "g2m",
+    .long_name      = NULL_IF_CONFIG_SMALL("Go2Meeting"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_G2M,
+    .priv_data_size = sizeof(G2MContext),
+    .init           = g2m_decode_init,
+    .close          = g2m_decode_end,
+    .decode         = g2m_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+};
diff --git a/libavcodec/g726.c b/libavcodec/g726.c
index 58d0468..d035b3e 100644
--- a/libavcodec/g726.c
+++ b/libavcodec/g726.c
@@ -368,7 +368,7 @@
     { NULL },
 };
 
-static const AVClass class = {
+static const AVClass g726_class = {
     .class_name = "g726",
     .item_name  = av_default_item_name,
     .option     = options,
@@ -391,7 +391,7 @@
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("G.726 ADPCM"),
-    .priv_class     = &class,
+    .priv_class     = &g726_class,
     .defaults       = defaults,
 };
 #endif
@@ -401,6 +401,10 @@
 {
     G726Context* c = avctx->priv_data;
 
+    if(avctx->channels > 1){
+        avpriv_request_sample(avctx, "Decoding more than one channel");
+        return AVERROR_PATCHWELCOME;
+    }
     avctx->channels       = 1;
     avctx->channel_layout = AV_CH_LAYOUT_MONO;
 
diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h
index f16a508..5da90b6 100644
--- a/libavcodec/get_bits.h
+++ b/libavcodec/get_bits.h
@@ -64,6 +64,7 @@
     int bits;
     VLC_TYPE (*table)[2]; ///< code, bits
     int table_size, table_allocated;
+    void * volatile init_state;
 } VLC;
 
 typedef struct RL_VLC_ELEM {
@@ -139,27 +140,34 @@
 
 #define CLOSE_READER(name, gb) (gb)->index = name ## _index
 
+# ifdef LONG_BITSTREAM_READER
+
+# define UPDATE_CACHE_LE(name, gb) name ## _cache = \
+      AV_RL64((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7)
+
+# define UPDATE_CACHE_BE(name, gb) name ## _cache = \
+      AV_RB64((gb)->buffer + (name ## _index >> 3)) >> (32 - (name ## _index & 7))
+
+#else
+
+# define UPDATE_CACHE_LE(name, gb) name ## _cache = \
+      AV_RL32((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7)
+
+# define UPDATE_CACHE_BE(name, gb) name ## _cache = \
+      AV_RB32((gb)->buffer + (name ## _index >> 3)) << (name ## _index & 7)
+
+#endif
+
+
 #ifdef BITSTREAM_READER_LE
 
-# ifdef LONG_BITSTREAM_READER
-#   define UPDATE_CACHE(name, gb) name ## _cache = \
-        AV_RL64((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7)
-# else
-#   define UPDATE_CACHE(name, gb) name ## _cache = \
-        AV_RL32((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7)
-# endif
+# define UPDATE_CACHE(name, gb) UPDATE_CACHE_LE(name, gb)
 
 # define SKIP_CACHE(name, gb, num) name ## _cache >>= (num)
 
 #else
 
-# ifdef LONG_BITSTREAM_READER
-#   define UPDATE_CACHE(name, gb) name ## _cache = \
-        AV_RB64((gb)->buffer + (name ## _index >> 3)) >> (32 - (name ## _index & 7))
-# else
-#   define UPDATE_CACHE(name, gb) name ## _cache = \
-        AV_RB32((gb)->buffer + (name ## _index >> 3)) << (name ## _index & 7)
-# endif
+# define UPDATE_CACHE(name, gb) UPDATE_CACHE_BE(name, gb)
 
 # define SKIP_CACHE(name, gb, num) name ## _cache <<= (num)
 
@@ -180,12 +188,18 @@
 
 #define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num)
 
+#define SHOW_UBITS_LE(name, gb, num) zero_extend(name ## _cache, num)
+#define SHOW_SBITS_LE(name, gb, num) sign_extend(name ## _cache, num)
+
+#define SHOW_UBITS_BE(name, gb, num) NEG_USR32(name ## _cache, num)
+#define SHOW_SBITS_BE(name, gb, num) NEG_SSR32(name ## _cache, num)
+
 #ifdef BITSTREAM_READER_LE
-#   define SHOW_UBITS(name, gb, num) zero_extend(name ## _cache, num)
-#   define SHOW_SBITS(name, gb, num) sign_extend(name ## _cache, num)
+#   define SHOW_UBITS(name, gb, num) SHOW_UBITS_LE(name, gb, num)
+#   define SHOW_SBITS(name, gb, num) SHOW_SBITS_LE(name, gb, num)
 #else
-#   define SHOW_UBITS(name, gb, num) NEG_USR32(name ## _cache, num)
-#   define SHOW_SBITS(name, gb, num) NEG_SSR32(name ## _cache, num)
+#   define SHOW_UBITS(name, gb, num) SHOW_UBITS_BE(name, gb, num)
+#   define SHOW_SBITS(name, gb, num) SHOW_SBITS_BE(name, gb, num)
 #endif
 
 #define GET_CACHE(name, gb) ((uint32_t) name ## _cache)
@@ -214,6 +228,7 @@
     register int sign;
     register int32_t cache;
     OPEN_READER(re, s);
+    av_assert2(n>0 && n<=25);
     UPDATE_CACHE(re, s);
     cache = GET_CACHE(re, s);
     sign  = ~cache >> 31;
@@ -249,6 +264,18 @@
     return tmp;
 }
 
+static inline unsigned int get_bits_le(GetBitContext *s, int n)
+{
+    register int tmp;
+    OPEN_READER(re, s);
+    av_assert2(n>0 && n<=25);
+    UPDATE_CACHE_LE(re, s);
+    tmp = SHOW_UBITS_LE(re, s, n);
+    LAST_SKIP_BITS(re, s, n);
+    CLOSE_READER(re, s);
+    return tmp;
+}
+
 /**
  * Show 1-25 bits.
  */
diff --git a/libavcodec/gif.c b/libavcodec/gif.c
index 52c1d44..bd14c13 100644
--- a/libavcodec/gif.c
+++ b/libavcodec/gif.c
@@ -28,6 +28,7 @@
  * @see http://www.w3.org/Graphics/GIF/spec-gif89a.txt
  */
 
+#define BITSTREAM_WRITER_LE
 #include "libavutil/opt.h"
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
@@ -36,12 +37,10 @@
 #include "lzw.h"
 #include "gif.h"
 
-#define BITSTREAM_WRITER_LE
 #include "put_bits.h"
 
 typedef struct {
     const AVClass *class;
-    AVFrame picture;
     LZWState *lzw;
     uint8_t *buf;
     AVFrame *last_frame;
@@ -163,13 +162,13 @@
             if (!pal_exdata)
                 return AVERROR(ENOMEM);
             memcpy(pal_exdata, s->palette, AVPALETTE_SIZE);
-            pal_exdata[trans*4 + 3] = 0x00;
+            pal_exdata[trans*4 + 3*!HAVE_BIGENDIAN] = 0x00;
         }
     }
 
     bytestream_put_byte(bytestream, 0x08);
 
-    ff_lzw_encode_init(s->lzw, s->buf, width * height,
+    ff_lzw_encode_init(s->lzw, s->buf, 2 * width * height,
                        12, FF_LZW_GIF, put_bits);
 
     ptr = buf + y_start*linesize + x_start;
@@ -217,7 +216,6 @@
         return AVERROR(EINVAL);
     }
 
-    avctx->coded_frame = &s->picture;
     s->lzw = av_mallocz(ff_lzw_encode_state_size);
     s->buf = av_malloc(avctx->width*avctx->height*2);
     s->tmpl = av_malloc(avctx->width);
@@ -234,7 +232,7 @@
                             const AVFrame *pict, int *got_packet)
 {
     GIFContext *s = avctx->priv_data;
-    AVFrame *const p = &s->picture;
+    AVFrame *const p = (AVFrame *)pict;
     uint8_t *outbuf_ptr, *end;
     const uint32_t *palette = NULL;
     int ret;
@@ -244,7 +242,6 @@
     outbuf_ptr = pkt->data;
     end        = pkt->data + pkt->size;
 
-    *p = *pict;
     p->pict_type = AV_PICTURE_TYPE_I;
     p->key_frame = 1;
 
diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c
index 997bd42..4c1cb83 100644
--- a/libavcodec/gifdec.c
+++ b/libavcodec/gifdec.c
@@ -21,8 +21,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-//#define DEBUG
-
 #include "libavutil/imgutils.h"
 #include "libavutil/opt.h"
 #include "avcodec.h"
@@ -461,6 +459,7 @@
 
     if (s->keyframe) {
         s->keyframe_ok = 0;
+        s->gce_prev_disposal = GCE_DISPOSAL_NONE;
         if ((ret = gif_read_header1(s)) < 0)
             return ret;
 
diff --git a/libavcodec/gsmdec.c b/libavcodec/gsmdec.c
index dc64267..5de6da4 100644
--- a/libavcodec/gsmdec.c
+++ b/libavcodec/gsmdec.c
@@ -34,6 +34,14 @@
 
 static av_cold int gsm_init(AVCodecContext *avctx)
 {
+    if (avctx->codec_tag == 0x0032 &&
+        avctx->bit_rate != 13000 &&
+        avctx->bit_rate != 17912 &&
+        avctx->bit_rate != 35824 &&
+        avctx->bit_rate != 71656) {
+        av_log(avctx, AV_LOG_ERROR, "Unsupported audio mode\n");
+        return AVERROR_PATCHWELCOME;
+    }
     avctx->channels       = 1;
     avctx->channel_layout = AV_CH_LAYOUT_MONO;
     if (!avctx->sample_rate)
diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c
index 8ed16bd..72b3b09 100644
--- a/libavcodec/h261dec.c
+++ b/libavcodec/h261dec.c
@@ -148,7 +148,7 @@
  * Decode the group of blocks / video packet header.
  * @return <0 if no resync found
  */
-static int ff_h261_resync(H261Context *h)
+static int h261_resync(H261Context *h)
 {
     MpegEncContext *const s = &h->s;
     int left, ret;
@@ -378,9 +378,11 @@
     // Read mtype
     h->mtype = get_vlc2(&s->gb, h261_mtype_vlc.table, H261_MTYPE_VLC_BITS, 2);
     if (h->mtype < 0) {
-        av_log(s->avctx, AV_LOG_ERROR, "illegal mtype %d\n", h->mtype);
+        av_log(s->avctx, AV_LOG_ERROR, "Invalid mtype index %d\n",
+               h->mtype);
         return SLICE_ERROR;
     }
+    av_assert0(h->mtype < FF_ARRAY_ELEMS(ff_h261_mtype_map));
     h->mtype = ff_h261_mtype_map[h->mtype];
 
     // Read mquant
@@ -632,7 +634,7 @@
     s->mb_y = 0;
 
     while (h->gob_number < (s->mb_height == 18 ? 12 : 5)) {
-        if (ff_h261_resync(h) < 0)
+        if (h261_resync(h) < 0)
             break;
         h261_decode_gob(h);
     }
diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index 84a8816..bfa34ea 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -25,6 +25,7 @@
  * H.261 encoder.
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
@@ -312,7 +313,7 @@
     }
 }
 
-void ff_h261_encode_init(MpegEncContext *s)
+av_cold void ff_h261_encode_init(MpegEncContext *s)
 {
     ff_h261_common_init();
 
diff --git a/libavcodec/h263.c b/libavcodec/h263.c
index e60e58e..eda61f6 100644
--- a/libavcodec/h263.c
+++ b/libavcodec/h263.c
@@ -27,7 +27,6 @@
  * h263/mpeg4 codec.
  */
 
-//#define DEBUG
 #include <limits.h>
 
 #include "avcodec.h"
@@ -39,8 +38,6 @@
 #include "flv.h"
 #include "mpeg4video.h"
 
-//#undef NDEBUG
-//#include <assert.h>
 
 uint8_t ff_h263_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
 
diff --git a/libavcodec/h263.h b/libavcodec/h263.h
index a95cfb0..0995494 100644
--- a/libavcodec/h263.h
+++ b/libavcodec/h263.h
@@ -53,6 +53,10 @@
 extern VLC ff_h263_inter_MCBPC_vlc;
 extern VLC ff_h263_cbpy_vlc;
 
+extern const uint16_t ff_inter_vlc[103][2];
+extern const int8_t ff_inter_level[102];
+extern const int8_t ff_inter_run[102];
+
 extern RLTable ff_h263_rl_inter;
 
 extern RLTable ff_rl_intra_aic;
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index 6e3d885..f1ffde9 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -39,9 +39,6 @@
 #include "flv.h"
 #include "mpeg4video.h"
 
-//#define DEBUG
-//#define PRINT_FRAME_TIME
-
 av_cold int ff_h263_decode_init(AVCodecContext *avctx)
 {
     MpegEncContext *s = avctx->priv_data;
@@ -353,9 +350,6 @@
     int ret;
     AVFrame *pict = data;
 
-#ifdef PRINT_FRAME_TIME
-uint64_t time= rdtsc();
-#endif
     s->flags= avctx->flags;
     s->flags2= avctx->flags2;
 
@@ -764,10 +758,6 @@
         *got_frame = 1;
     }
 
-#ifdef PRINT_FRAME_TIME
-av_log(avctx, AV_LOG_DEBUG, "%"PRId64"\n", rdtsc()-time);
-#endif
-
     return (ret && (avctx->err_recognition & AV_EF_EXPLODE))?ret:get_consumed_bytes(s, buf_size);
 }
 
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 05f586f..a302a8d 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -25,6 +25,7 @@
  * @author Michael Niedermayer <michaelni@gmx.at>
  */
 
+#include "libavutil/avassert.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/opt.h"
 #include "internal.h"
@@ -44,9 +45,7 @@
 #include "svq3.h"
 #include "thread.h"
 #include "vdpau_internal.h"
-#include "libavutil/avassert.h"
 
-// #undef NDEBUG
 #include <assert.h>
 
 const uint16_t ff_h264_mb_sizes[4] = { 256, 384, 512, 768 };
@@ -67,6 +66,93 @@
    14,14,14,14,
 };
 
+static const uint8_t field_scan[16+1] = {
+    0 + 0 * 4, 0 + 1 * 4, 1 + 0 * 4, 0 + 2 * 4,
+    0 + 3 * 4, 1 + 1 * 4, 1 + 2 * 4, 1 + 3 * 4,
+    2 + 0 * 4, 2 + 1 * 4, 2 + 2 * 4, 2 + 3 * 4,
+    3 + 0 * 4, 3 + 1 * 4, 3 + 2 * 4, 3 + 3 * 4,
+};
+
+static const uint8_t field_scan8x8[64+1] = {
+    0 + 0 * 8, 0 + 1 * 8, 0 + 2 * 8, 1 + 0 * 8,
+    1 + 1 * 8, 0 + 3 * 8, 0 + 4 * 8, 1 + 2 * 8,
+    2 + 0 * 8, 1 + 3 * 8, 0 + 5 * 8, 0 + 6 * 8,
+    0 + 7 * 8, 1 + 4 * 8, 2 + 1 * 8, 3 + 0 * 8,
+    2 + 2 * 8, 1 + 5 * 8, 1 + 6 * 8, 1 + 7 * 8,
+    2 + 3 * 8, 3 + 1 * 8, 4 + 0 * 8, 3 + 2 * 8,
+    2 + 4 * 8, 2 + 5 * 8, 2 + 6 * 8, 2 + 7 * 8,
+    3 + 3 * 8, 4 + 1 * 8, 5 + 0 * 8, 4 + 2 * 8,
+    3 + 4 * 8, 3 + 5 * 8, 3 + 6 * 8, 3 + 7 * 8,
+    4 + 3 * 8, 5 + 1 * 8, 6 + 0 * 8, 5 + 2 * 8,
+    4 + 4 * 8, 4 + 5 * 8, 4 + 6 * 8, 4 + 7 * 8,
+    5 + 3 * 8, 6 + 1 * 8, 6 + 2 * 8, 5 + 4 * 8,
+    5 + 5 * 8, 5 + 6 * 8, 5 + 7 * 8, 6 + 3 * 8,
+    7 + 0 * 8, 7 + 1 * 8, 6 + 4 * 8, 6 + 5 * 8,
+    6 + 6 * 8, 6 + 7 * 8, 7 + 2 * 8, 7 + 3 * 8,
+    7 + 4 * 8, 7 + 5 * 8, 7 + 6 * 8, 7 + 7 * 8,
+};
+
+static const uint8_t field_scan8x8_cavlc[64+1] = {
+    0 + 0 * 8, 1 + 1 * 8, 2 + 0 * 8, 0 + 7 * 8,
+    2 + 2 * 8, 2 + 3 * 8, 2 + 4 * 8, 3 + 3 * 8,
+    3 + 4 * 8, 4 + 3 * 8, 4 + 4 * 8, 5 + 3 * 8,
+    5 + 5 * 8, 7 + 0 * 8, 6 + 6 * 8, 7 + 4 * 8,
+    0 + 1 * 8, 0 + 3 * 8, 1 + 3 * 8, 1 + 4 * 8,
+    1 + 5 * 8, 3 + 1 * 8, 2 + 5 * 8, 4 + 1 * 8,
+    3 + 5 * 8, 5 + 1 * 8, 4 + 5 * 8, 6 + 1 * 8,
+    5 + 6 * 8, 7 + 1 * 8, 6 + 7 * 8, 7 + 5 * 8,
+    0 + 2 * 8, 0 + 4 * 8, 0 + 5 * 8, 2 + 1 * 8,
+    1 + 6 * 8, 4 + 0 * 8, 2 + 6 * 8, 5 + 0 * 8,
+    3 + 6 * 8, 6 + 0 * 8, 4 + 6 * 8, 6 + 2 * 8,
+    5 + 7 * 8, 6 + 4 * 8, 7 + 2 * 8, 7 + 6 * 8,
+    1 + 0 * 8, 1 + 2 * 8, 0 + 6 * 8, 3 + 0 * 8,
+    1 + 7 * 8, 3 + 2 * 8, 2 + 7 * 8, 4 + 2 * 8,
+    3 + 7 * 8, 5 + 2 * 8, 4 + 7 * 8, 5 + 4 * 8,
+    6 + 3 * 8, 6 + 5 * 8, 7 + 3 * 8, 7 + 7 * 8,
+};
+
+// zigzag_scan8x8_cavlc[i] = zigzag_scan8x8[(i/4) + 16*(i%4)]
+static const uint8_t zigzag_scan8x8_cavlc[64+1] = {
+    0 + 0 * 8, 1 + 1 * 8, 1 + 2 * 8, 2 + 2 * 8,
+    4 + 1 * 8, 0 + 5 * 8, 3 + 3 * 8, 7 + 0 * 8,
+    3 + 4 * 8, 1 + 7 * 8, 5 + 3 * 8, 6 + 3 * 8,
+    2 + 7 * 8, 6 + 4 * 8, 5 + 6 * 8, 7 + 5 * 8,
+    1 + 0 * 8, 2 + 0 * 8, 0 + 3 * 8, 3 + 1 * 8,
+    3 + 2 * 8, 0 + 6 * 8, 4 + 2 * 8, 6 + 1 * 8,
+    2 + 5 * 8, 2 + 6 * 8, 6 + 2 * 8, 5 + 4 * 8,
+    3 + 7 * 8, 7 + 3 * 8, 4 + 7 * 8, 7 + 6 * 8,
+    0 + 1 * 8, 3 + 0 * 8, 0 + 4 * 8, 4 + 0 * 8,
+    2 + 3 * 8, 1 + 5 * 8, 5 + 1 * 8, 5 + 2 * 8,
+    1 + 6 * 8, 3 + 5 * 8, 7 + 1 * 8, 4 + 5 * 8,
+    4 + 6 * 8, 7 + 4 * 8, 5 + 7 * 8, 6 + 7 * 8,
+    0 + 2 * 8, 2 + 1 * 8, 1 + 3 * 8, 5 + 0 * 8,
+    1 + 4 * 8, 2 + 4 * 8, 6 + 0 * 8, 4 + 3 * 8,
+    0 + 7 * 8, 4 + 4 * 8, 7 + 2 * 8, 3 + 6 * 8,
+    5 + 5 * 8, 6 + 5 * 8, 6 + 6 * 8, 7 + 7 * 8,
+};
+
+static const uint8_t dequant4_coeff_init[6][3] = {
+    { 10, 13, 16 },
+    { 11, 14, 18 },
+    { 13, 16, 20 },
+    { 14, 18, 23 },
+    { 16, 20, 25 },
+    { 18, 23, 29 },
+};
+
+static const uint8_t dequant8_coeff_init_scan[16] = {
+    0, 3, 4, 3, 3, 1, 5, 1, 4, 5, 2, 5, 3, 1, 5, 1
+};
+
+static const uint8_t dequant8_coeff_init[6][6] = {
+    { 20, 18, 32, 19, 25, 24 },
+    { 22, 19, 35, 21, 28, 26 },
+    { 26, 23, 42, 24, 33, 31 },
+    { 28, 25, 45, 26, 35, 33 },
+    { 32, 28, 51, 30, 40, 38 },
+    { 36, 32, 58, 34, 46, 43 },
+};
+
 static const enum AVPixelFormat h264_hwaccel_pixfmt_list_420[] = {
 #if CONFIG_H264_DXVA2_HWACCEL
     AV_PIX_FMT_DXVA2_VLD,
@@ -111,7 +197,7 @@
                               int (*mv)[2][4][2],
                               int mb_x, int mb_y, int mb_intra, int mb_skipped)
 {
-    H264Context    *h = opaque;
+    H264Context *h = opaque;
 
     h->mb_x  = mb_x;
     h->mb_y  = mb_y;
@@ -152,7 +238,7 @@
     const int field_pic = h->picture_structure != PICT_FRAME;
     if (field_pic) {
         height <<= 1;
-        y <<= 1;
+        y      <<= 1;
     }
 
     height = FFMIN(height, avctx->height - y);
@@ -166,7 +252,7 @@
         int i;
 
         if (cur->f.pict_type == AV_PICTURE_TYPE_B || h->low_delay ||
-           (avctx->slice_flags & SLICE_FLAG_CODED_ORDER))
+            (avctx->slice_flags & SLICE_FLAG_CODED_ORDER))
             src = &cur->f;
         else if (last)
             src = &last->f;
@@ -233,7 +319,6 @@
     if (ret < 0)
         goto fail;
 
-
     dst->qscale_table_buf = av_buffer_ref(src->qscale_table_buf);
     dst->mb_type_buf      = av_buffer_ref(src->mb_type_buf);
     if (!dst->qscale_table_buf || !dst->mb_type_buf)
@@ -241,7 +326,7 @@
     dst->qscale_table = src->qscale_table;
     dst->mb_type      = src->mb_type;
 
-    for (i = 0; i < 2; i ++) {
+    for (i = 0; i < 2; i++) {
         dst->motion_val_buf[i] = av_buffer_ref(src->motion_val_buf[i]);
         dst->ref_index_buf[i]  = av_buffer_ref(src->ref_index_buf[i]);
         if (!dst->motion_val_buf[i] || !dst->ref_index_buf[i])
@@ -263,19 +348,19 @@
     memcpy(dst->ref_poc,   src->ref_poc,   sizeof(src->ref_poc));
     memcpy(dst->ref_count, src->ref_count, sizeof(src->ref_count));
 
-    dst->poc                     = src->poc;
-    dst->frame_num               = src->frame_num;
-    dst->mmco_reset              = src->mmco_reset;
-    dst->pic_id                  = src->pic_id;
-    dst->long_ref                = src->long_ref;
-    dst->mbaff                   = src->mbaff;
-    dst->field_picture           = src->field_picture;
-    dst->needs_realloc           = src->needs_realloc;
-    dst->reference               = src->reference;
-    dst->sync                    = src->sync;
-    dst->crop                    = src->crop;
-    dst->crop_left               = src->crop_left;
-    dst->crop_top                = src->crop_top;
+    dst->poc           = src->poc;
+    dst->frame_num     = src->frame_num;
+    dst->mmco_reset    = src->mmco_reset;
+    dst->pic_id        = src->pic_id;
+    dst->long_ref      = src->long_ref;
+    dst->mbaff         = src->mbaff;
+    dst->field_picture = src->field_picture;
+    dst->needs_realloc = src->needs_realloc;
+    dst->reference     = src->reference;
+    dst->sync          = src->sync;
+    dst->crop          = src->crop;
+    dst->crop_left     = src->crop_left;
+    dst->crop_top      = src->crop_top;
 
     return 0;
 fail:
@@ -283,7 +368,6 @@
     return ret;
 }
 
-
 static int alloc_scratch_buffers(H264Context *h, int linesize)
 {
     int alloc_size = FFALIGN(FFABS(linesize) + 32, 32);
@@ -444,7 +528,7 @@
                 av_log(h->avctx, AV_LOG_ERROR,
                        "top block unavailable for requested intra4x4 mode %d at %d %d\n",
                        status, h->mb_x, h->mb_y);
-                return -1;
+                return AVERROR_INVALIDDATA;
             } else if (status) {
                 h->intra4x4_pred_mode_cache[scan8[0] + i] = status;
             }
@@ -460,7 +544,7 @@
                     av_log(h->avctx, AV_LOG_ERROR,
                            "left block unavailable for requested intra4x4 mode %d at %d %d\n",
                            status, h->mb_x, h->mb_y);
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 } else if (status) {
                     h->intra4x4_pred_mode_cache[scan8[0] + 8 * i] = status;
                 }
@@ -476,14 +560,14 @@
  */
 int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma)
 {
-    static const int8_t top[7]  = { LEFT_DC_PRED8x8, 1, -1, -1 };
-    static const int8_t left[7] = { TOP_DC_PRED8x8, -1, 2, -1, DC_128_PRED8x8 };
+    static const int8_t top[4]  = { LEFT_DC_PRED8x8, 1, -1, -1 };
+    static const int8_t left[5] = { TOP_DC_PRED8x8, -1, 2, -1, DC_128_PRED8x8 };
 
-    if (mode > 6U) {
+    if (mode > 3U) {
         av_log(h->avctx, AV_LOG_ERROR,
                "out of range intra chroma pred mode at %d %d\n",
                h->mb_x, h->mb_y);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (!(h->top_samples_available & 0x8000)) {
@@ -492,7 +576,7 @@
             av_log(h->avctx, AV_LOG_ERROR,
                    "top block unavailable for requested intra mode at %d %d\n",
                    h->mb_x, h->mb_y);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
 
@@ -508,7 +592,7 @@
             av_log(h->avctx, AV_LOG_ERROR,
                    "left block unavailable for requested intra mode at %d %d\n",
                    h->mb_x, h->mb_y);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
 
@@ -530,19 +614,21 @@
     length--;
 
 #define STARTCODE_TEST                                                  \
-        if (i + 2 < length && src[i + 1] == 0 && src[i + 2] <= 3) {     \
-            if (src[i + 2] != 3) {                                      \
-                /* startcode, so we must be past the end */             \
-                length = i;                                             \
-            }                                                           \
-            break;                                                      \
-        }
+    if (i + 2 < length && src[i + 1] == 0 && src[i + 2] <= 3) {         \
+        if (src[i + 2] != 3) {                                          \
+            /* startcode, so we must be past the end */                 \
+            length = i;                                                 \
+        }                                                               \
+        break;                                                          \
+    }
+
 #if HAVE_FAST_UNALIGNED
 #define FIND_FIRST_ZERO                                                 \
-        if (i > 0 && !src[i])                                           \
-            i--;                                                        \
-        while (src[i])                                                  \
-            i++
+    if (i > 0 && !src[i])                                               \
+        i--;                                                            \
+    while (src[i])                                                      \
+        i++
+
 #if HAVE_FAST_64BIT
     for (i = 0; i + 1 < length; i += 9) {
         if (!((~AV_RN64A(src + i) &
@@ -616,8 +702,8 @@
     }
     while (si < length)
         dst[di++] = src[si++];
-nsc:
 
+nsc:
     memset(dst + di, 0, FF_INPUT_BUFFER_PADDING_SIZE);
 
     *dst_length = di;
@@ -649,10 +735,10 @@
 static inline int get_lowest_part_list_y(H264Context *h, Picture *pic, int n,
                                          int height, int y_offset, int list)
 {
-    int raw_my        = h->mv_cache[list][scan8[n]][1];
+    int raw_my             = h->mv_cache[list][scan8[n]][1];
     int filter_height_down = (raw_my & 3) ? 3 : 0;
-    int full_my       = (raw_my >> 2) + y_offset;
-    int bottom        = full_my + filter_height_down + height;
+    int full_my            = (raw_my >> 2) + y_offset;
+    int bottom             = full_my + filter_height_down + height;
 
     av_assert2(height >= 0);
 
@@ -674,7 +760,7 @@
         // Error resilience puts the current picture in the ref list.
         // Don't try to wait on these as it will cause a deadlock.
         // Fields can wait on each other, though.
-        if (ref->tf.progress->data   != h->cur_pic.tf.progress->data ||
+        if (ref->tf.progress->data != h->cur_pic.tf.progress->data ||
             (ref->reference & 3) != h->picture_structure) {
             my = get_lowest_part_list_y(h, ref, n, height, y_offset, 0);
             if (refs[0][ref_n] < 0)
@@ -1238,8 +1324,8 @@
 
 int ff_h264_alloc_tables(H264Context *h)
 {
-    const int big_mb_num    = h->mb_stride * (h->mb_height + 1);
-    const int row_mb_num    = 2*h->mb_stride*FFMAX(h->avctx->thread_count, 1);
+    const int big_mb_num = h->mb_stride * (h->mb_height + 1);
+    const int row_mb_num = 2*h->mb_stride*FFMAX(h->avctx->thread_count, 1);
     int x, y, i;
 
     FF_ALLOCZ_OR_GOTO(h->avctx, h->intra4x4_pred_mode,
@@ -1294,7 +1380,7 @@
 
 fail:
     free_tables(h, 1);
-    return -1;
+    return AVERROR(ENOMEM);
 }
 
 /**
@@ -1369,7 +1455,7 @@
                 er->mb_index2xy[x + y * h->mb_width] = x + y * h->mb_stride;
 
         er->mb_index2xy[h->mb_height * h->mb_width] = (h->mb_height - 1) *
-                                                       h->mb_stride + h->mb_width;
+                                                      h->mb_stride + h->mb_width;
 
         FF_ALLOCZ_OR_GOTO(h->avctx, er->error_status_table,
                           mb_array_size * sizeof(uint8_t), fail);
@@ -1393,7 +1479,7 @@
     return 0;
 
 fail:
-    return -1; // free_tables will clean up for us
+    return AVERROR(ENOMEM); // free_tables will clean up for us
 }
 
 static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
@@ -1402,6 +1488,7 @@
 int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size)
 {
     AVCodecContext *avctx = h->avctx;
+    int ret;
 
     if (!buf || size <= 0)
         return -1;
@@ -1414,7 +1501,7 @@
 
         if (size < 7) {
             av_log(avctx, AV_LOG_ERROR, "avcC too short\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         /* sps and pps in the avcC always have length coded with 2 bytes,
          * so put a fake nal_length_size = 2 while parsing them */
@@ -1425,11 +1512,12 @@
         for (i = 0; i < cnt; i++) {
             nalsize = AV_RB16(p) + 2;
             if(nalsize > size - (p-buf))
-                return -1;
-            if (decode_nal_units(h, p, nalsize, 1) < 0) {
+                return AVERROR_INVALIDDATA;
+            ret = decode_nal_units(h, p, nalsize, 1);
+            if (ret < 0) {
                 av_log(avctx, AV_LOG_ERROR,
                        "Decoding sps %d from avcC failed\n", i);
-                return -1;
+                return ret;
             }
             p += nalsize;
         }
@@ -1438,11 +1526,12 @@
         for (i = 0; i < cnt; i++) {
             nalsize = AV_RB16(p) + 2;
             if(nalsize > size - (p-buf))
-                return -1;
-            if (decode_nal_units(h, p, nalsize, 1) < 0) {
+                return AVERROR_INVALIDDATA;
+            ret = decode_nal_units(h, p, nalsize, 1);
+            if (ret < 0) {
                 av_log(avctx, AV_LOG_ERROR,
                        "Decoding pps %d from avcC failed\n", i);
-                return -1;
+                return ret;
             }
             p += nalsize;
         }
@@ -1450,8 +1539,9 @@
         h->nal_length_size = (buf[4] & 0x03) + 1;
     } else {
         h->is_avc = 0;
-        if (decode_nal_units(h, buf, size, 1) < 0)
-            return -1;
+        ret = decode_nal_units(h, buf, size, 1);
+        if (ret < 0)
+            return ret;
     }
     return size;
 }
@@ -1460,6 +1550,7 @@
 {
     H264Context *h = avctx->priv_data;
     int i;
+    int ret;
 
     h->avctx = avctx;
 
@@ -1476,6 +1567,7 @@
     ff_h264_pred_init(&h->hpc, h->avctx->codec_id, 8, 1);
 
     h->dequant_coeff_pps = -1;
+    h->current_sps_id = -1;
 
     /* needed so that IDCT permutation is known early */
     if (CONFIG_ERROR_RESILIENCE)
@@ -1499,7 +1591,7 @@
 
     ff_h264_decode_init_vlc();
 
-    h->pixel_shift = 0;
+    h->pixel_shift        = 0;
     h->sps.bit_depth_luma = avctx->bits_per_raw_sample = 8;
 
     h->thread_context[0] = h;
@@ -1509,6 +1601,7 @@
     h->prev_poc_msb = 1 << 16;
     h->prev_frame_num = -1;
     h->x264_build   = -1;
+    h->sei_fpa.frame_packing_arrangement_cancel_flag = -1;
     ff_h264_reset_sei(h);
     if (avctx->codec_id == AV_CODEC_ID_H264) {
         if (avctx->ticks_per_frame == 1) {
@@ -1520,10 +1613,12 @@
         avctx->ticks_per_frame = 2;
     }
 
-    if (avctx->extradata_size > 0 && avctx->extradata &&
-        ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size) < 0) {
-        ff_h264_free_context(h);
-        return -1;
+    if (avctx->extradata_size > 0 && avctx->extradata) {
+        ret = ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size);
+        if (ret < 0) {
+            ff_h264_free_context(h);
+            return ret;
+        }
     }
 
     if (h->sps.bitstream_restriction_flag &&
@@ -1542,8 +1637,8 @@
 #undef REBASE_PICTURE
 #define REBASE_PICTURE(pic, new_ctx, old_ctx)             \
     ((pic && pic >= old_ctx->DPB &&                       \
-      pic < old_ctx->DPB + MAX_PICTURE_COUNT) ?      \
-        &new_ctx->DPB[pic - old_ctx->DPB] : NULL)
+      pic < old_ctx->DPB + MAX_PICTURE_COUNT) ?           \
+     &new_ctx->DPB[pic - old_ctx->DPB] : NULL)
 
 static void copy_picture_range(Picture **to, Picture **from, int count,
                                H264Context *new_base,
@@ -1609,10 +1704,10 @@
         return 0;
 
     if (inited &&
-        (h->width      != h1->width      ||
-         h->height     != h1->height     ||
-         h->mb_width   != h1->mb_width   ||
-         h->mb_height  != h1->mb_height  ||
+        (h->width                 != h1->width                 ||
+         h->height                != h1->height                ||
+         h->mb_width              != h1->mb_width              ||
+         h->mb_height             != h1->mb_height             ||
          h->sps.bit_depth_luma    != h1->sps.bit_depth_luma    ||
          h->sps.chroma_format_idc != h1->sps.chroma_format_idc ||
          h->sps.colorspace        != h1->sps.colorspace)) {
@@ -1680,12 +1775,12 @@
         memset(&h->mb_luma_dc, 0, sizeof(h->mb_luma_dc));
         memset(&h->mb_padding, 0, sizeof(h->mb_padding));
 
-        h->avctx = dst;
-        h->DPB   = NULL;
+        h->avctx             = dst;
+        h->DPB               = NULL;
         h->qscale_table_pool = NULL;
-        h->mb_type_pool = NULL;
-        h->ref_index_pool = NULL;
-        h->motion_val_pool = NULL;
+        h->mb_type_pool      = NULL;
+        h->ref_index_pool    = NULL;
+        h->motion_val_pool   = NULL;
 
         if (h1->context_initialized) {
         h->context_initialized = 0;
@@ -1694,11 +1789,16 @@
         avcodec_get_frame_defaults(&h->cur_pic.f);
         h->cur_pic.tf.f = &h->cur_pic.f;
 
-        if (ff_h264_alloc_tables(h) < 0) {
+        ret = ff_h264_alloc_tables(h);
+        if (ret < 0) {
             av_log(dst, AV_LOG_ERROR, "Could not allocate memory for h264\n");
-            return AVERROR(ENOMEM);
+            return ret;
         }
-        context_init(h);
+        ret = context_init(h);
+        if (ret < 0) {
+            av_log(dst, AV_LOG_ERROR, "context_init() failed.\n");
+            return ret;
+        }
         }
 
         for (i = 0; i < 2; i++) {
@@ -1731,7 +1831,7 @@
             return ret;
     }
 
-    h->cur_pic_ptr     = REBASE_PICTURE(h1->cur_pic_ptr, h, h1);
+    h->cur_pic_ptr = REBASE_PICTURE(h1->cur_pic_ptr, h, h1);
     unref_picture(h, &h->cur_pic);
     if (h1->cur_pic.f.buf[0] && (ret = ref_picture(h, &h->cur_pic, &h1->cur_pic)) < 0)
         return ret;
@@ -1823,7 +1923,7 @@
     }
     pic = &h->DPB[i];
 
-    pic->reference            = h->droppable ? 0 : h->picture_structure;
+    pic->reference              = h->droppable ? 0 : h->picture_structure;
     pic->f.coded_picture_number = h->coded_picture_number++;
     pic->field_picture          = h->picture_structure != PICT_FRAME;
 
@@ -1898,7 +1998,7 @@
     Picture *cur = h->cur_pic_ptr;
     int i, pics, out_of_order, out_idx;
 
-    h->cur_pic_ptr->f.pict_type   = h->pict_type;
+    h->cur_pic_ptr->f.pict_type = h->pict_type;
 
     if (h->next_output_pic)
         return;
@@ -2227,23 +2327,21 @@
             XCHG(h->top_borders[top_idx][h->mb_x + 1],
                  src_y + (17 << pixel_shift), 1);
         }
-    }
-    if (simple || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
-        if (chroma444) {
-            if (deblock_topleft) {
-                XCHG(top_border_m1 + (24 << pixel_shift), src_cb - (7 << pixel_shift), 1);
-                XCHG(top_border_m1 + (40 << pixel_shift), src_cr - (7 << pixel_shift), 1);
-            }
-            XCHG(top_border + (16 << pixel_shift), src_cb + (1 << pixel_shift), xchg);
-            XCHG(top_border + (24 << pixel_shift), src_cb + (9 << pixel_shift), 1);
-            XCHG(top_border + (32 << pixel_shift), src_cr + (1 << pixel_shift), xchg);
-            XCHG(top_border + (40 << pixel_shift), src_cr + (9 << pixel_shift), 1);
-            if (h->mb_x + 1 < h->mb_width) {
-                XCHG(h->top_borders[top_idx][h->mb_x + 1] + (16 << pixel_shift), src_cb + (17 << pixel_shift), 1);
-                XCHG(h->top_borders[top_idx][h->mb_x + 1] + (32 << pixel_shift), src_cr + (17 << pixel_shift), 1);
-            }
-        } else {
-            if (deblock_top) {
+        if (simple || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
+            if (chroma444) {
+                if (deblock_topleft) {
+                    XCHG(top_border_m1 + (24 << pixel_shift), src_cb - (7 << pixel_shift), 1);
+                    XCHG(top_border_m1 + (40 << pixel_shift), src_cr - (7 << pixel_shift), 1);
+                }
+                XCHG(top_border + (16 << pixel_shift), src_cb + (1 << pixel_shift), xchg);
+                XCHG(top_border + (24 << pixel_shift), src_cb + (9 << pixel_shift), 1);
+                XCHG(top_border + (32 << pixel_shift), src_cr + (1 << pixel_shift), xchg);
+                XCHG(top_border + (40 << pixel_shift), src_cr + (9 << pixel_shift), 1);
+                if (h->mb_x + 1 < h->mb_width) {
+                    XCHG(h->top_borders[top_idx][h->mb_x + 1] + (16 << pixel_shift), src_cb + (17 << pixel_shift), 1);
+                    XCHG(h->top_borders[top_idx][h->mb_x + 1] + (32 << pixel_shift), src_cr + (17 << pixel_shift), 1);
+                }
+            } else {
                 if (deblock_topleft) {
                     XCHG(top_border_m1 + (16 << pixel_shift), src_cb - (7 << pixel_shift), 1);
                     XCHG(top_border_m1 + (24 << pixel_shift), src_cr - (7 << pixel_shift), 1);
@@ -2290,8 +2388,8 @@
     if (IS_INTRA4x4(mb_type)) {
         if (IS_8x8DCT(mb_type)) {
             if (transform_bypass) {
-                idct_dc_add  =
-                idct_add     = h->h264dsp.h264_add_pixels8_clear;
+                idct_dc_add =
+                idct_add    = h->h264dsp.h264_add_pixels8_clear;
             } else {
                 idct_dc_add = h->h264dsp.h264_idct8_dc_add;
                 idct_add    = h->h264dsp.h264_idct8_add;
@@ -2374,7 +2472,8 @@
                          0 * 16,  1 * 16,  4 * 16,  5 * 16,
                          2 * 16,  3 * 16,  6 * 16,  7 * 16,
                          8 * 16,  9 * 16, 12 * 16, 13 * 16,
-                        10 * 16, 11 * 16, 14 * 16, 15 * 16 };
+                        10 * 16, 11 * 16, 14 * 16, 15 * 16
+                    };
                     for (i = 0; i < 16; i++)
                         dctcoef_set(h->mb + (p * 256 << pixel_shift),
                                     pixel_shift, dc_mapping[i],
@@ -2474,7 +2573,8 @@
 {
     const int mb_xy   = h->mb_xy;
     const int mb_type = h->cur_pic.mb_type[mb_xy];
-    int is_complex    = CONFIG_SMALL || h->is_complex || IS_INTRA_PCM(mb_type) || h->qscale == 0;
+    int is_complex    = CONFIG_SMALL || h->is_complex ||
+                        IS_INTRA_PCM(mb_type) || h->qscale == 0;
 
     if (CHROMA444(h)) {
         if (is_complex || h->pixel_shift)
@@ -2531,7 +2631,7 @@
                         h->chroma_weight[i][list][j][1] = get_se_golomb(&h->gb);
                         if (h->chroma_weight[i][list][j][0] != chroma_def ||
                             h->chroma_weight[i][list][j][1] != 0) {
-                            h->use_weight_chroma = 1;
+                            h->use_weight_chroma        = 1;
                             h->chroma_weight_flag[list] = 1;
                         }
                     }
@@ -2573,7 +2673,7 @@
         }
         if (h->ref_count[0] == 1 && h->ref_count[1] == 1 && !FRAME_MBAFF(h) &&
             h->ref_list[0][0].poc + h->ref_list[1][0].poc == 2 * cur_poc) {
-            h->use_weight = 0;
+            h->use_weight        = 0;
             h->use_weight_chroma = 0;
             return;
         }
@@ -2637,7 +2737,7 @@
 {
     int i, j;
 
-    h->outputed_poc = h->next_outputed_poc = INT_MIN;
+    h->outputed_poc          = h->next_outputed_poc = INT_MIN;
     h->prev_interlaced_frame = 1;
     idr(h);
 
@@ -2691,11 +2791,10 @@
     h->parse_context.last_index        = 0;
 }
 
-static int init_poc(H264Context *h)
+int ff_init_poc(H264Context *h, int pic_field_poc[2], int *pic_poc)
 {
     const int max_frame_num = 1 << h->sps.log2_max_frame_num;
     int field_poc[2];
-    Picture *cur = h->cur_pic_ptr;
 
     h->frame_num_offset = h->prev_frame_num_offset;
     if (h->frame_num < h->prev_frame_num)
@@ -2704,9 +2803,11 @@
     if (h->sps.poc_type == 0) {
         const int max_poc_lsb = 1 << h->sps.log2_max_poc_lsb;
 
-        if (h->poc_lsb < h->prev_poc_lsb && h->prev_poc_lsb - h->poc_lsb >= max_poc_lsb / 2)
+        if (h->poc_lsb < h->prev_poc_lsb &&
+            h->prev_poc_lsb - h->poc_lsb >= max_poc_lsb / 2)
             h->poc_msb = h->prev_poc_msb + max_poc_lsb;
-        else if (h->poc_lsb > h->prev_poc_lsb && h->prev_poc_lsb - h->poc_lsb < -max_poc_lsb / 2)
+        else if (h->poc_lsb > h->prev_poc_lsb &&
+                 h->prev_poc_lsb - h->poc_lsb < -max_poc_lsb / 2)
             h->poc_msb = h->prev_poc_msb - max_poc_lsb;
         else
             h->poc_msb = h->prev_poc_msb;
@@ -2760,10 +2861,10 @@
     }
 
     if (h->picture_structure != PICT_BOTTOM_FIELD)
-        h->cur_pic_ptr->field_poc[0] = field_poc[0];
+        pic_field_poc[0] = field_poc[0];
     if (h->picture_structure != PICT_TOP_FIELD)
-        h->cur_pic_ptr->field_poc[1] = field_poc[1];
-    cur->poc = FFMIN(cur->field_poc[0], cur->field_poc[1]);
+        pic_field_poc[1] = field_poc[1];
+    *pic_poc = FFMIN(pic_field_poc[0], pic_field_poc[1]);
 
     return 0;
 }
@@ -3059,6 +3160,8 @@
 {
     int width  = h->width  - (h->sps.crop_right + h->sps.crop_left);
     int height = h->height - (h->sps.crop_top   + h->sps.crop_bottom);
+    av_assert0(h->sps.crop_right + h->sps.crop_left < (unsigned)h->width);
+    av_assert0(h->sps.crop_top + h->sps.crop_bottom < (unsigned)h->height);
 
     /* handle container cropping */
     if (!h->sps.crop &&
@@ -3076,7 +3179,7 @@
 
         av_log(h->avctx, AV_LOG_WARNING, "Ignoring cropping information.\n");
         h->sps.crop_bottom = h->sps.crop_top = h->sps.crop_right = h->sps.crop_left = 0;
-        h->sps.crop = 0;
+        h->sps.crop        = 0;
 
         width  = h->width;
         height = h->height;
@@ -3095,7 +3198,7 @@
     int nb_slices = (HAVE_THREADS &&
                      h->avctx->active_thread_type & FF_THREAD_SLICE) ?
                     h->avctx->thread_count : 1;
-    int i;
+    int i, ret;
 
     h->avctx->sample_aspect_ratio = h->sps.sar;
     av_assert0(h->avctx->sample_aspect_ratio.den);
@@ -3114,14 +3217,15 @@
 
     if (reinit)
         free_tables(h, 0);
-    h->first_field = 0;
+    h->first_field           = 0;
     h->prev_interlaced_frame = 1;
 
     init_scan_tables(h);
-    if (ff_h264_alloc_tables(h) < 0) {
+    ret = ff_h264_alloc_tables(h);
+    if (ret < 0) {
         av_log(h->avctx, AV_LOG_ERROR,
                "Could not allocate memory for h264\n");
-        return AVERROR(ENOMEM);
+        return ret;
     }
 
     if (nb_slices > MAX_THREADS || (nb_slices > h->mb_height && h->mb_height)) {
@@ -3137,43 +3241,44 @@
     h->slice_context_count = nb_slices;
 
     if (!HAVE_THREADS || !(h->avctx->active_thread_type & FF_THREAD_SLICE)) {
-        if (context_init(h) < 0) {
+        ret = context_init(h);
+        if (ret < 0) {
             av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n");
-            return -1;
+            return ret;
         }
     } else {
         for (i = 1; i < h->slice_context_count; i++) {
             H264Context *c;
-            c = h->thread_context[i] = av_mallocz(sizeof(H264Context));
-            c->avctx       = h->avctx;
+            c                    = h->thread_context[i] = av_mallocz(sizeof(H264Context));
+            c->avctx             = h->avctx;
             if (CONFIG_ERROR_RESILIENCE) {
-                c->dsp         = h->dsp;
+                c->dsp               = h->dsp;
             }
-            c->vdsp        = h->vdsp;
-            c->h264dsp     = h->h264dsp;
-            c->h264qpel    = h->h264qpel;
-            c->h264chroma  = h->h264chroma;
-            c->sps         = h->sps;
-            c->pps         = h->pps;
-            c->pixel_shift = h->pixel_shift;
+            c->vdsp              = h->vdsp;
+            c->h264dsp           = h->h264dsp;
+            c->h264qpel          = h->h264qpel;
+            c->h264chroma        = h->h264chroma;
+            c->sps               = h->sps;
+            c->pps               = h->pps;
+            c->pixel_shift       = h->pixel_shift;
             c->cur_chroma_format_idc = h->cur_chroma_format_idc;
-            c->width       = h->width;
-            c->height      = h->height;
-            c->linesize    = h->linesize;
-            c->uvlinesize  = h->uvlinesize;
+            c->width             = h->width;
+            c->height            = h->height;
+            c->linesize          = h->linesize;
+            c->uvlinesize        = h->uvlinesize;
             c->chroma_x_shift = h->chroma_x_shift;
             c->chroma_y_shift = h->chroma_y_shift;
-            c->qscale      = h->qscale;
-            c->droppable   = h->droppable;
+            c->qscale            = h->qscale;
+            c->droppable         = h->droppable;
             c->data_partitioning = h->data_partitioning;
-            c->low_delay   = h->low_delay;
-            c->mb_width    = h->mb_width;
-            c->mb_height   = h->mb_height;
-            c->mb_stride   = h->mb_stride;
-            c->mb_num      = h->mb_num;
-            c->flags       = h->flags;
-            c->workaround_bugs = h->workaround_bugs;
-            c->pict_type   = h->pict_type;
+            c->low_delay         = h->low_delay;
+            c->mb_width          = h->mb_width;
+            c->mb_height         = h->mb_height;
+            c->mb_stride         = h->mb_stride;
+            c->mb_num            = h->mb_num;
+            c->flags             = h->flags;
+            c->workaround_bugs   = h->workaround_bugs;
+            c->pict_type         = h->pict_type;
 
             init_scan_tables(c);
             clone_tables(c, h, i);
@@ -3181,9 +3286,9 @@
         }
 
         for (i = 0; i < h->slice_context_count; i++)
-            if (context_init(h->thread_context[i]) < 0) {
+            if ((ret = context_init(h->thread_context[i])) < 0) {
                 av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n");
-                return -1;
+                return ret;
             }
     }
 
@@ -3211,6 +3316,7 @@
     int last_pic_structure, last_pic_droppable;
     int must_reinit;
     int needs_reinit = 0;
+    int field_pic_flag, bottom_field_flag;
 
     h->me.qpel_put = h->h264qpel.put_h264_qpel_pixels_tab;
     h->me.qpel_avg = h->h264qpel.avg_h264_qpel_pixels_tab;
@@ -3237,7 +3343,7 @@
         av_log(h->avctx, AV_LOG_ERROR,
                "slice type too large (%d) at %d %d\n",
                slice_type, h->mb_x, h->mb_y);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (slice_type > 4) {
         slice_type -= 5;
@@ -3255,13 +3361,13 @@
     pps_id = get_ue_golomb(&h->gb);
     if (pps_id >= MAX_PPS_COUNT) {
         av_log(h->avctx, AV_LOG_ERROR, "pps_id %d out of range\n", pps_id);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (!h0->pps_buffers[pps_id]) {
         av_log(h->avctx, AV_LOG_ERROR,
                "non-existing PPS %u referenced\n",
                pps_id);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     h->pps = *h0->pps_buffers[pps_id];
 
@@ -3269,7 +3375,7 @@
         av_log(h->avctx, AV_LOG_ERROR,
                "non-existing SPS %u referenced\n",
                h->pps.sps_id);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (h->pps.sps_id != h->current_sps_id ||
@@ -3305,7 +3411,10 @@
                      || 16*h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) != h->avctx->coded_height
                      || h->avctx->bits_per_raw_sample != h->sps.bit_depth_luma
                      || h->cur_chroma_format_idc != h->sps.chroma_format_idc
-                     || av_cmp_q(h->sps.sar, h->avctx->sample_aspect_ratio)));
+                     || av_cmp_q(h->sps.sar, h->avctx->sample_aspect_ratio)
+                     || h->mb_width  != h->sps.mb_width
+                     || h->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag)
+                    ));
     if (h0->avctx->pix_fmt != get_pixel_format(h0, 0))
         must_reinit = 1;
 
@@ -3342,7 +3451,6 @@
          h->height != h->avctx->coded_height  ||
          must_reinit ||
          needs_reinit)) {
-
         if (h != h0) {
             av_log(h->avctx, AV_LOG_ERROR, "changing width/height on "
                    "slice %d\n", h0->current_slice + 1);
@@ -3368,7 +3476,7 @@
         if (h != h0) {
             av_log(h->avctx, AV_LOG_ERROR,
                    "Cannot (re-)initialize context during parallel decoding.\n");
-            return -1;
+            return AVERROR_PATCHWELCOME;
         }
 
         if ((ret = get_pixel_format(h, 1)) < 0)
@@ -3401,8 +3509,10 @@
             av_log(h->avctx, AV_LOG_ERROR, "This stream was generated by a broken encoder, invalid 8x8 inference\n");
             return -1;
         }
-        if (get_bits1(&h->gb)) { // field_pic_flag
-            h->picture_structure = PICT_TOP_FIELD + get_bits1(&h->gb); // bottom_field_flag
+        field_pic_flag = get_bits1(&h->gb);
+        if (field_pic_flag) {
+            bottom_field_flag = get_bits1(&h->gb);
+            h->picture_structure = PICT_TOP_FIELD + bottom_field_flag;
         } else {
             h->picture_structure = PICT_FRAME;
             h->mb_aff_frame      = h->sps.mb_aff;
@@ -3509,30 +3619,36 @@
             if (!h->sps.gaps_in_frame_num_allowed_flag)
                 for(i=0; i<FF_ARRAY_ELEMS(h->last_pocs); i++)
                     h->last_pocs[i] = INT_MIN;
-            if (h264_frame_start(h) < 0)
-                return -1;
+            ret = h264_frame_start(h);
+            if (ret < 0)
+                return ret;
             h->prev_frame_num++;
-            h->prev_frame_num %= 1 << h->sps.log2_max_frame_num;
+            h->prev_frame_num        %= 1 << h->sps.log2_max_frame_num;
             h->cur_pic_ptr->frame_num = h->prev_frame_num;
             ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0);
             ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1);
-            if ((ret = ff_generate_sliding_window_mmcos(h, 1)) < 0 &&
-                h->avctx->err_recognition & AV_EF_EXPLODE)
+            ret = ff_generate_sliding_window_mmcos(h, 1);
+            if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
                 return ret;
-            if (ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index) < 0 &&
-                (h->avctx->err_recognition & AV_EF_EXPLODE))
-                return AVERROR_INVALIDDATA;
-            /* Error concealment: if a ref is missing, copy the previous ref in its place.
-             * FIXME: avoiding a memcpy would be nice, but ref handling makes many assumptions
-             * about there being no actual duplicates.
-             * FIXME: this doesn't copy padding for out-of-frame motion vectors.  Given we're
-             * concealing a lost frame, this probably isn't noticeable by comparison, but it should
-             * be fixed. */
+            ret = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
+            if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
+                return ret;
+            /* Error concealment: If a ref is missing, copy the previous ref
+             * in its place.
+             * FIXME: Avoiding a memcpy would be nice, but ref handling makes
+             * many assumptions about there being no actual duplicates.
+             * FIXME: This does not copy padding for out-of-frame motion
+             * vectors.  Given we are concealing a lost frame, this probably
+             * is not noticeable by comparison, but it should be fixed. */
             if (h->short_ref_count) {
                 if (prev) {
-                    av_image_copy(h->short_ref[0]->f.data, h->short_ref[0]->f.linesize,
-                                  (const uint8_t **)prev->f.data, prev->f.linesize,
-                                  h->avctx->pix_fmt, h->mb_width * 16, h->mb_height * 16);
+                    av_image_copy(h->short_ref[0]->f.data,
+                                  h->short_ref[0]->f.linesize,
+                                  (const uint8_t **)prev->f.data,
+                                  prev->f.linesize,
+                                  h->avctx->pix_fmt,
+                                  h->mb_width  * 16,
+                                  h->mb_height * 16);
                     h->short_ref[0]->poc = prev->poc + 2;
                 }
                 h->short_ref[0]->frame_num = h->prev_frame_num;
@@ -3575,7 +3691,7 @@
         if (!FIELD_PICTURE(h) || h0->first_field) {
             if (h264_frame_start(h) < 0) {
                 h0->first_field = 0;
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
         } else {
             release_unused_pictures(h, 0);
@@ -3609,10 +3725,11 @@
     if (first_mb_in_slice << FIELD_OR_MBAFF_PICTURE(h) >= h->mb_num ||
         first_mb_in_slice >= h->mb_num) {
         av_log(h->avctx, AV_LOG_ERROR, "first_mb_in_slice overflow\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     h->resync_mb_x = h->mb_x =  first_mb_in_slice % h->mb_width;
-    h->resync_mb_y = h->mb_y = (first_mb_in_slice / h->mb_width) << FIELD_OR_MBAFF_PICTURE(h);
+    h->resync_mb_y = h->mb_y = (first_mb_in_slice / h->mb_width) <<
+                               FIELD_OR_MBAFF_PICTURE(h);
     if (h->picture_structure == PICT_BOTTOM_FIELD)
         h->resync_mb_y = h->mb_y = h->mb_y + 1;
     av_assert1(h->mb_y < h->mb_height);
@@ -3642,7 +3759,7 @@
             h->delta_poc[1] = get_se_golomb(&h->gb);
     }
 
-    init_poc(h);
+    ff_init_poc(h, h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc);
 
     if (h->pps.redundant_pic_cnt_present)
         h->redundant_pic_count = get_ue_golomb(&h->gb);
@@ -3679,7 +3796,7 @@
         else
             h->list_count = 1;
     } else {
-        h->list_count = 0;
+        h->list_count   = 0;
         h->ref_count[0] = h->ref_count[1] = 0;
     }
     if (slice_type != AV_PICTURE_TYPE_I &&
@@ -3689,10 +3806,12 @@
         ff_h264_fill_default_ref_list(h);
     }
 
-    if (h->slice_type_nos != AV_PICTURE_TYPE_I &&
-        ff_h264_decode_ref_pic_list_reordering(h) < 0) {
-        h->ref_count[1] = h->ref_count[0] = 0;
-        return -1;
+    if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
+       ret = ff_h264_decode_ref_pic_list_reordering(h);
+       if (ret < 0) {
+           h->ref_count[1] = h->ref_count[0] = 0;
+           return ret;
+       }
     }
 
     if ((h->pps.weighted_pred && h->slice_type_nos == AV_PICTURE_TYPE_P) ||
@@ -3715,12 +3834,13 @@
     // or h->mmco, which will cause ref list mix-ups and decoding errors
     // further down the line. This may break decoding if the first slice is
     // corrupt, thus we only do this if frame-mt is enabled.
-    if (h->nal_ref_idc &&
-        ff_h264_decode_ref_pic_marking(h0, &h->gb,
-                            !(h->avctx->active_thread_type & FF_THREAD_FRAME) ||
-                            h0->current_slice == 0) < 0 &&
-        (h->avctx->err_recognition & AV_EF_EXPLODE))
-        return AVERROR_INVALIDDATA;
+    if (h->nal_ref_idc) {
+        ret = ff_h264_decode_ref_pic_marking(h0, &h->gb,
+                                             !(h->avctx->active_thread_type & FF_THREAD_FRAME) ||
+                                             h0->current_slice == 0);
+        if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
+            return AVERROR_INVALIDDATA;
+    }
 
     if (FRAME_MBAFF(h)) {
         ff_h264_fill_mbaff_ref_list(h);
@@ -3739,7 +3859,7 @@
         tmp = get_ue_golomb_31(&h->gb);
         if (tmp > 2) {
             av_log(h->avctx, AV_LOG_ERROR, "cabac_init_idc overflow\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         h->cabac_init_idc = tmp;
     }
@@ -3748,7 +3868,7 @@
     tmp = h->pps.init_qp + get_se_golomb(&h->gb);
     if (tmp > 51 + 6 * (h->sps.bit_depth_luma - 8)) {
         av_log(h->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     h->qscale       = tmp;
     h->chroma_qp[0] = get_chroma_qp(h, 0, h->qscale);
@@ -3768,7 +3888,7 @@
         if (tmp > 2) {
             av_log(h->avctx, AV_LOG_ERROR,
                    "deblocking_filter_idc %u out of range\n", tmp);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         h->deblocking_filter = tmp;
         if (h->deblocking_filter < 2)
@@ -3782,7 +3902,7 @@
                 av_log(h->avctx, AV_LOG_ERROR,
                        "deblocking filter parameters %d %d out of range\n",
                        h->slice_alpha_c0_offset, h->slice_beta_offset);
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
         }
     }
@@ -3824,7 +3944,7 @@
 
     h0->last_slice_type = slice_type;
     memcpy(h0->last_ref_count, h0->ref_count, sizeof(h0->last_ref_count));
-    h->slice_num = ++h0->current_slice;
+    h->slice_num        = ++h0->current_slice;
 
     if (h->slice_num)
         h0->slice_row[(h->slice_num-1)&(MAX_SLICES-1)]= h->resync_mb_y;
@@ -3840,7 +3960,8 @@
         int *ref2frm = h->ref2frm[h->slice_num & (MAX_SLICES - 1)][j];
         for (i = 0; i < 16; i++) {
             id_list[i] = 60;
-            if (j < h->list_count && i < h->ref_count[j] && h->ref_list[j][i].f.buf[0]) {
+            if (j < h->list_count && i < h->ref_count[j] &&
+                h->ref_list[j][i].f.buf[0]) {
                 int k;
                 AVBuffer *buf = h->ref_list[j][i].f.buf[0]->buffer;
                 for (k = 0; k < h->short_ref_count; k++)
@@ -3856,13 +3977,12 @@
             }
         }
 
-        ref2frm[0]     =
-            ref2frm[1] = -1;
+        ref2frm[0] =
+        ref2frm[1] = -1;
         for (i = 0; i < 16; i++)
-            ref2frm[i + 2] = 4 * id_list[i] +
-                             (h->ref_list[j][i].reference & 3);
-        ref2frm[18 + 0]     =
-            ref2frm[18 + 1] = -1;
+            ref2frm[i + 2] = 4 * id_list[i] + (h->ref_list[j][i].reference & 3);
+        ref2frm[18 + 0] =
+        ref2frm[18 + 1] = -1;
         for (i = 16; i < 48; i++)
             ref2frm[i + 4] = 4 * id_list[(i - 16) >> 1] +
                              (h->ref_list[j][i].reference & 3);
@@ -3909,7 +4029,7 @@
     case AV_PICTURE_TYPE_SI:
         return 4;
     default:
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 }
 
@@ -4020,7 +4140,7 @@
         } else {
             if (curr_mb_field_flag)
                 top_xy += h->mb_stride &
-                    (((h->cur_pic.mb_type[top_xy] >> 7) & 1) - 1);
+                          (((h->cur_pic.mb_type[top_xy] >> 7) & 1) - 1);
             if (left_mb_field_flag != curr_mb_field_flag)
                 left_xy[LBOT] += h->mb_stride;
         }
@@ -4102,18 +4222,18 @@
      * from what the loop filter needs */
     if (!CABAC(h) && h->pps.transform_8x8_mode) {
         if (IS_8x8DCT(top_type)) {
-            nnz_cache[4 + 8 * 0]     =
-                nnz_cache[5 + 8 * 0] = (h->cbp_table[top_xy] & 0x4000) >> 12;
-            nnz_cache[6 + 8 * 0]     =
-                nnz_cache[7 + 8 * 0] = (h->cbp_table[top_xy] & 0x8000) >> 12;
+            nnz_cache[4 + 8 * 0] =
+            nnz_cache[5 + 8 * 0] = (h->cbp_table[top_xy] & 0x4000) >> 12;
+            nnz_cache[6 + 8 * 0] =
+            nnz_cache[7 + 8 * 0] = (h->cbp_table[top_xy] & 0x8000) >> 12;
         }
         if (IS_8x8DCT(left_type[LTOP])) {
-            nnz_cache[3 + 8 * 1]     =
-                nnz_cache[3 + 8 * 2] = (h->cbp_table[left_xy[LTOP]] & 0x2000) >> 12; // FIXME check MBAFF
+            nnz_cache[3 + 8 * 1] =
+            nnz_cache[3 + 8 * 2] = (h->cbp_table[left_xy[LTOP]] & 0x2000) >> 12; // FIXME check MBAFF
         }
         if (IS_8x8DCT(left_type[LBOT])) {
-            nnz_cache[3 + 8 * 3]     =
-                nnz_cache[3 + 8 * 4] = (h->cbp_table[left_xy[LBOT]] & 0x8000) >> 12; // FIXME check MBAFF
+            nnz_cache[3 + 8 * 3] =
+            nnz_cache[3 + 8 * 4] = (h->cbp_table[left_xy[LBOT]] & 0x8000) >> 12; // FIXME check MBAFF
         }
 
         if (IS_8x8DCT(mb_type)) {
@@ -4279,7 +4399,7 @@
                     avctx->codec_id != AV_CODEC_ID_H264 ||
                     (CONFIG_GRAY && (h->flags & CODEC_FLAG_GRAY));
 
-    if (!(h->avctx->active_thread_type & FF_THREAD_SLICE) && h->picture_structure == PICT_FRAME) {
+    if (!(h->avctx->active_thread_type & FF_THREAD_SLICE) && h->picture_structure == PICT_FRAME && h->er.error_status_table) {
         const int start_i  = av_clip(h->resync_mb_x + h->resync_mb_y * h->mb_width, 0, h->mb_num - 1);
         if (start_i) {
             int prev_status = h->er.error_status_table[h->er.mb_index2xy[start_i - 1]];
@@ -4324,7 +4444,7 @@
             if ((h->workaround_bugs & FF_BUG_TRUNCATED) &&
                 h->cabac.bytestream > h->cabac.bytestream_end + 2) {
                 er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x - 1,
-                                h->mb_y, ER_MB_END);
+                             h->mb_y, ER_MB_END);
                 if (h->mb_x >= lf_x_start)
                     loop_filter(h, lf_x_start, h->mb_x + 1);
                 return 0;
@@ -4337,8 +4457,8 @@
                        h->mb_x, h->mb_y,
                        h->cabac.bytestream_end - h->cabac.bytestream);
                 er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x,
-                                h->mb_y, ER_MB_ERROR);
-                return -1;
+                             h->mb_y, ER_MB_ERROR);
+                return AVERROR_INVALIDDATA;
             }
 
             if (++h->mb_x >= h->mb_width) {
@@ -4357,7 +4477,7 @@
                 tprintf(h->avctx, "slice end %d %d\n",
                         get_bits_count(&h->gb), h->gb.size_in_bits);
                 er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x - 1,
-                                h->mb_y, ER_MB_END);
+                             h->mb_y, ER_MB_END);
                 if (h->mb_x > lf_x_start)
                     loop_filter(h, lf_x_start, h->mb_x);
                 return 0;
@@ -4384,8 +4504,8 @@
                 av_log(h->avctx, AV_LOG_ERROR,
                        "error while decoding MB %d %d\n", h->mb_x, h->mb_y);
                 er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x,
-                                h->mb_y, ER_MB_ERROR);
-                return -1;
+                             h->mb_y, ER_MB_ERROR);
+                return ret;
             }
 
             if (++h->mb_x >= h->mb_width) {
@@ -4405,16 +4525,16 @@
                     if (   get_bits_left(&h->gb) == 0
                         || get_bits_left(&h->gb) > 0 && !(h->avctx->err_recognition & AV_EF_AGGRESSIVE)) {
                         er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
-                                        h->mb_x - 1, h->mb_y,
-                                        ER_MB_END);
+                                     h->mb_x - 1, h->mb_y,
+                                     ER_MB_END);
 
                         return 0;
                     } else {
                         er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
-                                        h->mb_x, h->mb_y,
-                                        ER_MB_END);
+                                     h->mb_x, h->mb_y,
+                                     ER_MB_END);
 
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     }
                 }
             }
@@ -4422,19 +4542,20 @@
             if (get_bits_left(&h->gb) <= 0 && h->mb_skip_run <= 0) {
                 tprintf(h->avctx, "slice end %d %d\n",
                         get_bits_count(&h->gb), h->gb.size_in_bits);
+
                 if (get_bits_left(&h->gb) == 0) {
                     er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
-                                    h->mb_x - 1, h->mb_y,
-                                    ER_MB_END);
+                                 h->mb_x - 1, h->mb_y,
+                                 ER_MB_END);
                     if (h->mb_x > lf_x_start)
                         loop_filter(h, lf_x_start, h->mb_x);
 
                     return 0;
                 } else {
                     er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x,
-                                    h->mb_y, ER_MB_ERROR);
+                                 h->mb_y, ER_MB_ERROR);
 
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
             }
         }
@@ -4461,11 +4582,11 @@
     } else {
         av_assert0(context_count > 0);
         for (i = 1; i < context_count; i++) {
-            hx                    = h->thread_context[i];
+            hx                 = h->thread_context[i];
             if (CONFIG_ERROR_RESILIENCE) {
                 hx->er.error_count = 0;
             }
-            hx->x264_build        = h->x264_build;
+            hx->x264_build     = h->x264_build;
         }
 
         avctx->execute(avctx, decode_slice, h->thread_context,
@@ -4486,6 +4607,8 @@
     return 0;
 }
 
+static const uint8_t start_code[] = { 0x00, 0x00, 0x01 };
+
 static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
                             int parse_extradata)
 {
@@ -4499,6 +4622,7 @@
     int nal_index;
     int idr_cleared=0;
     int first_slice = 0;
+    int ret = 0;
 
     h->nal_unit_type= 0;
 
@@ -4568,7 +4692,7 @@
             ptr = ff_h264_decode_nal(hx, buf + buf_index, &dst_length,
                                      &consumed, next_avc - buf_index);
             if (ptr == NULL || dst_length < 0) {
-                buf_index = -1;
+                ret = -1;
                 goto end;
             }
             i = buf_index + consumed;
@@ -4653,7 +4777,7 @@
                 if (first_slice != NAL_IDR_SLICE) {
                     av_log(h->avctx, AV_LOG_ERROR,
                            "Invalid mix of idr and non-idr slices\n");
-                    buf_index = -1;
+                    ret = -1;
                     goto end;
                 }
                 if(!idr_cleared)
@@ -4661,8 +4785,8 @@
                 idr_cleared = 1;
             case NAL_SLICE:
                 init_get_bits(&hx->gb, ptr, bit_length);
-                hx->intra_gb_ptr        =
-                    hx->inter_gb_ptr    = &hx->gb;
+                hx->intra_gb_ptr      =
+                hx->inter_gb_ptr      = &hx->gb;
                 hx->data_partitioning = 0;
 
                 if ((err = decode_slice_header(hx, h)))
@@ -4698,8 +4822,8 @@
                         decode_postinit(h, nal_index >= nals_needed);
 
                     if (h->avctx->hwaccel &&
-                        h->avctx->hwaccel->start_frame(h->avctx, NULL, 0) < 0)
-                        return -1;
+                        (ret = h->avctx->hwaccel->start_frame(h->avctx, NULL, 0)) < 0)
+                        return ret;
                     if (CONFIG_H264_VDPAU_DECODER &&
                         h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
                         ff_vdpau_h264_picture_start(h);
@@ -4714,17 +4838,18 @@
                      hx->slice_type_nos == AV_PICTURE_TYPE_I) &&
                     avctx->skip_frame < AVDISCARD_ALL) {
                     if (avctx->hwaccel) {
-                        if (avctx->hwaccel->decode_slice(avctx,
-                                                         &buf[buf_index - consumed],
-                                                         consumed) < 0)
-                            return -1;
+                        ret = avctx->hwaccel->decode_slice(avctx,
+                                                           &buf[buf_index - consumed],
+                                                           consumed);
+                        if (ret < 0)
+                            return ret;
                     } else if (CONFIG_H264_VDPAU_DECODER &&
                                h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) {
-                        static const uint8_t start_code[] = {
-                            0x00, 0x00, 0x01 };
-                        ff_vdpau_add_data_chunk(h->cur_pic_ptr->f.data[0], start_code,
+                        ff_vdpau_add_data_chunk(h->cur_pic_ptr->f.data[0],
+                                                start_code,
                                                 sizeof(start_code));
-                        ff_vdpau_add_data_chunk(h->cur_pic_ptr->f.data[0], &buf[buf_index - consumed],
+                        ff_vdpau_add_data_chunk(h->cur_pic_ptr->f.data[0],
+                                                &buf[buf_index - consumed],
                                                 consumed);
                     } else
                         context_count++;
@@ -4769,7 +4894,7 @@
                 break;
             case NAL_SPS:
                 init_get_bits(&h->gb, ptr, bit_length);
-                if (ff_h264_decode_seq_parameter_set(h) < 0 && (h->is_avc ? (nalsize != consumed) && nalsize : 1)) {
+                if (ff_h264_decode_seq_parameter_set(h) < 0 && (h->is_avc ? nalsize : 1)) {
                     av_log(h->avctx, AV_LOG_DEBUG,
                            "SPS decoding failure, trying again with the complete NAL\n");
                     if (h->is_avc)
@@ -4829,7 +4954,7 @@
                                   h->picture_structure == PICT_BOTTOM_FIELD);
     }
 
-    return buf_index;
+    return (ret < 0) ? ret : buf_index;
 }
 
 /**
@@ -4853,6 +4978,8 @@
     if (ret < 0)
         return ret;
 
+    av_dict_set(&dst->metadata, "stereo_mode", ff_h264_sei_stereo_mode(h), 0);
+
     if (!srcp->crop)
         return 0;
 
@@ -4860,7 +4987,7 @@
         int hshift = (i > 0) ? h->chroma_x_shift : 0;
         int vshift = (i > 0) ? h->chroma_y_shift : 0;
         int off    = ((srcp->crop_left >> hshift) << h->pixel_shift) +
-            (srcp->crop_top  >> vshift) * dst->linesize[i];
+                      (srcp->crop_top  >> vshift) * dst->linesize[i];
         dst->data[i] += off;
     }
     return 0;
@@ -4878,7 +5005,7 @@
     int i, out_idx;
     int ret;
 
-    h->flags  = avctx->flags;
+    h->flags = avctx->flags;
 
     /* end of stream, output what is still in the buffers */
     if (buf_size == 0) {
@@ -4938,7 +5065,7 @@
 
     buf_index = decode_nal_units(h, buf, buf_size, 0);
     if (buf_index < 0)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     if (!h->cur_pic_ptr && h->nal_unit_type == NAL_END_SEQUENCE) {
         av_assert0(buf_index <= buf_size);
@@ -4950,7 +5077,7 @@
             buf_size >= 4 && !memcmp("Q264", buf, 4))
             return buf_size;
         av_log(avctx, AV_LOG_ERROR, "no frame!\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) ||
@@ -4995,7 +5122,7 @@
 
 static av_cold int h264_decode_end(AVCodecContext *avctx)
 {
-    H264Context *h    = avctx->priv_data;
+    H264Context *h = avctx->priv_data;
 
     ff_h264_remove_all_refs(h);
     ff_h264_free_context(h);
@@ -5074,7 +5201,7 @@
     .flush          = flush_dpb,
     .long_name      = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (VDPAU acceleration)"),
     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_VDPAU_H264,
-                                                   AV_PIX_FMT_NONE},
+                                                     AV_PIX_FMT_NONE},
     .profiles       = NULL_IF_CONFIG_SMALL(profiles),
     .priv_class     = &h264_vdpau_class,
 };
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index 61e1bcb..b2365bc 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -127,7 +127,8 @@
     SEI_TYPE_PIC_TIMING             = 1,   ///< picture timing
     SEI_TYPE_USER_DATA_ITU_T_T35    = 4,   ///< user data registered by ITU-T Recommendation T.35
     SEI_TYPE_USER_DATA_UNREGISTERED = 5,   ///< unregistered user data
-    SEI_TYPE_RECOVERY_POINT         = 6    ///< recovery point (frame # to decoder sync)
+    SEI_TYPE_RECOVERY_POINT         = 6,   ///< recovery point (frame # to decoder sync)
+    SEI_TYPE_FRAME_PACKING          = 45,  ///< frame packing arrangement
 } SEI_Type;
 
 /**
@@ -146,6 +147,19 @@
 } SEI_PicStructType;
 
 /**
+ * frame_packing_arrangement types
+ */
+typedef enum {
+    SEI_FPA_TYPE_CHECKERBOARD        = 0,
+    SEI_FPA_TYPE_INTERLEAVE_COLUMN   = 1,
+    SEI_FPA_TYPE_INTERLEAVE_ROW      = 2,
+    SEI_FPA_TYPE_SIDE_BY_SIDE        = 3,
+    SEI_FPA_TYPE_TOP_BOTTOM          = 4,
+    SEI_FPA_TYPE_INTERLEAVE_TEMPORAL = 5,
+    SEI_FPA_TYPE_2D                  = 6,
+} SEI_FpaType;
+
+/**
  * Sequence parameter set
  */
 typedef struct SPS {
@@ -233,6 +247,18 @@
 } PPS;
 
 /**
+ * Frame Packing Arrangement Type
+ */
+typedef struct FPA {
+    int         frame_packing_arrangement_id;
+    int         frame_packing_arrangement_cancel_flag; ///< is previous arrangement canceled, -1 if never received
+    SEI_FpaType frame_packing_arrangement_type;
+    int         frame_packing_arrangement_repetition_period;
+    int         content_interpretation_type;
+    int         quincunx_sampling_flag;
+} FPA;
+
+/**
  * Memory management control operation opcode.
  */
 typedef enum MMCOOpcode {
@@ -628,6 +654,8 @@
      */
     int valid_recovery_point;
 
+    FPA sei_fpa;
+
     int luma_weight_flag[2];    ///< 7.4.3.2 luma_weight_lX_flag
     int chroma_weight_flag[2];  ///< 7.4.3.2 chroma_weight_lX_flag
 
@@ -775,6 +803,12 @@
  */
 void ff_h264_reset_sei(H264Context *h);
 
+/**
+ * Get stereo_mode string from the h264 frame_packing_arrangement
+ * @param h H.264 context.
+ */
+const char* ff_h264_sei_stereo_mode(H264Context *h);
+
 /*
  * o-o o-o
  *  / / /
@@ -976,5 +1010,6 @@
 }
 
 void ff_h264_draw_horiz_band(H264Context *h, int y, int height);
+int ff_init_poc(H264Context *h, int pic_field_poc[2], int *pic_poc);
 
 #endif /* AVCODEC_H264_H */
diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c
index 2c23cae..ad902b8 100644
--- a/libavcodec/h264_cavlc.c
+++ b/libavcodec/h264_cavlc.c
@@ -711,7 +711,7 @@
                 down the code */
     if(h->slice_type_nos != AV_PICTURE_TYPE_I){
         if(h->mb_skip_run==-1)
-            h->mb_skip_run= get_ue_golomb(&h->gb);
+            h->mb_skip_run= get_ue_golomb_long(&h->gb);
 
         if (h->mb_skip_run--) {
             if(FRAME_MBAFF(h) && (h->mb_y&1) == 0){
diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c
index 2d93c2a..477359c 100644
--- a/libavcodec/h264_direct.c
+++ b/libavcodec/h264_direct.c
@@ -32,7 +32,6 @@
 #include "rectangle.h"
 #include "thread.h"
 
-//#undef NDEBUG
 #include <assert.h>
 
 
diff --git a/libavcodec/h264_mp4toannexb_bsf.c b/libavcodec/h264_mp4toannexb_bsf.c
index 2dea933..6ca0100 100644
--- a/libavcodec/h264_mp4toannexb_bsf.c
+++ b/libavcodec/h264_mp4toannexb_bsf.c
@@ -31,114 +31,138 @@
     int      extradata_parsed;
 } H264BSFContext;
 
-static int alloc_and_copy(uint8_t **poutbuf,          int *poutbuf_size,
+static int alloc_and_copy(uint8_t **poutbuf, int *poutbuf_size,
                           const uint8_t *sps_pps, uint32_t sps_pps_size,
-                          const uint8_t *in,      uint32_t in_size) {
-    uint32_t offset = *poutbuf_size;
+                          const uint8_t *in, uint32_t in_size)
+{
+    uint32_t offset         = *poutbuf_size;
     uint8_t nal_header_size = offset ? 3 : 4;
     void *tmp;
 
-    *poutbuf_size += sps_pps_size+in_size+nal_header_size;
-    tmp = av_realloc(*poutbuf, *poutbuf_size);
+    *poutbuf_size += sps_pps_size + in_size + nal_header_size;
+    tmp = av_realloc(*poutbuf, *poutbuf_size + FF_INPUT_BUFFER_PADDING_SIZE);
     if (!tmp)
         return AVERROR(ENOMEM);
     *poutbuf = tmp;
     if (sps_pps)
-        memcpy(*poutbuf+offset, sps_pps, sps_pps_size);
-    memcpy(*poutbuf+sps_pps_size+nal_header_size+offset, in, in_size);
+        memcpy(*poutbuf + offset, sps_pps, sps_pps_size);
+    memcpy(*poutbuf + sps_pps_size + nal_header_size + offset, in, in_size);
     if (!offset) {
-        AV_WB32(*poutbuf+sps_pps_size, 1);
+        AV_WB32(*poutbuf + sps_pps_size, 1);
     } else {
-        (*poutbuf+offset+sps_pps_size)[0] = (*poutbuf+offset+sps_pps_size)[1] = 0;
-        (*poutbuf+offset+sps_pps_size)[2] = 1;
+        (*poutbuf + offset + sps_pps_size)[0] =
+        (*poutbuf + offset + sps_pps_size)[1] = 0;
+        (*poutbuf + offset + sps_pps_size)[2] = 1;
     }
 
     return 0;
 }
 
+static int h264_extradata_to_annexb(AVCodecContext *avctx, const int padding)
+{
+    uint16_t unit_size;
+    uint64_t total_size                 = 0;
+    uint8_t *out                        = NULL, unit_nb, sps_done = 0,
+             sps_seen                   = 0, pps_seen = 0;
+    const uint8_t *extradata            = avctx->extradata + 4;
+    static const uint8_t nalu_header[4] = { 0, 0, 0, 1 };
+    int length_size = (*extradata++ & 0x3) + 1; // retrieve length coded size
+
+    /* retrieve sps and pps unit(s) */
+    unit_nb = *extradata++ & 0x1f; /* number of sps unit(s) */
+    if (!unit_nb) {
+        goto pps;
+    } else {
+        sps_seen = 1;
+    }
+
+    while (unit_nb--) {
+        void *tmp;
+
+        unit_size   = AV_RB16(extradata);
+        total_size += unit_size + 4;
+        if (total_size > INT_MAX - padding) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "Too big extradata size, corrupted stream or invalid MP4/AVCC bitstream\n");
+            av_free(out);
+            return AVERROR(EINVAL);
+        }
+        if (extradata + 2 + unit_size > avctx->extradata + avctx->extradata_size) {
+            av_log(avctx, AV_LOG_ERROR, "Packet header is not contained in global extradata, "
+                   "corrupted stream or invalid MP4/AVCC bitstream\n");
+            av_free(out);
+            return AVERROR(EINVAL);
+        }
+        tmp = av_realloc(out, total_size + padding);
+        if (!tmp) {
+            av_free(out);
+            return AVERROR(ENOMEM);
+        }
+        out = tmp;
+        memcpy(out + total_size - unit_size - 4, nalu_header, 4);
+        memcpy(out + total_size - unit_size, extradata + 2, unit_size);
+        extradata += 2 + unit_size;
+pps:
+        if (!unit_nb && !sps_done++) {
+            unit_nb = *extradata++; /* number of pps unit(s) */
+            if (unit_nb)
+                pps_seen = 1;
+        }
+    }
+
+    if (out)
+        memset(out + total_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+
+    if (!sps_seen)
+        av_log(avctx, AV_LOG_WARNING,
+               "Warning: SPS NALU missing or invalid. "
+               "The resulting stream may not play.\n");
+
+    if (!pps_seen)
+        av_log(avctx, AV_LOG_WARNING,
+               "Warning: PPS NALU missing or invalid. "
+               "The resulting stream may not play.\n");
+
+    av_free(avctx->extradata);
+    avctx->extradata      = out;
+    avctx->extradata_size = total_size;
+
+    return length_size;
+}
+
 static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc,
                                    AVCodecContext *avctx, const char *args,
-                                   uint8_t  **poutbuf, int *poutbuf_size,
-                                   const uint8_t *buf, int      buf_size,
-                                   int keyframe) {
+                                   uint8_t **poutbuf, int *poutbuf_size,
+                                   const uint8_t *buf, int buf_size,
+                                   int keyframe)
+{
     H264BSFContext *ctx = bsfc->priv_data;
     int i;
     uint8_t unit_type;
     int32_t nal_size;
-    uint32_t cumul_size = 0;
+    uint32_t cumul_size    = 0;
     const uint8_t *buf_end = buf + buf_size;
-    int ret = AVERROR(EINVAL);
+    int ret = 0;
 
     /* nothing to filter */
     if (!avctx->extradata || avctx->extradata_size < 6) {
-        *poutbuf = (uint8_t*) buf;
+        *poutbuf      = (uint8_t *)buf;
         *poutbuf_size = buf_size;
         return 0;
     }
 
     /* retrieve sps and pps NAL units from extradata */
     if (!ctx->extradata_parsed) {
-        uint16_t unit_size;
-        uint64_t total_size = 0;
-        uint8_t *out = NULL, unit_nb, sps_done = 0, sps_seen = 0, pps_seen = 0;
-        const uint8_t *extradata = avctx->extradata+4;
-        static const uint8_t nalu_header[4] = {0, 0, 0, 1};
-
-        /* retrieve length coded size */
-        ctx->length_size = (*extradata++ & 0x3) + 1;
-
-        /* retrieve sps and pps unit(s) */
-        unit_nb = *extradata++ & 0x1f; /* number of sps unit(s) */
-        if (!unit_nb) {
-            goto pps;
-        } else {
-            sps_seen = 1;
-        }
-
-        while (unit_nb--) {
-            void *tmp;
-
-            unit_size = AV_RB16(extradata);
-            total_size += unit_size+4;
-            if (total_size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE ||
-                extradata+2+unit_size > avctx->extradata+avctx->extradata_size) {
-                av_free(out);
-                return AVERROR(EINVAL);
-            }
-            tmp = av_realloc(out, total_size + FF_INPUT_BUFFER_PADDING_SIZE);
-            if (!tmp) {
-                av_free(out);
-                return AVERROR(ENOMEM);
-            }
-            out = tmp;
-            memcpy(out+total_size-unit_size-4, nalu_header, 4);
-            memcpy(out+total_size-unit_size,   extradata+2, unit_size);
-            extradata += 2+unit_size;
-pps:
-            if (!unit_nb && !sps_done++) {
-                unit_nb = *extradata++; /* number of pps unit(s) */
-                if (unit_nb)
-                    pps_seen = 1;
-            }
-        }
-
-        if(out)
-            memset(out + total_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
-
-        if (!sps_seen)
-            av_log(avctx, AV_LOG_WARNING, "Warning: SPS NALU missing or invalid. The resulting stream may not play.\n");
-        if (!pps_seen)
-            av_log(avctx, AV_LOG_WARNING, "Warning: PPS NALU missing or invalid. The resulting stream may not play.\n");
-
-        av_free(avctx->extradata);
-        avctx->extradata      = out;
-        avctx->extradata_size = total_size;
+        ret = h264_extradata_to_annexb(avctx, FF_INPUT_BUFFER_PADDING_SIZE);
+        if (ret < 0)
+            return ret;
+        ctx->length_size      = ret;
         ctx->first_idr        = 1;
         ctx->extradata_parsed = 1;
     }
 
     *poutbuf_size = 0;
-    *poutbuf = NULL;
+    *poutbuf      = NULL;
     do {
         ret= AVERROR(EINVAL);
         if (buf + ctx->length_size > buf_end)
@@ -147,7 +171,7 @@
         for (nal_size = 0, i = 0; i<ctx->length_size; i++)
             nal_size = (nal_size << 8) | buf[i];
 
-        buf += ctx->length_size;
+        buf      += ctx->length_size;
         unit_type = *buf & 0x1f;
 
         if (buf + nal_size > buf_end || nal_size < 0)
@@ -162,14 +186,13 @@
             ctx->first_idr = 0;
         } else {
             if ((ret=alloc_and_copy(poutbuf, poutbuf_size,
-                               NULL, 0,
-                               buf, nal_size)) < 0)
+                               NULL, 0, buf, nal_size)) < 0)
                 goto fail;
             if (!ctx->first_idr && unit_type == 1)
                 ctx->first_idr = 1;
         }
 
-        buf += nal_size;
+        buf        += nal_size;
         cumul_size += nal_size + ctx->length_size;
     } while (cumul_size < buf_size);
 
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index f373a1c..85b0f9c 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -25,13 +25,15 @@
  * @author Michael Niedermayer <michaelni@gmx.at>
  */
 
+#include "libavutil/attributes.h"
 #include "parser.h"
 #include "h264data.h"
 #include "golomb.h"
 #include "internal.h"
 
 
-static int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_size)
+static int h264_find_frame_end(H264Context *h, const uint8_t *buf,
+                               int buf_size)
 {
     int i, j;
     uint32_t state;
@@ -39,65 +41,53 @@
     int next_avc= h->is_avc ? 0 : buf_size;
 
 //    mb_addr= pc->mb_addr - 1;
-    state= pc->state;
-    if(state>13)
-        state= 7;
+    state = pc->state;
+    if (state > 13)
+        state = 7;
 
-    if(h->is_avc && !h->nal_length_size)
+    if (h->is_avc && !h->nal_length_size)
         av_log(h->avctx, AV_LOG_ERROR, "AVC-parser: nal length size invalid\n");
 
-    for(i=0; i<buf_size; i++){
-        if(i >= next_avc) {
+    for (i = 0; i < buf_size; i++) {
+        if (i >= next_avc) {
             int nalsize = 0;
             i = next_avc;
-            for(j = 0; j < h->nal_length_size; j++)
+            for (j = 0; j < h->nal_length_size; j++)
                 nalsize = (nalsize << 8) | buf[i++];
-            if(nalsize <= 0 || nalsize > buf_size - i){
+            if (nalsize <= 0 || nalsize > buf_size - i) {
                 av_log(h->avctx, AV_LOG_ERROR, "AVC-parser: nal size %d remaining %d\n", nalsize, buf_size - i);
                 return buf_size;
             }
-            next_avc= i + nalsize;
-            state= 5;
+            next_avc = i + nalsize;
+            state    = 5;
         }
 
-        if(state==7){
-#if HAVE_FAST_UNALIGNED
-        /* we check i<buf_size instead of i+3/7 because its simpler
-         * and there should be FF_INPUT_BUFFER_PADDING_SIZE bytes at the end
-         */
-#    if HAVE_FAST_64BIT
-            while(i<next_avc && !((~*(const uint64_t*)(buf+i) & (*(const uint64_t*)(buf+i) - 0x0101010101010101ULL)) & 0x8080808080808080ULL))
-                i+=8;
-#    else
-            while(i<next_avc && !((~*(const uint32_t*)(buf+i) & (*(const uint32_t*)(buf+i) - 0x01010101U)) & 0x80808080U))
-                i+=4;
-#    endif
-#endif
-            for(; i<next_avc; i++){
-                if(!buf[i]){
-                    state=2;
-                    break;
-                }
-            }
-        }else if(state<=2){
-            if(buf[i]==1)   state^= 5; //2->7, 1->4, 0->5
-            else if(buf[i]) state = 7;
-            else            state>>=1; //2->1, 1->0, 0->0
-        }else if(state<=5){
-            int v= buf[i] & 0x1F;
-            if(v==6 || v==7 || v==8 || v==9){
-                if(pc->frame_start_found){
+        if (state == 7) {
+            i += h->h264dsp.h264_find_start_code_candidate(buf + i, next_avc - i);
+            if (i < next_avc)
+                state = 2;
+        } else if (state <= 2) {
+            if (buf[i] == 1)
+                state ^= 5;            // 2->7, 1->4, 0->5
+            else if (buf[i])
+                state = 7;
+            else
+                state >>= 1;           // 2->1, 1->0, 0->0
+        } else if (state <= 5) {
+            int v = buf[i] & 0x1F;
+            if (v == 6 || v == 7 || v == 8 || v == 9) {
+                if (pc->frame_start_found) {
                     i++;
                     goto found;
                 }
-            }else if(v==1 || v==2 || v==5){
-                state+=8;
+            } else if (v == 1 || v == 2 || v == 5) {
+                state += 8;
                 continue;
             }
-            state= 7;
-        }else{
+            state = 7;
+        } else {
             h->parse_history[h->parse_history_count++]= buf[i];
-            if(h->parse_history_count>3){
+            if (h->parse_history_count>3) {
                 unsigned int mb, last_mb= h->parse_last_mb;
                 GetBitContext gb;
 
@@ -106,26 +96,26 @@
                 mb= get_ue_golomb_long(&gb);
                 last_mb= h->parse_last_mb;
                 h->parse_last_mb= mb;
-                if(pc->frame_start_found){
-                    if(mb <= last_mb)
+                if (pc->frame_start_found) {
+                    if (mb <= last_mb)
                         goto found;
-                }else
+                } else
                     pc->frame_start_found = 1;
-                state= 7;
+                state = 7;
             }
         }
     }
-    pc->state= state;
-    if(h->is_avc)
+    pc->state = state;
+    if (h->is_avc)
         return next_avc;
     return END_NOT_FOUND;
 
 found:
-    pc->state=7;
-    pc->frame_start_found= 0;
-    if(h->is_avc)
+    pc->state             = 7;
+    pc->frame_start_found = 0;
+    if (h->is_avc)
         return next_avc;
-    return i-(state&5) - 3*(state>7);
+    return i - (state & 5) - 3 * (state > 7);
 }
 
 /**
@@ -140,28 +130,31 @@
                                   AVCodecContext *avctx,
                                   const uint8_t *buf, int buf_size)
 {
-    H264Context *h = s->priv_data;
+    H264Context *h         = s->priv_data;
     const uint8_t *buf_end = buf + buf_size;
     unsigned int pps_id;
     unsigned int slice_type;
     int state = -1;
     const uint8_t *ptr;
     int q264 = buf_size >=4 && !memcmp("Q264", buf, 4);
+    int field_poc[2];
 
     /* set some sane default values */
-    s->pict_type = AV_PICTURE_TYPE_I;
-    s->key_frame = 0;
+    s->pict_type         = AV_PICTURE_TYPE_I;
+    s->key_frame         = 0;
+    s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN;
 
-    h->avctx= avctx;
-    h->sei_recovery_frame_cnt = -1;
-    h->sei_dpb_output_delay         =  0;
+    h->avctx                        = avctx;
+    h->sei_recovery_frame_cnt       = -1;
+    h->sei_dpb_output_delay         = 0;
     h->sei_cpb_removal_delay        = -1;
-    h->sei_buffering_period_present =  0;
+    h->sei_buffering_period_present = 0;
+    h->sei_fpa.frame_packing_arrangement_cancel_flag = -1;
 
     if (!buf_size)
         return 0;
 
-    for(;;) {
+    for (;;) {
         int src_length, dst_length, consumed, nalsize = 0;
         if (h->is_avc) {
             int i;
@@ -176,7 +169,7 @@
             src_length = nalsize;
         } else {
         buf = avpriv_find_start_code(buf, buf_end, &state);
-        if(buf >= buf_end)
+        if (buf >= buf_end)
             break;
         --buf;
         src_length = buf_end - buf;
@@ -189,12 +182,12 @@
                 src_length = 20;
             break;
         }
-        ptr= ff_h264_decode_nal(h, buf, &dst_length, &consumed, src_length);
-        if (ptr==NULL || dst_length < 0)
+        ptr = ff_h264_decode_nal(h, buf, &dst_length, &consumed, src_length);
+        if (ptr == NULL || dst_length < 0)
             break;
 
-        init_get_bits(&h->gb, ptr, 8*dst_length);
-        switch(h->nal_unit_type) {
+        init_get_bits(&h->gb, ptr, 8 * dst_length);
+        switch (h->nal_unit_type) {
         case NAL_SPS:
             ff_h264_decode_seq_parameter_set(h);
             break;
@@ -206,74 +199,135 @@
             break;
         case NAL_IDR_SLICE:
             s->key_frame = 1;
-            /* fall through */
+
+            h->prev_frame_num        = 0;
+            h->prev_frame_num_offset = 0;
+            h->prev_poc_msb          =
+            h->prev_poc_lsb          = 0;
+        /* fall through */
         case NAL_SLICE:
             get_ue_golomb_long(&h->gb);  // skip first_mb_in_slice
-            slice_type = get_ue_golomb_31(&h->gb);
+            slice_type   = get_ue_golomb_31(&h->gb);
             s->pict_type = golomb_to_pict_type[slice_type % 5];
             if (h->sei_recovery_frame_cnt >= 0) {
                 /* key frame, since recovery_frame_cnt is set */
                 s->key_frame = 1;
             }
-            pps_id= get_ue_golomb(&h->gb);
-            if(pps_id>=MAX_PPS_COUNT) {
-                av_log(h->avctx, AV_LOG_ERROR, "pps_id out of range\n");
+            pps_id = get_ue_golomb(&h->gb);
+            if (pps_id >= MAX_PPS_COUNT) {
+                av_log(h->avctx, AV_LOG_ERROR,
+                       "pps_id out of range\n");
                 return -1;
             }
-            if(!h->pps_buffers[pps_id]) {
-                av_log(h->avctx, AV_LOG_ERROR, "non-existing PPS referenced\n");
+            if (!h->pps_buffers[pps_id]) {
+                av_log(h->avctx, AV_LOG_ERROR,
+                       "non-existing PPS referenced\n");
                 return -1;
             }
-            h->pps= *h->pps_buffers[pps_id];
-            if(!h->sps_buffers[h->pps.sps_id]) {
-                av_log(h->avctx, AV_LOG_ERROR, "non-existing SPS referenced\n");
+            h->pps = *h->pps_buffers[pps_id];
+            if (!h->sps_buffers[h->pps.sps_id]) {
+                av_log(h->avctx, AV_LOG_ERROR,
+                       "non-existing SPS referenced\n");
                 return -1;
             }
-            h->sps = *h->sps_buffers[h->pps.sps_id];
+            h->sps       = *h->sps_buffers[h->pps.sps_id];
             h->frame_num = get_bits(&h->gb, h->sps.log2_max_frame_num);
 
             avctx->profile = ff_h264_get_profile(&h->sps);
             avctx->level   = h->sps.level_idc;
 
-            if(h->sps.frame_mbs_only_flag){
-                h->picture_structure= PICT_FRAME;
-            }else{
-                if(get_bits1(&h->gb)) { //field_pic_flag
-                    h->picture_structure= PICT_TOP_FIELD + get_bits1(&h->gb); //bottom_field_flag
+            if (h->sps.frame_mbs_only_flag) {
+                h->picture_structure = PICT_FRAME;
+            } else {
+                if (get_bits1(&h->gb)) { // field_pic_flag
+                    h->picture_structure = PICT_TOP_FIELD + get_bits1(&h->gb); // bottom_field_flag
                 } else {
-                    h->picture_structure= PICT_FRAME;
+                    h->picture_structure = PICT_FRAME;
                 }
             }
 
-            if(h->sps.pic_struct_present_flag) {
+            if (h->nal_unit_type == NAL_IDR_SLICE)
+                get_ue_golomb(&h->gb); /* idr_pic_id */
+            if (h->sps.poc_type == 0) {
+                h->poc_lsb = get_bits(&h->gb, h->sps.log2_max_poc_lsb);
+
+                if (h->pps.pic_order_present == 1 &&
+                    h->picture_structure == PICT_FRAME)
+                    h->delta_poc_bottom = get_se_golomb(&h->gb);
+            }
+
+            if (h->sps.poc_type == 1 &&
+                !h->sps.delta_pic_order_always_zero_flag) {
+                h->delta_poc[0] = get_se_golomb(&h->gb);
+
+                if (h->pps.pic_order_present == 1 &&
+                    h->picture_structure == PICT_FRAME)
+                    h->delta_poc[1] = get_se_golomb(&h->gb);
+            }
+
+            ff_init_poc(h, field_poc, &s->output_picture_number);
+
+            if (h->sps.pic_struct_present_flag) {
                 switch (h->sei_pic_struct) {
-                    case SEI_PIC_STRUCT_TOP_FIELD:
-                    case SEI_PIC_STRUCT_BOTTOM_FIELD:
-                        s->repeat_pict = 0;
-                        break;
-                    case SEI_PIC_STRUCT_FRAME:
-                    case SEI_PIC_STRUCT_TOP_BOTTOM:
-                    case SEI_PIC_STRUCT_BOTTOM_TOP:
-                        s->repeat_pict = 1;
-                        break;
-                    case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
-                    case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
-                        s->repeat_pict = 2;
-                        break;
-                    case SEI_PIC_STRUCT_FRAME_DOUBLING:
-                        s->repeat_pict = 3;
-                        break;
-                    case SEI_PIC_STRUCT_FRAME_TRIPLING:
-                        s->repeat_pict = 5;
-                        break;
-                    default:
-                        s->repeat_pict = h->picture_structure == PICT_FRAME ? 1 : 0;
-                        break;
+                case SEI_PIC_STRUCT_TOP_FIELD:
+                case SEI_PIC_STRUCT_BOTTOM_FIELD:
+                    s->repeat_pict = 0;
+                    break;
+                case SEI_PIC_STRUCT_FRAME:
+                case SEI_PIC_STRUCT_TOP_BOTTOM:
+                case SEI_PIC_STRUCT_BOTTOM_TOP:
+                    s->repeat_pict = 1;
+                    break;
+                case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
+                case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
+                    s->repeat_pict = 2;
+                    break;
+                case SEI_PIC_STRUCT_FRAME_DOUBLING:
+                    s->repeat_pict = 3;
+                    break;
+                case SEI_PIC_STRUCT_FRAME_TRIPLING:
+                    s->repeat_pict = 5;
+                    break;
+                default:
+                    s->repeat_pict = h->picture_structure == PICT_FRAME ? 1 : 0;
+                    break;
                 }
             } else {
                 s->repeat_pict = h->picture_structure == PICT_FRAME ? 1 : 0;
             }
 
+            if (h->picture_structure == PICT_FRAME) {
+                s->picture_structure = AV_PICTURE_STRUCTURE_FRAME;
+                if (h->sps.pic_struct_present_flag) {
+                    switch (h->sei_pic_struct) {
+                    case SEI_PIC_STRUCT_TOP_BOTTOM:
+                    case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
+                        s->field_order = AV_FIELD_TT;
+                        break;
+                    case SEI_PIC_STRUCT_BOTTOM_TOP:
+                    case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
+                        s->field_order = AV_FIELD_BB;
+                        break;
+                    default:
+                        s->field_order = AV_FIELD_PROGRESSIVE;
+                        break;
+                    }
+                } else {
+                    if (field_poc[0] < field_poc[1])
+                        s->field_order = AV_FIELD_TT;
+                    else if (field_poc[0] > field_poc[1])
+                        s->field_order = AV_FIELD_BB;
+                    else
+                        s->field_order = AV_FIELD_PROGRESSIVE;
+                }
+            } else {
+                if (h->picture_structure == PICT_TOP_FIELD)
+                    s->picture_structure = AV_PICTURE_STRUCTURE_TOP_FIELD;
+                else
+                    s->picture_structure = AV_PICTURE_STRUCTURE_BOTTOM_FIELD;
+                s->field_order = AV_FIELD_UNKNOWN;
+            }
+
             return 0; /* no need to evaluate the rest */
         }
         buf += h->is_avc ? nalsize : consumed;
@@ -290,7 +344,7 @@
                       const uint8_t **poutbuf, int *poutbuf_size,
                       const uint8_t *buf, int buf_size)
 {
-    H264Context *h = s->priv_data;
+    H264Context *h   = s->priv_data;
     ParseContext *pc = &h->parse_context;
     int next;
 
@@ -308,20 +362,20 @@
         }
     }
 
-    if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
-        next= buf_size;
-    }else{
-        next= ff_h264_find_frame_end(h, buf, buf_size);
+    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
+        next = buf_size;
+    } else {
+        next = h264_find_frame_end(h, buf, buf_size);
 
         if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
-            *poutbuf = NULL;
+            *poutbuf      = NULL;
             *poutbuf_size = 0;
             return buf_size;
         }
 
-        if(next<0 && next != END_NOT_FOUND){
-            av_assert1(pc->last_index + next >= 0 );
-            ff_h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state
+        if (next < 0 && next != END_NOT_FOUND) {
+            av_assert1(pc->last_index + next >= 0);
+            h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next); // update state
         }
     }
 
@@ -341,7 +395,7 @@
         s->flags &= PARSER_FLAG_COMPLETE_FRAMES;
     }
 
-    *poutbuf = buf;
+    *poutbuf      = buf;
     *poutbuf_size = buf_size;
     return next;
 }
@@ -351,39 +405,45 @@
 {
     int i;
     uint32_t state = -1;
-    int has_sps= 0;
+    int has_sps    = 0;
 
-    for(i=0; i<=buf_size; i++){
-        if((state&0xFFFFFF1F) == 0x107)
-            has_sps=1;
-/*        if((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105){
-        }*/
-        if((state&0xFFFFFF00) == 0x100 && (state&0xFFFFFF1F) != 0x107 && (state&0xFFFFFF1F) != 0x108 && (state&0xFFFFFF1F) != 0x109){
-            if(has_sps){
-                while(i>4 && buf[i-5]==0) i--;
-                return i-4;
+    for (i = 0; i <= buf_size; i++) {
+        if ((state & 0xFFFFFF1F) == 0x107)
+            has_sps = 1;
+        /*  if ((state&0xFFFFFF1F) == 0x101 ||
+         *     (state&0xFFFFFF1F) == 0x102 ||
+         *     (state&0xFFFFFF1F) == 0x105) {
+         *  }
+         */
+        if ((state & 0xFFFFFF00) == 0x100 && (state & 0xFFFFFF1F) != 0x107 &&
+            (state & 0xFFFFFF1F) != 0x108 && (state & 0xFFFFFF1F) != 0x109) {
+            if (has_sps) {
+                while (i > 4 && buf[i - 5] == 0)
+                    i--;
+                return i - 4;
             }
         }
-        if (i<buf_size)
-            state= (state<<8) | buf[i];
+        if (i < buf_size)
+            state = (state << 8) | buf[i];
     }
     return 0;
 }
 
 static void close(AVCodecParserContext *s)
 {
-    H264Context *h = s->priv_data;
+    H264Context *h   = s->priv_data;
     ParseContext *pc = &h->parse_context;
 
     av_free(pc->buffer);
     ff_h264_free_context(h);
 }
 
-static int init(AVCodecParserContext *s)
+static av_cold int init(AVCodecParserContext *s)
 {
     H264Context *h = s->priv_data;
-    h->thread_context[0] = h;
+    h->thread_context[0]   = h;
     h->slice_context_count = 1;
+    ff_h264dsp_init(&h->h264dsp, 8, 1);
     return 0;
 }
 
diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c
index 68f504a..e667359 100644
--- a/libavcodec/h264_ps.c
+++ b/libavcodec/h264_ps.c
@@ -32,245 +32,234 @@
 #include "h264data.h" //FIXME FIXME FIXME (just for zigzag_scan)
 #include "golomb.h"
 
-
-//#undef NDEBUG
-#include <assert.h>
-
 #define MAX_LOG2_MAX_FRAME_NUM    (12 + 4)
 #define MIN_LOG2_MAX_FRAME_NUM    4
 
-static const AVRational pixel_aspect[17]={
- {0, 1},
- {1, 1},
- {12, 11},
- {10, 11},
- {16, 11},
- {40, 33},
- {24, 11},
- {20, 11},
- {32, 11},
- {80, 33},
- {18, 11},
- {15, 11},
- {64, 33},
- {160,99},
- {4, 3},
- {3, 2},
- {2, 1},
+static const AVRational pixel_aspect[17] = {
+    {   0,  1 },
+    {   1,  1 },
+    {  12, 11 },
+    {  10, 11 },
+    {  16, 11 },
+    {  40, 33 },
+    {  24, 11 },
+    {  20, 11 },
+    {  32, 11 },
+    {  80, 33 },
+    {  18, 11 },
+    {  15, 11 },
+    {  64, 33 },
+    { 160, 99 },
+    {   4,  3 },
+    {   3,  2 },
+    {   2,  1 },
 };
 
-#define QP(qP,depth) ( (qP)+6*((depth)-8) )
+#define QP(qP, depth) ((qP) + 6 * ((depth) - 8))
 
-#define CHROMA_QP_TABLE_END(d) \
-     QP(0,d),  QP(1,d),  QP(2,d),  QP(3,d),  QP(4,d),  QP(5,d),\
-     QP(6,d),  QP(7,d),  QP(8,d),  QP(9,d), QP(10,d), QP(11,d),\
-    QP(12,d), QP(13,d), QP(14,d), QP(15,d), QP(16,d), QP(17,d),\
-    QP(18,d), QP(19,d), QP(20,d), QP(21,d), QP(22,d), QP(23,d),\
-    QP(24,d), QP(25,d), QP(26,d), QP(27,d), QP(28,d), QP(29,d),\
-    QP(29,d), QP(30,d), QP(31,d), QP(32,d), QP(32,d), QP(33,d),\
-    QP(34,d), QP(34,d), QP(35,d), QP(35,d), QP(36,d), QP(36,d),\
-    QP(37,d), QP(37,d), QP(37,d), QP(38,d), QP(38,d), QP(38,d),\
-    QP(39,d), QP(39,d), QP(39,d), QP(39,d)
+#define CHROMA_QP_TABLE_END(d)                                          \
+    QP(0,  d), QP(1,  d), QP(2,  d), QP(3,  d), QP(4,  d), QP(5,  d),   \
+    QP(6,  d), QP(7,  d), QP(8,  d), QP(9,  d), QP(10, d), QP(11, d),   \
+    QP(12, d), QP(13, d), QP(14, d), QP(15, d), QP(16, d), QP(17, d),   \
+    QP(18, d), QP(19, d), QP(20, d), QP(21, d), QP(22, d), QP(23, d),   \
+    QP(24, d), QP(25, d), QP(26, d), QP(27, d), QP(28, d), QP(29, d),   \
+    QP(29, d), QP(30, d), QP(31, d), QP(32, d), QP(32, d), QP(33, d),   \
+    QP(34, d), QP(34, d), QP(35, d), QP(35, d), QP(36, d), QP(36, d),   \
+    QP(37, d), QP(37, d), QP(37, d), QP(38, d), QP(38, d), QP(38, d),   \
+    QP(39, d), QP(39, d), QP(39, d), QP(39, d)
 
-const uint8_t ff_h264_chroma_qp[7][QP_MAX_NUM+1] = {
-    {
-        CHROMA_QP_TABLE_END(8)
-    },
-    {
-        0, 1, 2, 3, 4, 5,
-        CHROMA_QP_TABLE_END(9)
-    },
-    {
-        0, 1, 2, 3,  4,  5,
-        6, 7, 8, 9, 10, 11,
-        CHROMA_QP_TABLE_END(10)
-    },
-    {
-        0,  1, 2, 3,  4,  5,
-        6,  7, 8, 9, 10, 11,
-        12,13,14,15, 16, 17,
-        CHROMA_QP_TABLE_END(11)
-    },
-    {
-        0,  1, 2, 3,  4,  5,
-        6,  7, 8, 9, 10, 11,
-        12,13,14,15, 16, 17,
-        18,19,20,21, 22, 23,
-        CHROMA_QP_TABLE_END(12)
-    },
-    {
-        0,  1, 2, 3,  4,  5,
-        6,  7, 8, 9, 10, 11,
-        12,13,14,15, 16, 17,
-        18,19,20,21, 22, 23,
-        24,25,26,27, 28, 29,
-        CHROMA_QP_TABLE_END(13)
-    },
-    {
-        0,  1, 2, 3,  4,  5,
-        6,  7, 8, 9, 10, 11,
-        12,13,14,15, 16, 17,
-        18,19,20,21, 22, 23,
-        24,25,26,27, 28, 29,
-        30,31,32,33, 34, 35,
-        CHROMA_QP_TABLE_END(14)
-    },
+const uint8_t ff_h264_chroma_qp[7][QP_MAX_NUM + 1] = {
+    { CHROMA_QP_TABLE_END(8) },
+    { 0, 1, 2, 3, 4, 5,
+      CHROMA_QP_TABLE_END(9) },
+    { 0, 1, 2, 3,  4,  5,
+      6, 7, 8, 9, 10, 11,
+      CHROMA_QP_TABLE_END(10) },
+    { 0,  1, 2, 3,  4,  5,
+      6,  7, 8, 9, 10, 11,
+      12,13,14,15, 16, 17,
+      CHROMA_QP_TABLE_END(11) },
+    { 0,  1, 2, 3,  4,  5,
+      6,  7, 8, 9, 10, 11,
+      12,13,14,15, 16, 17,
+      18,19,20,21, 22, 23,
+      CHROMA_QP_TABLE_END(12) },
+    { 0,  1, 2, 3,  4,  5,
+      6,  7, 8, 9, 10, 11,
+      12,13,14,15, 16, 17,
+      18,19,20,21, 22, 23,
+      24,25,26,27, 28, 29,
+      CHROMA_QP_TABLE_END(13) },
+    { 0,  1, 2, 3,  4,  5,
+      6,  7, 8, 9, 10, 11,
+      12,13,14,15, 16, 17,
+      18,19,20,21, 22, 23,
+      24,25,26,27, 28, 29,
+      30,31,32,33, 34, 35,
+      CHROMA_QP_TABLE_END(14) },
 };
 
-static const uint8_t default_scaling4[2][16]={
-{   6,13,20,28,
-   13,20,28,32,
-   20,28,32,37,
-   28,32,37,42
-},{
-   10,14,20,24,
-   14,20,24,27,
-   20,24,27,30,
-   24,27,30,34
-}};
+static const uint8_t default_scaling4[2][16] = {
+    {  6, 13, 20, 28, 13, 20, 28, 32,
+      20, 28, 32, 37, 28, 32, 37, 42 },
+    { 10, 14, 20, 24, 14, 20, 24, 27,
+      20, 24, 27, 30, 24, 27, 30, 34 }
+};
 
-static const uint8_t default_scaling8[2][64]={
-{   6,10,13,16,18,23,25,27,
-   10,11,16,18,23,25,27,29,
-   13,16,18,23,25,27,29,31,
-   16,18,23,25,27,29,31,33,
-   18,23,25,27,29,31,33,36,
-   23,25,27,29,31,33,36,38,
-   25,27,29,31,33,36,38,40,
-   27,29,31,33,36,38,40,42
-},{
-    9,13,15,17,19,21,22,24,
-   13,13,17,19,21,22,24,25,
-   15,17,19,21,22,24,25,27,
-   17,19,21,22,24,25,27,28,
-   19,21,22,24,25,27,28,30,
-   21,22,24,25,27,28,30,32,
-   22,24,25,27,28,30,32,33,
-   24,25,27,28,30,32,33,35
-}};
+static const uint8_t default_scaling8[2][64] = {
+    {  6, 10, 13, 16, 18, 23, 25, 27,
+      10, 11, 16, 18, 23, 25, 27, 29,
+      13, 16, 18, 23, 25, 27, 29, 31,
+      16, 18, 23, 25, 27, 29, 31, 33,
+      18, 23, 25, 27, 29, 31, 33, 36,
+      23, 25, 27, 29, 31, 33, 36, 38,
+      25, 27, 29, 31, 33, 36, 38, 40,
+      27, 29, 31, 33, 36, 38, 40, 42 },
+    {  9, 13, 15, 17, 19, 21, 22, 24,
+      13, 13, 17, 19, 21, 22, 24, 25,
+      15, 17, 19, 21, 22, 24, 25, 27,
+      17, 19, 21, 22, 24, 25, 27, 28,
+      19, 21, 22, 24, 25, 27, 28, 30,
+      21, 22, 24, 25, 27, 28, 30, 32,
+      22, 24, 25, 27, 28, 30, 32, 33,
+      24, 25, 27, 28, 30, 32, 33, 35 }
+};
 
-static inline int decode_hrd_parameters(H264Context *h, SPS *sps){
+static inline int decode_hrd_parameters(H264Context *h, SPS *sps)
+{
     int cpb_count, i;
     cpb_count = get_ue_golomb_31(&h->gb) + 1;
 
-    if(cpb_count > 32U){
+    if (cpb_count > 32U) {
         av_log(h->avctx, AV_LOG_ERROR, "cpb_count %d invalid\n", cpb_count);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     get_bits(&h->gb, 4); /* bit_rate_scale */
     get_bits(&h->gb, 4); /* cpb_size_scale */
-    for(i=0; i<cpb_count; i++){
+    for (i = 0; i < cpb_count; i++) {
         get_ue_golomb_long(&h->gb); /* bit_rate_value_minus1 */
         get_ue_golomb_long(&h->gb); /* cpb_size_value_minus1 */
-        get_bits1(&h->gb);     /* cbr_flag */
+        get_bits1(&h->gb);          /* cbr_flag */
     }
     sps->initial_cpb_removal_delay_length = get_bits(&h->gb, 5) + 1;
-    sps->cpb_removal_delay_length = get_bits(&h->gb, 5) + 1;
-    sps->dpb_output_delay_length = get_bits(&h->gb, 5) + 1;
-    sps->time_offset_length = get_bits(&h->gb, 5);
-    sps->cpb_cnt = cpb_count;
+    sps->cpb_removal_delay_length         = get_bits(&h->gb, 5) + 1;
+    sps->dpb_output_delay_length          = get_bits(&h->gb, 5) + 1;
+    sps->time_offset_length               = get_bits(&h->gb, 5);
+    sps->cpb_cnt                          = cpb_count;
     return 0;
 }
 
-static inline int decode_vui_parameters(H264Context *h, SPS *sps){
+static inline int decode_vui_parameters(H264Context *h, SPS *sps)
+{
     int aspect_ratio_info_present_flag;
     unsigned int aspect_ratio_idc;
 
-    aspect_ratio_info_present_flag= get_bits1(&h->gb);
+    aspect_ratio_info_present_flag = get_bits1(&h->gb);
 
-    if( aspect_ratio_info_present_flag ) {
-        aspect_ratio_idc= get_bits(&h->gb, 8);
-        if( aspect_ratio_idc == EXTENDED_SAR ) {
-            sps->sar.num= get_bits(&h->gb, 16);
-            sps->sar.den= get_bits(&h->gb, 16);
-        }else if(aspect_ratio_idc < FF_ARRAY_ELEMS(pixel_aspect)){
-            sps->sar=  pixel_aspect[aspect_ratio_idc];
-        }else{
+    if (aspect_ratio_info_present_flag) {
+        aspect_ratio_idc = get_bits(&h->gb, 8);
+        if (aspect_ratio_idc == EXTENDED_SAR) {
+            sps->sar.num = get_bits(&h->gb, 16);
+            sps->sar.den = get_bits(&h->gb, 16);
+        } else if (aspect_ratio_idc < FF_ARRAY_ELEMS(pixel_aspect)) {
+            sps->sar = pixel_aspect[aspect_ratio_idc];
+        } else {
             av_log(h->avctx, AV_LOG_ERROR, "illegal aspect ratio\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
-    }else{
-        sps->sar.num=
-        sps->sar.den= 0;
+    } else {
+        sps->sar.num =
+        sps->sar.den = 0;
     }
-//            s->avctx->aspect_ratio= sar_width*s->width / (float)(s->height*sar_height);
 
-    if(get_bits1(&h->gb)){      /* overscan_info_present_flag */
+    if (get_bits1(&h->gb))      /* overscan_info_present_flag */
         get_bits1(&h->gb);      /* overscan_appropriate_flag */
-    }
 
     sps->video_signal_type_present_flag = get_bits1(&h->gb);
-    if(sps->video_signal_type_present_flag){
-        get_bits(&h->gb, 3);    /* video_format */
+    if (sps->video_signal_type_present_flag) {
+        get_bits(&h->gb, 3);                 /* video_format */
         sps->full_range = get_bits1(&h->gb); /* video_full_range_flag */
 
         sps->colour_description_present_flag = get_bits1(&h->gb);
-        if(sps->colour_description_present_flag){
+        if (sps->colour_description_present_flag) {
             sps->color_primaries = get_bits(&h->gb, 8); /* colour_primaries */
             sps->color_trc       = get_bits(&h->gb, 8); /* transfer_characteristics */
             sps->colorspace      = get_bits(&h->gb, 8); /* matrix_coefficients */
             if (sps->color_primaries >= AVCOL_PRI_NB)
-                sps->color_primaries  = AVCOL_PRI_UNSPECIFIED;
+                sps->color_primaries = AVCOL_PRI_UNSPECIFIED;
             if (sps->color_trc >= AVCOL_TRC_NB)
-                sps->color_trc  = AVCOL_TRC_UNSPECIFIED;
+                sps->color_trc = AVCOL_TRC_UNSPECIFIED;
             if (sps->colorspace >= AVCOL_SPC_NB)
-                sps->colorspace  = AVCOL_SPC_UNSPECIFIED;
+                sps->colorspace = AVCOL_SPC_UNSPECIFIED;
         }
     }
 
-    if(get_bits1(&h->gb)){      /* chroma_location_info_present_flag */
-        h->avctx->chroma_sample_location = get_ue_golomb(&h->gb)+1;  /* chroma_sample_location_type_top_field */
+    /* chroma_location_info_present_flag */
+    if (get_bits1(&h->gb)) {
+        /* chroma_sample_location_type_top_field */
+        h->avctx->chroma_sample_location = get_ue_golomb(&h->gb) + 1;
         get_ue_golomb(&h->gb);  /* chroma_sample_location_type_bottom_field */
     }
 
+    if (show_bits1(&h->gb) && get_bits_left(&h->gb) < 10) {
+        av_log(h->avctx, AV_LOG_WARNING, "Truncated VUI\n");
+        return 0;
+    }
+
     sps->timing_info_present_flag = get_bits1(&h->gb);
-    if(sps->timing_info_present_flag){
+    if (sps->timing_info_present_flag) {
         sps->num_units_in_tick = get_bits_long(&h->gb, 32);
-        sps->time_scale = get_bits_long(&h->gb, 32);
-        if(!sps->num_units_in_tick || !sps->time_scale){
-            av_log(h->avctx, AV_LOG_ERROR, "time_scale/num_units_in_tick invalid or unsupported (%d/%d)\n", sps->time_scale, sps->num_units_in_tick);
-            return -1;
+        sps->time_scale        = get_bits_long(&h->gb, 32);
+        if (!sps->num_units_in_tick || !sps->time_scale) {
+            av_log(h->avctx, AV_LOG_ERROR,
+                   "time_scale/num_units_in_tick invalid or unsupported (%d/%d)\n",
+                   sps->time_scale, sps->num_units_in_tick);
+            return AVERROR_INVALIDDATA;
         }
         sps->fixed_frame_rate_flag = get_bits1(&h->gb);
     }
 
     sps->nal_hrd_parameters_present_flag = get_bits1(&h->gb);
-    if(sps->nal_hrd_parameters_present_flag)
-        if(decode_hrd_parameters(h, sps) < 0)
-            return -1;
+    if (sps->nal_hrd_parameters_present_flag)
+        if (decode_hrd_parameters(h, sps) < 0)
+            return AVERROR_INVALIDDATA;
     sps->vcl_hrd_parameters_present_flag = get_bits1(&h->gb);
-    if(sps->vcl_hrd_parameters_present_flag)
-        if(decode_hrd_parameters(h, sps) < 0)
-            return -1;
-    if(sps->nal_hrd_parameters_present_flag || sps->vcl_hrd_parameters_present_flag)
+    if (sps->vcl_hrd_parameters_present_flag)
+        if (decode_hrd_parameters(h, sps) < 0)
+            return AVERROR_INVALIDDATA;
+    if (sps->nal_hrd_parameters_present_flag ||
+        sps->vcl_hrd_parameters_present_flag)
         get_bits1(&h->gb);     /* low_delay_hrd_flag */
     sps->pic_struct_present_flag = get_bits1(&h->gb);
-    if(!get_bits_left(&h->gb))
+    if (!get_bits_left(&h->gb))
         return 0;
     sps->bitstream_restriction_flag = get_bits1(&h->gb);
-    if(sps->bitstream_restriction_flag){
+    if (sps->bitstream_restriction_flag) {
         get_bits1(&h->gb);     /* motion_vectors_over_pic_boundaries_flag */
         get_ue_golomb(&h->gb); /* max_bytes_per_pic_denom */
         get_ue_golomb(&h->gb); /* max_bits_per_mb_denom */
         get_ue_golomb(&h->gb); /* log2_max_mv_length_horizontal */
         get_ue_golomb(&h->gb); /* log2_max_mv_length_vertical */
-        sps->num_reorder_frames= get_ue_golomb(&h->gb);
+        sps->num_reorder_frames = get_ue_golomb(&h->gb);
         get_ue_golomb(&h->gb); /*max_dec_frame_buffering*/
 
         if (get_bits_left(&h->gb) < 0) {
-            sps->num_reorder_frames=0;
-            sps->bitstream_restriction_flag= 0;
+            sps->num_reorder_frames         = 0;
+            sps->bitstream_restriction_flag = 0;
         }
 
-        if(sps->num_reorder_frames > 16U /*max_dec_frame_buffering || max_dec_frame_buffering > 16*/){
-            av_log(h->avctx, AV_LOG_ERROR, "illegal num_reorder_frames %d\n", sps->num_reorder_frames);
-            return -1;
+        if (sps->num_reorder_frames > 16U
+            /* max_dec_frame_buffering || max_dec_frame_buffering > 16 */) {
+            av_log(h->avctx, AV_LOG_ERROR,
+                   "illegal num_reorder_frames %d\n", sps->num_reorder_frames);
+            return AVERROR_INVALIDDATA;
         }
     }
 
     if (get_bits_left(&h->gb) < 0) {
-        av_log(h->avctx, AV_LOG_ERROR, "Overread VUI by %d bits\n", -get_bits_left(&h->gb));
+        av_log(h->avctx, AV_LOG_ERROR,
+               "Overread VUI by %d bits\n", -get_bits_left(&h->gb));
         return AVERROR_INVALIDDATA;
     }
 
@@ -278,25 +267,30 @@
 }
 
 static void decode_scaling_list(H264Context *h, uint8_t *factors, int size,
-                                const uint8_t *jvt_list, const uint8_t *fallback_list){
+                                const uint8_t *jvt_list,
+                                const uint8_t *fallback_list)
+{
     int i, last = 8, next = 8;
     const uint8_t *scan = size == 16 ? zigzag_scan : ff_zigzag_direct;
-    if(!get_bits1(&h->gb)) /* matrix not written, we use the predicted one */
-        memcpy(factors, fallback_list, size*sizeof(uint8_t));
+    if (!get_bits1(&h->gb)) /* matrix not written, we use the predicted one */
+        memcpy(factors, fallback_list, size * sizeof(uint8_t));
     else
-    for(i=0;i<size;i++){
-        if(next)
-            next = (last + get_se_golomb(&h->gb)) & 0xff;
-        if(!i && !next){ /* matrix not written, we use the preset one */
-            memcpy(factors, jvt_list, size*sizeof(uint8_t));
-            break;
+        for (i = 0; i < size; i++) {
+            if (next)
+                next = (last + get_se_golomb(&h->gb)) & 0xff;
+            if (!i && !next) { /* matrix not written, we use the preset one */
+                memcpy(factors, jvt_list, size * sizeof(uint8_t));
+                break;
+            }
+            last = factors[scan[i]] = next ? next : last;
         }
-        last = factors[scan[i]] = next ? next : last;
-    }
 }
 
-static void decode_scaling_matrices(H264Context *h, SPS *sps, PPS *pps, int is_sps,
-                                   uint8_t (*scaling_matrix4)[16], uint8_t (*scaling_matrix8)[64]){
+static void decode_scaling_matrices(H264Context *h, SPS *sps,
+                                    PPS *pps, int is_sps,
+                                    uint8_t(*scaling_matrix4)[16],
+                                    uint8_t(*scaling_matrix8)[64])
+{
     int fallback_sps = !is_sps && sps->scaling_matrix_present;
     const uint8_t *fallback[4] = {
         fallback_sps ? sps->scaling_matrix4[0] : default_scaling4[0],
@@ -304,57 +298,58 @@
         fallback_sps ? sps->scaling_matrix8[0] : default_scaling8[0],
         fallback_sps ? sps->scaling_matrix8[3] : default_scaling8[1]
     };
-    if(get_bits1(&h->gb)){
+    if (get_bits1(&h->gb)) {
         sps->scaling_matrix_present |= is_sps;
-        decode_scaling_list(h,scaling_matrix4[0],16,default_scaling4[0],fallback[0]); // Intra, Y
-        decode_scaling_list(h,scaling_matrix4[1],16,default_scaling4[0],scaling_matrix4[0]); // Intra, Cr
-        decode_scaling_list(h,scaling_matrix4[2],16,default_scaling4[0],scaling_matrix4[1]); // Intra, Cb
-        decode_scaling_list(h,scaling_matrix4[3],16,default_scaling4[1],fallback[1]); // Inter, Y
-        decode_scaling_list(h,scaling_matrix4[4],16,default_scaling4[1],scaling_matrix4[3]); // Inter, Cr
-        decode_scaling_list(h,scaling_matrix4[5],16,default_scaling4[1],scaling_matrix4[4]); // Inter, Cb
-        if(is_sps || pps->transform_8x8_mode){
-            decode_scaling_list(h,scaling_matrix8[0],64,default_scaling8[0],fallback[2]);  // Intra, Y
-            decode_scaling_list(h,scaling_matrix8[3],64,default_scaling8[1],fallback[3]);  // Inter, Y
-            if(sps->chroma_format_idc == 3){
-                decode_scaling_list(h,scaling_matrix8[1],64,default_scaling8[0],scaling_matrix8[0]);  // Intra, Cr
-                decode_scaling_list(h,scaling_matrix8[4],64,default_scaling8[1],scaling_matrix8[3]);  // Inter, Cr
-                decode_scaling_list(h,scaling_matrix8[2],64,default_scaling8[0],scaling_matrix8[1]);  // Intra, Cb
-                decode_scaling_list(h,scaling_matrix8[5],64,default_scaling8[1],scaling_matrix8[4]);  // Inter, Cb
+        decode_scaling_list(h, scaling_matrix4[0], 16, default_scaling4[0], fallback[0]);        // Intra, Y
+        decode_scaling_list(h, scaling_matrix4[1], 16, default_scaling4[0], scaling_matrix4[0]); // Intra, Cr
+        decode_scaling_list(h, scaling_matrix4[2], 16, default_scaling4[0], scaling_matrix4[1]); // Intra, Cb
+        decode_scaling_list(h, scaling_matrix4[3], 16, default_scaling4[1], fallback[1]);        // Inter, Y
+        decode_scaling_list(h, scaling_matrix4[4], 16, default_scaling4[1], scaling_matrix4[3]); // Inter, Cr
+        decode_scaling_list(h, scaling_matrix4[5], 16, default_scaling4[1], scaling_matrix4[4]); // Inter, Cb
+        if (is_sps || pps->transform_8x8_mode) {
+            decode_scaling_list(h, scaling_matrix8[0], 64, default_scaling8[0], fallback[2]); // Intra, Y
+            decode_scaling_list(h, scaling_matrix8[3], 64, default_scaling8[1], fallback[3]); // Inter, Y
+            if (sps->chroma_format_idc == 3) {
+                decode_scaling_list(h, scaling_matrix8[1], 64, default_scaling8[0], scaling_matrix8[0]); // Intra, Cr
+                decode_scaling_list(h, scaling_matrix8[4], 64, default_scaling8[1], scaling_matrix8[3]); // Inter, Cr
+                decode_scaling_list(h, scaling_matrix8[2], 64, default_scaling8[0], scaling_matrix8[1]); // Intra, Cb
+                decode_scaling_list(h, scaling_matrix8[5], 64, default_scaling8[1], scaling_matrix8[4]); // Inter, Cb
             }
         }
     }
 }
 
-int ff_h264_decode_seq_parameter_set(H264Context *h){
+int ff_h264_decode_seq_parameter_set(H264Context *h)
+{
     int profile_idc, level_idc, constraint_set_flags = 0;
     unsigned int sps_id;
     int i, log2_max_frame_num_minus4;
     SPS *sps;
 
-    profile_idc= get_bits(&h->gb, 8);
-    constraint_set_flags |= get_bits1(&h->gb) << 0;   //constraint_set0_flag
-    constraint_set_flags |= get_bits1(&h->gb) << 1;   //constraint_set1_flag
-    constraint_set_flags |= get_bits1(&h->gb) << 2;   //constraint_set2_flag
-    constraint_set_flags |= get_bits1(&h->gb) << 3;   //constraint_set3_flag
-    constraint_set_flags |= get_bits1(&h->gb) << 4;   //constraint_set4_flag
-    constraint_set_flags |= get_bits1(&h->gb) << 5;   //constraint_set5_flag
+    profile_idc           = get_bits(&h->gb, 8);
+    constraint_set_flags |= get_bits1(&h->gb) << 0;   // constraint_set0_flag
+    constraint_set_flags |= get_bits1(&h->gb) << 1;   // constraint_set1_flag
+    constraint_set_flags |= get_bits1(&h->gb) << 2;   // constraint_set2_flag
+    constraint_set_flags |= get_bits1(&h->gb) << 3;   // constraint_set3_flag
+    constraint_set_flags |= get_bits1(&h->gb) << 4;   // constraint_set4_flag
+    constraint_set_flags |= get_bits1(&h->gb) << 5;   // constraint_set5_flag
     get_bits(&h->gb, 2); // reserved
-    level_idc= get_bits(&h->gb, 8);
-    sps_id= get_ue_golomb_31(&h->gb);
+    level_idc = get_bits(&h->gb, 8);
+    sps_id    = get_ue_golomb_31(&h->gb);
 
-    if(sps_id >= MAX_SPS_COUNT) {
+    if (sps_id >= MAX_SPS_COUNT) {
         av_log(h->avctx, AV_LOG_ERROR, "sps_id (%d) out of range\n", sps_id);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
-    sps= av_mallocz(sizeof(SPS));
-    if(sps == NULL)
-        return -1;
+    sps = av_mallocz(sizeof(SPS));
+    if (!sps)
+        return AVERROR(ENOMEM);
 
-    sps->time_offset_length = 24;
-    sps->profile_idc= profile_idc;
+    sps->time_offset_length   = 24;
+    sps->profile_idc          = profile_idc;
     sps->constraint_set_flags = constraint_set_flags;
-    sps->level_idc= level_idc;
-    sps->full_range = -1;
+    sps->level_idc            = level_idc;
+    sps->full_range           = -1;
 
     memset(sps->scaling_matrix4, 16, sizeof(sps->scaling_matrix4));
     memset(sps->scaling_matrix8, 16, sizeof(sps->scaling_matrix8));
@@ -366,13 +361,15 @@
         sps->profile_idc ==  44 || sps->profile_idc ==  83 ||
         sps->profile_idc ==  86 || sps->profile_idc == 118 ||
         sps->profile_idc == 128 || sps->profile_idc == 144) {
-        sps->chroma_format_idc= get_ue_golomb_31(&h->gb);
+        sps->chroma_format_idc = get_ue_golomb_31(&h->gb);
         if (sps->chroma_format_idc > 3U) {
-            av_log(h->avctx, AV_LOG_ERROR, "chroma_format_idc %d is illegal\n", sps->chroma_format_idc);
+            av_log(h->avctx, AV_LOG_ERROR,
+                   "chroma_format_idc %d is illegal\n",
+                   sps->chroma_format_idc);
             goto fail;
-        } else if(sps->chroma_format_idc == 3) {
+        } else if (sps->chroma_format_idc == 3) {
             sps->residual_color_transform_flag = get_bits1(&h->gb);
-            if(sps->residual_color_transform_flag) {
+            if (sps->residual_color_transform_flag) {
                 av_log(h->avctx, AV_LOG_ERROR, "separate color planes are not supported\n");
                 goto fail;
             }
@@ -385,11 +382,12 @@
             goto fail;
         }
         sps->transform_bypass = get_bits1(&h->gb);
-        decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8);
-    }else{
-        sps->chroma_format_idc= 1;
-        sps->bit_depth_luma   = 8;
-        sps->bit_depth_chroma = 8;
+        decode_scaling_matrices(h, sps, NULL, 1,
+                                sps->scaling_matrix4, sps->scaling_matrix8);
+    } else {
+        sps->chroma_format_idc = 1;
+        sps->bit_depth_luma    = 8;
+        sps->bit_depth_chroma  = 8;
     }
 
     log2_max_frame_num_minus4 = get_ue_golomb(&h->gb);
@@ -402,115 +400,137 @@
     }
     sps->log2_max_frame_num = log2_max_frame_num_minus4 + 4;
 
-    sps->poc_type= get_ue_golomb_31(&h->gb);
+    sps->poc_type = get_ue_golomb_31(&h->gb);
 
-    if(sps->poc_type == 0){ //FIXME #define
+    if (sps->poc_type == 0) { // FIXME #define
         unsigned t = get_ue_golomb(&h->gb);
-        if(t>12){
+        if (t>12) {
             av_log(h->avctx, AV_LOG_ERROR, "log2_max_poc_lsb (%d) is out of range\n", t);
             goto fail;
         }
-        sps->log2_max_poc_lsb= t + 4;
-    } else if(sps->poc_type == 1){//FIXME #define
-        sps->delta_pic_order_always_zero_flag= get_bits1(&h->gb);
-        sps->offset_for_non_ref_pic= get_se_golomb(&h->gb);
-        sps->offset_for_top_to_bottom_field= get_se_golomb(&h->gb);
-        sps->poc_cycle_length                = get_ue_golomb(&h->gb);
+        sps->log2_max_poc_lsb = t + 4;
+    } else if (sps->poc_type == 1) { // FIXME #define
+        sps->delta_pic_order_always_zero_flag = get_bits1(&h->gb);
+        sps->offset_for_non_ref_pic           = get_se_golomb(&h->gb);
+        sps->offset_for_top_to_bottom_field   = get_se_golomb(&h->gb);
+        sps->poc_cycle_length                 = get_ue_golomb(&h->gb);
 
-        if((unsigned)sps->poc_cycle_length >= FF_ARRAY_ELEMS(sps->offset_for_ref_frame)){
-            av_log(h->avctx, AV_LOG_ERROR, "poc_cycle_length overflow %u\n", sps->poc_cycle_length);
+        if ((unsigned)sps->poc_cycle_length >=
+            FF_ARRAY_ELEMS(sps->offset_for_ref_frame)) {
+            av_log(h->avctx, AV_LOG_ERROR,
+                   "poc_cycle_length overflow %u\n", sps->poc_cycle_length);
             goto fail;
         }
 
-        for(i=0; i<sps->poc_cycle_length; i++)
-            sps->offset_for_ref_frame[i]= get_se_golomb(&h->gb);
-    }else if(sps->poc_type != 2){
+        for (i = 0; i < sps->poc_cycle_length; i++)
+            sps->offset_for_ref_frame[i] = get_se_golomb(&h->gb);
+    } else if (sps->poc_type != 2) {
         av_log(h->avctx, AV_LOG_ERROR, "illegal POC type %d\n", sps->poc_type);
         goto fail;
     }
 
-    sps->ref_frame_count= get_ue_golomb_31(&h->gb);
+    sps->ref_frame_count = get_ue_golomb_31(&h->gb);
     if (h->avctx->codec_tag == MKTAG('S', 'M', 'V', '2'))
-        sps->ref_frame_count= FFMAX(2, sps->ref_frame_count);
-    if(sps->ref_frame_count > MAX_PICTURE_COUNT-2 || sps->ref_frame_count > 16U){
+        sps->ref_frame_count = FFMAX(2, sps->ref_frame_count);
+    if (sps->ref_frame_count > MAX_PICTURE_COUNT - 2 ||
+        sps->ref_frame_count > 16U) {
         av_log(h->avctx, AV_LOG_ERROR, "too many reference frames\n");
         goto fail;
     }
-    sps->gaps_in_frame_num_allowed_flag= get_bits1(&h->gb);
-    sps->mb_width = get_ue_golomb(&h->gb) + 1;
-    sps->mb_height= get_ue_golomb(&h->gb) + 1;
-    if((unsigned)sps->mb_width >= INT_MAX/16 || (unsigned)sps->mb_height >= INT_MAX/16 ||
-       av_image_check_size(16*sps->mb_width, 16*sps->mb_height, 0, h->avctx)){
+    sps->gaps_in_frame_num_allowed_flag = get_bits1(&h->gb);
+    sps->mb_width                       = get_ue_golomb(&h->gb) + 1;
+    sps->mb_height                      = get_ue_golomb(&h->gb) + 1;
+    if ((unsigned)sps->mb_width  >= INT_MAX / 16 ||
+        (unsigned)sps->mb_height >= INT_MAX / 16 ||
+        av_image_check_size(16 * sps->mb_width,
+                            16 * sps->mb_height, 0, h->avctx)) {
         av_log(h->avctx, AV_LOG_ERROR, "mb_width/height overflow\n");
         goto fail;
     }
 
-    sps->frame_mbs_only_flag= get_bits1(&h->gb);
-    if(!sps->frame_mbs_only_flag)
-        sps->mb_aff= get_bits1(&h->gb);
+    sps->frame_mbs_only_flag = get_bits1(&h->gb);
+    if (!sps->frame_mbs_only_flag)
+        sps->mb_aff = get_bits1(&h->gb);
     else
-        sps->mb_aff= 0;
+        sps->mb_aff = 0;
 
-    sps->direct_8x8_inference_flag= get_bits1(&h->gb);
+    sps->direct_8x8_inference_flag = get_bits1(&h->gb);
 
 #ifndef ALLOW_INTERLACE
-    if(sps->mb_aff)
-        av_log(h->avctx, AV_LOG_ERROR, "MBAFF support not included; enable it at compile-time.\n");
+    if (sps->mb_aff)
+        av_log(h->avctx, AV_LOG_ERROR,
+               "MBAFF support not included; enable it at compile-time.\n");
 #endif
-    sps->crop= get_bits1(&h->gb);
-    if(sps->crop){
+    sps->crop = get_bits1(&h->gb);
+    if (sps->crop) {
         int crop_left   = get_ue_golomb(&h->gb);
         int crop_right  = get_ue_golomb(&h->gb);
         int crop_top    = get_ue_golomb(&h->gb);
         int crop_bottom = get_ue_golomb(&h->gb);
+        int width  = 16 * sps->mb_width;
+        int height = 16 * sps->mb_height * (2 - sps->frame_mbs_only_flag);
 
         if (h->avctx->flags2 & CODEC_FLAG2_IGNORE_CROP) {
             av_log(h->avctx, AV_LOG_DEBUG, "discarding sps cropping, original "
-                   "values are l:%u r:%u t:%u b:%u\n", crop_left, crop_right,
-                   crop_top, crop_bottom);
+                                           "values are l:%u r:%u t:%u b:%u\n",
+                   crop_left, crop_right, crop_top, crop_bottom);
 
             sps->crop_left   =
             sps->crop_right  =
             sps->crop_top    =
             sps->crop_bottom = 0;
         } else {
-            int vsub = (sps->chroma_format_idc == 1) ? 1 : 0;
-            int hsub = (sps->chroma_format_idc == 1 || sps->chroma_format_idc == 2) ? 1 : 0;
+            int vsub   = (sps->chroma_format_idc == 1) ? 1 : 0;
+            int hsub   = (sps->chroma_format_idc == 1 ||
+                          sps->chroma_format_idc == 2) ? 1 : 0;
             int step_x = 1 << hsub;
             int step_y = (2 - sps->frame_mbs_only_flag) << vsub;
 
             if (crop_left & (0x1F >> (sps->bit_depth_luma > 8)) &&
                 !(h->avctx->flags & CODEC_FLAG_UNALIGNED)) {
                 crop_left &= ~(0x1F >> (sps->bit_depth_luma > 8));
-                av_log(h->avctx, AV_LOG_WARNING, "Reducing left cropping to %d "
+                av_log(h->avctx, AV_LOG_WARNING,
+                       "Reducing left cropping to %d "
                        "chroma samples to preserve alignment.\n",
                        crop_left);
             }
 
+            if (crop_left  > (unsigned)INT_MAX / 4 / step_x ||
+                crop_right > (unsigned)INT_MAX / 4 / step_x ||
+                crop_top   > (unsigned)INT_MAX / 4 / step_y ||
+                crop_bottom> (unsigned)INT_MAX / 4 / step_y ||
+                (crop_left + crop_right ) * step_x >= width ||
+                (crop_top  + crop_bottom) * step_y >= height
+            ) {
+                av_log(h->avctx, AV_LOG_ERROR, "crop values invalid %d %d %d %d / %d %d\n", crop_left, crop_right, crop_top, crop_bottom, width, height);
+                goto fail;
+            }
+
             sps->crop_left   = crop_left   * step_x;
             sps->crop_right  = crop_right  * step_x;
             sps->crop_top    = crop_top    * step_y;
             sps->crop_bottom = crop_bottom * step_y;
         }
-    }else{
-        sps->crop_left  =
-        sps->crop_right =
-        sps->crop_top   =
-        sps->crop_bottom= 0;
-        sps->crop = 0;
+    } else {
+        sps->crop_left   =
+        sps->crop_right  =
+        sps->crop_top    =
+        sps->crop_bottom =
+        sps->crop        = 0;
     }
 
-    sps->vui_parameters_present_flag= get_bits1(&h->gb);
-    if( sps->vui_parameters_present_flag )
+    sps->vui_parameters_present_flag = get_bits1(&h->gb);
+    if (sps->vui_parameters_present_flag)
         if (decode_vui_parameters(h, sps) < 0)
             goto fail;
 
-    if(!sps->sar.den)
-        sps->sar.den= 1;
+    if (!sps->sar.den)
+        sps->sar.den = 1;
 
-    if(h->avctx->debug&FF_DEBUG_PICT_INFO){
+    if (h->avctx->debug & FF_DEBUG_PICT_INFO) {
         static const char csp[4][5] = { "Gray", "420", "422", "444" };
-        av_log(h->avctx, AV_LOG_DEBUG, "sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s %s %d/%d b%d reo:%d\n",
+        av_log(h->avctx, AV_LOG_DEBUG,
+               "sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s %s %d/%d b%d reo:%d\n",
                sps_id, sps->profile_idc, sps->level_idc,
                sps->poc_type,
                sps->ref_frame_count,
@@ -531,22 +551,21 @@
 
     av_free(h->sps_buffers[sps_id]);
     h->sps_buffers[sps_id] = sps;
-    h->sps                 = *sps;
-    h->current_sps_id      = sps_id;
 
     return 0;
+
 fail:
     av_free(sps);
     return -1;
 }
 
-static void
-build_qp_table(PPS *pps, int t, int index, const int depth)
+static void build_qp_table(PPS *pps, int t, int index, const int depth)
 {
     int i;
-    const int max_qp = 51 + 6*(depth-8);
-    for(i = 0; i < max_qp+1; i++)
-        pps->chroma_qp_table[t][i] = ff_h264_chroma_qp[depth-8][av_clip(i + index, 0, max_qp)];
+    const int max_qp = 51 + 6 * (depth - 8);
+    for (i = 0; i < max_qp + 1; i++)
+        pps->chroma_qp_table[t][i] =
+            ff_h264_chroma_qp[depth - 8][av_clip(i + index, 0, max_qp)];
 }
 
 static int more_rbsp_data_in_pps(H264Context *h, PPS *pps)
@@ -564,109 +583,123 @@
     return 1;
 }
 
-int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){
-    unsigned int pps_id= get_ue_golomb(&h->gb);
+int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length)
+{
+    unsigned int pps_id = get_ue_golomb(&h->gb);
     PPS *pps;
-    const int qp_bd_offset = 6*(h->sps.bit_depth_luma-8);
+    SPS *sps;
+    int qp_bd_offset;
     int bits_left;
 
-    if(pps_id >= MAX_PPS_COUNT) {
+    if (pps_id >= MAX_PPS_COUNT) {
         av_log(h->avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id);
-        return -1;
-    } else if (h->sps.bit_depth_luma > 14) {
-        av_log(h->avctx, AV_LOG_ERROR, "Invalid luma bit depth=%d\n", h->sps.bit_depth_luma);
         return AVERROR_INVALIDDATA;
-    } else if (h->sps.bit_depth_luma == 11 || h->sps.bit_depth_luma == 13) {
-        av_log(h->avctx, AV_LOG_ERROR, "Unimplemented luma bit depth=%d\n", h->sps.bit_depth_luma);
-        return AVERROR_PATCHWELCOME;
     }
 
-    pps= av_mallocz(sizeof(PPS));
-    if(pps == NULL)
-        return -1;
-    pps->sps_id= get_ue_golomb_31(&h->gb);
-    if((unsigned)pps->sps_id>=MAX_SPS_COUNT || h->sps_buffers[pps->sps_id] == NULL){
+    pps = av_mallocz(sizeof(PPS));
+    if (!pps)
+        return AVERROR(ENOMEM);
+    pps->sps_id = get_ue_golomb_31(&h->gb);
+    if ((unsigned)pps->sps_id >= MAX_SPS_COUNT ||
+        h->sps_buffers[pps->sps_id] == NULL) {
         av_log(h->avctx, AV_LOG_ERROR, "sps_id out of range\n");
         goto fail;
     }
+    sps = h->sps_buffers[pps->sps_id];
+    qp_bd_offset = 6 * (sps->bit_depth_luma - 8);
+    if (sps->bit_depth_luma > 14) {
+        av_log(h->avctx, AV_LOG_ERROR,
+               "Invalid luma bit depth=%d\n",
+               sps->bit_depth_luma);
+        goto fail;
+    } else if (sps->bit_depth_luma == 11 || sps->bit_depth_luma == 13) {
+        av_log(h->avctx, AV_LOG_ERROR,
+               "Unimplemented luma bit depth=%d\n",
+               sps->bit_depth_luma);
+        goto fail;
+    }
 
-    pps->cabac= get_bits1(&h->gb);
-    pps->pic_order_present= get_bits1(&h->gb);
-    pps->slice_group_count= get_ue_golomb(&h->gb) + 1;
-    if(pps->slice_group_count > 1 ){
-        pps->mb_slice_group_map_type= get_ue_golomb(&h->gb);
+    pps->cabac             = get_bits1(&h->gb);
+    pps->pic_order_present = get_bits1(&h->gb);
+    pps->slice_group_count = get_ue_golomb(&h->gb) + 1;
+    if (pps->slice_group_count > 1) {
+        pps->mb_slice_group_map_type = get_ue_golomb(&h->gb);
         av_log(h->avctx, AV_LOG_ERROR, "FMO not supported\n");
-        switch(pps->mb_slice_group_map_type){
+        switch (pps->mb_slice_group_map_type) {
         case 0:
 #if 0
-|   for( i = 0; i <= num_slice_groups_minus1; i++ ) |   |        |
-|    run_length[ i ]                                |1  |ue(v)   |
+    |       for (i = 0; i <= num_slice_groups_minus1; i++)  |   |      |
+    |           run_length[i]                               |1  |ue(v) |
 #endif
             break;
         case 2:
 #if 0
-|   for( i = 0; i < num_slice_groups_minus1; i++ )  |   |        |
-|{                                                  |   |        |
-|    top_left_mb[ i ]                               |1  |ue(v)   |
-|    bottom_right_mb[ i ]                           |1  |ue(v)   |
-|   }                                               |   |        |
+    |       for (i = 0; i < num_slice_groups_minus1; i++) { |   |      |
+    |           top_left_mb[i]                              |1  |ue(v) |
+    |           bottom_right_mb[i]                          |1  |ue(v) |
+    |       }                                               |   |      |
 #endif
             break;
         case 3:
         case 4:
         case 5:
 #if 0
-|   slice_group_change_direction_flag               |1  |u(1)    |
-|   slice_group_change_rate_minus1                  |1  |ue(v)   |
+    |       slice_group_change_direction_flag               |1  |u(1)  |
+    |       slice_group_change_rate_minus1                  |1  |ue(v) |
 #endif
             break;
         case 6:
 #if 0
-|   slice_group_id_cnt_minus1                       |1  |ue(v)   |
-|   for( i = 0; i <= slice_group_id_cnt_minus1; i++ |   |        |
-|)                                                  |   |        |
-|    slice_group_id[ i ]                            |1  |u(v)    |
+    |       slice_group_id_cnt_minus1                       |1  |ue(v) |
+    |       for (i = 0; i <= slice_group_id_cnt_minus1; i++)|   |      |
+    |           slice_group_id[i]                           |1  |u(v)  |
 #endif
             break;
         }
     }
-    pps->ref_count[0]= get_ue_golomb(&h->gb) + 1;
-    pps->ref_count[1]= get_ue_golomb(&h->gb) + 1;
-    if(pps->ref_count[0]-1 > 32-1 || pps->ref_count[1]-1 > 32-1){
+    pps->ref_count[0] = get_ue_golomb(&h->gb) + 1;
+    pps->ref_count[1] = get_ue_golomb(&h->gb) + 1;
+    if (pps->ref_count[0] - 1 > 32 - 1 || pps->ref_count[1] - 1 > 32 - 1) {
         av_log(h->avctx, AV_LOG_ERROR, "reference overflow (pps)\n");
         goto fail;
     }
 
-    pps->weighted_pred= get_bits1(&h->gb);
-    pps->weighted_bipred_idc= get_bits(&h->gb, 2);
-    pps->init_qp= get_se_golomb(&h->gb) + 26 + qp_bd_offset;
-    pps->init_qs= get_se_golomb(&h->gb) + 26 + qp_bd_offset;
-    pps->chroma_qp_index_offset[0]= get_se_golomb(&h->gb);
-    pps->deblocking_filter_parameters_present= get_bits1(&h->gb);
-    pps->constrained_intra_pred= get_bits1(&h->gb);
-    pps->redundant_pic_cnt_present = get_bits1(&h->gb);
+    pps->weighted_pred                        = get_bits1(&h->gb);
+    pps->weighted_bipred_idc                  = get_bits(&h->gb, 2);
+    pps->init_qp                              = get_se_golomb(&h->gb) + 26 + qp_bd_offset;
+    pps->init_qs                              = get_se_golomb(&h->gb) + 26 + qp_bd_offset;
+    pps->chroma_qp_index_offset[0]            = get_se_golomb(&h->gb);
+    pps->deblocking_filter_parameters_present = get_bits1(&h->gb);
+    pps->constrained_intra_pred               = get_bits1(&h->gb);
+    pps->redundant_pic_cnt_present            = get_bits1(&h->gb);
 
-    pps->transform_8x8_mode= 0;
-    h->dequant_coeff_pps= -1; //contents of sps/pps can change even if id doesn't, so reinit
-    memcpy(pps->scaling_matrix4, h->sps_buffers[pps->sps_id]->scaling_matrix4, sizeof(pps->scaling_matrix4));
-    memcpy(pps->scaling_matrix8, h->sps_buffers[pps->sps_id]->scaling_matrix8, sizeof(pps->scaling_matrix8));
+    pps->transform_8x8_mode = 0;
+    // contents of sps/pps can change even if id doesn't, so reinit
+    h->dequant_coeff_pps = -1;
+    memcpy(pps->scaling_matrix4, h->sps_buffers[pps->sps_id]->scaling_matrix4,
+           sizeof(pps->scaling_matrix4));
+    memcpy(pps->scaling_matrix8, h->sps_buffers[pps->sps_id]->scaling_matrix8,
+           sizeof(pps->scaling_matrix8));
 
     bits_left = bit_length - get_bits_count(&h->gb);
-    if(bits_left > 0 && more_rbsp_data_in_pps(h, pps)){
-        pps->transform_8x8_mode= get_bits1(&h->gb);
-        decode_scaling_matrices(h, h->sps_buffers[pps->sps_id], pps, 0, pps->scaling_matrix4, pps->scaling_matrix8);
-        pps->chroma_qp_index_offset[1]= get_se_golomb(&h->gb); //second_chroma_qp_index_offset
+    if (bits_left > 0 && more_rbsp_data_in_pps(h, pps)) {
+        pps->transform_8x8_mode = get_bits1(&h->gb);
+        decode_scaling_matrices(h, h->sps_buffers[pps->sps_id], pps, 0,
+                                pps->scaling_matrix4, pps->scaling_matrix8);
+        // second_chroma_qp_index_offset
+        pps->chroma_qp_index_offset[1] = get_se_golomb(&h->gb);
     } else {
-        pps->chroma_qp_index_offset[1]= pps->chroma_qp_index_offset[0];
+        pps->chroma_qp_index_offset[1] = pps->chroma_qp_index_offset[0];
     }
 
-    build_qp_table(pps, 0, pps->chroma_qp_index_offset[0], h->sps.bit_depth_luma);
-    build_qp_table(pps, 1, pps->chroma_qp_index_offset[1], h->sps.bit_depth_luma);
-    if(pps->chroma_qp_index_offset[0] != pps->chroma_qp_index_offset[1])
-        pps->chroma_qp_diff= 1;
+    build_qp_table(pps, 0, pps->chroma_qp_index_offset[0], sps->bit_depth_luma);
+    build_qp_table(pps, 1, pps->chroma_qp_index_offset[1], sps->bit_depth_luma);
+    if (pps->chroma_qp_index_offset[0] != pps->chroma_qp_index_offset[1])
+        pps->chroma_qp_diff = 1;
 
-    if(h->avctx->debug&FF_DEBUG_PICT_INFO){
-        av_log(h->avctx, AV_LOG_DEBUG, "pps:%u sps:%u %s slice_groups:%d ref:%d/%d %s qp:%d/%d/%d/%d %s %s %s %s\n",
+    if (h->avctx->debug & FF_DEBUG_PICT_INFO) {
+        av_log(h->avctx, AV_LOG_DEBUG,
+               "pps:%u sps:%u %s slice_groups:%d ref:%d/%d %s qp:%d/%d/%d/%d %s %s %s %s\n",
                pps_id, pps->sps_id,
                pps->cabac ? "CABAC" : "CAVLC",
                pps->slice_group_count,
@@ -676,13 +709,13 @@
                pps->deblocking_filter_parameters_present ? "LPAR" : "",
                pps->constrained_intra_pred ? "CONSTR" : "",
                pps->redundant_pic_cnt_present ? "REDU" : "",
-               pps->transform_8x8_mode ? "8x8DCT" : ""
-               );
+               pps->transform_8x8_mode ? "8x8DCT" : "");
     }
 
     av_free(h->pps_buffers[pps_id]);
-    h->pps_buffers[pps_id]= pps;
+    h->pps_buffers[pps_id] = pps;
     return 0;
+
 fail:
     av_free(pps);
     return -1;
diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c
index 4b69a90..7dffa9b 100644
--- a/libavcodec/h264_refs.c
+++ b/libavcodec/h264_refs.c
@@ -31,7 +31,6 @@
 #include "h264.h"
 #include "golomb.h"
 
-//#undef NDEBUG
 #include <assert.h>
 
 #define COPY_PICTURE(dst, src) \
@@ -746,7 +745,7 @@
                                    int first_slice)
 {
     int i, ret;
-    MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = first_slice ? h->mmco : mmco_temp;
+    MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = mmco_temp;
     int mmco_index = 0;
 
     if (h->nal_unit_type == NAL_IDR_SLICE) { // FIXME fields
@@ -812,10 +811,11 @@
     }
 
     if (first_slice && mmco_index != -1) {
+        memcpy(h->mmco, mmco_temp, sizeof(h->mmco));
         h->mmco_index = mmco_index;
     } else if (!first_slice && mmco_index >= 0 &&
                (mmco_index != h->mmco_index ||
-                (i = check_opcodes(h->mmco, mmco_temp, mmco_index)))) {
+                check_opcodes(h->mmco, mmco_temp, mmco_index))) {
         av_log(h->avctx, AV_LOG_ERROR,
                "Inconsistent MMCO state between slices [%d, %d]\n",
                mmco_index, h->mmco_index);
diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c
index be6cb58..d5e8a4f 100644
--- a/libavcodec/h264_sei.c
+++ b/libavcodec/h264_sei.c
@@ -30,71 +30,86 @@
 #include "h264.h"
 #include "golomb.h"
 
-//#undef NDEBUG
 #include <assert.h>
 
-static const uint8_t sei_num_clock_ts_table[9]={
-    1,  1,  1,  2,  2,  3,  3,  2,  3
+static const uint8_t sei_num_clock_ts_table[9] = {
+    1, 1, 1, 2, 2, 3, 3, 2, 3
 };
 
-void ff_h264_reset_sei(H264Context *h) {
+void ff_h264_reset_sei(H264Context *h)
+{
     h->sei_recovery_frame_cnt       = -1;
     h->sei_dpb_output_delay         =  0;
     h->sei_cpb_removal_delay        = -1;
     h->sei_buffering_period_present =  0;
 }
 
-static int decode_picture_timing(H264Context *h){
-    if(h->sps.nal_hrd_parameters_present_flag || h->sps.vcl_hrd_parameters_present_flag){
-        h->sei_cpb_removal_delay = get_bits_long(&h->gb, h->sps.cpb_removal_delay_length);
-        h->sei_dpb_output_delay = get_bits_long(&h->gb, h->sps.dpb_output_delay_length);
+static int decode_picture_timing(H264Context *h)
+{
+    SPS *sps = &h->sps;
+    int i;
+
+    for (i = 0; i<MAX_SPS_COUNT; i++)
+        if (!sps->log2_max_frame_num && h->sps_buffers[i])
+            sps = h->sps_buffers[i];
+
+    if (sps->nal_hrd_parameters_present_flag || sps->vcl_hrd_parameters_present_flag) {
+        h->sei_cpb_removal_delay = get_bits_long(&h->gb,
+                                                 sps->cpb_removal_delay_length);
+        h->sei_dpb_output_delay  = get_bits_long(&h->gb,
+                                                 sps->dpb_output_delay_length);
     }
-    if(h->sps.pic_struct_present_flag){
+    if (sps->pic_struct_present_flag) {
         unsigned int i, num_clock_ts;
+
         h->sei_pic_struct = get_bits(&h->gb, 4);
         h->sei_ct_type    = 0;
 
         if (h->sei_pic_struct > SEI_PIC_STRUCT_FRAME_TRIPLING)
-            return -1;
+            return AVERROR_INVALIDDATA;
 
         num_clock_ts = sei_num_clock_ts_table[h->sei_pic_struct];
 
-        for (i = 0 ; i < num_clock_ts ; i++){
-            if(get_bits(&h->gb, 1)){                  /* clock_timestamp_flag */
+        for (i = 0; i < num_clock_ts; i++) {
+            if (get_bits(&h->gb, 1)) {                /* clock_timestamp_flag */
                 unsigned int full_timestamp_flag;
-                h->sei_ct_type |= 1<<get_bits(&h->gb, 2);
+
+                h->sei_ct_type |= 1 << get_bits(&h->gb, 2);
                 skip_bits(&h->gb, 1);                 /* nuit_field_based_flag */
                 skip_bits(&h->gb, 5);                 /* counting_type */
                 full_timestamp_flag = get_bits(&h->gb, 1);
                 skip_bits(&h->gb, 1);                 /* discontinuity_flag */
                 skip_bits(&h->gb, 1);                 /* cnt_dropped_flag */
                 skip_bits(&h->gb, 8);                 /* n_frames */
-                if(full_timestamp_flag){
+                if (full_timestamp_flag) {
                     skip_bits(&h->gb, 6);             /* seconds_value 0..59 */
                     skip_bits(&h->gb, 6);             /* minutes_value 0..59 */
                     skip_bits(&h->gb, 5);             /* hours_value 0..23 */
-                }else{
-                    if(get_bits(&h->gb, 1)){          /* seconds_flag */
+                } else {
+                    if (get_bits(&h->gb, 1)) {        /* seconds_flag */
                         skip_bits(&h->gb, 6);         /* seconds_value range 0..59 */
-                        if(get_bits(&h->gb, 1)){      /* minutes_flag */
+                        if (get_bits(&h->gb, 1)) {    /* minutes_flag */
                             skip_bits(&h->gb, 6);     /* minutes_value 0..59 */
-                            if(get_bits(&h->gb, 1))   /* hours_flag */
+                            if (get_bits(&h->gb, 1))  /* hours_flag */
                                 skip_bits(&h->gb, 5); /* hours_value 0..23 */
                         }
                     }
                 }
-                if(h->sps.time_offset_length > 0)
-                    skip_bits(&h->gb, h->sps.time_offset_length); /* time_offset */
+                if (sps->time_offset_length > 0)
+                    skip_bits(&h->gb,
+                              sps->time_offset_length); /* time_offset */
             }
         }
 
-        if(h->avctx->debug & FF_DEBUG_PICT_INFO)
-            av_log(h->avctx, AV_LOG_DEBUG, "ct_type:%X pic_struct:%d\n", h->sei_ct_type, h->sei_pic_struct);
+        if (h->avctx->debug & FF_DEBUG_PICT_INFO)
+            av_log(h->avctx, AV_LOG_DEBUG, "ct_type:%X pic_struct:%d\n",
+                   h->sei_ct_type, h->sei_pic_struct);
     }
     return 0;
 }
 
-static int decode_user_data_itu_t_t35(H264Context *h, int size) {
+static int decode_user_data_itu_t_t35(H264Context *h, int size)
+{
     uint32_t user_identifier;
     int dtg_active_format;
 
@@ -130,66 +145,77 @@
     return 0;
 }
 
-static int decode_unregistered_user_data(H264Context *h, int size){
-    uint8_t user_data[16+256];
+static int decode_unregistered_user_data(H264Context *h, int size)
+{
+    uint8_t user_data[16 + 256];
     int e, build, i;
 
-    if(size<16)
-        return -1;
+    if (size < 16)
+        return AVERROR_INVALIDDATA;
 
-    for(i=0; i<sizeof(user_data)-1 && i<size; i++){
-        user_data[i]= get_bits(&h->gb, 8);
-    }
+    for (i = 0; i < sizeof(user_data) - 1 && i < size; i++)
+        user_data[i] = get_bits(&h->gb, 8);
 
-    user_data[i]= 0;
-    e= sscanf(user_data+16, "x264 - core %d"/*%s - H.264/MPEG-4 AVC codec - Copyleft 2005 - http://www.videolan.org/x264.html*/, &build);
-    if(e==1 && build>0)
-        h->x264_build= build;
-    if(e==1 && build==1 && !strncmp(user_data+16, "x264 - core 0000", 16))
+    user_data[i] = 0;
+    e = sscanf(user_data + 16, "x264 - core %d", &build);
+    if (e == 1 && build > 0)
+        h->x264_build = build;
+    if (e == 1 && build == 1 && !strncmp(user_data+16, "x264 - core 0000", 16))
         h->x264_build = 67;
 
-    if(h->avctx->debug & FF_DEBUG_BUGS)
-        av_log(h->avctx, AV_LOG_DEBUG, "user data:\"%s\"\n", user_data+16);
+    if (h->avctx->debug & FF_DEBUG_BUGS)
+        av_log(h->avctx, AV_LOG_DEBUG, "user data:\"%s\"\n", user_data + 16);
 
-    for(; i<size; i++)
+    for (; i < size; i++)
         skip_bits(&h->gb, 8);
 
     return 0;
 }
 
-static int decode_recovery_point(H264Context *h){
+static int decode_recovery_point(H264Context *h)
+{
     h->sei_recovery_frame_cnt = get_ue_golomb(&h->gb);
-    skip_bits(&h->gb, 4);       /* 1b exact_match_flag, 1b broken_link_flag, 2b changing_slice_group_idc */
 
-    if(h->avctx->debug & FF_DEBUG_PICT_INFO)
+    /* 1b exact_match_flag,
+     * 1b broken_link_flag,
+     * 2b changing_slice_group_idc */
+    skip_bits(&h->gb, 4);
+
+    if (h->avctx->debug & FF_DEBUG_PICT_INFO)
         av_log(h->avctx, AV_LOG_DEBUG, "sei_recovery_frame_cnt: %d\n", h->sei_recovery_frame_cnt);
 
     return 0;
 }
 
-static int decode_buffering_period(H264Context *h){
+static int decode_buffering_period(H264Context *h)
+{
     unsigned int sps_id;
     int sched_sel_idx;
     SPS *sps;
 
     sps_id = get_ue_golomb_31(&h->gb);
-    if(sps_id > 31 || !h->sps_buffers[sps_id]) {
-        av_log(h->avctx, AV_LOG_ERROR, "non-existing SPS %d referenced in buffering period\n", sps_id);
-        return -1;
+    if (sps_id > 31 || !h->sps_buffers[sps_id]) {
+        av_log(h->avctx, AV_LOG_ERROR,
+               "non-existing SPS %d referenced in buffering period\n", sps_id);
+        return AVERROR_INVALIDDATA;
     }
     sps = h->sps_buffers[sps_id];
 
     // NOTE: This is really so duplicated in the standard... See H.264, D.1.1
     if (sps->nal_hrd_parameters_present_flag) {
         for (sched_sel_idx = 0; sched_sel_idx < sps->cpb_cnt; sched_sel_idx++) {
-            h->initial_cpb_removal_delay[sched_sel_idx] = get_bits_long(&h->gb, sps->initial_cpb_removal_delay_length);
-            skip_bits(&h->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset
+            h->initial_cpb_removal_delay[sched_sel_idx] =
+                get_bits_long(&h->gb, sps->initial_cpb_removal_delay_length);
+            // initial_cpb_removal_delay_offset
+            skip_bits(&h->gb, sps->initial_cpb_removal_delay_length);
         }
     }
     if (sps->vcl_hrd_parameters_present_flag) {
         for (sched_sel_idx = 0; sched_sel_idx < sps->cpb_cnt; sched_sel_idx++) {
-            h->initial_cpb_removal_delay[sched_sel_idx] = get_bits_long(&h->gb, sps->initial_cpb_removal_delay_length);
-            skip_bits(&h->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset
+            h->initial_cpb_removal_delay[sched_sel_idx] =
+                get_bits_long(&h->gb, sps->initial_cpb_removal_delay_length);
+            // initial_cpb_removal_delay_offset
+            skip_bits(&h->gb, sps->initial_cpb_removal_delay_length);
         }
     }
 
@@ -197,55 +223,152 @@
     return 0;
 }
 
-int ff_h264_decode_sei(H264Context *h){
+static int decode_frame_packing(H264Context *h, int size) {
+    int bits = get_bits_left(&h->gb);
+
+    h->sei_fpa.frame_packing_arrangement_id          = get_ue_golomb(&h->gb);
+    h->sei_fpa.frame_packing_arrangement_cancel_flag = get_bits(&h->gb, 1);
+    if (!h->sei_fpa.frame_packing_arrangement_cancel_flag) {
+        h->sei_fpa.frame_packing_arrangement_type  = get_bits(&h->gb, 7);
+        h->sei_fpa.quincunx_sampling_flag          = get_bits(&h->gb, 1);
+        h->sei_fpa.content_interpretation_type     = get_bits(&h->gb, 6);
+        skip_bits(&h->gb, 1); /* spatial_flipping_flag */
+        skip_bits(&h->gb, 1); /* frame0_flipped_flag */
+        skip_bits(&h->gb, 1); /* field_views_flag */
+        skip_bits(&h->gb, 1); /* current_frame_is_frame0_flag */
+        skip_bits(&h->gb, 1); /* frame0_self_contained_flag */
+        skip_bits(&h->gb, 1); /* frame1_self_contained_flag */
+        if (!h->sei_fpa.quincunx_sampling_flag && h->sei_fpa.frame_packing_arrangement_type != 5) {
+            skip_bits(&h->gb, 4); /* frame0_grid_position_x */
+            skip_bits(&h->gb, 4); /* frame0_grid_position_y */
+            skip_bits(&h->gb, 4); /* frame1_grid_position_x */
+            skip_bits(&h->gb, 4); /* frame1_grid_position_y */
+        }
+        skip_bits(&h->gb, 8); /* frame_packing_arrangement_reserved_byte */
+        h->sei_fpa.frame_packing_arrangement_repetition_period = get_ue_golomb(&h->gb) /* frame_packing_arrangement_repetition_period */;
+    }
+    skip_bits(&h->gb, 1); /* frame_packing_arrangement_extension_flag */
+
+    if (h->avctx->debug & FF_DEBUG_PICT_INFO)
+        av_log(h->avctx, AV_LOG_DEBUG, "SEI FPA %d %d %d %d %d %d\n",
+                                       h->sei_fpa.frame_packing_arrangement_id,
+                                       h->sei_fpa.frame_packing_arrangement_cancel_flag,
+                                       h->sei_fpa.frame_packing_arrangement_type,
+                                       h->sei_fpa.quincunx_sampling_flag,
+                                       h->sei_fpa.content_interpretation_type,
+                                       h->sei_fpa.frame_packing_arrangement_repetition_period);
+    skip_bits_long(&h->gb, 8 * size - (bits - get_bits_left(&h->gb)));
+    return 0;
+}
+
+int ff_h264_decode_sei(H264Context *h)
+{
     while (get_bits_left(&h->gb) > 16) {
-        int size, type;
+        int type = 0;
+        unsigned size = 0;
+        unsigned next;
+        int ret  = 0;
 
-        type=0;
-        do{
+        do {
             if (get_bits_left(&h->gb) < 8)
-                return -1;
-            type+= show_bits(&h->gb, 8);
-        }while(get_bits(&h->gb, 8) == 255);
+                return AVERROR_INVALIDDATA;
+            type += show_bits(&h->gb, 8);
+        } while (get_bits(&h->gb, 8) == 255);
 
-        size=0;
-        do{
+        do {
             if (get_bits_left(&h->gb) < 8)
-                return -1;
-            size+= show_bits(&h->gb, 8);
-        }while(get_bits(&h->gb, 8) == 255);
+                return AVERROR_INVALIDDATA;
+            size += show_bits(&h->gb, 8);
+        } while (get_bits(&h->gb, 8) == 255);
 
-        if(h->avctx->debug&FF_DEBUG_STARTCODE)
+        if (h->avctx->debug&FF_DEBUG_STARTCODE)
             av_log(h->avctx, AV_LOG_DEBUG, "SEI %d len:%d\n", type, size);
 
-        switch(type){
+        if (size > get_bits_left(&h->gb) / 8) {
+            av_log(h->avctx, AV_LOG_ERROR, "SEI truncated\n");
+            return AVERROR_INVALIDDATA;
+        }
+        next = get_bits_count(&h->gb) + 8 * size;
+
+        switch (type) {
         case SEI_TYPE_PIC_TIMING: // Picture timing SEI
-            if(decode_picture_timing(h) < 0)
-                return -1;
+            ret = decode_picture_timing(h);
+            if (ret < 0)
+                return ret;
             break;
         case SEI_TYPE_USER_DATA_ITU_T_T35:
-            if(decode_user_data_itu_t_t35(h, size) < 0)
+            if (decode_user_data_itu_t_t35(h, size) < 0)
                 return -1;
             break;
         case SEI_TYPE_USER_DATA_UNREGISTERED:
-            if(decode_unregistered_user_data(h, size) < 0)
-                return -1;
+            ret = decode_unregistered_user_data(h, size);
+            if (ret < 0)
+                return ret;
             break;
         case SEI_TYPE_RECOVERY_POINT:
-            if(decode_recovery_point(h) < 0)
-                return -1;
+            ret = decode_recovery_point(h);
+            if (ret < 0)
+                return ret;
             break;
         case SEI_BUFFERING_PERIOD:
-            if(decode_buffering_period(h) < 0)
-                return -1;
+            ret = decode_buffering_period(h);
+            if (ret < 0)
+                return ret;
             break;
-        default:
-            skip_bits(&h->gb, 8*size);
+        case SEI_TYPE_FRAME_PACKING:
+            if (decode_frame_packing(h, size) < 0)
+                return -1;
         }
+        skip_bits_long(&h->gb, next - get_bits_count(&h->gb));
 
-        //FIXME check bits here
+        // FIXME check bits here
         align_get_bits(&h->gb);
     }
 
     return 0;
 }
+
+const char* ff_h264_sei_stereo_mode(H264Context *h)
+{
+    if (h->sei_fpa.frame_packing_arrangement_cancel_flag == 0) {
+        switch (h->sei_fpa.frame_packing_arrangement_type) {
+            case SEI_FPA_TYPE_CHECKERBOARD:
+                if (h->sei_fpa.content_interpretation_type == 2)
+                    return "checkerboard_rl";
+                else
+                    return "checkerboard_lr";
+            case SEI_FPA_TYPE_INTERLEAVE_COLUMN:
+                if (h->sei_fpa.content_interpretation_type == 2)
+                    return "col_interleaved_rl";
+                else
+                    return "col_interleaved_lr";
+            case SEI_FPA_TYPE_INTERLEAVE_ROW:
+                if (h->sei_fpa.content_interpretation_type == 2)
+                    return "row_interleaved_rl";
+                else
+                    return "row_interleaved_lr";
+            case SEI_FPA_TYPE_SIDE_BY_SIDE:
+                if (h->sei_fpa.content_interpretation_type == 2)
+                    return "right_left";
+                else
+                    return "left_right";
+            case SEI_FPA_TYPE_TOP_BOTTOM:
+                if (h->sei_fpa.content_interpretation_type == 2)
+                    return "bottom_top";
+                else
+                    return "top_bottom";
+            case SEI_FPA_TYPE_INTERLEAVE_TEMPORAL:
+                if (h->sei_fpa.content_interpretation_type == 2)
+                    return "block_rl";
+                else
+                    return "block_lr";
+            case SEI_FPA_TYPE_2D:
+            default:
+                return "mono";
+        }
+    } else if (h->sei_fpa.frame_packing_arrangement_cancel_flag == 1) {
+        return "mono";
+    } else {
+        return NULL;
+    }
+}
diff --git a/libavcodec/h264chroma.c b/libavcodec/h264chroma.c
index ed41afe..5f8ed91 100644
--- a/libavcodec/h264chroma.c
+++ b/libavcodec/h264chroma.c
@@ -17,6 +17,7 @@
  */
 
 #include "config.h"
+#include "libavutil/attributes.h"
 #include "h264chroma.h"
 
 #define BIT_DEPTH 8
@@ -31,11 +32,13 @@
     c->put_h264_chroma_pixels_tab[0] = put_h264_chroma_mc8_ ## depth ## _c; \
     c->put_h264_chroma_pixels_tab[1] = put_h264_chroma_mc4_ ## depth ## _c; \
     c->put_h264_chroma_pixels_tab[2] = put_h264_chroma_mc2_ ## depth ## _c; \
+    c->put_h264_chroma_pixels_tab[3] = put_h264_chroma_mc1_ ## depth ## _c; \
     c->avg_h264_chroma_pixels_tab[0] = avg_h264_chroma_mc8_ ## depth ## _c; \
     c->avg_h264_chroma_pixels_tab[1] = avg_h264_chroma_mc4_ ## depth ## _c; \
     c->avg_h264_chroma_pixels_tab[2] = avg_h264_chroma_mc2_ ## depth ## _c; \
+    c->avg_h264_chroma_pixels_tab[3] = avg_h264_chroma_mc1_ ## depth ## _c; \
 
-void ff_h264chroma_init(H264ChromaContext *c, int bit_depth)
+av_cold void ff_h264chroma_init(H264ChromaContext *c, int bit_depth)
 {
     if (bit_depth > 8 && bit_depth <= 16) {
         SET_CHROMA(16);
diff --git a/libavcodec/h264chroma.h b/libavcodec/h264chroma.h
index 46fae42..45bbc7d 100644
--- a/libavcodec/h264chroma.h
+++ b/libavcodec/h264chroma.h
@@ -24,8 +24,8 @@
 typedef void (*h264_chroma_mc_func)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y);
 
 typedef struct H264ChromaContext {
-    h264_chroma_mc_func put_h264_chroma_pixels_tab[3];
-    h264_chroma_mc_func avg_h264_chroma_pixels_tab[3];
+    h264_chroma_mc_func put_h264_chroma_pixels_tab[4];
+    h264_chroma_mc_func avg_h264_chroma_pixels_tab[4];
 } H264ChromaContext;
 
 void ff_h264chroma_init(H264ChromaContext *c, int bit_depth);
diff --git a/libavcodec/h264chroma_template.c b/libavcodec/h264chroma_template.c
index 93559d7..b64172a 100644
--- a/libavcodec/h264chroma_template.c
+++ b/libavcodec/h264chroma_template.c
@@ -24,6 +24,34 @@
 #include "bit_depth_template.c"
 
 #define H264_CHROMA_MC(OPNAME, OP)\
+static void FUNCC(OPNAME ## h264_chroma_mc1)(uint8_t *_dst/*align 8*/, uint8_t *_src/*align 1*/, int stride, int h, int x, int y){\
+    pixel *dst = (pixel*)_dst;\
+    pixel *src = (pixel*)_src;\
+    const int A=(8-x)*(8-y);\
+    const int B=(  x)*(8-y);\
+    const int C=(8-x)*(  y);\
+    const int D=(  x)*(  y);\
+    int i;\
+    stride >>= sizeof(pixel)-1;\
+    \
+    av_assert2(x<8 && y<8 && x>=0 && y>=0);\
+\
+    if(D){\
+        for(i=0; i<h; i++){\
+            OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\
+            dst+= stride;\
+            src+= stride;\
+        }\
+    }else{\
+        const int E= B+C;\
+        const int step= C ? stride : 1;\
+        for(i=0; i<h; i++){\
+            OP(dst[0], (A*src[0] + E*src[step+0]));\
+            dst+= stride;\
+            src+= stride;\
+        }\
+    }\
+}\
 static void FUNCC(OPNAME ## h264_chroma_mc2)(uint8_t *_dst/*align 8*/, uint8_t *_src/*align 1*/, int stride, int h, int x, int y){\
     pixel *dst = (pixel*)_dst;\
     pixel *src = (pixel*)_src;\
diff --git a/libavcodec/h264data.h b/libavcodec/h264data.h
index f3fc7f9..eb229f3 100644
--- a/libavcodec/h264data.h
+++ b/libavcodec/h264data.h
@@ -59,27 +59,6 @@
     3 + 1 * 4, 3 + 2 * 4, 2 + 3 * 4, 3 + 3 * 4,
 };
 
-static const uint8_t field_scan[16+1] = {
-    0 + 0 * 4, 0 + 1 * 4, 1 + 0 * 4, 0 + 2 * 4,
-    0 + 3 * 4, 1 + 1 * 4, 1 + 2 * 4, 1 + 3 * 4,
-    2 + 0 * 4, 2 + 1 * 4, 2 + 2 * 4, 2 + 3 * 4,
-    3 + 0 * 4, 3 + 1 * 4, 3 + 2 * 4, 3 + 3 * 4,
-};
-
-static const uint8_t luma_dc_zigzag_scan[16] = {
-    0 * 16 + 0 * 64, 1 * 16 + 0 * 64, 2 * 16 + 0 * 64, 0 * 16 + 2 * 64,
-    3 * 16 + 0 * 64, 0 * 16 + 1 * 64, 1 * 16 + 1 * 64, 2 * 16 + 1 * 64,
-    1 * 16 + 2 * 64, 2 * 16 + 2 * 64, 3 * 16 + 2 * 64, 0 * 16 + 3 * 64,
-    3 * 16 + 1 * 64, 1 * 16 + 3 * 64, 2 * 16 + 3 * 64, 3 * 16 + 3 * 64,
-};
-
-static const uint8_t luma_dc_field_scan[16] = {
-    0 * 16 + 0 * 64, 2 * 16 + 0 * 64, 1 * 16 + 0 * 64, 0 * 16 + 2 * 64,
-    2 * 16 + 2 * 64, 3 * 16 + 0 * 64, 1 * 16 + 2 * 64, 3 * 16 + 2 * 64,
-    0 * 16 + 1 * 64, 2 * 16 + 1 * 64, 0 * 16 + 3 * 64, 2 * 16 + 3 * 64,
-    1 * 16 + 1 * 64, 3 * 16 + 1 * 64, 1 * 16 + 3 * 64, 3 * 16 + 3 * 64,
-};
-
 static const uint8_t chroma_dc_scan[4] = {
     (0 + 0 * 2) * 16, (1 + 0 * 2) * 16,
     (0 + 1 * 2) * 16, (1 + 1 * 2) * 16,
@@ -92,64 +71,6 @@
     (1 + 2 * 2) * 16, (1 + 3 * 2) * 16,
 };
 
-// zigzag_scan8x8_cavlc[i] = zigzag_scan8x8[(i/4) + 16*(i%4)]
-static const uint8_t zigzag_scan8x8_cavlc[64+1] = {
-    0 + 0 * 8, 1 + 1 * 8, 1 + 2 * 8, 2 + 2 * 8,
-    4 + 1 * 8, 0 + 5 * 8, 3 + 3 * 8, 7 + 0 * 8,
-    3 + 4 * 8, 1 + 7 * 8, 5 + 3 * 8, 6 + 3 * 8,
-    2 + 7 * 8, 6 + 4 * 8, 5 + 6 * 8, 7 + 5 * 8,
-    1 + 0 * 8, 2 + 0 * 8, 0 + 3 * 8, 3 + 1 * 8,
-    3 + 2 * 8, 0 + 6 * 8, 4 + 2 * 8, 6 + 1 * 8,
-    2 + 5 * 8, 2 + 6 * 8, 6 + 2 * 8, 5 + 4 * 8,
-    3 + 7 * 8, 7 + 3 * 8, 4 + 7 * 8, 7 + 6 * 8,
-    0 + 1 * 8, 3 + 0 * 8, 0 + 4 * 8, 4 + 0 * 8,
-    2 + 3 * 8, 1 + 5 * 8, 5 + 1 * 8, 5 + 2 * 8,
-    1 + 6 * 8, 3 + 5 * 8, 7 + 1 * 8, 4 + 5 * 8,
-    4 + 6 * 8, 7 + 4 * 8, 5 + 7 * 8, 6 + 7 * 8,
-    0 + 2 * 8, 2 + 1 * 8, 1 + 3 * 8, 5 + 0 * 8,
-    1 + 4 * 8, 2 + 4 * 8, 6 + 0 * 8, 4 + 3 * 8,
-    0 + 7 * 8, 4 + 4 * 8, 7 + 2 * 8, 3 + 6 * 8,
-    5 + 5 * 8, 6 + 5 * 8, 6 + 6 * 8, 7 + 7 * 8,
-};
-
-static const uint8_t field_scan8x8[64+1] = {
-    0 + 0 * 8, 0 + 1 * 8, 0 + 2 * 8, 1 + 0 * 8,
-    1 + 1 * 8, 0 + 3 * 8, 0 + 4 * 8, 1 + 2 * 8,
-    2 + 0 * 8, 1 + 3 * 8, 0 + 5 * 8, 0 + 6 * 8,
-    0 + 7 * 8, 1 + 4 * 8, 2 + 1 * 8, 3 + 0 * 8,
-    2 + 2 * 8, 1 + 5 * 8, 1 + 6 * 8, 1 + 7 * 8,
-    2 + 3 * 8, 3 + 1 * 8, 4 + 0 * 8, 3 + 2 * 8,
-    2 + 4 * 8, 2 + 5 * 8, 2 + 6 * 8, 2 + 7 * 8,
-    3 + 3 * 8, 4 + 1 * 8, 5 + 0 * 8, 4 + 2 * 8,
-    3 + 4 * 8, 3 + 5 * 8, 3 + 6 * 8, 3 + 7 * 8,
-    4 + 3 * 8, 5 + 1 * 8, 6 + 0 * 8, 5 + 2 * 8,
-    4 + 4 * 8, 4 + 5 * 8, 4 + 6 * 8, 4 + 7 * 8,
-    5 + 3 * 8, 6 + 1 * 8, 6 + 2 * 8, 5 + 4 * 8,
-    5 + 5 * 8, 5 + 6 * 8, 5 + 7 * 8, 6 + 3 * 8,
-    7 + 0 * 8, 7 + 1 * 8, 6 + 4 * 8, 6 + 5 * 8,
-    6 + 6 * 8, 6 + 7 * 8, 7 + 2 * 8, 7 + 3 * 8,
-    7 + 4 * 8, 7 + 5 * 8, 7 + 6 * 8, 7 + 7 * 8,
-};
-
-static const uint8_t field_scan8x8_cavlc[64+1] = {
-    0 + 0 * 8, 1 + 1 * 8, 2 + 0 * 8, 0 + 7 * 8,
-    2 + 2 * 8, 2 + 3 * 8, 2 + 4 * 8, 3 + 3 * 8,
-    3 + 4 * 8, 4 + 3 * 8, 4 + 4 * 8, 5 + 3 * 8,
-    5 + 5 * 8, 7 + 0 * 8, 6 + 6 * 8, 7 + 4 * 8,
-    0 + 1 * 8, 0 + 3 * 8, 1 + 3 * 8, 1 + 4 * 8,
-    1 + 5 * 8, 3 + 1 * 8, 2 + 5 * 8, 4 + 1 * 8,
-    3 + 5 * 8, 5 + 1 * 8, 4 + 5 * 8, 6 + 1 * 8,
-    5 + 6 * 8, 7 + 1 * 8, 6 + 7 * 8, 7 + 5 * 8,
-    0 + 2 * 8, 0 + 4 * 8, 0 + 5 * 8, 2 + 1 * 8,
-    1 + 6 * 8, 4 + 0 * 8, 2 + 6 * 8, 5 + 0 * 8,
-    3 + 6 * 8, 6 + 0 * 8, 4 + 6 * 8, 6 + 2 * 8,
-    5 + 7 * 8, 6 + 4 * 8, 7 + 2 * 8, 7 + 6 * 8,
-    1 + 0 * 8, 1 + 2 * 8, 0 + 6 * 8, 3 + 0 * 8,
-    1 + 7 * 8, 3 + 2 * 8, 2 + 7 * 8, 4 + 2 * 8,
-    3 + 7 * 8, 5 + 2 * 8, 4 + 7 * 8, 5 + 4 * 8,
-    6 + 3 * 8, 6 + 5 * 8, 7 + 3 * 8, 7 + 7 * 8,
-};
-
 typedef struct IMbInfo {
     uint16_t type;
     uint8_t pred_mode;
@@ -247,26 +168,4 @@
     { MB_TYPE_8x8   | MB_TYPE_P0L0 | MB_TYPE_P0L1 | MB_TYPE_P1L0 | MB_TYPE_P1L1, 4, },
 };
 
-static const uint8_t dequant4_coeff_init[6][3] = {
-    { 10, 13, 16 },
-    { 11, 14, 18 },
-    { 13, 16, 20 },
-    { 14, 18, 23 },
-    { 16, 20, 25 },
-    { 18, 23, 29 },
-};
-
-static const uint8_t dequant8_coeff_init_scan[16] = {
-    0, 3, 4, 3, 3, 1, 5, 1, 4, 5, 2, 5, 3, 1, 5, 1
-};
-
-static const uint8_t dequant8_coeff_init[6][6] = {
-    { 20, 18, 32, 19, 25, 24 },
-    { 22, 19, 35, 21, 28, 26 },
-    { 26, 23, 42, 24, 33, 31 },
-    { 28, 25, 45, 26, 35, 33 },
-    { 32, 28, 51, 30, 40, 38 },
-    { 36, 32, 58, 34, 46, 43 },
-};
-
 #endif /* AVCODEC_H264DATA_H */
diff --git a/libavcodec/h264dsp.c b/libavcodec/h264dsp.c
index da9e417..72f699f 100644
--- a/libavcodec/h264dsp.c
+++ b/libavcodec/h264dsp.c
@@ -26,7 +26,9 @@
  */
 
 #include <stdint.h>
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
+
 #include "avcodec.h"
 #include "h264dsp.h"
 #include "h264idct.h"
@@ -60,7 +62,36 @@
 #include "h264addpx_template.c"
 #undef BIT_DEPTH
 
-void ff_h264dsp_init(H264DSPContext *c, const int bit_depth, const int chroma_format_idc)
+static int h264_find_start_code_candidate_c(const uint8_t *buf, int size)
+{
+    int i = 0;
+#if HAVE_FAST_UNALIGNED
+    /* we check i < size instead of i + 3 / 7 because it is
+     * simpler and there must be FF_INPUT_BUFFER_PADDING_SIZE
+     * bytes at the end.
+     */
+#       if HAVE_FAST_64BIT
+    while (i < size &&
+            !((~*(const uint64_t *)(buf + i) &
+                    (*(const uint64_t *)(buf + i) - 0x0101010101010101ULL)) &
+                    0x8080808080808080ULL))
+        i += 8;
+#       else
+    while (i < size &&
+            !((~*(const uint32_t *)(buf + i) &
+                    (*(const uint32_t *)(buf + i) - 0x01010101U)) &
+                    0x80808080U))
+        i += 4;
+#       endif
+#endif
+    for (; i < size; i++)
+        if (!buf[i])
+            break;
+    return i;
+}
+
+av_cold void ff_h264dsp_init(H264DSPContext *c, const int bit_depth,
+                             const int chroma_format_idc)
 {
 #undef FUNC
 #define FUNC(a, depth) a ## _ ## depth ## _c
@@ -146,8 +177,9 @@
         H264_DSP(8);
         break;
     }
+    c->h264_find_start_code_candidate = h264_find_start_code_candidate_c;
 
     if (ARCH_ARM) ff_h264dsp_init_arm(c, bit_depth, chroma_format_idc);
-    if (HAVE_ALTIVEC) ff_h264dsp_init_ppc(c, bit_depth, chroma_format_idc);
+    if (ARCH_PPC) ff_h264dsp_init_ppc(c, bit_depth, chroma_format_idc);
     if (ARCH_X86) ff_h264dsp_init_x86(c, bit_depth, chroma_format_idc);
 }
diff --git a/libavcodec/h264dsp.h b/libavcodec/h264dsp.h
index 98ea15c..1be4804 100644
--- a/libavcodec/h264dsp.h
+++ b/libavcodec/h264dsp.h
@@ -105,6 +105,15 @@
     /* bypass-transform */
     void (*h264_add_pixels8_clear)(uint8_t *dst, int16_t *block, int stride);
     void (*h264_add_pixels4_clear)(uint8_t *dst, int16_t *block, int stride);
+
+    /**
+     * Search buf from the start for up to size bytes. Return the index
+     * of a zero byte, or >= size if not found. Ideally, use lookahead
+     * to filter out any zero bytes that are known to not be followed by
+     * one or more further zero bytes and a one byte. Better still, filter
+     * out any bytes that form the trailing_zero_8bits syntax element too.
+     */
+    int (*h264_find_start_code_candidate)(const uint8_t *buf, int size);
 } H264DSPContext;
 
 void ff_h264dsp_init(H264DSPContext *c, const int bit_depth,
diff --git a/libavcodec/h264pred.c b/libavcodec/h264pred.c
index ed4f287..3a96654 100644
--- a/libavcodec/h264pred.c
+++ b/libavcodec/h264pred.c
@@ -25,6 +25,7 @@
  * @author Michael Niedermayer <michaelni@gmx.at>
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "dsputil.h"
 #include "h264pred.h"
@@ -407,8 +408,9 @@
 /**
  * Set the intra prediction function pointers.
  */
-void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth,
-                       int chroma_format_idc)
+av_cold void ff_h264_pred_init(H264PredContext *h, int codec_id,
+                               const int bit_depth,
+                               int chroma_format_idc)
 {
 #undef FUNC
 #undef FUNCC
diff --git a/libavcodec/h264qpel.c b/libavcodec/h264qpel.c
index f46da8f..7c86d2a 100644
--- a/libavcodec/h264qpel.c
+++ b/libavcodec/h264qpel.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "h264qpel.h"
 
 #define pixeltmp int16_t
@@ -45,7 +46,7 @@
 #undef BIT_DEPTH
 
 
-void ff_h264qpel_init(H264QpelContext *c, int bit_depth)
+av_cold void ff_h264qpel_init(H264QpelContext *c, int bit_depth)
 {
 #undef FUNCC
 #define FUNCC(f, depth) f ## _ ## depth ## _c
diff --git a/libavcodec/huffman.c b/libavcodec/huffman.c
index 27fed9f..6e38829 100644
--- a/libavcodec/huffman.c
+++ b/libavcodec/huffman.c
@@ -122,7 +122,7 @@
 
     get_tree_codes(bits, lens, xlat, nodes, head, 0, 0,
                    &pos, no_zero_count);
-    return ff_init_vlc_sparse(vlc, 9, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0);
+    return ff_init_vlc_sparse(vlc, FF_HUFFMAN_BITS, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0);
 }
 
 
diff --git a/libavcodec/huffman.h b/libavcodec/huffman.h
index 4f9ccba..729c09e 100644
--- a/libavcodec/huffman.h
+++ b/libavcodec/huffman.h
@@ -37,6 +37,7 @@
 
 #define FF_HUFFMAN_FLAG_HNODE_FIRST 0x01
 #define FF_HUFFMAN_FLAG_ZERO_COUNT  0x02
+#define FF_HUFFMAN_BITS 10
 
 typedef int (*HuffCmp)(const void *va, const void *vb);
 int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes,
diff --git a/libavcodec/huffyuvenc.c b/libavcodec/huffyuvenc.c
index 95dcb88..5d3fe9a 100644
--- a/libavcodec/huffyuvenc.c
+++ b/libavcodec/huffyuvenc.c
@@ -56,14 +56,16 @@
 
 static inline void sub_left_prediction_bgr32(HYuvContext *s, uint8_t *dst,
                                              const uint8_t *src, int w,
-                                             int *red, int *green, int *blue, int *alpha)
+                                             int *red, int *green, int *blue,
+                                             int *alpha)
 {
     int i;
-    int r,g,b,a;
+    int r, g, b, a;
     r = *red;
     g = *green;
     b = *blue;
     a = *alpha;
+
     for (i = 0; i < FFMIN(w, 4); i++) {
         const int rt = src[i * 4 + R];
         const int gt = src[i * 4 + G];
@@ -87,29 +89,32 @@
     *alpha = src[(w - 1) * 4 + A];
 }
 
-static inline void sub_left_prediction_rgb24(HYuvContext *s, uint8_t *dst, const uint8_t *src, int w, int *red, int *green, int *blue){
+static inline void sub_left_prediction_rgb24(HYuvContext *s, uint8_t *dst,
+                                             uint8_t *src, int w,
+                                             int *red, int *green, int *blue)
+{
     int i;
-    int r,g,b;
+    int r, g, b;
     r = *red;
     g = *green;
     b = *blue;
-    for (i = 0; i < FFMIN(w,16); i++) {
-        const int rt = src[i*3 + 0];
-        const int gt = src[i*3 + 1];
-        const int bt = src[i*3 + 2];
-        dst[i*3 + 0] = rt - r;
-        dst[i*3 + 1] = gt - g;
-        dst[i*3 + 2] = bt - b;
+    for (i = 0; i < FFMIN(w, 16); i++) {
+        const int rt = src[i * 3 + 0];
+        const int gt = src[i * 3 + 1];
+        const int bt = src[i * 3 + 2];
+        dst[i * 3 + 0] = rt - r;
+        dst[i * 3 + 1] = gt - g;
+        dst[i * 3 + 2] = bt - b;
         r = rt;
         g = gt;
         b = bt;
     }
 
-    s->dsp.diff_bytes(dst + 48, src + 48, src + 48 - 3, w*3 - 48);
+    s->dsp.diff_bytes(dst + 48, src + 48, src + 48 - 3, w * 3 - 48);
 
-    *red   = src[(w - 1)*3 + 0];
-    *green = src[(w - 1)*3 + 1];
-    *blue  = src[(w - 1)*3 + 2];
+    *red   = src[(w - 1) * 3 + 0];
+    *green = src[(w - 1) * 3 + 1];
+    *blue  = src[(w - 1) * 3 + 2];
 }
 
 static int store_table(HYuvContext *s, const uint8_t *len, uint8_t *buf)
@@ -157,7 +162,7 @@
     case AV_PIX_FMT_YUV420P:
     case AV_PIX_FMT_YUV422P:
         if (s->width & 1) {
-            av_log(avctx, AV_LOG_ERROR, "width must be even for this colorspace\n");
+            av_log(avctx, AV_LOG_ERROR, "Width must be even for this colorspace.\n");
             return AVERROR(EINVAL);
         }
         s->bitstream_bpp = avctx->pix_fmt == AV_PIX_FMT_YUV420P ? 12 : 16;
@@ -384,43 +389,48 @@
 {
     int i;
 
-    if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 4*planes*count) {
+    if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb) >> 3) <
+        4 * planes * count) {
         av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
         return -1;
     }
 
-#define LOAD3\
-            int g =  s->temp[0][planes==3 ? 3*i + 1 : 4*i + G];\
-            int b = (s->temp[0][planes==3 ? 3*i + 2 : 4*i + B] - g) & 0xff;\
-            int r = (s->temp[0][planes==3 ? 3*i + 0 : 4*i + R] - g) & 0xff;\
-            int a =  s->temp[0][planes*i + A];
-#define STAT3\
-            s->stats[0][b]++;\
-            s->stats[1][g]++;\
-            s->stats[2][r]++;\
-            if(planes==4) s->stats[2][a]++;
-#define WRITE3\
-            put_bits(&s->pb, s->len[1][g], s->bits[1][g]);\
-            put_bits(&s->pb, s->len[0][b], s->bits[0][b]);\
-            put_bits(&s->pb, s->len[2][r], s->bits[2][r]);\
-            if(planes==4) put_bits(&s->pb, s->len[2][a], s->bits[2][a]);
+#define LOAD_GBRA                                                       \
+    int g = s->temp[0][planes == 3 ? 3 * i + 1 : 4 * i + G];            \
+    int b =(s->temp[0][planes == 3 ? 3 * i + 2 : 4 * i + B] - g) & 0xFF;\
+    int r =(s->temp[0][planes == 3 ? 3 * i + 0 : 4 * i + R] - g) & 0xFF;\
+    int a = s->temp[0][planes * i + A];
+
+#define STAT_BGRA                                                       \
+    s->stats[0][b]++;                                                   \
+    s->stats[1][g]++;                                                   \
+    s->stats[2][r]++;                                                   \
+    if (planes == 4)                                                    \
+        s->stats[2][a]++;
+
+#define WRITE_GBRA                                                      \
+    put_bits(&s->pb, s->len[1][g], s->bits[1][g]);                      \
+    put_bits(&s->pb, s->len[0][b], s->bits[0][b]);                      \
+    put_bits(&s->pb, s->len[2][r], s->bits[2][r]);                      \
+    if (planes == 4)                                                    \
+        put_bits(&s->pb, s->len[2][a], s->bits[2][a]);
 
     if ((s->flags & CODEC_FLAG_PASS1) &&
         (s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)) {
         for (i = 0; i < count; i++) {
-            LOAD3;
-            STAT3;
+            LOAD_GBRA;
+            STAT_BGRA;
         }
     } else if (s->context || (s->flags & CODEC_FLAG_PASS1)) {
         for (i = 0; i < count; i++) {
-            LOAD3;
-            STAT3;
-            WRITE3;
+            LOAD_GBRA;
+            STAT_BGRA;
+            WRITE_GBRA;
         }
     } else {
         for (i = 0; i < count; i++) {
-            LOAD3;
-            WRITE3;
+            LOAD_GBRA;
+            WRITE_GBRA;
         }
     }
     return 0;
@@ -578,41 +588,48 @@
         put_bits(&s->pb, 8, leftg = data[G]);
         put_bits(&s->pb, 8, leftb = data[B]);
 
-        sub_left_prediction_bgr32(s, s->temp[0], data + 4, width - 1, &leftr, &leftg, &leftb, &lefta);
+        sub_left_prediction_bgr32(s, s->temp[0], data + 4, width - 1,
+                                  &leftr, &leftg, &leftb, &lefta);
         encode_bgra_bitstream(s, width - 1, 4);
 
         for (y = 1; y < s->height; y++) {
             uint8_t *dst = data + y*stride;
             if (s->predictor == PLANE && s->interlaced < y) {
                 s->dsp.diff_bytes(s->temp[1], dst, dst - fake_stride, width * 4);
-                sub_left_prediction_bgr32(s, s->temp[0], s->temp[1], width, &leftr, &leftg, &leftb, &lefta);
+                sub_left_prediction_bgr32(s, s->temp[0], s->temp[1], width,
+                                          &leftr, &leftg, &leftb, &lefta);
             } else {
-                sub_left_prediction_bgr32(s, s->temp[0], dst, width, &leftr, &leftg, &leftb, &lefta);
+                sub_left_prediction_bgr32(s, s->temp[0], dst, width,
+                                          &leftr, &leftg, &leftb, &lefta);
             }
             encode_bgra_bitstream(s, width, 4);
         }
-    }else if(avctx->pix_fmt == AV_PIX_FMT_RGB24){
-        uint8_t *data = p->data[0] + (height-1)*p->linesize[0];
+    } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) {
+        uint8_t *data = p->data[0] + (height - 1) * p->linesize[0];
         const int stride = -p->linesize[0];
         const int fake_stride = -fake_ystride;
         int y;
         int leftr, leftg, leftb;
 
-        put_bits(&s->pb, 8, leftr= data[0]);
-        put_bits(&s->pb, 8, leftg= data[1]);
-        put_bits(&s->pb, 8, leftb= data[2]);
+        put_bits(&s->pb, 8, leftr = data[0]);
+        put_bits(&s->pb, 8, leftg = data[1]);
+        put_bits(&s->pb, 8, leftb = data[2]);
         put_bits(&s->pb, 8, 0);
 
-        sub_left_prediction_rgb24(s, s->temp[0], data+3, width-1, &leftr, &leftg, &leftb);
+        sub_left_prediction_rgb24(s, s->temp[0], data + 3, width - 1,
+                                  &leftr, &leftg, &leftb);
         encode_bgra_bitstream(s, width-1, 3);
 
-        for(y=1; y<s->height; y++){
-            uint8_t *dst = data + y*stride;
-            if(s->predictor == PLANE && s->interlaced < y){
-                s->dsp.diff_bytes(s->temp[1], dst, dst - fake_stride, width*3);
-                sub_left_prediction_rgb24(s, s->temp[0], s->temp[1], width, &leftr, &leftg, &leftb);
-            }else{
-                sub_left_prediction_rgb24(s, s->temp[0], dst, width, &leftr, &leftg, &leftb);
+        for (y = 1; y < s->height; y++) {
+            uint8_t *dst = data + y * stride;
+            if (s->predictor == PLANE && s->interlaced < y) {
+                s->dsp.diff_bytes(s->temp[1], dst, dst - fake_stride,
+                                  width * 3);
+                sub_left_prediction_rgb24(s, s->temp[0], s->temp[1], width,
+                                          &leftr, &leftg, &leftb);
+            } else {
+                sub_left_prediction_rgb24(s, s->temp[0], dst, width,
+                                          &leftr, &leftg, &leftb);
             }
             encode_bgra_bitstream(s, width, 3);
         }
@@ -677,7 +694,8 @@
     .encode2        = encode_frame,
     .close          = encode_end,
     .pix_fmts       = (const enum AVPixelFormat[]){
-        AV_PIX_FMT_YUV422P, AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE
+        AV_PIX_FMT_YUV422P, AV_PIX_FMT_RGB24,
+        AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE
     },
     .long_name      = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
 };
@@ -693,7 +711,8 @@
     .encode2        = encode_frame,
     .close          = encode_end,
     .pix_fmts       = (const enum AVPixelFormat[]){
-        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE
+        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_RGB24,
+        AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE
     },
     .long_name      = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
 };
diff --git a/libavcodec/iff.c b/libavcodec/iff.c
index 716a731..ab2f172 100644
--- a/libavcodec/iff.c
+++ b/libavcodec/iff.c
@@ -155,9 +155,8 @@
     // If extradata is smaller than actually needed, fill the remaining with black.
     count = FFMIN(palette_size / 3, count);
     if (count) {
-        for (i=0; i < count; i++) {
+        for (i = 0; i < count; i++)
             pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
-        }
         if (s->flags && count >= 32) { // EHB
             for (i = 0; i < 32; i++)
                 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
@@ -166,9 +165,8 @@
     } else { // Create gray-scale color palette for bps < 8
         count = 1 << avctx->bits_per_coded_sample;
 
-        for (i=0; i < count; i++) {
+        for (i = 0; i < count; i++)
             pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
-        }
     }
     if (s->masking == MASK_HAS_MASK) {
         memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
@@ -335,11 +333,11 @@
         avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
                          (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
     } else if (avctx->bits_per_coded_sample <= 32) {
-        if (avctx->codec_tag == MKTAG('R','G','B','8')) {
+        if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
             avctx->pix_fmt = AV_PIX_FMT_RGB32;
-        } else if (avctx->codec_tag == MKTAG('R','G','B','N')) {
+        } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
             avctx->pix_fmt = AV_PIX_FMT_RGB444;
-        } else if (avctx->codec_tag != MKTAG('D','E','E','P')) {
+        } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
             if (avctx->bits_per_coded_sample == 24) {
                 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
             } else if (avctx->bits_per_coded_sample == 32) {
@@ -356,7 +354,7 @@
     if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
         return err;
     s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
-    s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
+    s->planebuf  = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
     if (!s->planebuf)
         return AVERROR(ENOMEM);
 
@@ -408,12 +406,12 @@
         dst[1] |= lut[mask++];
         dst[2] |= lut[mask++];
         dst[3] |= lut[mask];
-        mask = (*buf++ << 2) & 0x3F;
+        mask    = (*buf++ << 2) & 0x3F;
         dst[4] |= lut[mask++];
         dst[5] |= lut[mask++];
         dst[6] |= lut[mask++];
         dst[7] |= lut[mask];
-        dst += 8;
+        dst    += 8;
     } while (--buf_size);
 }
 
@@ -466,9 +464,10 @@
  * @param buf the source byterun1 compressed bitstream
  * @param buf_end the EOF of source byterun1 compressed bitstream
  * @return number of consumed bytes in byterun1 compressed bitstream
-*/
+ */
 static int decode_byterun(uint8_t *dst, int dst_size,
-                          const uint8_t *buf, const uint8_t *const buf_end) {
+                          const uint8_t *buf, const uint8_t *const buf_end)
+{
     const uint8_t *const buf_start = buf;
     unsigned x;
     for (x = 0; x < dst_size && buf < buf_end;) {
@@ -651,13 +650,13 @@
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                            void *data, int *got_frame,
-                            AVPacket *avpkt)
+                        void *data, int *got_frame,
+                        AVPacket *avpkt)
 {
-    IffContext *s = avctx->priv_data;
-    const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
-    const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
-    const uint8_t *buf_end = buf+buf_size;
+    IffContext *s          = avctx->priv_data;
+    const uint8_t *buf     = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
+    const int buf_size     = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
+    const uint8_t *buf_end = buf + buf_size;
     int y, plane, res;
     GetByteContext gb;
 
@@ -667,7 +666,7 @@
         return res;
     if (!s->init && avctx->bits_per_coded_sample <= 8 &&
         avctx->pix_fmt == AV_PIX_FMT_PAL8) {
-        if ((res = cmap_read_palette(avctx, (uint32_t*)s->frame->data[1])) < 0)
+        if ((res = cmap_read_palette(avctx, (uint32_t *)s->frame->data[1])) < 0)
             return res;
     } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
                avctx->pix_fmt == AV_PIX_FMT_RGB32) {
@@ -678,19 +677,19 @@
 
     switch (s->compression) {
     case 0:
-        if (avctx->codec_tag == MKTAG('A','C','B','M')) {
+        if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
                 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
                 for (plane = 0; plane < s->bpp; plane++) {
-                    for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
-                        uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
+                    for (y = 0; y < avctx->height && buf < buf_end; y++) {
+                        uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
                         buf += s->planesize;
                     }
                 }
             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
                 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
-                for(y = 0; y < avctx->height; y++) {
+                for (y = 0; y < avctx->height; y++) {
                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                     memset(s->ham_buf, 0, s->planesize * 8);
                     for (plane = 0; plane < s->bpp; plane++) {
@@ -699,27 +698,27 @@
                             break;
                         decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
                     }
-                    decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
+                    decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
                 }
             } else
                 return unsupported(avctx);
-        } else if (avctx->codec_tag == MKTAG('D','E','E','P')) {
+        } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
             int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
             int x;
-            for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
+            for (y = 0; y < avctx->height && buf < buf_end; y++) {
                 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
                 buf += raw_width;
                 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
-                    for(x = 0; x < avctx->width; x++)
+                    for (x = 0; x < avctx->width; x++)
                         row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
                 }
             }
-        } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
+        } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
-                for(y = 0; y < avctx->height; y++ ) {
-                    uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
+                for (y = 0; y < avctx->height; y++) {
+                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                     memset(row, 0, avctx->width);
                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
@@ -728,47 +727,48 @@
                 }
             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
                 for (y = 0; y < avctx->height; y++) {
-                    uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
+                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                     memset(s->ham_buf, 0, s->planesize * 8);
                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
                         decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
                         buf += s->planesize;
                     }
-                    decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
+                    decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
                 }
             } else { // AV_PIX_FMT_BGR32
-                for(y = 0; y < avctx->height; y++ ) {
-                    uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
+                for (y = 0; y < avctx->height; y++) {
+                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                     memset(row, 0, avctx->width << 2);
                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
-                        decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
+                        decodeplane32((uint32_t *)row, buf,
+                                      FFMIN(s->planesize, buf_end - buf), plane);
                         buf += s->planesize;
                     }
                 }
             }
-        } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
+        } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
-                for(y = 0; y < avctx->height && buf_end > buf; y++ ) {
+                for (y = 0; y < avctx->height && buf_end > buf; y++) {
                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                     memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
                     buf += avctx->width + (avctx->width % 2); // padding if odd
                 }
             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
-                    uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
+                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                     memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
                     buf += avctx->width + (avctx->width & 1); // padding if odd
-                    decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
+                    decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
                 }
             } else
                 return unsupported(avctx);
         }
         break;
     case 1:
-        if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
+        if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
-                for(y = 0; y < avctx->height ; y++ ) {
-                    uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
+                for (y = 0; y < avctx->height; y++) {
+                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                     memset(row, 0, avctx->width);
                     for (plane = 0; plane < s->bpp; plane++) {
                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
@@ -776,50 +776,50 @@
                     }
                 }
             } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
-                for (y = 0; y < avctx->height ; y++ ) {
-                    uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
+                for (y = 0; y < avctx->height; y++) {
+                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                     memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
                     for (plane = 0; plane < s->bpp; plane++) {
                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
                         decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
                     }
-                    lookup_pal_indicies((uint32_t *) row, s->mask_buf, s->mask_palbuf, avctx->width);
+                    lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
                 }
             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
-                for (y = 0; y < avctx->height ; y++) {
-                    uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
+                for (y = 0; y < avctx->height; y++) {
+                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                     memset(s->ham_buf, 0, s->planesize * 8);
                     for (plane = 0; plane < s->bpp; plane++) {
                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
                         decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
                     }
-                    decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
+                    decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
                 }
-            } else { //AV_PIX_FMT_BGR32
-                for(y = 0; y < avctx->height ; y++ ) {
-                    uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
+            } else { // AV_PIX_FMT_BGR32
+                for (y = 0; y < avctx->height; y++) {
+                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                     memset(row, 0, avctx->width << 2);
                     for (plane = 0; plane < s->bpp; plane++) {
                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
-                        decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
+                        decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
                     }
                 }
             }
-        } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
+        } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
-                for(y = 0; y < avctx->height ; y++ ) {
-                    uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
+                for (y = 0; y < avctx->height; y++) {
+                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                     buf += decode_byterun(row, avctx->width, buf, buf_end);
                 }
             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
-                for (y = 0; y < avctx->height ; y++) {
-                    uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
+                for (y = 0; y < avctx->height; y++) {
+                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                     buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
-                    decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
+                    decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
                 }
             } else
                 return unsupported(avctx);
-        } else if (avctx->codec_tag == MKTAG('D','E','E','P')) { // IFF-DEEP
+        } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
             if (av_get_bits_per_pixel(desc) == 32)
                 decode_deep_rle32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0]);
@@ -829,15 +829,15 @@
         break;
     case 4:
         bytestream2_init(&gb, buf, buf_size);
-        if (avctx->codec_tag == MKTAG('R','G','B','8'))
+        if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8'))
             decode_rgb8(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
-        else if (avctx->codec_tag == MKTAG('R','G','B','N'))
+        else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N'))
             decode_rgbn(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
         else
             return unsupported(avctx);
         break;
     case 5:
-        if (avctx->codec_tag == MKTAG('D','E','E','P')) {
+        if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
             if (av_get_bits_per_pixel(desc) == 32)
                 decode_deep_tvdc32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0], s->tvdc);
diff --git a/libavcodec/iirfilter.c b/libavcodec/iirfilter.c
index 049150e..a2d9d11 100644
--- a/libavcodec/iirfilter.c
+++ b/libavcodec/iirfilter.c
@@ -26,6 +26,7 @@
 
 #include "iirfilter.h"
 #include <math.h>
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
 
 /**
@@ -48,10 +49,11 @@
 /// maximum supported filter order
 #define MAXORDER 30
 
-static int butterworth_init_coeffs(void *avc, struct FFIIRFilterCoeffs *c,
-                                   enum IIRFilterMode filt_mode,
-                                   int order, float cutoff_ratio,
-                                   float stopband)
+static av_cold int butterworth_init_coeffs(void *avc,
+                                           struct FFIIRFilterCoeffs *c,
+                                           enum IIRFilterMode filt_mode,
+                                           int order, float cutoff_ratio,
+                                           float stopband)
 {
     int i, j;
     double wa;
@@ -113,9 +115,9 @@
     return 0;
 }
 
-static int biquad_init_coeffs(void *avc, struct FFIIRFilterCoeffs *c,
-                              enum IIRFilterMode filt_mode, int order,
-                              float cutoff_ratio, float stopband)
+static av_cold int biquad_init_coeffs(void *avc, struct FFIIRFilterCoeffs *c,
+                                      enum IIRFilterMode filt_mode, int order,
+                                      float cutoff_ratio, float stopband)
 {
     double cos_w0, sin_w0;
     double a0, x0, x1;
diff --git a/libavcodec/imc.c b/libavcodec/imc.c
index eb7c255..deec0a1 100644
--- a/libavcodec/imc.c
+++ b/libavcodec/imc.c
@@ -450,6 +450,10 @@
         iacc  += chctx->bandWidthT[i];
         summa += chctx->bandWidthT[i] * chctx->flcoeffs4[i];
     }
+
+    if (!iacc)
+        return AVERROR_INVALIDDATA;
+
     chctx->bandWidthT[BANDS - 1] = 0;
     summa = (summa * 0.5 - freebits) / iacc;
 
diff --git a/libavcodec/imgconvert.c b/libavcodec/imgconvert.c
index 616cf78..1835e00 100644
--- a/libavcodec/imgconvert.c
+++ b/libavcodec/imgconvert.c
@@ -41,7 +41,7 @@
 #include "libavutil/imgutils.h"
 
 #if HAVE_MMX_EXTERNAL
-#include "x86/dsputil_mmx.h"
+#include "x86/dsputil_x86.h"
 #endif
 
 #define FF_COLOR_NA      -1
@@ -59,7 +59,7 @@
 #endif
 
 #define pixdesc_has_alpha(pixdesc) \
-    ((pixdesc)->nb_components == 2 || (pixdesc)->nb_components == 4 || (pixdesc)->flags & PIX_FMT_PAL)
+    ((pixdesc)->nb_components == 2 || (pixdesc)->nb_components == 4 || (pixdesc)->flags & AV_PIX_FMT_FLAG_PAL)
 
 
 void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
@@ -77,7 +77,7 @@
     if(desc->name && !strncmp(desc->name, "yuvj", 4))
         return FF_COLOR_YUV_JPEG;
 
-    if(desc->flags & PIX_FMT_RGB)
+    if(desc->flags & AV_PIX_FMT_FLAG_RGB)
         return  FF_COLOR_RGB;
 
     if(desc->nb_components == 0)
@@ -113,7 +113,7 @@
     int src_color, dst_color;
     int src_min_depth, src_max_depth, dst_min_depth, dst_max_depth;
     int ret, loss, i, nb_components;
-    int score = INT_MAX;
+    int score = INT_MAX - 1;
 
     if (dst_pix_fmt >= AV_PIX_FMT_NB || dst_pix_fmt <= AV_PIX_FMT_NONE)
         return ~0;
@@ -148,7 +148,7 @@
             loss |= FF_LOSS_RESOLUTION;
             score -= 256 << dst_desc->log2_chroma_h;
         }
-        // dont favor 422 over 420 if downsampling is needed, because 420 has much better support on the decoder side
+        // don't favor 422 over 420 if downsampling is needed, because 420 has much better support on the decoder side
         if (dst_desc->log2_chroma_w == 1 && src_desc->log2_chroma_w == 0 &&
             dst_desc->log2_chroma_h == 1 && src_desc->log2_chroma_h == 0 ) {
             score += 512;
@@ -247,7 +247,7 @@
     return dst_pix_fmt;
 }
 
-#if AV_HAVE_INCOMPATIBLE_FORK_ABI
+#if AV_HAVE_INCOMPATIBLE_LIBAV_ABI
 enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat *pix_fmt_list,
                                             enum AVPixelFormat src_pix_fmt,
                                             int has_alpha, int *loss_ptr){
@@ -366,8 +366,8 @@
     int i;
     int planes[4] = { 0 };
 
-    if (     desc->flags & PIX_FMT_RGB
-        || !(desc->flags & PIX_FMT_PLANAR))
+    if (     desc->flags & AV_PIX_FMT_FLAG_RGB
+        || !(desc->flags & AV_PIX_FMT_FLAG_PLANAR))
         return 0;
 
     /* set the used planes */
@@ -644,7 +644,7 @@
     int skip = 0;
 
     for (i=0; i<AV_PIX_FMT_NB*2; i++) {
-        AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(i);
+        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(i);
         if(!desc || !desc->name) {
             skip ++;
             continue;
@@ -654,7 +654,7 @@
             skip = 0;
         }
         av_log(NULL, AV_LOG_INFO, "pix fmt %s yuv_plan:%d avg_bpp:%d colortype:%d\n", desc->name, is_yuv_planar(desc), av_get_padded_bits_per_pixel(desc), get_color_type(desc));
-        if ((!(desc->flags & PIX_FMT_ALPHA)) != (desc->nb_components != 2 && desc->nb_components != 4)) {
+        if ((!(desc->flags & AV_PIX_FMT_FLAG_ALPHA)) != (desc->nb_components != 2 && desc->nb_components != 4)) {
             av_log(NULL, AV_LOG_ERROR, "Alpha flag mismatch\n");
             err = 1;
         }
diff --git a/libavcodec/indeo2.c b/libavcodec/indeo2.c
index f8e7415..79b844e 100644
--- a/libavcodec/indeo2.c
+++ b/libavcodec/indeo2.c
@@ -34,7 +34,7 @@
 
 typedef struct Ir2Context{
     AVCodecContext *avctx;
-    AVFrame picture;
+    AVFrame *picture;
     GetBitContext gb;
     int decode_delta;
 } Ir2Context;
@@ -146,7 +146,7 @@
     const uint8_t *buf   = avpkt->data;
     int buf_size         = avpkt->size;
     AVFrame *picture     = data;
-    AVFrame * const p    = &s->picture;
+    AVFrame * const p    = s->picture;
     int start, ret;
 
     if ((ret = ff_reget_buffer(avctx, p)) < 0)
@@ -171,36 +171,36 @@
 
     if (s->decode_delta) { /* intraframe */
         if ((ret = ir2_decode_plane(s, avctx->width, avctx->height,
-                                    s->picture.data[0], s->picture.linesize[0],
+                                    s->picture->data[0], s->picture->linesize[0],
                                     ir2_luma_table)) < 0)
             return ret;
 
         /* swapped U and V */
         if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
-                                    s->picture.data[2], s->picture.linesize[2],
+                                    s->picture->data[2], s->picture->linesize[2],
                                     ir2_luma_table)) < 0)
             return ret;
         if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
-                                    s->picture.data[1], s->picture.linesize[1],
+                                    s->picture->data[1], s->picture->linesize[1],
                                     ir2_luma_table)) < 0)
             return ret;
     } else { /* interframe */
         if ((ret = ir2_decode_plane_inter(s, avctx->width, avctx->height,
-                                          s->picture.data[0], s->picture.linesize[0],
+                                          s->picture->data[0], s->picture->linesize[0],
                                           ir2_luma_table)) < 0)
             return ret;
         /* swapped U and V */
         if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
-                                          s->picture.data[2], s->picture.linesize[2],
+                                          s->picture->data[2], s->picture->linesize[2],
                                           ir2_luma_table)) < 0)
             return ret;
         if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
-                                          s->picture.data[1], s->picture.linesize[1],
+                                          s->picture->data[1], s->picture->linesize[1],
                                           ir2_luma_table)) < 0)
             return ret;
     }
 
-    if ((ret = av_frame_ref(picture, &s->picture)) < 0)
+    if ((ret = av_frame_ref(picture, s->picture)) < 0)
         return ret;
 
     *got_frame = 1;
@@ -213,12 +213,13 @@
     Ir2Context * const ic = avctx->priv_data;
     static VLC_TYPE vlc_tables[1 << CODE_VLC_BITS][2];
 
-    avcodec_get_frame_defaults(&ic->picture);
     ic->avctx = avctx;
 
     avctx->pix_fmt= AV_PIX_FMT_YUV410P;
 
-    avcodec_get_frame_defaults(&ic->picture);
+    ic->picture = av_frame_alloc();
+    if (!ic->picture)
+        return AVERROR(ENOMEM);
 
     ir2_vlc.table = vlc_tables;
     ir2_vlc.table_allocated = 1 << CODE_VLC_BITS;
@@ -238,9 +239,8 @@
 static av_cold int ir2_decode_end(AVCodecContext *avctx)
 {
     Ir2Context * const ic = avctx->priv_data;
-    AVFrame *pic = &ic->picture;
 
-    av_frame_unref(pic);
+    av_frame_free(&ic->picture);
 
     return 0;
 }
diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c
index 1ad1e4b..7959f91 100644
--- a/libavcodec/indeo3.c
+++ b/libavcodec/indeo3.c
@@ -148,6 +148,20 @@
 }
 
 
+static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx)
+{
+    int p;
+
+    ctx->width = ctx->height = 0;
+
+    for (p = 0; p < 3; p++) {
+        av_freep(&ctx->planes[p].buffers[0]);
+        av_freep(&ctx->planes[p].buffers[1]);
+        ctx->planes[p].pixels[0] = ctx->planes[p].pixels[1] = 0;
+    }
+}
+
+
 static av_cold int allocate_frame_buffers(Indeo3DecodeContext *ctx,
                                           AVCodecContext *avctx, int luma_width, int luma_height)
 {
@@ -188,6 +202,11 @@
         ctx->planes[p].buffers[0] = av_malloc(!p ? luma_size : chroma_size);
         ctx->planes[p].buffers[1] = av_malloc(!p ? luma_size : chroma_size);
 
+        if (!ctx->planes[p].buffers[0] || !ctx->planes[p].buffers[1]) {
+            free_frame_buffers(ctx);
+            return AVERROR(ENOMEM);
+        }
+
         /* fill the INTRA prediction lines with the middle pixel value = 64 */
         memset(ctx->planes[p].buffers[0], 0x40, ctx->planes[p].pitch);
         memset(ctx->planes[p].buffers[1], 0x40, ctx->planes[p].pitch);
@@ -202,22 +221,6 @@
     return 0;
 }
 
-
-static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx)
-{
-    int p;
-
-    ctx->width=
-    ctx->height= 0;
-
-    for (p = 0; p < 3; p++) {
-        av_freep(&ctx->planes[p].buffers[0]);
-        av_freep(&ctx->planes[p].buffers[1]);
-        ctx->planes[p].pixels[0] = ctx->planes[p].pixels[1] = 0;
-    }
-}
-
-
 /**
  *  Copy pixels of the cell(x + mv_x, y + mv_y) from the previous frame into
  *  the cell(x, y) in the current frame.
@@ -242,8 +245,8 @@
 
     /* -1 because there is an extra line on top for prediction */
     if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 ||
-        ((cell->ypos + cell->height) << 2) + mv_y >= plane->height    ||
-        ((cell->xpos + cell->width)  << 2) + mv_x >= plane->width) {
+        ((cell->ypos + cell->height) << 2) + mv_y > plane->height     ||
+        ((cell->xpos + cell->width)  << 2) + mv_x > plane->width) {
         av_log(ctx->avctx, AV_LOG_ERROR,
                "Motion vectors point out of the frame.\n");
         return AVERROR_INVALIDDATA;
@@ -258,19 +261,17 @@
         /* copy using 16xH blocks */
         if (!((cell->xpos << 2) & 15) && w >= 4) {
             for (; w >= 4; src += 16, dst += 16, w -= 4)
-                ctx->hdsp.put_no_rnd_pixels_tab[0][0](dst, src, plane->pitch, h);
+                ctx->hdsp.put_pixels_tab[0][0](dst, src, plane->pitch, h);
         }
 
         /* copy using 8xH blocks */
         if (!((cell->xpos << 2) & 7) && w >= 2) {
-            ctx->hdsp.put_no_rnd_pixels_tab[1][0](dst, src, plane->pitch, h);
+            ctx->hdsp.put_pixels_tab[1][0](dst, src, plane->pitch, h);
             w -= 2;
             src += 8;
             dst += 8;
-        }
-
-        if (w >= 1) {
-            copy_block4(dst, src, plane->pitch, plane->pitch, h);
+        } else if (w >= 1) {
+            ctx->hdsp.put_pixels_tab[2][0](dst, src, plane->pitch, h);
             w--;
             src += 4;
             dst += 4;
@@ -283,10 +284,10 @@
 
 /* Average 4/8 pixels at once without rounding using SWAR */
 #define AVG_32(dst, src, ref) \
-    AV_WN32A(dst, ((AV_RN32A(src) + AV_RN32A(ref)) >> 1) & 0x7F7F7F7FUL)
+    AV_WN32A(dst, ((AV_RN32(src) + AV_RN32(ref)) >> 1) & 0x7F7F7F7FUL)
 
 #define AVG_64(dst, src, ref) \
-    AV_WN64A(dst, ((AV_RN64A(src) + AV_RN64A(ref)) >> 1) & 0x7F7F7F7F7F7F7F7FULL)
+    AV_WN64A(dst, ((AV_RN64(src) + AV_RN64(ref)) >> 1) & 0x7F7F7F7F7F7F7F7FULL)
 
 
 /*
@@ -345,7 +346,7 @@
         copy_block4(dst, ref, row_offset, row_offset, 4 << v_zoom)
 
 #define RLE_BLOCK_COPY_8 \
-    pix64 = AV_RN64A(ref);\
+    pix64 = AV_RN64(ref);\
     if (is_first_row) {/* special prediction case: top line of a cell */\
         pix64 = replicate64(pix64);\
         fill_64(dst + row_offset, pix64, 7, row_offset);\
@@ -357,7 +358,7 @@
     copy_block4(dst, ref, row_offset, row_offset, num_lines << v_zoom)
 
 #define RLE_LINES_COPY_M10 \
-    pix64 = AV_RN64A(ref);\
+    pix64 = AV_RN64(ref);\
     if (is_top_of_cell) {\
         pix64 = replicate64(pix64);\
         fill_64(dst + row_offset, pix64, (num_lines << 1) - 1, row_offset);\
@@ -367,12 +368,12 @@
 
 #define APPLY_DELTA_4 \
     AV_WN16A(dst + line_offset    ,\
-             (AV_RN16A(ref    ) + delta_tab->deltas[dyad1]) & 0x7F7F);\
+             (AV_RN16(ref    ) + delta_tab->deltas[dyad1]) & 0x7F7F);\
     AV_WN16A(dst + line_offset + 2,\
-             (AV_RN16A(ref + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\
+             (AV_RN16(ref + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\
     if (mode >= 3) {\
         if (is_top_of_cell && !cell->ypos) {\
-            AV_COPY32(dst, dst + row_offset);\
+            AV_COPY32U(dst, dst + row_offset);\
         } else {\
             AVG_32(dst, ref, dst + row_offset);\
         }\
@@ -382,20 +383,20 @@
     /* apply two 32-bit VQ deltas to next even line */\
     if (is_top_of_cell) { \
         AV_WN32A(dst + row_offset    , \
-                 (replicate32(AV_RN32A(ref    )) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
+                 (replicate32(AV_RN32(ref    )) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
         AV_WN32A(dst + row_offset + 4, \
-                 (replicate32(AV_RN32A(ref + 4)) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
+                 (replicate32(AV_RN32(ref + 4)) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
     } else { \
         AV_WN32A(dst + row_offset    , \
-                 (AV_RN32A(ref    ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
+                 (AV_RN32(ref    ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
         AV_WN32A(dst + row_offset + 4, \
-                 (AV_RN32A(ref + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
+                 (AV_RN32(ref + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
     } \
     /* odd lines are not coded but rather interpolated/replicated */\
     /* first line of the cell on the top of image? - replicate */\
     /* otherwise - interpolate */\
     if (is_top_of_cell && !cell->ypos) {\
-        AV_COPY64(dst, dst + row_offset);\
+        AV_COPY64U(dst, dst + row_offset);\
     } else \
         AVG_64(dst, ref, dst + row_offset);
 
@@ -403,22 +404,22 @@
 #define APPLY_DELTA_1011_INTER \
     if (mode == 10) { \
         AV_WN32A(dst                 , \
-                 (AV_RN32A(dst                 ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
+                 (AV_RN32(dst                 ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
         AV_WN32A(dst + 4             , \
-                 (AV_RN32A(dst + 4             ) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
+                 (AV_RN32(dst + 4             ) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
         AV_WN32A(dst + row_offset    , \
-                 (AV_RN32A(dst + row_offset    ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
+                 (AV_RN32(dst + row_offset    ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
         AV_WN32A(dst + row_offset + 4, \
-                 (AV_RN32A(dst + row_offset + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
+                 (AV_RN32(dst + row_offset + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
     } else { \
         AV_WN16A(dst                 , \
-                 (AV_RN16A(dst                 ) + delta_tab->deltas[dyad1]) & 0x7F7F);\
+                 (AV_RN16(dst                 ) + delta_tab->deltas[dyad1]) & 0x7F7F);\
         AV_WN16A(dst + 2             , \
-                 (AV_RN16A(dst + 2             ) + delta_tab->deltas[dyad2]) & 0x7F7F);\
+                 (AV_RN16(dst + 2             ) + delta_tab->deltas[dyad2]) & 0x7F7F);\
         AV_WN16A(dst + row_offset    , \
-                 (AV_RN16A(dst + row_offset    ) + delta_tab->deltas[dyad1]) & 0x7F7F);\
+                 (AV_RN16(dst + row_offset    ) + delta_tab->deltas[dyad1]) & 0x7F7F);\
         AV_WN16A(dst + row_offset + 2, \
-                 (AV_RN16A(dst + row_offset + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\
+                 (AV_RN16(dst + row_offset + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\
     }
 
 
@@ -615,8 +616,8 @@
 
         /* -1 because there is an extra line on top for prediction */
         if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 ||
-            ((cell->ypos + cell->height) << 2) + mv_y >= plane->height    ||
-            ((cell->xpos + cell->width)  << 2) + mv_x >= plane->width) {
+            ((cell->ypos + cell->height) << 2) + mv_y > plane->height     ||
+            ((cell->xpos + cell->width)  << 2) + mv_x > plane->width) {
             av_log(ctx->avctx, AV_LOG_ERROR,
                    "Motion vectors point out of the frame.\n");
             return AVERROR_INVALIDDATA;
diff --git a/libavcodec/indeo4.c b/libavcodec/indeo4.c
index 5b107fb..0f77253 100644
--- a/libavcodec/indeo4.c
+++ b/libavcodec/indeo4.c
@@ -56,8 +56,8 @@
     int             is_2d_trans;
 } transforms[18] = {
     { ff_ivi_inverse_haar_8x8,  ff_ivi_dc_haar_2d,       1 },
-    { ff_ivi_inverse_haar_8x1,  ff_ivi_dc_haar_2d,       1 },
-    { ff_ivi_inverse_haar_1x8,  ff_ivi_dc_haar_2d,       1 },
+    { ff_ivi_row_haar8,         ff_ivi_dc_haar_2d,       0 },
+    { ff_ivi_col_haar8,         ff_ivi_dc_haar_2d,       0 },
     { ff_ivi_put_pixels_8x8,    ff_ivi_put_dc_pixel_8x8, 1 },
     { ff_ivi_inverse_slant_8x8, ff_ivi_dc_slant_2d,      1 },
     { ff_ivi_row_slant8,        ff_ivi_dc_row_slant,     1 },
@@ -65,13 +65,13 @@
     { NULL, NULL, 0 }, /* inverse DCT 8x8 */
     { NULL, NULL, 0 }, /* inverse DCT 8x1 */
     { NULL, NULL, 0 }, /* inverse DCT 1x8 */
-    { NULL, NULL, 0 }, /* inverse Haar 4x4 */
+    { ff_ivi_inverse_haar_4x4,  ff_ivi_dc_haar_2d,       1 },
     { ff_ivi_inverse_slant_4x4, ff_ivi_dc_slant_2d,      1 },
     { NULL, NULL, 0 }, /* no transform 4x4 */
-    { NULL, NULL, 0 }, /* inverse Haar 1x4 */
-    { NULL, NULL, 0 }, /* inverse Haar 4x1 */
-    { NULL, NULL, 0 }, /* inverse slant 1x4 */
-    { NULL, NULL, 0 }, /* inverse slant 4x1 */
+    { ff_ivi_row_haar4,         ff_ivi_dc_haar_2d,       0 },
+    { ff_ivi_col_haar4,         ff_ivi_dc_haar_2d,       0 },
+    { ff_ivi_row_slant4,        ff_ivi_dc_row_slant,     0 },
+    { ff_ivi_col_slant4,        ff_ivi_dc_col_slant,     0 },
     { NULL, NULL, 0 }, /* inverse DCT 4x4 */
 };
 
@@ -210,6 +210,7 @@
     if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf)) {
         if (ff_ivi_init_planes(ctx->planes, &pic_conf)) {
             av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate color planes!\n");
+            ctx->pic_conf.luma_bands = 0;
             return AVERROR(ENOMEM);
         }
 
@@ -352,17 +353,32 @@
             band->inv_transform = transforms[transform_id].inv_trans;
             band->dc_transform  = transforms[transform_id].dc_trans;
             band->is_2d_trans   = transforms[transform_id].is_2d_trans;
-            band->transform_size= (transform_id < 10) ? 8 : 4;
 
-            scan_indx = get_bits(&ctx->gb, 4);
-            if ((scan_indx>4 && scan_indx<10) != (band->blk_size==4)) {
-                av_log(avctx, AV_LOG_ERROR, "mismatching scan table!\n");
+            if (transform_id < 10)
+                band->transform_size = 8;
+            else
+                band->transform_size = 4;
+
+            if (band->blk_size != band->transform_size) {
+                av_log(avctx, AV_LOG_ERROR, "transform and block size mismatch (%d != %d)\n", band->transform_size, band->blk_size);
                 return AVERROR_INVALIDDATA;
             }
+
+            scan_indx = get_bits(&ctx->gb, 4);
             if (scan_indx == 15) {
                 av_log(avctx, AV_LOG_ERROR, "Custom scan pattern encountered!\n");
                 return AVERROR_INVALIDDATA;
             }
+            if (scan_indx > 4 && scan_indx < 10) {
+                if (band->blk_size != 4) {
+                    av_log(avctx, AV_LOG_ERROR, "mismatching scan table!\n");
+                    return AVERROR_INVALIDDATA;
+                }
+            } else if (band->blk_size != 8) {
+                av_log(avctx, AV_LOG_ERROR, "mismatching scan table!\n");
+                return AVERROR_INVALIDDATA;
+            }
+
             band->scan = scan_index_to_tab[scan_indx];
             band->scan_size = band->blk_size;
 
@@ -371,8 +387,9 @@
                 av_log(avctx, AV_LOG_ERROR, "Custom quant matrix encountered!\n");
                 return AVERROR_INVALIDDATA;
             }
-            if (quant_mat > 21) {
-                av_log(avctx, AV_LOG_ERROR, "Invalid quant matrix encountered!\n");
+            if (quant_mat >= FF_ARRAY_ELEMS(quant_index_to_tab)) {
+                avpriv_request_sample(avctx, "Quantization matrix %d",
+                                      quant_mat);
                 return AVERROR_INVALIDDATA;
             }
             band->quant_mat = quant_mat;
@@ -392,9 +409,12 @@
         }
 
         /* decode block huffman codebook */
-        if (ff_ivi_dec_huff_desc(&ctx->gb, get_bits1(&ctx->gb), IVI_BLK_HUFF,
-                                 &band->blk_vlc, avctx))
-            return AVERROR_INVALIDDATA;
+        if (!get_bits1(&ctx->gb))
+            band->blk_vlc.tab = ctx->blk_vlc.tab;
+        else
+            if (ff_ivi_dec_huff_desc(&ctx->gb, 1, IVI_BLK_HUFF,
+                                     &band->blk_vlc, avctx))
+                return AVERROR_INVALIDDATA;
 
         /* select appropriate rvmap table for this band */
         band->rvmap_sel = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 3) : 8;
@@ -507,8 +527,13 @@
                     }
                 }
             } else {
-                if (band->inherit_mv && ref_mb) {
-                    mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */
+                if (band->inherit_mv) {
+                    /* copy mb_type from corresponding reference mb */
+                    if (!ref_mb) {
+                        av_log(avctx, AV_LOG_ERROR, "ref_mb unavailable\n");
+                        return AVERROR_INVALIDDATA;
+                    }
+                    mb->type = ref_mb->type;
                 } else if (ctx->frame_type == FRAMETYPE_INTRA ||
                            ctx->frame_type == FRAMETYPE_INTRA1) {
                     mb->type = 0; /* mb_type is always INTRA for intra-frames */
@@ -531,15 +556,16 @@
                 if (!mb->type) {
                     mb->mv_x = mb->mv_y = 0; /* there is no motion vector in intra-macroblocks */
                 } else {
-                    if (band->inherit_mv && ref_mb) {
-                        /* motion vector inheritance */
-                        if (mv_scale) {
-                            mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
-                            mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale);
-                        } else {
-                            mb->mv_x = ref_mb->mv_x;
-                            mb->mv_y = ref_mb->mv_y;
-                        }
+                    if (band->inherit_mv) {
+                        if (ref_mb)
+                            /* motion vector inheritance */
+                            if (mv_scale) {
+                                mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
+                                mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale);
+                            } else {
+                                mb->mv_x = ref_mb->mv_x;
+                                mb->mv_y = ref_mb->mv_y;
+                            }
                     } else {
                         /* decode motion vector deltas */
                         mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table,
diff --git a/libavcodec/indeo5.c b/libavcodec/indeo5.c
index 65bd9f2..5e3259a 100644
--- a/libavcodec/indeo5.c
+++ b/libavcodec/indeo5.c
@@ -74,7 +74,7 @@
     tile_size = (ctx->gop_flags & 0x40) ? 64 << get_bits(&ctx->gb, 2) : 0;
     if (tile_size > 256) {
         av_log(avctx, AV_LOG_ERROR, "Invalid tile size: %d\n", tile_size);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* decode number of wavelet bands */
@@ -85,7 +85,7 @@
     if (is_scalable && (pic_conf.luma_bands != 4 || pic_conf.chroma_bands != 1)) {
         av_log(avctx, AV_LOG_ERROR, "Scalability: unsupported subdivision! Luma bands: %d, chroma bands: %d\n",
                pic_conf.luma_bands, pic_conf.chroma_bands);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     pic_size_indx = get_bits(&ctx->gb, 4);
@@ -98,8 +98,8 @@
     }
 
     if (ctx->gop_flags & 2) {
-        av_log(avctx, AV_LOG_ERROR, "YV12 picture format not supported!\n");
-        return -1;
+        avpriv_report_missing_feature(avctx, "YV12 picture format");
+        return AVERROR_PATCHWELCOME;
     }
 
     pic_conf.chroma_height = (pic_conf.pic_height + 3) >> 2;
@@ -113,11 +113,11 @@
     }
 
     /* check if picture layout was changed and reallocate buffers */
-    if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf)) {
+    if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf) || ctx->gop_invalid) {
         result = ff_ivi_init_planes(ctx->planes, &pic_conf);
-        if (result) {
+        if (result < 0) {
             av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate color planes!\n");
-            return -1;
+            return result;
         }
         ctx->pic_conf = pic_conf;
         ctx->is_scalable = is_scalable;
@@ -146,51 +146,56 @@
             }
 
             if (get_bits1(&ctx->gb)) {
-                av_log(avctx, AV_LOG_ERROR, "Extended transform info encountered!\n");
-                return -1;
+                avpriv_report_missing_feature(avctx, "Extended transform info");
+                return AVERROR_PATCHWELCOME;
             }
 
             /* select transform function and scan pattern according to plane and band number */
             switch ((p << 2) + i) {
             case 0:
-                band->inv_transform = ff_ivi_inverse_slant_8x8;
-                band->dc_transform  = ff_ivi_dc_slant_2d;
-                band->scan          = ff_zigzag_direct;
-                band->transform_size= 8;
+                band->inv_transform  = ff_ivi_inverse_slant_8x8;
+                band->dc_transform   = ff_ivi_dc_slant_2d;
+                band->scan           = ff_zigzag_direct;
+                band->transform_size = 8;
                 break;
 
             case 1:
-                band->inv_transform = ff_ivi_row_slant8;
-                band->dc_transform  = ff_ivi_dc_row_slant;
-                band->scan          = ff_ivi_vertical_scan_8x8;
-                band->transform_size= 8;
+                band->inv_transform  = ff_ivi_row_slant8;
+                band->dc_transform   = ff_ivi_dc_row_slant;
+                band->scan           = ff_ivi_vertical_scan_8x8;
+                band->transform_size = 8;
                 break;
 
             case 2:
-                band->inv_transform = ff_ivi_col_slant8;
-                band->dc_transform  = ff_ivi_dc_col_slant;
-                band->scan          = ff_ivi_horizontal_scan_8x8;
-                band->transform_size= 8;
+                band->inv_transform  = ff_ivi_col_slant8;
+                band->dc_transform   = ff_ivi_dc_col_slant;
+                band->scan           = ff_ivi_horizontal_scan_8x8;
+                band->transform_size = 8;
                 break;
 
             case 3:
-                band->inv_transform = ff_ivi_put_pixels_8x8;
-                band->dc_transform  = ff_ivi_put_dc_pixel_8x8;
-                band->scan          = ff_ivi_horizontal_scan_8x8;
-                band->transform_size= 8;
+                band->inv_transform  = ff_ivi_put_pixels_8x8;
+                band->dc_transform   = ff_ivi_put_dc_pixel_8x8;
+                band->scan           = ff_ivi_horizontal_scan_8x8;
+                band->transform_size = 8;
                 break;
 
             case 4:
-                band->inv_transform = ff_ivi_inverse_slant_4x4;
-                band->dc_transform  = ff_ivi_dc_slant_2d;
-                band->scan          = ff_ivi_direct_scan_4x4;
-                band->transform_size= 4;
+                band->inv_transform  = ff_ivi_inverse_slant_4x4;
+                band->dc_transform   = ff_ivi_dc_slant_2d;
+                band->scan           = ff_ivi_direct_scan_4x4;
+                band->transform_size = 4;
                 break;
             }
 
             band->is_2d_trans = band->inv_transform == ff_ivi_inverse_slant_8x8 ||
                                 band->inv_transform == ff_ivi_inverse_slant_4x4;
 
+            if (band->transform_size != band->blk_size) {
+                av_log(avctx, AV_LOG_ERROR, "transform and block size mismatch (%d != %d)\n", band->transform_size, band->blk_size);
+                return AVERROR_INVALIDDATA;
+            }
+
             /* select dequant matrix according to plane and band number */
             if (!p) {
                 quant_mat = (pic_conf.luma_bands > 1) ? i+1 : 0;
@@ -216,7 +221,7 @@
 
             if (get_bits(&ctx->gb, 2)) {
                 av_log(avctx, AV_LOG_ERROR, "End marker missing!\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
         }
     }
@@ -246,17 +251,17 @@
     if (blk_size_changed) {
         result = ff_ivi_init_tiles(ctx->planes, pic_conf.tile_width,
                                    pic_conf.tile_height);
-        if (result) {
+        if (result < 0) {
             av_log(avctx, AV_LOG_ERROR,
                    "Couldn't reallocate internal structures!\n");
-            return -1;
+            return result;
         }
     }
 
     if (ctx->gop_flags & 8) {
         if (get_bits(&ctx->gb, 3)) {
             av_log(avctx, AV_LOG_ERROR, "Alignment bits are not zero!\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
 
         if (get_bits1(&ctx->gb))
@@ -305,25 +310,27 @@
  */
 static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx)
 {
+    int ret;
+
     if (get_bits(&ctx->gb, 5) != 0x1F) {
         av_log(avctx, AV_LOG_ERROR, "Invalid picture start code!\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     ctx->prev_frame_type = ctx->frame_type;
     ctx->frame_type      = get_bits(&ctx->gb, 3);
     if (ctx->frame_type >= 5) {
         av_log(avctx, AV_LOG_ERROR, "Invalid frame type: %d \n", ctx->frame_type);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     ctx->frame_num = get_bits(&ctx->gb, 8);
 
     if (ctx->frame_type == FRAMETYPE_INTRA) {
-        ctx->gop_invalid = 1;
-        if (decode_gop_header(ctx, avctx)) {
+        if ((ret = decode_gop_header(ctx, avctx)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "Invalid GOP header, skipping frames.\n");
-            return AVERROR_INVALIDDATA;
+            ctx->gop_invalid = 1;
+            return ret;
         }
         ctx->gop_invalid = 0;
     }
@@ -346,8 +353,10 @@
             skip_hdr_extension(&ctx->gb); /* XXX: untested */
 
         /* decode macroblock huffman codebook */
-        if (ff_ivi_dec_huff_desc(&ctx->gb, ctx->frame_flags & 0x40, IVI_MB_HUFF, &ctx->mb_vlc, avctx))
-            return -1;
+        ret = ff_ivi_dec_huff_desc(&ctx->gb, ctx->frame_flags & 0x40,
+                                   IVI_MB_HUFF, &ctx->mb_vlc, avctx);
+        if (ret < 0)
+            return ret;
 
         skip_bits(&ctx->gb, 3); /* FIXME: unknown meaning! */
     }
@@ -369,7 +378,7 @@
 static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band,
                            AVCodecContext *avctx)
 {
-    int         i;
+    int         i, ret;
     uint8_t     band_flags;
 
     band_flags = get_bits(&ctx->gb, 8);
@@ -393,7 +402,7 @@
         if (band->num_corr > 61) {
             av_log(avctx, AV_LOG_ERROR, "Too many corrections: %d\n",
                    band->num_corr);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
 
         /* read correction pairs */
@@ -405,8 +414,10 @@
     band->rvmap_sel = (band_flags & 0x40) ? get_bits(&ctx->gb, 3) : 8;
 
     /* decode block huffman codebook */
-    if (ff_ivi_dec_huff_desc(&ctx->gb, band_flags & 0x80, IVI_BLK_HUFF, &band->blk_vlc, avctx))
-        return -1;
+    ret = ff_ivi_dec_huff_desc(&ctx->gb, band_flags & 0x80, IVI_BLK_HUFF,
+                               &band->blk_vlc, avctx);
+    if (ret < 0)
+        return ret;
 
     band->checksum_present = get_bits1(&ctx->gb);
     if (band->checksum_present)
@@ -473,7 +484,7 @@
             if (get_bits1(&ctx->gb)) {
                 if (ctx->frame_type == FRAMETYPE_INTRA) {
                     av_log(avctx, AV_LOG_ERROR, "Empty macroblock in an INTRA picture!\n");
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 mb->type = 1; /* empty macroblocks are always INTER */
                 mb->cbp  = 0; /* all blocks are empty */
@@ -646,7 +657,7 @@
     result = ff_ivi_init_planes(ctx->planes, &ctx->pic_conf);
     if (result) {
         av_log(avctx, AV_LOG_ERROR, "Couldn't allocate color planes!\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     ctx->buf_switch = 0;
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 4962f06..8959243 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -82,7 +82,7 @@
      * Internal sample count used by avcodec_encode_audio() to fabricate pts.
      * Can be removed along with avcodec_encode_audio().
      */
-    int sample_count;
+    int64_t sample_count;
 #endif
 
     /**
@@ -140,11 +140,6 @@
 
 void avpriv_color_frame(AVFrame *frame, const int color[4]);
 
-/**
- * Remove and free all side data from packet.
- */
-void ff_packet_free_side_data(AVPacket *pkt);
-
 extern volatile int ff_avcodec_locked;
 int ff_lock_avcodec(AVCodecContext *log_ctx);
 int ff_unlock_avcodec(void);
@@ -207,8 +202,6 @@
 
 int ff_thread_can_start_frame(AVCodecContext *avctx);
 
-int ff_get_logical_cpus(AVCodecContext *avctx);
-
 int avpriv_h264_has_num_reorder_frames(AVCodecContext *avctx);
 
 /**
diff --git a/libavcodec/intrax8.c b/libavcodec/intrax8.c
index 67e16ab..ffdfb07 100644
--- a/libavcodec/intrax8.c
+++ b/libavcodec/intrax8.c
@@ -437,7 +437,7 @@
 static void x8_ac_compensation(IntraX8Context * const w, int const direction, int const dc_level){
     MpegEncContext * const s= w->s;
     int t;
-#define B(x,y)  s->block[0][s->dsp.idct_permutation[(x)+(y)*8]]
+#define B(x,y)  s->block[0][w->idct_permutation[(x)+(y)*8]]
 #define T(x)  ((x) * dc_level + 0x8000) >> 16;
     switch(direction){
     case 0:
@@ -643,7 +643,7 @@
                                             s->current_picture.f.linesize[!!chroma] );
     }
     if(!zeros_only)
-        s->dsp.idct_add ( s->dest[chroma],
+        w->wdsp.idct_add (s->dest[chroma],
                           s->current_picture.f.linesize[!!chroma],
                           s->block[0] );
 
@@ -695,9 +695,13 @@
     av_assert0(s->mb_width>0);
     w->prediction_table=av_mallocz(s->mb_width*2*2);//two rows, 2 blocks per cannon mb
 
-    ff_init_scantable(s->dsp.idct_permutation, &w->scantable[0], ff_wmv1_scantable[0]);
-    ff_init_scantable(s->dsp.idct_permutation, &w->scantable[1], ff_wmv1_scantable[2]);
-    ff_init_scantable(s->dsp.idct_permutation, &w->scantable[2], ff_wmv1_scantable[3]);
+    ff_wmv2dsp_init(&w->wdsp);
+    ff_init_scantable_permutation(w->idct_permutation,
+                                  w->wdsp.idct_perm);
+
+    ff_init_scantable(w->idct_permutation, &w->scantable[0], ff_wmv1_scantable[0]);
+    ff_init_scantable(w->idct_permutation, &w->scantable[1], ff_wmv1_scantable[2]);
+    ff_init_scantable(w->idct_permutation, &w->scantable[2], ff_wmv1_scantable[3]);
 
     ff_intrax8dsp_init(&w->dsp);
 }
@@ -722,7 +726,6 @@
  * @param dquant doubled quantizer, it would be odd in case of VC-1 halfpq==1.
  * @param quant_offset offset away from zero
  */
-//FIXME extern uint8_t ff_wmv3_dc_scale_table[32];
 int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_offset){
     MpegEncContext * const s= w->s;
     int mb_xy;
diff --git a/libavcodec/intrax8.h b/libavcodec/intrax8.h
index 40d689a..9981785 100644
--- a/libavcodec/intrax8.h
+++ b/libavcodec/intrax8.h
@@ -22,6 +22,7 @@
 #include "get_bits.h"
 #include "mpegvideo.h"
 #include "intrax8dsp.h"
+#include "wmv2dsp.h"
 
 typedef struct IntraX8Context {
     VLC * j_ac_vlc[4];//they point to the static j_mb_vlc
@@ -32,6 +33,8 @@
 //set by ff_intrax8_common_init
     uint8_t * prediction_table;//2*(mb_w*2)
     ScanTable scantable[3];
+    WMV2DSPContext wdsp;
+    uint8_t idct_permutation[64];
 //set by the caller codec
     MpegEncContext * s;
     IntraX8DSPContext dsp;
diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c
index a28ed52..f7e0cd6 100644
--- a/libavcodec/ituh263dec.c
+++ b/libavcodec/ituh263dec.c
@@ -27,9 +27,9 @@
  * h263 decoder.
  */
 
-//#define DEBUG
 #include <limits.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
 #include "avcodec.h"
@@ -98,7 +98,7 @@
 /* init vlcs */
 
 /* XXX: find a better solution to handle static init */
-void ff_h263_decode_init_vlc(void)
+av_cold void ff_h263_decode_init_vlc(void)
 {
     static volatile int done = 0;
 
diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 9a03f02..2db9581 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -27,9 +27,9 @@
  * h263 bitstream encoder.
  */
 
-//#define DEBUG
 #include <limits.h>
 
+#include "libavutil/attributes.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h263.h"
@@ -679,7 +679,7 @@
     }
 }
 
-static void init_mv_penalty_and_fcode(MpegEncContext *s)
+static av_cold void init_mv_penalty_and_fcode(MpegEncContext *s)
 {
     int f_code;
     int mv;
@@ -721,7 +721,9 @@
     }
 }
 
-static void init_uni_h263_rl_tab(RLTable *rl, uint32_t *bits_tab, uint8_t *len_tab){
+static av_cold void init_uni_h263_rl_tab(RLTable *rl, uint32_t *bits_tab,
+                                         uint8_t *len_tab)
+{
     int slevel, run, last;
 
     av_assert0(MAX_LEVEL >= 64);
@@ -764,7 +766,7 @@
     }
 }
 
-void ff_h263_encode_init(MpegEncContext *s)
+av_cold void ff_h263_encode_init(MpegEncContext *s)
 {
     static int done = 0;
 
diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c
index 265c645..681e6e5 100644
--- a/libavcodec/ivi_common.c
+++ b/libavcodec/ivi_common.c
@@ -35,12 +35,59 @@
 #include "ivi_common.h"
 #include "ivi_dsp.h"
 
-extern const IVIHuffDesc ff_ivi_mb_huff_desc[8];  ///< static macroblock huffman tables
-extern const IVIHuffDesc ff_ivi_blk_huff_desc[8]; ///< static block huffman tables
+/**
+ * These are 2x8 predefined Huffman codebooks for coding macroblock/block
+ * signals. They are specified using "huffman descriptors" in order to
+ * avoid huge static tables. The decoding tables will be generated at
+ * startup from these descriptors.
+ */
+/** static macroblock huffman tables */
+static const IVIHuffDesc ivi_mb_huff_desc[8] = {
+    {8,  {0, 4, 5, 4, 4, 4, 6, 6}},
+    {12, {0, 2, 2, 3, 3, 3, 3, 5, 3, 2, 2, 2}},
+    {12, {0, 2, 3, 4, 3, 3, 3, 3, 4, 3, 2, 2}},
+    {12, {0, 3, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2}},
+    {13, {0, 4, 4, 3, 3, 3, 3, 2, 3, 3, 2, 1, 1}},
+    {9,  {0, 4, 4, 4, 4, 3, 3, 3, 2}},
+    {10, {0, 4, 4, 4, 4, 3, 3, 2, 2, 2}},
+    {12, {0, 4, 4, 4, 3, 3, 2, 3, 2, 2, 2, 2}}
+};
+
+/** static block huffman tables */
+static const IVIHuffDesc ivi_blk_huff_desc[8] = {
+    {10, {1, 2, 3, 4, 4, 7, 5, 5, 4, 1}},
+    {11, {2, 3, 4, 4, 4, 7, 5, 4, 3, 3, 2}},
+    {12, {2, 4, 5, 5, 5, 5, 6, 4, 4, 3, 1, 1}},
+    {13, {3, 3, 4, 4, 5, 6, 6, 4, 4, 3, 2, 1, 1}},
+    {11, {3, 4, 4, 5, 5, 5, 6, 5, 4, 2, 2}},
+    {13, {3, 4, 5, 5, 5, 5, 6, 4, 3, 3, 2, 1, 1}},
+    {13, {3, 4, 5, 5, 5, 6, 5, 4, 3, 3, 2, 1, 1}},
+    {9,  {3, 4, 4, 5, 5, 5, 6, 5, 5}}
+};
 
 static VLC ivi_mb_vlc_tabs [8]; ///< static macroblock Huffman tables
 static VLC ivi_blk_vlc_tabs[8]; ///< static block Huffman tables
 
+typedef void (*ivi_mc_func) (int16_t *buf, const int16_t *ref_buf,
+                             uint32_t pitch, int mc_type);
+
+static int ivi_mc(IVIBandDesc *band, ivi_mc_func mc,
+                  int offs, int mv_x, int mv_y, int mc_type)
+{
+    int ref_offs = offs + mv_y * band->pitch + mv_x;
+    int buf_size = band->pitch * band->aheight;
+    int min_size = band->pitch * (band->blk_size - 1) + band->blk_size;
+    int ref_size = (mc_type > 1) * band->pitch + (mc_type & 1);
+
+    av_assert0(offs >= 0 && ref_offs >= 0 && band->ref_buf);
+    av_assert0(buf_size - min_size >= offs);
+    av_assert0(buf_size - min_size - ref_size >= ref_offs);
+
+    mc(band->buf + offs, band->ref_buf + ref_offs, band->pitch, mc_type);
+
+    return 0;
+}
+
 /**
  *  Reverse "nbits" bits of the value "val" and return the result
  *  in the least significant bits.
@@ -50,9 +97,10 @@
     uint16_t res;
 
     if (nbits <= 8) {
-        res = ff_reverse[val] >> (8-nbits);
+        res = ff_reverse[val] >> (8 - nbits);
     } else
-        res = ((ff_reverse[val & 0xFF] << 8) + (ff_reverse[val >> 8])) >> (16-nbits);
+        res = ((ff_reverse[val & 0xFF] << 8) +
+               (ff_reverse[val >> 8])) >> (16 - nbits);
 
     return res;
 }
@@ -85,7 +133,7 @@
 
             bits[pos] = i + cb->xbits[i] + not_last_row;
             if (bits[pos] > IVI_VLC_BITS)
-                return -1; /* invalid descriptor */
+                return AVERROR_INVALIDDATA; /* invalid descriptor */
 
             codewords[pos] = inv_bits((prefix | j), bits[pos]);
             if (!bits[pos])
@@ -100,7 +148,7 @@
                     (flag ? INIT_VLC_USE_NEW_STATIC : 0) | INIT_VLC_LE);
 }
 
-void ff_ivi_init_static_vlc(void)
+av_cold void ff_ivi_init_static_vlc(void)
 {
     int i;
     static VLC_TYPE table_data[8192 * 16][2];
@@ -111,10 +159,12 @@
     for (i = 0; i < 8; i++) {
         ivi_mb_vlc_tabs[i].table = table_data + i * 2 * 8192;
         ivi_mb_vlc_tabs[i].table_allocated = 8192;
-        ivi_create_huff_from_desc(&ff_ivi_mb_huff_desc[i],  &ivi_mb_vlc_tabs[i],  1);
+        ivi_create_huff_from_desc(&ivi_mb_huff_desc[i],
+                                  &ivi_mb_vlc_tabs[i], 1);
         ivi_blk_vlc_tabs[i].table = table_data + (i * 2 + 1) * 8192;
         ivi_blk_vlc_tabs[i].table_allocated = 8192;
-        ivi_create_huff_from_desc(&ff_ivi_blk_huff_desc[i], &ivi_blk_vlc_tabs[i], 1);
+        ivi_create_huff_from_desc(&ivi_blk_huff_desc[i],
+                                  &ivi_blk_vlc_tabs[i], 1);
     }
     initialized_vlcs = 1;
 }
@@ -138,56 +188,59 @@
  *  @param[in]  desc2  ptr to the 2nd descriptor to compare
  *  @return         comparison result: 0 - equal, 1 - not equal
  */
-static int ivi_huff_desc_cmp(const IVIHuffDesc *desc1, const IVIHuffDesc *desc2)
+static int ivi_huff_desc_cmp(const IVIHuffDesc *desc1,
+                             const IVIHuffDesc *desc2)
 {
-    return    desc1->num_rows != desc2->num_rows
-           || memcmp(desc1->xbits, desc2->xbits, desc1->num_rows);
+    return desc1->num_rows != desc2->num_rows ||
+           memcmp(desc1->xbits, desc2->xbits, desc1->num_rows);
 }
 
 int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab,
                          IVIHuffTab *huff_tab, AVCodecContext *avctx)
 {
-    int         i, result;
+    int i, result;
     IVIHuffDesc new_huff;
 
     if (!desc_coded) {
         /* select default table */
         huff_tab->tab = (which_tab) ? &ivi_blk_vlc_tabs[7]
-            : &ivi_mb_vlc_tabs [7];
-    } else {
-        huff_tab->tab_sel = get_bits(gb, 3);
-        if (huff_tab->tab_sel == 7) {
-            /* custom huffman table (explicitly encoded) */
-            new_huff.num_rows = get_bits(gb, 4);
-            if (!new_huff.num_rows) {
-                av_log(avctx, AV_LOG_ERROR, "Empty custom Huffman table!\n");
-                return AVERROR_INVALIDDATA;
-            }
+                                    : &ivi_mb_vlc_tabs [7];
+        return 0;
+    }
 
-            for (i = 0; i < new_huff.num_rows; i++)
-                new_huff.xbits[i] = get_bits(gb, 4);
-
-            /* Have we got the same custom table? Rebuild if not. */
-            if (ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc) || !huff_tab->cust_tab.table) {
-                ivi_huff_desc_copy(&huff_tab->cust_desc, &new_huff);
-
-                if (huff_tab->cust_tab.table)
-                    ff_free_vlc(&huff_tab->cust_tab);
-                result = ivi_create_huff_from_desc(&huff_tab->cust_desc,
-                        &huff_tab->cust_tab, 0);
-                if (result) {
-                    huff_tab->cust_desc.num_rows = 0; // reset faulty description
-                    av_log(avctx, AV_LOG_ERROR,
-                           "Error while initializing custom vlc table!\n");
-                    return result;
-                }
-            }
-            huff_tab->tab = &huff_tab->cust_tab;
-        } else {
-            /* select one of predefined tables */
-            huff_tab->tab = (which_tab) ? &ivi_blk_vlc_tabs[huff_tab->tab_sel]
-                : &ivi_mb_vlc_tabs [huff_tab->tab_sel];
+    huff_tab->tab_sel = get_bits(gb, 3);
+    if (huff_tab->tab_sel == 7) {
+        /* custom huffman table (explicitly encoded) */
+        new_huff.num_rows = get_bits(gb, 4);
+        if (!new_huff.num_rows) {
+            av_log(avctx, AV_LOG_ERROR, "Empty custom Huffman table!\n");
+            return AVERROR_INVALIDDATA;
         }
+
+        for (i = 0; i < new_huff.num_rows; i++)
+            new_huff.xbits[i] = get_bits(gb, 4);
+
+        /* Have we got the same custom table? Rebuild if not. */
+        if (ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc) || !huff_tab->cust_tab.table) {
+            ivi_huff_desc_copy(&huff_tab->cust_desc, &new_huff);
+
+            if (huff_tab->cust_tab.table)
+                ff_free_vlc(&huff_tab->cust_tab);
+            result = ivi_create_huff_from_desc(&huff_tab->cust_desc,
+                    &huff_tab->cust_tab, 0);
+            if (result) {
+                // reset faulty description
+                huff_tab->cust_desc.num_rows = 0;
+                av_log(avctx, AV_LOG_ERROR,
+                       "Error while initializing custom vlc table!\n");
+                return result;
+            }
+        }
+        huff_tab->tab = &huff_tab->cust_tab;
+    } else {
+        /* select one of predefined tables */
+        huff_tab->tab = (which_tab) ? &ivi_blk_vlc_tabs[huff_tab->tab_sel]
+            : &ivi_mb_vlc_tabs [huff_tab->tab_sel];
     }
 
     return 0;
@@ -216,17 +269,23 @@
             av_freep(&planes[p].bands[b].tiles);
         }
         av_freep(&planes[p].bands);
+        planes[p].num_bands = 0;
     }
 }
 
 av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg)
 {
-    int         p, b;
-    uint32_t    b_width, b_height, align_fac, width_aligned, height_aligned, buf_size;
+    int p, b;
+    uint32_t b_width, b_height, align_fac, width_aligned,
+             height_aligned, buf_size;
     IVIBandDesc *band;
 
     ivi_free_buffers(planes);
 
+    if (cfg->pic_width < 1 || cfg->pic_height < 1 ||
+        cfg->luma_bands < 1 || cfg->chroma_bands < 1)
+        return AVERROR_INVALIDDATA;
+
     /* fill in the descriptor of the luminance plane */
     planes[0].width     = cfg->pic_width;
     planes[0].height    = cfg->pic_height;
@@ -245,8 +304,10 @@
         /* select band dimensions: if there is only one band then it
          *  has the full size, if there are several bands each of them
          *  has only half size */
-        b_width  = planes[p].num_bands == 1 ? planes[p].width  : (planes[p].width  + 1) >> 1;
-        b_height = planes[p].num_bands == 1 ? planes[p].height : (planes[p].height + 1) >> 1;
+        b_width  = planes[p].num_bands == 1 ? planes[p].width
+                                            : (planes[p].width  + 1) >> 1;
+        b_height = planes[p].num_bands == 1 ? planes[p].height
+                                            : (planes[p].height + 1) >> 1;
 
         /* luma   band buffers will be aligned on 16x16 (max macroblock size) */
         /* chroma band buffers will be aligned on   8x8 (max macroblock size) */
@@ -275,19 +336,58 @@
                 if (!band->bufs[2])
                     return AVERROR(ENOMEM);
             }
-
-            planes[p].bands[0].blk_vlc.cust_desc.num_rows = 0; /* reset custom vlc */
+            /* reset custom vlc */
+            planes[p].bands[0].blk_vlc.cust_desc.num_rows = 0;
         }
     }
 
     return 0;
 }
 
-av_cold int ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_height)
+static int ivi_init_tiles(IVIBandDesc *band, IVITile *ref_tile,
+                          int p, int b, int t_height, int t_width)
 {
-    int         p, b, x, y, x_tiles, y_tiles, t_width, t_height;
+    int x, y;
+    IVITile *tile = band->tiles;
+
+    for (y = 0; y < band->height; y += t_height) {
+        for (x = 0; x < band->width; x += t_width) {
+            tile->xpos     = x;
+            tile->ypos     = y;
+            tile->mb_size  = band->mb_size;
+            tile->width    = FFMIN(band->width - x,  t_width);
+            tile->height   = FFMIN(band->height - y, t_height);
+            tile->is_empty = tile->data_size = 0;
+            /* calculate number of macroblocks */
+            tile->num_MBs  = IVI_MBs_PER_TILE(tile->width, tile->height,
+                                              band->mb_size);
+
+            av_freep(&tile->mbs);
+            tile->mbs = av_malloc(tile->num_MBs * sizeof(IVIMbInfo));
+            if (!tile->mbs)
+                return AVERROR(ENOMEM);
+
+            tile->ref_mbs = 0;
+            if (p || b) {
+                if (tile->num_MBs != ref_tile->num_MBs) {
+                    av_log(NULL, AV_LOG_DEBUG, "ref_tile mismatch\n");
+                    return AVERROR_INVALIDDATA;
+                }
+                tile->ref_mbs = ref_tile->mbs;
+                ref_tile++;
+            }
+            tile++;
+        }
+    }
+
+    return 0;
+}
+
+av_cold int ff_ivi_init_tiles(IVIPlaneDesc *planes,
+                              int tile_width, int tile_height)
+{
+    int p, b, x_tiles, y_tiles, t_width, t_height, ret;
     IVIBandDesc *band;
-    IVITile     *tile, *ref_tile;
 
     for (p = 0; p < 3; p++) {
         t_width  = !p ? tile_width  : (tile_width  + 3) >> 2;
@@ -311,44 +411,14 @@
             if (!band->tiles)
                 return AVERROR(ENOMEM);
 
-            tile = band->tiles;
-
             /* use the first luma band as reference for motion vectors
              * and quant */
-            ref_tile = planes[0].bands[0].tiles;
-
-            for (y = 0; y < band->height; y += t_height) {
-                for (x = 0; x < band->width; x += t_width) {
-                    tile->xpos     = x;
-                    tile->ypos     = y;
-                    tile->mb_size  = band->mb_size;
-                    tile->width    = FFMIN(band->width - x,  t_width);
-                    tile->height   = FFMIN(band->height - y, t_height);
-                    tile->is_empty = tile->data_size = 0;
-                    /* calculate number of macroblocks */
-                    tile->num_MBs  = IVI_MBs_PER_TILE(tile->width, tile->height,
-                                                      band->mb_size);
-
-                    av_freep(&tile->mbs);
-                    tile->mbs = av_malloc(tile->num_MBs * sizeof(IVIMbInfo));
-                    if (!tile->mbs)
-                        return AVERROR(ENOMEM);
-
-                    tile->ref_mbs = 0;
-                    if (p || b) {
-                        if (tile->num_MBs <= ref_tile->num_MBs) {
-                            tile->ref_mbs = ref_tile->mbs;
-                        }else
-                            av_log(NULL, AV_LOG_DEBUG, "Cannot use ref_tile, too few mbs\n");
-                        ref_tile++;
-                    }
-
-                    tile++;
-                }
-            }
-
-        }// for b
-    }// for p
+            ret = ivi_init_tiles(band, planes[0].bands[0].tiles,
+                                 p, b, t_height, t_width);
+            if (ret < 0)
+                return ret;
+        }
+    }
 
     return 0;
 }
@@ -380,6 +450,117 @@
     return len;
 }
 
+static int ivi_dc_transform(IVIBandDesc *band, int *prev_dc, int buf_offs,
+                            int blk_size)
+{
+    int buf_size = band->pitch * band->aheight - buf_offs;
+    int min_size = (blk_size - 1) * band->pitch + blk_size;
+
+    if (min_size > buf_size)
+        return AVERROR_INVALIDDATA;
+
+    band->dc_transform(prev_dc, band->buf + buf_offs,
+                       band->pitch, blk_size);
+
+    return 0;
+}
+
+static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band,
+                                   ivi_mc_func mc, int mv_x, int mv_y,
+                                   int *prev_dc, int is_intra, int mc_type,
+                                   uint32_t quant, int offs,
+                                   AVCodecContext *avctx)
+{
+    const uint16_t *base_tab  = is_intra ? band->intra_base : band->inter_base;
+    RVMapDesc *rvmap = band->rv_map;
+    uint8_t col_flags[8];
+    int32_t trvec[64];
+    uint32_t sym = 0, lo, hi, q;
+    int pos, run, val;
+    int blk_size   = band->blk_size;
+    int num_coeffs = blk_size * blk_size;
+    int col_mask   = blk_size - 1;
+    int scan_pos   = -1;
+    int min_size   = band->pitch * (band->transform_size - 1) +
+                     band->transform_size;
+    int buf_size   = band->pitch * band->aheight - offs;
+
+    if (min_size > buf_size)
+        return AVERROR_INVALIDDATA;
+
+    if (!band->scan) {
+        av_log(avctx, AV_LOG_ERROR, "Scan pattern is not set.\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    /* zero transform vector */
+    memset(trvec, 0, num_coeffs * sizeof(trvec[0]));
+    /* zero column flags */
+    memset(col_flags, 0, sizeof(col_flags));
+    while (scan_pos <= num_coeffs) {
+        sym = get_vlc2(gb, band->blk_vlc.tab->table,
+                       IVI_VLC_BITS, 1);
+        if (sym == rvmap->eob_sym)
+            break; /* End of block */
+
+        /* Escape - run/val explicitly coded using 3 vlc codes */
+        if (sym == rvmap->esc_sym) {
+            run = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1) + 1;
+            lo  = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1);
+            hi  = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1);
+            /* merge them and convert into signed val */
+            val = IVI_TOSIGNED((hi << 6) | lo);
+        } else {
+            if (sym >= 256U) {
+                av_log(avctx, AV_LOG_ERROR, "Invalid sym encountered: %d.\n", sym);
+                return AVERROR_INVALIDDATA;
+            }
+            run = rvmap->runtab[sym];
+            val = rvmap->valtab[sym];
+        }
+
+        /* de-zigzag and dequantize */
+        scan_pos += run;
+        if (scan_pos >= num_coeffs || scan_pos < 0)
+            break;
+        pos = band->scan[scan_pos];
+
+        if (!val)
+            av_dlog(avctx, "Val = 0 encountered!\n");
+
+        q = (base_tab[pos] * quant) >> 9;
+        if (q > 1)
+            val = val * q + FFSIGN(val) * (((q ^ 1) - 1) >> 1);
+        trvec[pos] = val;
+        /* track columns containing non-zero coeffs */
+        col_flags[pos & col_mask] |= !!val;
+    }
+
+    if (scan_pos < 0 || scan_pos >= num_coeffs && sym != rvmap->eob_sym)
+        return AVERROR_INVALIDDATA; /* corrupt block data */
+
+    /* undoing DC coeff prediction for intra-blocks */
+    if (is_intra && band->is_2d_trans) {
+        *prev_dc     += trvec[0];
+        trvec[0]      = *prev_dc;
+        col_flags[0] |= !!*prev_dc;
+    }
+
+    if(band->transform_size > band->blk_size){
+        av_log(NULL, AV_LOG_ERROR, "Too large transform\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    /* apply inverse transform */
+    band->inv_transform(trvec, band->buf + offs,
+                        band->pitch, col_flags);
+
+    /* apply motion compensation */
+    if (!is_intra)
+        return ivi_mc(band, mc, offs, mv_x, mv_y, mc_type);
+
+    return 0;
+}
 /*
  *  Decode block data:
  *  extract huffman-coded transform coefficients from the bitstream,
@@ -391,27 +572,22 @@
  *  @param[in]      tile  pointer to the tile descriptor
  *  @return     result code: 0 - OK, -1 = error (corrupted blocks data)
  */
-static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile,
-                             AVCodecContext *avctx)
+static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band,
+                             IVITile *tile, AVCodecContext *avctx)
 {
-    int         mbn, blk, num_blocks, num_coeffs, blk_size, scan_pos, run, val,
-                pos, is_intra, mc_type = 0, av_uninit(mv_x), av_uninit(mv_y), col_mask;
-    uint8_t     col_flags[8];
-    int32_t     prev_dc, trvec[64];
-    uint32_t    cbp, av_uninit(sym), lo, hi, quant, buf_offs, q;
-    IVIMbInfo   *mb;
-    RVMapDesc   *rvmap = band->rv_map;
-    void (*mc_with_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type);
-    void (*mc_no_delta_func)  (int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type);
-    const uint16_t  *base_tab;
-    const uint8_t   *scale_tab;
+    int mbn, blk, num_blocks, blk_size, ret, is_intra, mc_type = 0;
+    int mv_x = 0, mv_y = 0;
+    int32_t prev_dc;
+    uint32_t cbp, quant, buf_offs;
+    IVIMbInfo *mb;
+    ivi_mc_func mc_with_delta_func, mc_no_delta_func;
+    const uint8_t *scale_tab;
 
-    prev_dc = 0; /* init intra prediction for the DC coefficient */
-
+    /* init intra prediction for the DC coefficient */
+    prev_dc    = 0;
     blk_size   = band->blk_size;
-    col_mask   = blk_size - 1; /* column mask for tracking non-zero coeffs */
-    num_blocks = (band->mb_size != blk_size) ? 4 : 1; /* number of blocks per mb */
-    num_coeffs = blk_size * blk_size;
+    /* number of blocks per mb */
+    num_blocks = (band->mb_size != blk_size) ? 4 : 1;
     if (blk_size == 8) {
         mc_with_delta_func = ff_ivi_mc_8x8_delta;
         mc_no_delta_func   = ff_ivi_mc_8x8_no_delta;
@@ -425,9 +601,12 @@
         cbp      = mb->cbp;
         buf_offs = mb->buf_offs;
 
-        quant = av_clip(band->glob_quant + mb->q_delta, 0, 23);
+        quant = band->glob_quant + mb->q_delta;
+        if (avctx->codec_id == AV_CODEC_ID_INDEO4)
+            quant = av_clip(quant, 0, 31);
+        else
+            quant = av_clip(quant, 0, 23);
 
-        base_tab  = is_intra ? band->intra_base  : band->inter_base;
         scale_tab = is_intra ? band->intra_scale : band->inter_scale;
         if (scale_tab)
             quant = scale_tab[quant];
@@ -448,10 +627,10 @@
                 cx    = mb->mv_x &  band->is_halfpel;
                 cy    = mb->mv_y &  band->is_halfpel;
 
-                if (   mb->xpos + dmv_x < 0
-                    || mb->xpos + dmv_x + band->mb_size + cx > band->pitch
-                    || mb->ypos + dmv_y < 0
-                    || mb->ypos + dmv_y + band->mb_size + cy > band->aheight) {
+                if (mb->xpos + dmv_x < 0 ||
+                    mb->xpos + dmv_x + band->mb_size + cx > band->pitch ||
+                    mb->ypos + dmv_y < 0 ||
+                    mb->ypos + dmv_y + band->mb_size + cy > band->aheight) {
                     return AVERROR_INVALIDDATA;
                 }
             }
@@ -467,83 +646,25 @@
             }
 
             if (cbp & 1) { /* block coded ? */
-                if (!band->scan) {
-                    av_log(avctx, AV_LOG_ERROR, "Scan pattern is not set.\n");
-                    return AVERROR_INVALIDDATA;
-                }
-
-                scan_pos = -1;
-                memset(trvec, 0, num_coeffs*sizeof(trvec[0])); /* zero transform vector */
-                memset(col_flags, 0, sizeof(col_flags));      /* zero column flags */
-
-                while (scan_pos <= num_coeffs) {
-                    sym = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1);
-                    if (sym == rvmap->eob_sym)
-                        break; /* End of block */
-
-                    if (sym == rvmap->esc_sym) { /* Escape - run/val explicitly coded using 3 vlc codes */
-                        run = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1) + 1;
-                        lo  = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1);
-                        hi  = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1);
-                        val = IVI_TOSIGNED((hi << 6) | lo); /* merge them and convert into signed val */
-                    } else {
-                        if (sym >= 256U) {
-                            av_log(avctx, AV_LOG_ERROR, "Invalid sym encountered: %d.\n", sym);
-                            return -1;
-                        }
-                        run = rvmap->runtab[sym];
-                        val = rvmap->valtab[sym];
-                    }
-
-                    /* de-zigzag and dequantize */
-                    scan_pos += run;
-                    if (scan_pos >= (unsigned)num_coeffs)
-                        break;
-                    pos = band->scan[scan_pos];
-
-                    if (!val)
-                        av_dlog(avctx, "Val = 0 encountered!\n");
-
-                    q = (base_tab[pos] * quant) >> 9;
-                    if (q > 1)
-                        val = val * q + FFSIGN(val) * (((q ^ 1) - 1) >> 1);
-                    trvec[pos] = val;
-                    col_flags[pos & col_mask] |= !!val; /* track columns containing non-zero coeffs */
-                }// while
-
-                if (scan_pos >= num_coeffs && sym != rvmap->eob_sym)
-                    return -1; /* corrupt block data */
-
-                /* undoing DC coeff prediction for intra-blocks */
-                if (is_intra && band->is_2d_trans) {
-                    prev_dc      += trvec[0];
-                    trvec[0]      = prev_dc;
-                    col_flags[0] |= !!prev_dc;
-                }
-                if(band->transform_size > band->blk_size){
-                    av_log(NULL, AV_LOG_ERROR, "Too large transform\n");
-                    return AVERROR_INVALIDDATA;
-                }
-                /* apply inverse transform */
-                band->inv_transform(trvec, band->buf + buf_offs,
-                                    band->pitch, col_flags);
-
-                /* apply motion compensation */
-                if (!is_intra)
-                    mc_with_delta_func(band->buf + buf_offs,
-                                       band->ref_buf + buf_offs + mv_y * band->pitch + mv_x,
-                                       band->pitch, mc_type);
+                ret = ivi_decode_coded_blocks(gb, band, mc_with_delta_func,
+                                              mv_x, mv_y, &prev_dc, is_intra,
+                                              mc_type, quant, buf_offs, avctx);
+                if (ret < 0)
+                    return ret;
             } else {
                 /* block not coded */
                 /* for intra blocks apply the dc slant transform */
                 /* for inter - perform the motion compensation without delta */
                 if (is_intra) {
-                        band->dc_transform(&prev_dc, band->buf + buf_offs,
-                                           band->pitch, blk_size);
-                } else
-                    mc_no_delta_func(band->buf + buf_offs,
-                                     band->ref_buf + buf_offs + mv_y * band->pitch + mv_x,
-                                     band->pitch, mc_type);
+                    ret = ivi_dc_transform(band, &prev_dc, buf_offs, blk_size);
+                    if (ret < 0)
+                        return ret;
+                } else {
+                    ret = ivi_mc(band, mc_no_delta_func, buf_offs,
+                                 mv_x, mv_y, mc_type);
+                    if (ret < 0)
+                        return ret;
+                }
             }
 
             cbp >>= 1;
@@ -568,12 +689,11 @@
                                   IVITile *tile, int32_t mv_scale)
 {
     int             x, y, need_mc, mbn, blk, num_blocks, mv_x, mv_y, mc_type;
-    int             offs, mb_offset, row_offset;
+    int             offs, mb_offset, row_offset, ret;
     IVIMbInfo       *mb, *ref_mb;
     const int16_t   *src;
     int16_t         *dst;
-    void (*mc_no_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch,
-                             int mc_type);
+    ivi_mc_func     mc_no_delta_func;
 
     if (tile->num_MBs != IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size)) {
         av_log(avctx, AV_LOG_ERROR, "Allocated tile size %d mismatches "
@@ -663,9 +783,10 @@
             for (blk = 0; blk < num_blocks; blk++) {
                 /* adjust block position in the buffer according with its number */
                 offs = mb->buf_offs + band->blk_size * ((blk & 1) + !!(blk & 2) * band->pitch);
-                mc_no_delta_func(band->buf + offs,
-                                 band->ref_buf + offs + mv_y * band->pitch + mv_x,
-                                 band->pitch, mc_type);
+                ret = ivi_mc(band, mc_no_delta_func, offs,
+                             mv_x, mv_y, mc_type);
+                if (ret < 0)
+                    return ret;
             }
         }
     } else {
@@ -804,8 +925,16 @@
                 break;
 
             result = ivi_decode_blocks(&ctx->gb, band, tile, avctx);
-            if (result < 0 || ((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) {
-                av_log(avctx, AV_LOG_ERROR, "Corrupted tile data encountered!\n");
+            if (result < 0) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Corrupted tile data encountered!\n");
+                break;
+            }
+
+            if (((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Tile data_size mismatch!\n");
+                result = AVERROR_INVALIDDATA;
                 break;
             }
 
@@ -813,7 +942,8 @@
         }
     }
 
-    /* restore the selected rvmap table by applying its corrections in reverse order */
+    /* restore the selected rvmap table by applying its corrections in
+     * reverse order */
     for (i = band->num_corr-1; i >= 0; i--) {
         idx1 = band->corr[i*2];
         idx2 = band->corr[i*2+1];
@@ -830,7 +960,8 @@
         uint16_t chksum = ivi_calc_band_checksum(band);
         if (chksum != band->checksum) {
             av_log(avctx, AV_LOG_ERROR,
-                   "Band checksum mismatch! Plane %d, band %d, received: %x, calculated: %x\n",
+                   "Band checksum mismatch! Plane %d, band %d, "
+                   "received: %x, calculated: %x\n",
                    band->plane, band->band_num, band->checksum, chksum);
         }
     }
@@ -858,14 +989,14 @@
     if (result) {
         av_log(avctx, AV_LOG_ERROR,
                "Error while decoding picture header: %d\n", result);
-        return -1;
+        return result;
     }
     if (ctx->gop_invalid)
         return AVERROR_INVALIDDATA;
 
     if (ctx->gop_flags & IVI5_IS_PROTECTED) {
-        av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n");
-        return -1;
+        avpriv_report_missing_feature(avctx, "Password-protected clip!\n");
+        return AVERROR_PATCHWELCOME;
     }
 
     ctx->switch_buffers(ctx);
@@ -877,24 +1008,35 @@
         for (p = 0; p < 3; p++) {
             for (b = 0; b < ctx->planes[p].num_bands; b++) {
                 result = decode_band(ctx, &ctx->planes[p].bands[b], avctx);
-                if (result) {
+                if (result < 0) {
                     av_log(avctx, AV_LOG_ERROR,
                            "Error while decoding band: %d, plane: %d\n", b, p);
-                    return -1;
+                    return result;
                 }
             }
         }
         ctx->buf_invalid[ctx->dst_buf] = 0;
+    } else {
+        if (ctx->is_scalable)
+            return AVERROR_INVALIDDATA;
+
+        for (p = 0; p < 3; p++) {
+            if (!ctx->planes[p].bands[0].buf)
+                return AVERROR_INVALIDDATA;
+        }
     }
     if (ctx->buf_invalid[ctx->dst_buf])
         return -1;
 
     //STOP_TIMER("decode_planes"); }
 
-    /* If the bidirectional mode is enabled, next I and the following P frame will */
-    /* be sent together. Unfortunately the approach below seems to be the only way */
-    /* to handle the B-frames mode. That's exactly the same Intel decoders do.     */
-    if (avctx->codec_id == AV_CODEC_ID_INDEO4 && ctx->frame_type == 0/*FRAMETYPE_INTRA*/) {
+    /* If the bidirectional mode is enabled, next I and the following P
+     * frame will be sent together. Unfortunately the approach below seems
+     * to be the only way to handle the B-frames mode.
+     * That's exactly the same Intel decoders do.
+     */
+    if (avctx->codec_id == AV_CODEC_ID_INDEO4 &&
+        ctx->frame_type == 0/*FRAMETYPE_INTRA*/) {
         while (get_bits(&ctx->gb, 8)); // skip version string
         skip_bits_long(&ctx->gb, 64);  // skip padding, TODO: implement correct 8-bytes alignment
         if (get_bits_left(&ctx->gb) > 18 && show_bits(&ctx->gb, 18) == 0x3FFF8)
@@ -959,35 +1101,6 @@
 
 
 /**
- * These are 2x8 predefined Huffman codebooks for coding macroblock/block
- * signals. They are specified using "huffman descriptors" in order to
- * avoid huge static tables. The decoding tables will be generated at
- * startup from these descriptors.
- */
-const IVIHuffDesc ff_ivi_mb_huff_desc[8] = {
-    {8,  {0, 4, 5, 4, 4, 4, 6, 6}},
-    {12, {0, 2, 2, 3, 3, 3, 3, 5, 3, 2, 2, 2}},
-    {12, {0, 2, 3, 4, 3, 3, 3, 3, 4, 3, 2, 2}},
-    {12, {0, 3, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2}},
-    {13, {0, 4, 4, 3, 3, 3, 3, 2, 3, 3, 2, 1, 1}},
-    {9,  {0, 4, 4, 4, 4, 3, 3, 3, 2}},
-    {10, {0, 4, 4, 4, 4, 3, 3, 2, 2, 2}},
-    {12, {0, 4, 4, 4, 3, 3, 2, 3, 2, 2, 2, 2}}
-};
-
-const IVIHuffDesc ff_ivi_blk_huff_desc[8] = {
-    {10, {1, 2, 3, 4, 4, 7, 5, 5, 4, 1}},
-    {11, {2, 3, 4, 4, 4, 7, 5, 4, 3, 3, 2}},
-    {12, {2, 4, 5, 5, 5, 5, 6, 4, 4, 3, 1, 1}},
-    {13, {3, 3, 4, 4, 5, 6, 6, 4, 4, 3, 2, 1, 1}},
-    {11, {3, 4, 4, 5, 5, 5, 6, 5, 4, 2, 2}},
-    {13, {3, 4, 5, 5, 5, 5, 6, 4, 3, 3, 2, 1, 1}},
-    {13, {3, 4, 5, 5, 5, 6, 5, 4, 3, 3, 2, 1, 1}},
-    {9,  {3, 4, 4, 5, 5, 5, 6, 5, 5}}
-};
-
-
-/**
  *  Scan patterns shared between indeo4 and indeo5
  */
 const uint8_t ff_ivi_vertical_scan_8x8[64] = {
diff --git a/libavcodec/ivi_common.h b/libavcodec/ivi_common.h
index 130fd12..72ab54f 100644
--- a/libavcodec/ivi_common.h
+++ b/libavcodec/ivi_common.h
@@ -160,9 +160,9 @@
     int             num_tiles;      ///< number of tiles in this band
     IVITile         *tiles;         ///< array of tile descriptors
     InvTransformPtr *inv_transform;
+    int             transform_size;
     DCTransformPtr  *dc_transform;
     int             is_2d_trans;    ///< 1 indicates that the two-dimensional inverse transform is used
-    int             transform_size; ///< block size of the transform
     int32_t         checksum;       ///< for debug purposes
     int             checksum_present;
     int             bufsize;        ///< band buffer size in bytes
diff --git a/libavcodec/ivi_dsp.c b/libavcodec/ivi_dsp.c
index 9c35aa0..f5e5e6b 100644
--- a/libavcodec/ivi_dsp.c
+++ b/libavcodec/ivi_dsp.c
@@ -258,12 +258,14 @@
     d8 = COMPENSATE(t8); }
 
 /** inverse 4-point Haar transform */
-#define INV_HAAR4(s1, s3, s5, s7) {\
-    HAAR_BFLY(s1, s5);  HAAR_BFLY(s1, s3);  HAAR_BFLY(s5, s7);\
-    s1 = COMPENSATE(s1);\
-    s3 = COMPENSATE(s3);\
-    s5 = COMPENSATE(s5);\
-    s7 = COMPENSATE(s7); }
+#define INV_HAAR4(s1, s3, s5, s7, d1, d2, d3, d4, t0, t1, t2, t3, t4) {\
+    IVI_HAAR_BFLY(s1, s3, t0, t1, t4);\
+    IVI_HAAR_BFLY(t0, s5, t2, t3, t4);\
+    d1 = COMPENSATE(t2);\
+    d2 = COMPENSATE(t3);\
+    IVI_HAAR_BFLY(t1, s7, t2, t3, t4);\
+    d3 = COMPENSATE(t2);\
+    d4 = COMPENSATE(t3); }
 
 void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch,
                              const uint8_t *flags)
@@ -320,60 +322,153 @@
 #undef  COMPENSATE
 }
 
-void ff_ivi_inverse_haar_1x8(const int32_t *in, int16_t *out, uint32_t pitch,
-                             const uint8_t *flags)
+void ff_ivi_row_haar8(const int32_t *in, int16_t *out, uint32_t pitch,
+                      const uint8_t *flags)
 {
     int     i;
-    const int32_t *src;
+    int     t0, t1, t2, t3, t4, t5, t6, t7, t8;
+
+    /* apply the InvHaar8 to all rows */
+#define COMPENSATE(x) (x)
+    for (i = 0; i < 8; i++) {
+        if (   !in[0] && !in[1] && !in[2] && !in[3]
+            && !in[4] && !in[5] && !in[6] && !in[7]) {
+            memset(out, 0, 8 * sizeof(out[0]));
+        } else {
+            INV_HAAR8(in[0],  in[1],  in[2],  in[3],
+                      in[4],  in[5],  in[6],  in[7],
+                      out[0], out[1], out[2], out[3],
+                      out[4], out[5], out[6], out[7],
+                      t0, t1, t2, t3, t4, t5, t6, t7, t8);
+        }
+        in  += 8;
+        out += pitch;
+    }
+#undef  COMPENSATE
+}
+
+void ff_ivi_col_haar8(const int32_t *in, int16_t *out, uint32_t pitch,
+                      const uint8_t *flags)
+{
+    int     i;
     int     t0, t1, t2, t3, t4, t5, t6, t7, t8;
 
     /* apply the InvHaar8 to all columns */
 #define COMPENSATE(x) (x)
-    src = in;
     for (i = 0; i < 8; i++) {
         if (flags[i]) {
-            INV_HAAR8(src[ 0], src[ 8], src[16], src[24],
-                      src[32], src[40], src[48], src[56],
-                      out[ 0], out[pitch], out[2*pitch], out[3*pitch],
-                      out[4*pitch], out[5*pitch], out[6*pitch], out[7*pitch],
+            INV_HAAR8(in[ 0], in[ 8], in[16], in[24],
+                      in[32], in[40], in[48], in[56],
+                      out[0 * pitch], out[1 * pitch],
+                      out[2 * pitch], out[3 * pitch],
+                      out[4 * pitch], out[5 * pitch],
+                      out[6 * pitch], out[7 * pitch],
                       t0, t1, t2, t3, t4, t5, t6, t7, t8);
         } else
-            out[      0]= out[  pitch]= out[2*pitch]= out[3*pitch]=
-            out[4*pitch]= out[5*pitch]= out[6*pitch]= out[7*pitch]= 0;
+            out[0 * pitch] = out[1 * pitch] =
+            out[2 * pitch] = out[3 * pitch] =
+            out[4 * pitch] = out[5 * pitch] =
+            out[6 * pitch] = out[7 * pitch] = 0;
 
-        src++;
+        in++;
         out++;
     }
 #undef  COMPENSATE
 }
 
-void ff_ivi_inverse_haar_8x1(const int32_t *in, int16_t *out, uint32_t pitch,
+void ff_ivi_inverse_haar_4x4(const int32_t *in, int16_t *out, uint32_t pitch,
                              const uint8_t *flags)
 {
-    int     i;
+    int     i, shift, sp1, sp2;
     const int32_t *src;
-    int     t0, t1, t2, t3, t4, t5, t6, t7, t8;
+    int32_t *dst;
+    int     tmp[16];
+    int     t0, t1, t2, t3, t4;
+
+    /* apply the InvHaar4 to all columns */
+#define COMPENSATE(x) (x)
+    src = in;
+    dst = tmp;
+    for (i = 0; i < 4; i++) {
+        if (flags[i]) {
+            /* pre-scaling */
+            shift = !(i & 2);
+            sp1 = src[0] << shift;
+            sp2 = src[4] << shift;
+            INV_HAAR4(   sp1,    sp2, src[8], src[12],
+                      dst[0], dst[4], dst[8], dst[12],
+                      t0, t1, t2, t3, t4);
+        } else
+            dst[0] = dst[4] = dst[8] = dst[12] = 0;
+
+        src++;
+        dst++;
+    }
+#undef  COMPENSATE
 
     /* apply the InvHaar8 to all rows */
 #define COMPENSATE(x) (x)
-    src = in;
-    for (i = 0; i < 8; i++) {
-        if (   !src[0] && !src[1] && !src[2] && !src[3]
-            && !src[4] && !src[5] && !src[6] && !src[7]) {
-            memset(out, 0, 8 * sizeof(out[0]));
+    src = tmp;
+    for (i = 0; i < 4; i++) {
+        if (!src[0] && !src[1] && !src[2] && !src[3]) {
+            memset(out, 0, 4 * sizeof(out[0]));
         } else {
-            INV_HAAR8(src[0], src[1], src[2], src[3],
-                      src[4], src[5], src[6], src[7],
+            INV_HAAR4(src[0], src[1], src[2], src[3],
                       out[0], out[1], out[2], out[3],
-                      out[4], out[5], out[6], out[7],
-                      t0, t1, t2, t3, t4, t5, t6, t7, t8);
+                      t0, t1, t2, t3, t4);
         }
-        src += 8;
+        src += 4;
         out += pitch;
     }
 #undef  COMPENSATE
 }
 
+void ff_ivi_row_haar4(const int32_t *in, int16_t *out, uint32_t pitch,
+                      const uint8_t *flags)
+{
+    int     i;
+    int     t0, t1, t2, t3, t4;
+
+    /* apply the InvHaar4 to all rows */
+#define COMPENSATE(x) (x)
+    for (i = 0; i < 4; i++) {
+        if (!in[0] && !in[1] && !in[2] && !in[3]) {
+            memset(out, 0, 4 * sizeof(out[0]));
+        } else {
+            INV_HAAR4(in[0], in[1], in[2], in[3],
+                      out[0], out[1], out[2], out[3],
+                      t0, t1, t2, t3, t4);
+        }
+        in  += 4;
+        out += pitch;
+    }
+#undef  COMPENSATE
+}
+
+void ff_ivi_col_haar4(const int32_t *in, int16_t *out, uint32_t pitch,
+                      const uint8_t *flags)
+{
+    int     i;
+    int     t0, t1, t2, t3, t4;
+
+    /* apply the InvHaar8 to all columns */
+#define COMPENSATE(x) (x)
+    for (i = 0; i < 4; i++) {
+        if (flags[i]) {
+            INV_HAAR4(in[0], in[4], in[8], in[12],
+                      out[0 * pitch], out[1 * pitch],
+                      out[2 * pitch], out[3 * pitch],
+                      t0, t1, t2, t3, t4);
+        } else
+            out[0 * pitch] = out[1 * pitch] =
+            out[2 * pitch] = out[3 * pitch] = 0;
+
+        in++;
+        out++;
+    }
+#undef  COMPENSATE
+}
+
 void ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, uint32_t pitch,
                        int blk_size)
 {
@@ -610,6 +705,49 @@
     }
 }
 
+void ff_ivi_row_slant4(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags)
+{
+    int     i;
+    int     t0, t1, t2, t3, t4;
+
+#define COMPENSATE(x) ((x + 1)>>1)
+    for (i = 0; i < 4; i++) {
+        if (!in[0] && !in[1] && !in[2] && !in[3]) {
+            memset(out, 0, 4*sizeof(out[0]));
+        } else {
+            IVI_INV_SLANT4( in[0],  in[1],  in[2],  in[3],
+                           out[0], out[1], out[2], out[3],
+                           t0, t1, t2, t3, t4);
+        }
+        in  += 4;
+        out += pitch;
+    }
+#undef COMPENSATE
+}
+
+void ff_ivi_col_slant4(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags)
+{
+    int     i, row2;
+    int     t0, t1, t2, t3, t4;
+
+    row2 = pitch << 1;
+
+#define COMPENSATE(x) ((x + 1)>>1)
+    for (i = 0; i < 4; i++) {
+        if (flags[i]) {
+            IVI_INV_SLANT4(in[0], in[4], in[8], in[12],
+                           out[0], out[pitch], out[row2], out[row2 + pitch],
+                           t0, t1, t2, t3, t4);
+        } else {
+            out[0] = out[pitch] = out[row2] = out[row2 + pitch] = 0;
+        }
+
+        in++;
+        out++;
+    }
+#undef COMPENSATE
+}
+
 void ff_ivi_put_pixels_8x8(const int32_t *in, int16_t *out, uint32_t pitch,
                            const uint8_t *flags)
 {
diff --git a/libavcodec/ivi_dsp.h b/libavcodec/ivi_dsp.h
index 748b3f4..245f01d 100644
--- a/libavcodec/ivi_dsp.h
+++ b/libavcodec/ivi_dsp.h
@@ -70,6 +70,71 @@
                              const uint8_t *flags);
 
 /**
+ *  one-dimensional inverse 8-point Haar transform on rows for Indeo 4
+ *
+ *  @param[in]  in        pointer to the vector of transform coefficients
+ *  @param[out] out       pointer to the output buffer (frame)
+ *  @param[in]  pitch     pitch to move to the next y line
+ *  @param[in]  flags     pointer to the array of column flags:
+ *                        != 0 - non_empty column, 0 - empty one
+ *                        (this array must be filled by caller)
+ */
+void ff_ivi_row_haar8(const int32_t *in, int16_t *out, uint32_t pitch,
+                      const uint8_t *flags);
+
+/**
+ *  one-dimensional inverse 8-point Haar transform on columns for Indeo 4
+ *
+ *  @param[in]  in        pointer to the vector of transform coefficients
+ *  @param[out] out       pointer to the output buffer (frame)
+ *  @param[in]  pitch     pitch to move to the next y line
+ *  @param[in]  flags     pointer to the array of column flags:
+ *                        != 0 - non_empty column, 0 - empty one
+ *                        (this array must be filled by caller)
+ */
+void ff_ivi_col_haar8(const int32_t *in, int16_t *out, uint32_t pitch,
+                      const uint8_t *flags);
+
+/**
+ *  two-dimensional inverse Haar 4x4 transform for Indeo 4
+ *
+ *  @param[in]  in        pointer to the vector of transform coefficients
+ *  @param[out] out       pointer to the output buffer (frame)
+ *  @param[in]  pitch     pitch to move to the next y line
+ *  @param[in]  flags     pointer to the array of column flags:
+ *                        != 0 - non_empty column, 0 - empty one
+ *                        (this array must be filled by caller)
+ */
+void ff_ivi_inverse_haar_4x4(const int32_t *in, int16_t *out, uint32_t pitch,
+                             const uint8_t *flags);
+
+/**
+ *  one-dimensional inverse 4-point Haar transform on rows for Indeo 4
+ *
+ *  @param[in]  in        pointer to the vector of transform coefficients
+ *  @param[out] out       pointer to the output buffer (frame)
+ *  @param[in]  pitch     pitch to move to the next y line
+ *  @param[in]  flags     pointer to the array of column flags:
+ *                        != 0 - non_empty column, 0 - empty one
+ *                        (this array must be filled by caller)
+ */
+void ff_ivi_row_haar4(const int32_t *in, int16_t *out, uint32_t pitch,
+                      const uint8_t *flags);
+
+/**
+ *  one-dimensional inverse 4-point Haar transform on columns for Indeo 4
+ *
+ *  @param[in]  in        pointer to the vector of transform coefficients
+ *  @param[out] out       pointer to the output buffer (frame)
+ *  @param[in]  pitch     pitch to move to the next y line
+ *  @param[in]  flags     pointer to the array of column flags:
+ *                        != 0 - non_empty column, 0 - empty one
+ *                        (this array must be filled by caller)
+ */
+void ff_ivi_col_haar4(const int32_t *in, int16_t *out, uint32_t pitch,
+                      const uint8_t *flags);
+
+/**
  *  DC-only two-dimensional inverse Haar transform for Indeo 4.
  *  Performing the inverse transform in this case is equivalent to
  *  spreading DC_coeff >> 3 over the whole block.
@@ -146,6 +211,30 @@
                        const uint8_t *flags);
 
 /**
+ *  inverse 1D row slant transform
+ *
+ *  @param[in]    in      pointer to the vector of transform coefficients
+ *  @param[out]   out     pointer to the output buffer (frame)
+ *  @param[in]    pitch   pitch to move to the next y line
+ *  @param[in]    flags   pointer to the array of column flags (unused here)
+ */
+void ff_ivi_row_slant4(const int32_t *in, int16_t *out, uint32_t pitch,
+                       const uint8_t *flags);
+
+/**
+ *  inverse 1D column slant transform
+ *
+ *  @param[in]    in      pointer to the vector of transform coefficients
+ *  @param[out]   out     pointer to the output buffer (frame)
+ *  @param[in]    pitch   pitch to move to the next y line
+ *  @param[in]    flags   pointer to the array of column flags:
+ *                        != 0 - non_empty column, 0 - empty one
+ *                        (this array must be filled by caller)
+ */
+void ff_ivi_col_slant4(const int32_t *in, int16_t *out, uint32_t pitch,
+                       const uint8_t *flags);
+
+/**
  *  DC-only inverse row slant transform
  */
 void ff_ivi_dc_row_slant(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size);
diff --git a/libavcodec/j2k.c b/libavcodec/j2k.c
deleted file mode 100644
index e3c0c13..0000000
--- a/libavcodec/j2k.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * JPEG2000 encoder and decoder common functions
- * Copyright (c) 2007 Kamil Nowosad
- *
- * 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
- */
-
-/**
- * JPEG2000 image encoder and decoder common functions
- * @file
- * @author Kamil Nowosad
- */
-
-
-#include "avcodec.h"
-#include "j2k.h"
-
-#define SHL(a, n) ((n)>=0 ? (a) << (n) : (a) >> -(n))
-
-#if 0
-void ff_j2k_printv(int *tab, int l)
-{
-    int i;
-    for (i = 0; i < l; i++)
-        av_log(NULL, AV_LOG_DEBUG, "%.3d ", tab[i]);
-    av_log(NULL, AV_LOG_DEBUG, "\n");
-}
-
-void ff_j2k_printu(uint8_t *tab, int l)
-{
-    int i;
-    for (i = 0; i < l; i++)
-        av_log(NULL, AV_LOG_DEBUG, "%.3hd ", tab[i]);
-    av_log(NULL, AV_LOG_DEBUG, "\n");
-}
-#endif
-
-/* tag tree routines */
-
-/** allocate the memory for tag tree */
-
-static int tag_tree_size(int w, int h)
-{
-    int res = 0;
-    while (w > 1 || h > 1){
-        res += w * h;
-        w = (w+1) >> 1;
-        h = (h+1) >> 1;
-    }
-    return res + 1;
-}
-
-J2kTgtNode *ff_j2k_tag_tree_init(int w, int h)
-{
-    int pw = w, ph = h;
-    J2kTgtNode *res, *t, *t2;
-
-    t = res = av_mallocz(tag_tree_size(w, h)*sizeof(J2kTgtNode));
-
-    if (res == NULL)
-        return NULL;
-
-    while (w > 1 || h > 1){
-        int i, j;
-        pw = w;
-        ph = h;
-
-        w = (w+1) >> 1;
-        h = (h+1) >> 1;
-        t2 = t + pw*ph;
-
-        for (i = 0; i < ph; i++)
-            for (j = 0; j < pw; j++){
-                t[i*pw + j].parent = &t2[(i>>1)*w + (j>>1)];
-            }
-        t = t2;
-    }
-    t[0].parent = NULL;
-    return res;
-}
-
-static void tag_tree_zero(J2kTgtNode *t, int w, int h)
-{
-    int i, siz = tag_tree_size(w, h);
-
-    for (i = 0; i < siz; i++){
-        t[i].val = 0;
-        t[i].vis = 0;
-    }
-}
-
-uint8_t ff_j2k_nbctxno_lut[256][4];
-
-static int getnbctxno(int flag, int bandno, int vert_causal_ctx_csty_symbol)
-{
-    int h, v, d;
-
-    h = ((flag & J2K_T1_SIG_E) ? 1:0)+
-        ((flag & J2K_T1_SIG_W) ? 1:0);
-    v = ((flag & J2K_T1_SIG_N) ? 1:0);
-    if (!vert_causal_ctx_csty_symbol)
-         v = v + ((flag & J2K_T1_SIG_S) ? 1:0);
-    d = ((flag & J2K_T1_SIG_NE) ? 1:0)+
-        ((flag & J2K_T1_SIG_NW) ? 1:0);
-    if (!vert_causal_ctx_csty_symbol)
-        d = d + ((flag & J2K_T1_SIG_SE) ? 1:0)+
-                ((flag & J2K_T1_SIG_SW) ? 1:0);
-    if (bandno < 3){
-            if (bandno == 1)
-                FFSWAP(int, h, v);
-            if (h == 2) return 8;
-            if (h == 1){
-                if (v >= 1) return 7;
-                if (d >= 1) return 6;
-                return 5;
-            }
-            if (v == 2) return 4;
-            if (v == 1) return 3;
-            if (d >= 2) return 2;
-            if (d == 1) return 1;
-            return 0;
-    } else{
-            if (d >= 3) return 8;
-            if (d == 2){
-                if (h+v >= 1) return 7;
-                return 6;
-            }
-            if (d == 1){
-                if (h+v >= 2) return 5;
-                if (h+v == 1) return 4;
-                return 3;
-            }
-            if (h+v >= 2) return 2;
-            if (h+v == 1) return 1;
-            return 0;
-    }
-}
-
-uint8_t ff_j2k_sgnctxno_lut[16][16], ff_j2k_xorbit_lut[16][16];
-
-static int getsgnctxno(int flag, uint8_t *xorbit)
-{
-    int vcontrib, hcontrib;
-    static const int contribtab[3][3] = {{0, -1, 1}, {-1, -1, 0}, {1, 0, 1}};
-    static const int ctxlbltab[3][3] = {{13, 12, 11}, {10, 9, 10}, {11, 12, 13}};
-    static const int xorbittab[3][3] = {{1, 1, 1,}, {1, 0, 0}, {0, 0, 0}};
-
-    hcontrib = contribtab[flag & J2K_T1_SIG_E ? flag & J2K_T1_SGN_E ? 1:2:0]
-                         [flag & J2K_T1_SIG_W ? flag & J2K_T1_SGN_W ? 1:2:0]+1;
-    vcontrib = contribtab[flag & J2K_T1_SIG_S ? flag & J2K_T1_SGN_S ? 1:2:0]
-                         [flag & J2K_T1_SIG_N ? flag & J2K_T1_SGN_N ? 1:2:0]+1;
-    *xorbit = xorbittab[hcontrib][vcontrib];
-    return ctxlbltab[hcontrib][vcontrib];
-}
-
-void ff_j2k_init_tier1_luts(void)
-{
-    int i, j;
-    for (i = 0; i < 256; i++)
-        for (j = 0; j < 4; j++)
-            ff_j2k_nbctxno_lut[i][j] = getnbctxno(i, j, 0);
-    for (i = 0; i < 16; i++)
-        for (j = 0; j < 16; j++)
-            ff_j2k_sgnctxno_lut[i][j] = getsgnctxno(i + (j << 8), &ff_j2k_xorbit_lut[i][j]);
-}
-
-void ff_j2k_set_significant(J2kT1Context *t1, int x, int y, int negative)
-{
-    x++; y++;
-    t1->flags[y][x] |= J2K_T1_SIG;
-    if (negative){
-        t1->flags[y][x+1] |= J2K_T1_SIG_W | J2K_T1_SGN_W;
-        t1->flags[y][x-1] |= J2K_T1_SIG_E | J2K_T1_SGN_E;
-        t1->flags[y+1][x] |= J2K_T1_SIG_N | J2K_T1_SGN_N;
-        t1->flags[y-1][x] |= J2K_T1_SIG_S | J2K_T1_SGN_S;
-    } else{
-        t1->flags[y][x+1] |= J2K_T1_SIG_W;
-        t1->flags[y][x-1] |= J2K_T1_SIG_E;
-        t1->flags[y+1][x] |= J2K_T1_SIG_N;
-        t1->flags[y-1][x] |= J2K_T1_SIG_S;
-    }
-    t1->flags[y+1][x+1] |= J2K_T1_SIG_NW;
-    t1->flags[y+1][x-1] |= J2K_T1_SIG_NE;
-    t1->flags[y-1][x+1] |= J2K_T1_SIG_SW;
-    t1->flags[y-1][x-1] |= J2K_T1_SIG_SE;
-}
-
-int ff_j2k_init_component(J2kComponent *comp, J2kCodingStyle *codsty, J2kQuantStyle *qntsty, int cbps, int dx, int dy)
-{
-    int reslevelno, bandno, gbandno = 0, ret, i, j, csize = 1;
-
-    if (ret=ff_j2k_dwt_init(&comp->dwt, comp->coord, codsty->nreslevels-1, codsty->transform))
-        return ret;
-    for (i = 0; i < 2; i++)
-        csize *= comp->coord[i][1] - comp->coord[i][0];
-
-    comp->data = av_malloc(csize * sizeof(int));
-    if (!comp->data)
-        return AVERROR(ENOMEM);
-    comp->reslevel = av_malloc(codsty->nreslevels * sizeof(J2kResLevel));
-
-    if (!comp->reslevel)
-        return AVERROR(ENOMEM);
-    for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){
-        int declvl = codsty->nreslevels - reslevelno;
-        J2kResLevel *reslevel = comp->reslevel + reslevelno;
-
-        for (i = 0; i < 2; i++)
-            for (j = 0; j < 2; j++)
-                reslevel->coord[i][j] =
-                    ff_j2k_ceildivpow2(comp->coord[i][j], declvl - 1);
-
-        if (reslevelno == 0)
-            reslevel->nbands = 1;
-        else
-            reslevel->nbands = 3;
-
-        if (reslevel->coord[0][1] == reslevel->coord[0][0])
-            reslevel->num_precincts_x = 0;
-        else
-            reslevel->num_precincts_x = ff_j2k_ceildivpow2(reslevel->coord[0][1], codsty->log2_prec_width)
-                                        - (reslevel->coord[0][0] >> codsty->log2_prec_width);
-
-        if (reslevel->coord[1][1] == reslevel->coord[1][0])
-            reslevel->num_precincts_y = 0;
-        else
-            reslevel->num_precincts_y = ff_j2k_ceildivpow2(reslevel->coord[1][1], codsty->log2_prec_height)
-                                        - (reslevel->coord[1][0] >> codsty->log2_prec_height);
-
-        reslevel->band = av_malloc(reslevel->nbands * sizeof(J2kBand));
-        if (!reslevel->band)
-            return AVERROR(ENOMEM);
-        for (bandno = 0; bandno < reslevel->nbands; bandno++, gbandno++){
-            J2kBand *band = reslevel->band + bandno;
-            int cblkno, precx, precy, precno;
-            int x0, y0, x1, y1;
-            int xi0, yi0, xi1, yi1;
-            int cblkperprecw, cblkperprech;
-
-            if (qntsty->quantsty != J2K_QSTY_NONE){
-                static const uint8_t lut_gain[2][4] = {{0, 0, 0, 0}, {0, 1, 1, 2}};
-                int numbps;
-
-                numbps = cbps + lut_gain[codsty->transform][bandno + reslevelno>0];
-                band->stepsize = SHL(2048 + qntsty->mant[gbandno], 2 + numbps - qntsty->expn[gbandno]);
-            } else
-                band->stepsize = 1 << 13;
-
-            if (reslevelno == 0){  // the same everywhere
-                band->codeblock_width = 1 << FFMIN(codsty->log2_cblk_width, codsty->log2_prec_width-1);
-                band->codeblock_height = 1 << FFMIN(codsty->log2_cblk_height, codsty->log2_prec_height-1);
-                for (i = 0; i < 2; i++)
-                    for (j = 0; j < 2; j++)
-                        band->coord[i][j] = ff_j2k_ceildivpow2(comp->coord[i][j], declvl-1);
-            } else{
-                band->codeblock_width = 1 << FFMIN(codsty->log2_cblk_width, codsty->log2_prec_width);
-                band->codeblock_height = 1 << FFMIN(codsty->log2_cblk_height, codsty->log2_prec_height);
-
-                for (i = 0; i < 2; i++)
-                    for (j = 0; j < 2; j++)
-                        band->coord[i][j] = ff_j2k_ceildivpow2(comp->coord[i][j] - (((bandno+1>>i)&1) << declvl-1), declvl);
-            }
-            band->cblknx = ff_j2k_ceildiv(band->coord[0][1], band->codeblock_width)  - band->coord[0][0] / band->codeblock_width;
-            band->cblkny = ff_j2k_ceildiv(band->coord[1][1], band->codeblock_height) - band->coord[1][0] / band->codeblock_height;
-
-            for (j = 0; j < 2; j++)
-                band->coord[0][j] = ff_j2k_ceildiv(band->coord[0][j], dx);
-            for (j = 0; j < 2; j++)
-                band->coord[1][j] = ff_j2k_ceildiv(band->coord[1][j], dy);
-
-            band->cblknx = ff_j2k_ceildiv(band->cblknx, dx);
-            band->cblkny = ff_j2k_ceildiv(band->cblkny, dy);
-
-            band->cblk = av_malloc(sizeof(J2kCblk) * band->cblknx * band->cblkny);
-            if (!band->cblk)
-                return AVERROR(ENOMEM);
-            band->prec = av_malloc(sizeof(J2kCblk) * reslevel->num_precincts_x * reslevel->num_precincts_y);
-            if (!band->prec)
-                return AVERROR(ENOMEM);
-
-            for (cblkno = 0; cblkno < band->cblknx * band->cblkny; cblkno++){
-                J2kCblk *cblk = band->cblk + cblkno;
-                cblk->zero = 0;
-                cblk->lblock = 3;
-                cblk->length = 0;
-                cblk->lengthinc = 0;
-                cblk->npasses = 0;
-            }
-
-            y0 = band->coord[1][0];
-            y1 = ((band->coord[1][0] + (1<<codsty->log2_prec_height)) & ~((1<<codsty->log2_prec_height)-1)) - y0;
-            yi0 = 0;
-            yi1 = ff_j2k_ceildivpow2(y1 - y0, codsty->log2_cblk_height) << codsty->log2_cblk_height;
-            yi1 = FFMIN(yi1, band->cblkny);
-            cblkperprech = 1<<(codsty->log2_prec_height - codsty->log2_cblk_height);
-            for (precy = 0, precno = 0; precy < reslevel->num_precincts_y; precy++){
-                for (precx = 0; precx < reslevel->num_precincts_x; precx++, precno++){
-                    band->prec[precno].yi0 = yi0;
-                    band->prec[precno].yi1 = yi1;
-                }
-                yi1 += cblkperprech;
-                yi0 = yi1 - cblkperprech;
-                yi1 = FFMIN(yi1, band->cblkny);
-            }
-            x0 = band->coord[0][0];
-            x1 = ((band->coord[0][0] + (1<<codsty->log2_prec_width)) & ~((1<<codsty->log2_prec_width)-1)) - x0;
-            xi0 = 0;
-            xi1 = ff_j2k_ceildivpow2(x1 - x0, codsty->log2_cblk_width) << codsty->log2_cblk_width;
-            xi1 = FFMIN(xi1, band->cblknx);
-
-            cblkperprecw = 1<<(codsty->log2_prec_width - codsty->log2_cblk_width);
-            for (precx = 0, precno = 0; precx < reslevel->num_precincts_x; precx++){
-                for (precy = 0; precy < reslevel->num_precincts_y; precy++, precno = 0){
-                    J2kPrec *prec = band->prec + precno;
-                    prec->xi0 = xi0;
-                    prec->xi1 = xi1;
-                    prec->cblkincl = ff_j2k_tag_tree_init(prec->xi1 - prec->xi0,
-                                                          prec->yi1 - prec->yi0);
-                    prec->zerobits = ff_j2k_tag_tree_init(prec->xi1 - prec->xi0,
-                                                          prec->yi1 - prec->yi0);
-                    if (!prec->cblkincl || !prec->zerobits)
-                        return AVERROR(ENOMEM);
-
-                }
-                xi1 += cblkperprecw;
-                xi0 = xi1 - cblkperprecw;
-                xi1 = FFMIN(xi1, band->cblknx);
-            }
-        }
-    }
-    return 0;
-}
-
-void ff_j2k_reinit(J2kComponent *comp, J2kCodingStyle *codsty)
-{
-    int reslevelno, bandno, cblkno, precno;
-    for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){
-        J2kResLevel *rlevel = comp->reslevel + reslevelno;
-        for (bandno = 0; bandno < rlevel->nbands; bandno++){
-            J2kBand *band = rlevel->band + bandno;
-            for(precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++){
-                J2kPrec *prec = band->prec + precno;
-                tag_tree_zero(prec->zerobits, prec->xi1 - prec->xi0, prec->yi1 - prec->yi0);
-                tag_tree_zero(prec->cblkincl, prec->xi1 - prec->xi0, prec->yi1 - prec->yi0);
-            }
-            for (cblkno = 0; cblkno < band->cblknx * band->cblkny; cblkno++){
-                J2kCblk *cblk = band->cblk + cblkno;
-                cblk->length = 0;
-                cblk->lblock = 3;
-            }
-        }
-    }
-}
-
-void ff_j2k_cleanup(J2kComponent *comp, J2kCodingStyle *codsty)
-{
-    int reslevelno, bandno, precno;
-    for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){
-        J2kResLevel *reslevel = comp->reslevel + reslevelno;
-
-        for (bandno = 0; bandno < reslevel->nbands ; bandno++){
-            J2kBand *band = reslevel->band + bandno;
-                for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){
-                    J2kPrec *prec = band->prec + precno;
-                    av_freep(&prec->zerobits);
-                    av_freep(&prec->cblkincl);
-                }
-                av_freep(&band->cblk);
-                av_freep(&band->prec);
-            }
-        av_freep(&reslevel->band);
-    }
-
-    ff_j2k_dwt_destroy(&comp->dwt);
-    av_freep(&comp->reslevel);
-    av_freep(&comp->data);
-}
diff --git a/libavcodec/j2k.h b/libavcodec/j2k.h
deleted file mode 100644
index 85d5cd0..0000000
--- a/libavcodec/j2k.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * JPEG2000 tables
- * Copyright (c) 2007 Kamil Nowosad
- *
- * 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
- */
-
-#ifndef AVCODEC_J2K_H
-#define AVCODEC_J2K_H
-
-/**
- * JPEG2000 tables
- * @file
- * @author Kamil Nowosad
- */
-
-#include "mqc.h"
-#include "j2k_dwt.h"
-
-enum J2kMarkers{
-    J2K_SOC = 0xff4f, ///< start of codestream
-    J2K_SIZ = 0xff51, ///< image and tile size
-    J2K_COD,          ///< coding style default
-    J2K_COC,          ///< coding style component
-    J2K_TLM = 0xff55, ///< packed packet headers, tile-part header
-    J2K_PLM = 0xff57, ///< tile-part lengths
-    J2K_PLT,          ///< packet length, main header
-    J2K_QCD = 0xff5c, ///< quantization default
-    J2K_QCC,          ///< quantization component
-    J2K_RGN,          ///< region of interest
-    J2K_POC,          ///< progression order change
-    J2K_PPM,          ///< packet length, tile-part header
-    J2K_PPT,          ///< packed packet headers, main header
-    J2K_CRG = 0xff63, ///< component registration
-    J2K_COM,          ///< comment
-    J2K_SOT = 0xff90, ///< start of tile-part
-    J2K_SOP,          ///< start of packet
-    J2K_EPH,          ///< end of packet header
-    J2K_SOD,          ///< start of data
-    J2K_EOC = 0xffd9, ///< end of codestream
-};
-
-enum J2kQuantsty{ ///< quantization style
-    J2K_QSTY_NONE, ///< no quantization
-    J2K_QSTY_SI,   ///< scalar derived
-    J2K_QSTY_SE    ///< scalar expoounded
-};
-
-#define J2K_MAX_CBLKW 64
-#define J2K_MAX_CBLKH 64
-
-// T1 flags
-// flags determining significance of neighbour coefficients
-#define J2K_T1_SIG_N  0x0001
-#define J2K_T1_SIG_E  0x0002
-#define J2K_T1_SIG_W  0x0004
-#define J2K_T1_SIG_S  0x0008
-#define J2K_T1_SIG_NE 0x0010
-#define J2K_T1_SIG_NW 0x0020
-#define J2K_T1_SIG_SE 0x0040
-#define J2K_T1_SIG_SW 0x0080
-#define J2K_T1_SIG_NB (J2K_T1_SIG_N | J2K_T1_SIG_E | J2K_T1_SIG_S | J2K_T1_SIG_W \
-                      |J2K_T1_SIG_NE | J2K_T1_SIG_NW | J2K_T1_SIG_SE | J2K_T1_SIG_SW)
-// flags determining sign bit of neighbour coefficients
-#define J2K_T1_SGN_N  0x0100
-#define J2K_T1_SGN_S  0x0200
-#define J2K_T1_SGN_W  0x0400
-#define J2K_T1_SGN_E  0x0800
-
-#define J2K_T1_VIS    0x1000
-#define J2K_T1_SIG    0x2000
-#define J2K_T1_REF    0x4000
-
-#define J2K_T1_SGN    0x8000
-
-// Codeblock coding styles
-#define J2K_CBLK_BYPASS    0x01 // Selective arithmetic coding bypass
-#define J2K_CBLK_RESET     0x02 // Reset context probabilities
-#define J2K_CBLK_TERMALL   0x04 // Terminate after each coding pass
-#define J2K_CBLK_VSC       0x08 // Vertical stripe causal context formation
-#define J2K_CBLK_PREDTERM  0x10 // Predictable termination
-#define J2K_CBLK_SEGSYM    0x20 // Segmentation symbols present
-
-// Coding styles
-#define J2K_CSTY_PREC      0x01 // Precincts defined in coding style
-#define J2K_CSTY_SOP       0x02 // SOP marker present
-#define J2K_CSTY_EPH       0x04 // EPH marker present
-
-typedef struct {
-    int data[J2K_MAX_CBLKW][J2K_MAX_CBLKH];
-    int flags[J2K_MAX_CBLKW+2][J2K_MAX_CBLKH+2];
-    MqcState mqc;
-} J2kT1Context;
-
-typedef struct J2kTgtNode {
-    uint8_t val;
-    uint8_t vis;
-    struct J2kTgtNode *parent;
-} J2kTgtNode;
-
-typedef struct {
-    uint8_t nreslevels;       ///< number of resolution levels
-    uint8_t log2_cblk_width,
-            log2_cblk_height; ///< exponent of codeblock size
-    uint8_t transform;        ///< DWT type
-    uint8_t csty;             ///< coding style
-    uint8_t log2_prec_width,
-            log2_prec_height; ///< precinct size
-    uint8_t nlayers;          ///< number of layers
-    uint8_t mct;              ///< multiple component transformation
-    uint8_t cblk_style;       ///< codeblock coding style
-} J2kCodingStyle;
-
-typedef struct {
-    uint8_t  expn[32 * 3]; ///< quantization exponent
-    uint16_t mant[32 * 3]; ///< quantization mantissa
-    uint8_t  quantsty;     ///< quantization style
-    uint8_t  nguardbits;   ///< number of guard bits
-} J2kQuantStyle;
-
-typedef struct {
-    uint16_t rate;
-    int64_t disto;
-} J2kPass;
-
-typedef struct {
-    uint8_t npasses;
-    uint8_t ninclpasses; ///< number coding of passes included in codestream
-    uint8_t nonzerobits;
-    uint16_t length;
-    uint16_t lengthinc;
-    uint8_t lblock;
-    uint8_t zero;
-    uint8_t data[8192];
-    J2kPass passes[100];
-} J2kCblk; ///< code block
-
-typedef struct {
-    uint16_t xi0, xi1, yi0, yi1; ///< codeblock indexes ([xi0, xi1))
-    J2kTgtNode *zerobits;
-    J2kTgtNode *cblkincl;
-} J2kPrec; ///< precinct
-
-typedef struct {
-    uint16_t coord[2][2]; ///< border coordinates {{x0, x1}, {y0, y1}}
-    uint16_t codeblock_width, codeblock_height;
-    uint16_t cblknx, cblkny;
-    uint32_t stepsize; ///< quantization stepsize (* 2^13)
-    J2kPrec *prec;
-    J2kCblk *cblk;
-} J2kBand; ///< subband
-
-typedef struct {
-    uint8_t nbands;
-    uint16_t coord[2][2]; ///< border coordinates {{x0, x1}, {y0, y1}}
-    uint16_t num_precincts_x, num_precincts_y; ///< number of precincts in x/y direction
-    uint8_t log2_prec_width, log2_prec_height; ///< exponent of precinct size
-    J2kBand *band;
-} J2kResLevel; ///< resolution level
-
-typedef struct {
-   J2kResLevel *reslevel;
-   DWTContext dwt;
-   int *data;
-   uint16_t coord[2][2]; ///< border coordinates {{x0, x1}, {y0, y1}}
-} J2kComponent;
-
-/* debug routines */
-#if 0
-#undef fprintf
-#undef printf
-void ff_j2k_printv(int *tab, int l);
-void ff_j2k_printu(uint8_t *tab, int l);
-#endif
-
-/* misc tools */
-static inline int ff_j2k_ceildivpow2(int a, int b)
-{
-    return (a + (1 << b) - 1)>> b;
-}
-
-static inline int ff_j2k_ceildiv(int a, int b)
-{
-    return (a + b - 1) / b;
-}
-
-/* tag tree routines */
-J2kTgtNode *ff_j2k_tag_tree_init(int w, int h);
-
-/* TIER-1 routines */
-void ff_j2k_init_tier1_luts(void);
-
-void ff_j2k_set_significant(J2kT1Context *t1, int x, int y, int negative);
-
-extern uint8_t ff_j2k_nbctxno_lut[256][4];
-
-static inline int ff_j2k_getnbctxno(int flag, int bandno, int vert_causal_ctx_csty_symbol)
-{
-    return ff_j2k_nbctxno_lut[flag&255][bandno];
-}
-
-static inline int ff_j2k_getrefctxno(int flag)
-{
-    static const uint8_t refctxno_lut[2][2] = {{14, 15}, {16, 16}};
-    return refctxno_lut[(flag>>14)&1][(flag & 255) != 0];
-}
-
-extern uint8_t ff_j2k_sgnctxno_lut[16][16], ff_j2k_xorbit_lut[16][16];
-
-static inline int ff_j2k_getsgnctxno(int flag, int *xorbit)
-{
-    *xorbit = ff_j2k_xorbit_lut[flag&15][(flag>>8)&15];
-    return  ff_j2k_sgnctxno_lut[flag&15][(flag>>8)&15];
-}
-
-int ff_j2k_init_component(J2kComponent *comp, J2kCodingStyle *codsty, J2kQuantStyle *qntsty, int cbps, int dx, int dy);
-void ff_j2k_reinit(J2kComponent *comp, J2kCodingStyle *codsty);
-void ff_j2k_cleanup(J2kComponent *comp, J2kCodingStyle *codsty);
-
-#endif /* AVCODEC_J2K_H */
diff --git a/libavcodec/j2k_dwt.c b/libavcodec/j2k_dwt.c
deleted file mode 100644
index 6f1457f..0000000
--- a/libavcodec/j2k_dwt.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * Discrete wavelet transform
- * Copyright (c) 2007 Kamil Nowosad
- *
- * 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
- */
-
-/**
- * Discrete wavelet transform
- * @file
- * @author Kamil Nowosad
- */
-
-#include "j2k_dwt.h"
-
-static const float scale97[] = {1.625786, 1.230174};
-
-static inline void extend53(int *p, int i0, int i1)
-{
-    p[i0 - 1] = p[i0 + 1];
-    p[i1    ] = p[i1 - 2];
-    p[i0 - 2] = p[i0 + 2];
-    p[i1 + 1] = p[i1 - 3];
-}
-
-static inline void extend97(float *p, int i0, int i1)
-{
-    int i;
-
-    for (i = 1; i <= 4; i++){
-        p[i0 - i] = p[i0 + i];
-        p[i1 + i - 1] = p[i1 - i - 1];
-    }
-}
-
-static void sd_1d53(int *p, int i0, int i1)
-{
-    int i;
-
-    if (i1 == i0 + 1)
-        return;
-
-    extend53(p, i0, i1);
-
-    for (i = (i0+1)/2 - 1; i < (i1+1)/2; i++)
-        p[2*i+1] -= (p[2*i] + p[2*i+2]) >> 1;
-    for (i = (i0+1)/2; i < (i1+1)/2; i++)
-        p[2*i] += (p[2*i-1] + p[2*i+1] + 2) >> 2;
-}
-
-static void dwt_encode53(DWTContext *s, int *t)
-{
-    int lev,
-        w = s->linelen[s->ndeclevels-1][0];
-    int *line = s->linebuf;
-    line += 3;
-
-    for (lev = s->ndeclevels-1; lev >= 0; lev--){
-        int lh = s->linelen[lev][0],
-            lv = s->linelen[lev][1],
-            mh = s->mod[lev][0],
-            mv = s->mod[lev][1],
-            lp;
-        int *l;
-
-        // HOR_SD
-        l = line + mh;
-        for (lp = 0; lp < lv; lp++){
-            int i, j = 0;
-
-            for (i = 0; i < lh; i++)
-                l[i] = t[w*lp + i];
-
-            sd_1d53(line, mh, mh + lh);
-
-            // copy back and deinterleave
-            for (i =   mh; i < lh; i+=2, j++)
-                t[w*lp + j] = l[i];
-            for (i = 1-mh; i < lh; i+=2, j++)
-                t[w*lp + j] = l[i];
-        }
-
-        // VER_SD
-        l = line + mv;
-        for (lp = 0; lp < lh; lp++) {
-            int i, j = 0;
-
-            for (i = 0; i < lv; i++)
-                l[i] = t[w*i + lp];
-
-            sd_1d53(line, mv, mv + lv);
-
-            // copy back and deinterleave
-            for (i =   mv; i < lv; i+=2, j++)
-                t[w*j + lp] = l[i];
-            for (i = 1-mv; i < lv; i+=2, j++)
-                t[w*j + lp] = l[i];
-        }
-    }
-}
-
-static void sd_1d97(float *p, int i0, int i1)
-{
-    int i;
-
-    if (i1 == i0 + 1)
-        return;
-
-    extend97(p, i0, i1);
-    i0++; i1++;
-
-    for (i = i0/2 - 2; i < i1/2 + 1; i++)
-        p[2*i+1] -= 1.586134 * (p[2*i] + p[2*i+2]);
-    for (i = i0/2 - 1; i < i1/2 + 1; i++)
-        p[2*i] -= 0.052980 * (p[2*i-1] + p[2*i+1]);
-    for (i = i0/2 - 1; i < i1/2; i++)
-        p[2*i+1] += 0.882911 * (p[2*i] + p[2*i+2]);
-    for (i = i0/2; i < i1/2; i++)
-        p[2*i] += 0.443506 * (p[2*i-1] + p[2*i+1]);
-}
-
-static void dwt_encode97(DWTContext *s, int *t)
-{
-    int lev,
-        w = s->linelen[s->ndeclevels-1][0];
-    float *line = s->linebuf;
-    line += 5;
-
-    for (lev = s->ndeclevels-1; lev >= 0; lev--){
-        int lh = s->linelen[lev][0],
-            lv = s->linelen[lev][1],
-            mh = s->mod[lev][0],
-            mv = s->mod[lev][1],
-            lp;
-        float *l;
-
-        // HOR_SD
-        l = line + mh;
-        for (lp = 0; lp < lv; lp++){
-            int i, j = 0;
-
-            for (i = 0; i < lh; i++)
-                l[i] = t[w*lp + i];
-
-            sd_1d97(line, mh, mh + lh);
-
-            // copy back and deinterleave
-            for (i =   mh; i < lh; i+=2, j++)
-                t[w*lp + j] = scale97[mh] * l[i] / 2;
-            for (i = 1-mh; i < lh; i+=2, j++)
-                t[w*lp + j] = scale97[mh] * l[i] / 2;
-        }
-
-        // VER_SD
-        l = line + mv;
-        for (lp = 0; lp < lh; lp++) {
-            int i, j = 0;
-
-            for (i = 0; i < lv; i++)
-                l[i] = t[w*i + lp];
-
-            sd_1d97(line, mv, mv + lv);
-
-            // copy back and deinterleave
-            for (i =   mv; i < lv; i+=2, j++)
-                t[w*j + lp] = scale97[mv] * l[i] / 2;
-            for (i = 1-mv; i < lv; i+=2, j++)
-                t[w*j + lp] = scale97[mv] * l[i] / 2;
-        }
-    }
-}
-
-static void sr_1d53(int *p, int i0, int i1)
-{
-    int i;
-
-    if (i1 == i0 + 1)
-        return;
-
-    extend53(p, i0, i1);
-
-    for (i = i0/2; i < i1/2 + 1; i++)
-        p[2*i] -= (p[2*i-1] + p[2*i+1] + 2) >> 2;
-    for (i = i0/2; i < i1/2; i++)
-        p[2*i+1] += (p[2*i] + p[2*i+2]) >> 1;
-}
-
-static void dwt_decode53(DWTContext *s, int *t)
-{
-    int lev,
-        w = s->linelen[s->ndeclevels-1][0];
-    int *line = s->linebuf;
-    line += 3;
-
-    for (lev = 0; lev < s->ndeclevels; lev++){
-        int lh = s->linelen[lev][0],
-            lv = s->linelen[lev][1],
-            mh = s->mod[lev][0],
-            mv = s->mod[lev][1],
-            lp;
-        int *l;
-
-        // HOR_SD
-        l = line + mh;
-        for (lp = 0; lp < lv; lp++){
-            int i, j = 0;
-            // copy with interleaving
-            for (i =   mh; i < lh; i+=2, j++)
-                l[i] = t[w*lp + j];
-            for (i = 1-mh; i < lh; i+=2, j++)
-                l[i] = t[w*lp + j];
-
-            sr_1d53(line, mh, mh + lh);
-
-            for (i = 0; i < lh; i++)
-                t[w*lp + i] = l[i];
-        }
-
-        // VER_SD
-        l = line + mv;
-        for (lp = 0; lp < lh; lp++){
-            int i, j = 0;
-            // copy with interleaving
-            for (i =   mv; i < lv; i+=2, j++)
-                l[i] = t[w*j + lp];
-            for (i = 1-mv; i < lv; i+=2, j++)
-                l[i] = t[w*j + lp];
-
-            sr_1d53(line, mv, mv + lv);
-
-            for (i = 0; i < lv; i++)
-                t[w*i + lp] = l[i];
-        }
-    }
-}
-
-static void sr_1d97(float *p, int i0, int i1)
-{
-    int i;
-
-    if (i1 == i0 + 1)
-        return;
-
-    extend97(p, i0, i1);
-
-    for (i = i0/2 - 1; i < i1/2 + 2; i++)
-        p[2*i] -= 0.443506 * (p[2*i-1] + p[2*i+1]);
-    for (i = i0/2 - 1; i < i1/2 + 1; i++)
-        p[2*i+1] -= 0.882911 * (p[2*i] + p[2*i+2]);
-    for (i = i0/2; i < i1/2 + 1; i++)
-        p[2*i] += 0.052980 * (p[2*i-1] + p[2*i+1]);
-    for (i = i0/2; i < i1/2; i++)
-        p[2*i+1] += 1.586134 * (p[2*i] + p[2*i+2]);
-}
-
-static void dwt_decode97(DWTContext *s, int *t)
-{
-    int lev,
-        w = s->linelen[s->ndeclevels-1][0];
-    float *line = s->linebuf;
-    line += 5;
-
-    for (lev = 0; lev < s->ndeclevels; lev++){
-        int lh = s->linelen[lev][0],
-            lv = s->linelen[lev][1],
-            mh = s->mod[lev][0],
-            mv = s->mod[lev][1],
-            lp;
-        float *l;
-
-        // HOR_SD
-        l = line + mh;
-        for (lp = 0; lp < lv; lp++){
-            int i, j = 0;
-            // copy with interleaving
-            for (i =   mh; i < lh; i+=2, j++)
-                l[i] = scale97[1-mh] * t[w*lp + j];
-            for (i = 1-mh; i < lh; i+=2, j++)
-                l[i] = scale97[1-mh] * t[w*lp + j];
-
-            sr_1d97(line, mh, mh + lh);
-
-            for (i = 0; i < lh; i++)
-                t[w*lp + i] = l[i];
-        }
-
-        // VER_SD
-        l = line + mv;
-        for (lp = 0; lp < lh; lp++){
-            int i, j = 0;
-            // copy with interleaving
-            for (i =   mv; i < lv; i+=2, j++)
-                l[i] = scale97[1-mv] * t[w*j + lp];
-            for (i = 1-mv; i < lv; i+=2, j++)
-                l[i] = scale97[1-mv] * t[w*j + lp];
-
-            sr_1d97(line, mv, mv + lv);
-
-            for (i = 0; i < lv; i++)
-                t[w*i + lp] = l[i];
-        }
-    }
-}
-
-int ff_j2k_dwt_init(DWTContext *s, uint16_t border[2][2], int decomp_levels, int type)
-{
-    int i, j, lev = decomp_levels, maxlen,
-        b[2][2];
-
-    if ((unsigned)decomp_levels >= FF_DWT_MAX_DECLVLS)
-        return AVERROR_INVALIDDATA;
-    s->ndeclevels = decomp_levels;
-    s->type = type;
-
-    for (i = 0; i < 2; i++)
-        for(j = 0; j < 2; j++)
-            b[i][j] = border[i][j];
-
-    maxlen = FFMAX(b[0][1] - b[0][0],
-                   b[1][1] - b[1][0]);
-
-    while(--lev >= 0){
-        for (i = 0; i < 2; i++){
-            s->linelen[lev][i] = b[i][1] - b[i][0];
-            s->mod[lev][i] = b[i][0] & 1;
-            for (j = 0; j < 2; j++)
-                b[i][j] = (b[i][j] + 1) >> 1;
-        }
-    }
-    if (type == FF_DWT97)
-        s->linebuf = av_malloc((maxlen + 12) * sizeof(float));
-    else if (type == FF_DWT53)
-        s->linebuf = av_malloc((maxlen + 6) * sizeof(int));
-    else
-        return -1;
-
-    if (!s->linebuf)
-        return AVERROR(ENOMEM);
-
-    return 0;
-}
-
-int ff_j2k_dwt_encode(DWTContext *s, int *t)
-{
-    switch(s->type){
-        case FF_DWT97:
-            dwt_encode97(s, t); break;
-        case FF_DWT53:
-            dwt_encode53(s, t); break;
-        default:
-            return -1;
-    }
-    return 0;
-}
-
-int ff_j2k_dwt_decode(DWTContext *s, int *t)
-{
-    switch(s->type){
-        case FF_DWT97:
-            dwt_decode97(s, t); break;
-        case FF_DWT53:
-            dwt_decode53(s, t); break;
-        default:
-            return -1;
-    }
-    return 0;
-}
-
-void ff_j2k_dwt_destroy(DWTContext *s)
-{
-    av_freep(&s->linebuf);
-}
diff --git a/libavcodec/j2k_dwt.h b/libavcodec/j2k_dwt.h
deleted file mode 100644
index a2a25a6..0000000
--- a/libavcodec/j2k_dwt.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Discrete wavelet transform
- * Copyright (c) 2007 Kamil Nowosad
- *
- * 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
- */
-
-#ifndef AVCODEC_DWT_H
-#define AVCODEC_DWT_H
-
-/**
- * Discrete wavelet transform
- * @file
- * @author Kamil Nowosad
- */
-
-#include "avcodec.h"
-
-#define FF_DWT_MAX_DECLVLS 32 ///< max number of decomposition levels
-
-enum DWTType{
-    FF_DWT97,
-    FF_DWT53
-};
-
-typedef struct {
-    ///line lengths {horizontal, vertical} in consecutive decomposition levels
-    uint16_t linelen[FF_DWT_MAX_DECLVLS][2];
-    uint8_t  mod[FF_DWT_MAX_DECLVLS][2]; ///< coordinates (x0, y0) of decomp. levels mod 2
-    uint8_t  ndeclevels;                 ///< number of decomposition levels
-    uint8_t  type;                       ///< 0 for 9/7; 1 for 5/3
-    void     *linebuf;                   ///< buffer used by transform (int or float)
-} DWTContext;
-
-/**
- * initialize DWT
- * @param s DWT context
- * @param border coordinates of transformed region {{x0, x1}, {y0, y1}}
- * @param decomp_levels number of decomposition levels
- * @param type 0 for DWT 9/7; 1 for DWT 5/3
- */
-int ff_j2k_dwt_init(DWTContext *s, uint16_t border[2][2], int decomp_levels, int type);
-
-int ff_j2k_dwt_encode(DWTContext *s, int *t);
-int ff_j2k_dwt_decode(DWTContext *s, int *t);
-
-void ff_j2k_dwt_destroy(DWTContext *s);
-
-#endif /* AVCODEC_DWT_H */
diff --git a/libavcodec/j2kdec.c b/libavcodec/j2kdec.c
deleted file mode 100644
index 683062d..0000000
--- a/libavcodec/j2kdec.c
+++ /dev/null
@@ -1,1093 +0,0 @@
-/*
- * JPEG2000 image decoder
- * Copyright (c) 2007 Kamil Nowosad
- *
- * 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
- */
-
-/**
- * JPEG2000 image decoder
- * @file
- * @author Kamil Nowosad
- */
-
-// #define DEBUG
-
-#include "avcodec.h"
-#include "bytestream.h"
-#include "internal.h"
-#include "j2k.h"
-#include "libavutil/common.h"
-
-#define JP2_SIG_TYPE    0x6A502020
-#define JP2_SIG_VALUE   0x0D0A870A
-#define JP2_CODESTREAM  0x6A703263
-
-#define HAD_COC 0x01
-#define HAD_QCC 0x02
-
-typedef struct {
-   J2kComponent *comp;
-   uint8_t properties[4];
-   J2kCodingStyle codsty[4];
-   J2kQuantStyle  qntsty[4];
-} J2kTile;
-
-typedef struct {
-    AVCodecContext *avctx;
-    AVFrame *picture;
-    GetByteContext g;
-
-    int width, height; ///< image width and height
-    int image_offset_x, image_offset_y;
-    int tile_offset_x, tile_offset_y;
-    uint8_t cbps[4]; ///< bits per sample in particular components
-    uint8_t sgnd[4]; ///< if a component is signed
-    uint8_t properties[4];
-    int cdx[4], cdy[4];
-    int precision;
-    int ncomponents;
-    int tile_width, tile_height; ///< tile size
-    int numXtiles, numYtiles;
-    int maxtilelen;
-
-    J2kCodingStyle codsty[4];
-    J2kQuantStyle  qntsty[4];
-
-    int bit_index;
-
-    int curtileno;
-
-    J2kTile *tile;
-} J2kDecoderContext;
-
-static int get_bits(J2kDecoderContext *s, int n)
-{
-    int res = 0;
-
-    while (--n >= 0){
-        res <<= 1;
-        if (s->bit_index == 0) {
-            s->bit_index = 7 + (bytestream2_get_byte(&s->g) != 0xFFu);
-        }
-        s->bit_index--;
-        res |= (bytestream2_peek_byte(&s->g) >> s->bit_index) & 1;
-    }
-    return res;
-}
-
-static void j2k_flush(J2kDecoderContext *s)
-{
-    if (bytestream2_get_byte(&s->g) == 0xff)
-        bytestream2_skip(&s->g, 1);
-    s->bit_index = 8;
-}
-#if 0
-void printcomp(J2kComponent *comp)
-{
-    int i;
-    for (i = 0; i < comp->y1 - comp->y0; i++)
-        ff_j2k_printv(comp->data + i * (comp->x1 - comp->x0), comp->x1 - comp->x0);
-}
-
-static void nspaces(FILE *fd, int n)
-{
-    while(n--) putc(' ', fd);
-}
-
-static void dump(J2kDecoderContext *s, FILE *fd)
-{
-    int tileno, compno, reslevelno, bandno, precno;
-    fprintf(fd, "XSiz = %d, YSiz = %d, tile_width = %d, tile_height = %d\n"
-                "numXtiles = %d, numYtiles = %d, ncomponents = %d\n"
-                "tiles:\n",
-            s->width, s->height, s->tile_width, s->tile_height,
-            s->numXtiles, s->numYtiles, s->ncomponents);
-    for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){
-        J2kTile *tile = s->tile + tileno;
-        nspaces(fd, 2);
-        fprintf(fd, "tile %d:\n", tileno);
-        for(compno = 0; compno < s->ncomponents; compno++){
-            J2kComponent *comp = tile->comp + compno;
-            nspaces(fd, 4);
-            fprintf(fd, "component %d:\n", compno);
-            nspaces(fd, 4);
-            fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d\n",
-                        comp->x0, comp->x1, comp->y0, comp->y1);
-            for(reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){
-                J2kResLevel *reslevel = comp->reslevel + reslevelno;
-                nspaces(fd, 6);
-                fprintf(fd, "reslevel %d:\n", reslevelno);
-                nspaces(fd, 6);
-                fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d, nbands = %d\n",
-                        reslevel->x0, reslevel->x1, reslevel->y0,
-                        reslevel->y1, reslevel->nbands);
-                for(bandno = 0; bandno < reslevel->nbands; bandno++){
-                    J2kBand *band = reslevel->band + bandno;
-                    nspaces(fd, 8);
-                    fprintf(fd, "band %d:\n", bandno);
-                    nspaces(fd, 8);
-                    fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d,"
-                                "codeblock_width = %d, codeblock_height = %d cblknx = %d cblkny = %d\n",
-                                band->x0, band->x1,
-                                band->y0, band->y1,
-                                band->codeblock_width, band->codeblock_height,
-                                band->cblknx, band->cblkny);
-                    for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){
-                        J2kPrec *prec = band->prec + precno;
-                        nspaces(fd, 10);
-                        fprintf(fd, "prec %d:\n", precno);
-                        nspaces(fd, 10);
-                        fprintf(fd, "xi0 = %d, xi1 = %d, yi0 = %d, yi1 = %d\n",
-                                     prec->xi0, prec->xi1, prec->yi0, prec->yi1);
-                    }
-                }
-            }
-        }
-    }
-}
-#endif
-
-/** decode the value stored in node */
-static int tag_tree_decode(J2kDecoderContext *s, J2kTgtNode *node, int threshold)
-{
-    J2kTgtNode *stack[30];
-    int sp = -1, curval = 0;
-
-    if(!node)
-        return AVERROR(EINVAL);
-
-    while(node && !node->vis){
-        stack[++sp] = node;
-        node = node->parent;
-    }
-
-    if (node)
-        curval = node->val;
-    else
-        curval = stack[sp]->val;
-
-    while(curval < threshold && sp >= 0){
-        if (curval < stack[sp]->val)
-            curval = stack[sp]->val;
-        while (curval < threshold){
-            int ret;
-            if ((ret = get_bits(s, 1)) > 0){
-                stack[sp]->vis++;
-                break;
-            } else if (!ret)
-                curval++;
-            else
-                return ret;
-        }
-        stack[sp]->val = curval;
-        sp--;
-    }
-    return curval;
-}
-
-/* marker segments */
-/** get sizes and offsets of image, tiles; number of components */
-static int get_siz(J2kDecoderContext *s)
-{
-    int i, ret;
-
-    if (bytestream2_get_bytes_left(&s->g) < 36)
-        return AVERROR(EINVAL);
-
-                        bytestream2_get_be16u(&s->g); // Rsiz (skipped)
-             s->width = bytestream2_get_be32u(&s->g); // width
-            s->height = bytestream2_get_be32u(&s->g); // height
-    s->image_offset_x = bytestream2_get_be32u(&s->g); // X0Siz
-    s->image_offset_y = bytestream2_get_be32u(&s->g); // Y0Siz
-
-        s->tile_width = bytestream2_get_be32u(&s->g); // XTSiz
-       s->tile_height = bytestream2_get_be32u(&s->g); // YTSiz
-     s->tile_offset_x = bytestream2_get_be32u(&s->g); // XT0Siz
-     s->tile_offset_y = bytestream2_get_be32u(&s->g); // YT0Siz
-       s->ncomponents = bytestream2_get_be16u(&s->g); // CSiz
-
-    if(s->ncomponents <= 0 || s->ncomponents > 4) {
-        av_log(s->avctx, AV_LOG_ERROR, "unsupported/invalid ncomponents: %d\n", s->ncomponents);
-        return AVERROR(EINVAL);
-    }
-    if(s->tile_width<=0 || s->tile_height<=0)
-        return AVERROR(EINVAL);
-
-    if (bytestream2_get_bytes_left(&s->g) < 3 * s->ncomponents)
-        return AVERROR(EINVAL);
-
-    for (i = 0; i < s->ncomponents; i++){ // Ssiz_i XRsiz_i, YRsiz_i
-        uint8_t x = bytestream2_get_byteu(&s->g);
-        s->cbps[i] = (x & 0x7f) + 1;
-        s->precision = FFMAX(s->cbps[i], s->precision);
-        s->sgnd[i] = !!(x & 0x80);
-        s->cdx[i] = bytestream2_get_byteu(&s->g);
-        s->cdy[i] = bytestream2_get_byteu(&s->g);
-    }
-
-    s->numXtiles = ff_j2k_ceildiv(s->width - s->tile_offset_x, s->tile_width);
-    s->numYtiles = ff_j2k_ceildiv(s->height - s->tile_offset_y, s->tile_height);
-
-    if(s->numXtiles * (uint64_t)s->numYtiles > INT_MAX/sizeof(J2kTile))
-        return AVERROR(EINVAL);
-
-    s->tile = av_mallocz(s->numXtiles * s->numYtiles * sizeof(J2kTile));
-    if (!s->tile)
-        return AVERROR(ENOMEM);
-
-    for (i = 0; i < s->numXtiles * s->numYtiles; i++){
-        J2kTile *tile = s->tile + i;
-
-        tile->comp = av_mallocz(s->ncomponents * sizeof(J2kComponent));
-        if (!tile->comp)
-            return AVERROR(ENOMEM);
-    }
-
-    s->avctx->width  = s->width  - s->image_offset_x;
-    s->avctx->height = s->height - s->image_offset_y;
-
-    switch(s->ncomponents){
-    case 1:
-        if (s->precision > 8) {
-            s->avctx->pix_fmt = AV_PIX_FMT_GRAY16;
-        } else {
-            s->avctx->pix_fmt = AV_PIX_FMT_GRAY8;
-        }
-        break;
-    case 3:
-        if (s->precision > 8) {
-            s->avctx->pix_fmt = AV_PIX_FMT_RGB48;
-        } else {
-            s->avctx->pix_fmt = AV_PIX_FMT_RGB24;
-        }
-        break;
-    case 4:
-        s->avctx->pix_fmt = AV_PIX_FMT_RGBA;
-        break;
-    }
-
-
-    if ((ret = ff_get_buffer(s->avctx, s->picture, 0)) < 0)
-        return ret;
-
-    s->picture->pict_type = AV_PICTURE_TYPE_I;
-    s->picture->key_frame = 1;
-
-    return 0;
-}
-
-/** get common part for COD and COC segments */
-static int get_cox(J2kDecoderContext *s, J2kCodingStyle *c)
-{
-    if (bytestream2_get_bytes_left(&s->g) < 5)
-        return AVERROR(EINVAL);
-          c->nreslevels = bytestream2_get_byteu(&s->g) + 1; // num of resolution levels - 1
-     c->log2_cblk_width = bytestream2_get_byteu(&s->g) + 2; // cblk width
-    c->log2_cblk_height = bytestream2_get_byteu(&s->g) + 2; // cblk height
-
-    c->cblk_style = bytestream2_get_byteu(&s->g);
-    if (c->cblk_style != 0){ // cblk style
-        av_log(s->avctx, AV_LOG_WARNING, "extra cblk styles %X\n", c->cblk_style);
-    }
-    c->transform = bytestream2_get_byteu(&s->g); // transformation
-    if (c->csty & J2K_CSTY_PREC) {
-        int i;
-
-        for (i = 0; i < c->nreslevels; i++)
-            bytestream2_get_byte(&s->g);
-    }
-    return 0;
-}
-
-/** get coding parameters for a particular tile or whole image*/
-static int get_cod(J2kDecoderContext *s, J2kCodingStyle *c, uint8_t *properties)
-{
-    J2kCodingStyle tmp;
-    int compno;
-
-    if (bytestream2_get_bytes_left(&s->g) < 5)
-        return AVERROR(EINVAL);
-
-    tmp.log2_prec_width  =
-    tmp.log2_prec_height = 15;
-
-    tmp.csty = bytestream2_get_byteu(&s->g);
-
-    if (bytestream2_get_byteu(&s->g)){ // progression level
-        av_log(s->avctx, AV_LOG_ERROR, "only LRCP progression supported\n");
-        return -1;
-    }
-
-    tmp.nlayers = bytestream2_get_be16u(&s->g);
-        tmp.mct = bytestream2_get_byteu(&s->g); // multiple component transformation
-
-    get_cox(s, &tmp);
-    for (compno = 0; compno < s->ncomponents; compno++){
-        if (!(properties[compno] & HAD_COC))
-            memcpy(c + compno, &tmp, sizeof(J2kCodingStyle));
-    }
-    return 0;
-}
-
-/** get coding parameters for a component in the whole image on a particular tile */
-static int get_coc(J2kDecoderContext *s, J2kCodingStyle *c, uint8_t *properties)
-{
-    int compno;
-
-    if (bytestream2_get_bytes_left(&s->g) < 2)
-        return AVERROR(EINVAL);
-
-    compno = bytestream2_get_byteu(&s->g);
-
-    c += compno;
-    c->csty = bytestream2_get_byte(&s->g);
-    get_cox(s, c);
-
-    properties[compno] |= HAD_COC;
-    return 0;
-}
-
-/** get common part for QCD and QCC segments */
-static int get_qcx(J2kDecoderContext *s, int n, J2kQuantStyle *q)
-{
-    int i, x;
-
-    if (bytestream2_get_bytes_left(&s->g) < 1)
-        return AVERROR(EINVAL);
-
-    x = bytestream2_get_byteu(&s->g); // Sqcd
-
-    q->nguardbits = x >> 5;
-      q->quantsty = x & 0x1f;
-
-    if (q->quantsty == J2K_QSTY_NONE){
-        n -= 3;
-        if (bytestream2_get_bytes_left(&s->g) < n || 32*3 < n)
-            return AVERROR(EINVAL);
-        for (i = 0; i < n; i++)
-            q->expn[i] = bytestream2_get_byteu(&s->g) >> 3;
-    } else if (q->quantsty == J2K_QSTY_SI){
-        if (bytestream2_get_bytes_left(&s->g) < 2)
-            return AVERROR(EINVAL);
-        x = bytestream2_get_be16u(&s->g);
-        q->expn[0] = x >> 11;
-        q->mant[0] = x & 0x7ff;
-        for (i = 1; i < 32 * 3; i++){
-            int curexpn = FFMAX(0, q->expn[0] - (i-1)/3);
-            q->expn[i] = curexpn;
-            q->mant[i] = q->mant[0];
-        }
-    } else{
-        n = (n - 3) >> 1;
-        if (bytestream2_get_bytes_left(&s->g) < 2 * n || 32*3 < n)
-            return AVERROR(EINVAL);
-        for (i = 0; i < n; i++){
-            x = bytestream2_get_be16u(&s->g);
-            q->expn[i] = x >> 11;
-            q->mant[i] = x & 0x7ff;
-        }
-    }
-    return 0;
-}
-
-/** get quantization parameters for a particular tile or a whole image */
-static int get_qcd(J2kDecoderContext *s, int n, J2kQuantStyle *q, uint8_t *properties)
-{
-    J2kQuantStyle tmp;
-    int compno;
-
-    if (get_qcx(s, n, &tmp))
-        return -1;
-    for (compno = 0; compno < s->ncomponents; compno++)
-        if (!(properties[compno] & HAD_QCC))
-            memcpy(q + compno, &tmp, sizeof(J2kQuantStyle));
-    return 0;
-}
-
-/** get quantization parameters for a component in the whole image on in a particular tile */
-static int get_qcc(J2kDecoderContext *s, int n, J2kQuantStyle *q, uint8_t *properties)
-{
-    int compno;
-
-    if (bytestream2_get_bytes_left(&s->g) < 1)
-        return AVERROR(EINVAL);
-
-    compno = bytestream2_get_byteu(&s->g);
-    properties[compno] |= HAD_QCC;
-    return get_qcx(s, n-1, q+compno);
-}
-
-/** get start of tile segment */
-static uint8_t get_sot(J2kDecoderContext *s)
-{
-    if (bytestream2_get_bytes_left(&s->g) < 8)
-        return AVERROR(EINVAL);
-
-    s->curtileno = bytestream2_get_be16u(&s->g); ///< Isot
-    if((unsigned)s->curtileno >= s->numXtiles * s->numYtiles){
-        s->curtileno=0;
-        return AVERROR(EINVAL);
-    }
-
-    bytestream2_skipu(&s->g, 4); ///< Psot (ignored)
-
-    if (!bytestream2_get_byteu(&s->g)){ ///< TPsot
-        J2kTile *tile = s->tile + s->curtileno;
-
-        /* copy defaults */
-        memcpy(tile->codsty, s->codsty, s->ncomponents * sizeof(J2kCodingStyle));
-        memcpy(tile->qntsty, s->qntsty, s->ncomponents * sizeof(J2kQuantStyle));
-    }
-    bytestream2_get_byteu(&s->g); ///< TNsot
-
-    return 0;
-}
-
-static int init_tile(J2kDecoderContext *s, int tileno)
-{
-    int compno,
-        tilex = tileno % s->numXtiles,
-        tiley = tileno / s->numXtiles;
-    J2kTile *tile = s->tile + tileno;
-
-    if (!tile->comp)
-        return AVERROR(ENOMEM);
-    for (compno = 0; compno < s->ncomponents; compno++){
-        J2kComponent *comp = tile->comp + compno;
-        J2kCodingStyle *codsty = tile->codsty + compno;
-        J2kQuantStyle  *qntsty = tile->qntsty + compno;
-        int ret; // global bandno
-
-        comp->coord[0][0] = FFMAX(tilex * s->tile_width + s->tile_offset_x, s->image_offset_x);
-        comp->coord[0][1] = FFMIN((tilex+1)*s->tile_width + s->tile_offset_x, s->width);
-        comp->coord[1][0] = FFMAX(tiley * s->tile_height + s->tile_offset_y, s->image_offset_y);
-        comp->coord[1][1] = FFMIN((tiley+1)*s->tile_height + s->tile_offset_y, s->height);
-
-        if (ret = ff_j2k_init_component(comp, codsty, qntsty, s->cbps[compno], s->cdx[compno], s->cdy[compno]))
-            return ret;
-    }
-    return 0;
-}
-
-/** read the number of coding passes */
-static int getnpasses(J2kDecoderContext *s)
-{
-    int num;
-    if (!get_bits(s, 1))
-        return 1;
-    if (!get_bits(s, 1))
-        return 2;
-    if ((num = get_bits(s, 2)) != 3)
-        return num < 0 ? num : 3 + num;
-    if ((num = get_bits(s, 5)) != 31)
-        return num < 0 ? num : 6 + num;
-    num = get_bits(s, 7);
-    return num < 0 ? num : 37 + num;
-}
-
-static int getlblockinc(J2kDecoderContext *s)
-{
-    int res = 0, ret;
-    while (ret = get_bits(s, 1)){
-        if (ret < 0)
-            return ret;
-        res++;
-    }
-    return res;
-}
-
-static int decode_packet(J2kDecoderContext *s, J2kCodingStyle *codsty, J2kResLevel *rlevel, int precno,
-                         int layno, uint8_t *expn, int numgbits)
-{
-    int bandno, cblkny, cblknx, cblkno, ret;
-
-    if (!(ret = get_bits(s, 1))){
-        j2k_flush(s);
-        return 0;
-    } else if (ret < 0)
-        return ret;
-
-    for (bandno = 0; bandno < rlevel->nbands; bandno++){
-        J2kBand *band = rlevel->band + bandno;
-        J2kPrec *prec = band->prec + precno;
-        int pos = 0;
-
-        if (band->coord[0][0] == band->coord[0][1]
-        ||  band->coord[1][0] == band->coord[1][1])
-            continue;
-
-        for (cblkny = prec->yi0; cblkny < prec->yi1; cblkny++)
-            for(cblknx = prec->xi0, cblkno = cblkny * band->cblknx + cblknx; cblknx < prec->xi1; cblknx++, cblkno++, pos++){
-                J2kCblk *cblk = band->cblk + cblkno;
-                int incl, newpasses, llen;
-
-                if (cblk->npasses)
-                    incl = get_bits(s, 1);
-                else
-                    incl = tag_tree_decode(s, prec->cblkincl + pos, layno+1) == layno;
-                if (!incl)
-                    continue;
-                else if (incl < 0)
-                    return incl;
-
-                if (!cblk->npasses)
-                    cblk->nonzerobits = expn[bandno] + numgbits - 1 - tag_tree_decode(s, prec->zerobits + pos, 100);
-                if ((newpasses = getnpasses(s)) < 0)
-                    return newpasses;
-                if ((llen = getlblockinc(s)) < 0)
-                    return llen;
-                cblk->lblock += llen;
-                if ((ret = get_bits(s, av_log2(newpasses) + cblk->lblock)) < 0)
-                    return ret;
-                cblk->lengthinc = ret;
-                cblk->npasses += newpasses;
-            }
-    }
-    j2k_flush(s);
-
-    if (codsty->csty & J2K_CSTY_EPH) {
-        if (bytestream2_peek_be16(&s->g) == J2K_EPH) {
-            bytestream2_skip(&s->g, 2);
-        } else {
-            av_log(s->avctx, AV_LOG_ERROR, "EPH marker not found.\n");
-        }
-    }
-
-    for (bandno = 0; bandno < rlevel->nbands; bandno++){
-        J2kBand *band = rlevel->band + bandno;
-        int yi, cblknw = band->prec[precno].xi1 - band->prec[precno].xi0;
-        for (yi = band->prec[precno].yi0; yi < band->prec[precno].yi1; yi++){
-            int xi;
-            for (xi = band->prec[precno].xi0; xi < band->prec[precno].xi1; xi++){
-                J2kCblk *cblk = band->cblk + yi * cblknw + xi;
-                if (bytestream2_get_bytes_left(&s->g) < cblk->lengthinc)
-                    return AVERROR(EINVAL);
-                bytestream2_get_bufferu(&s->g, cblk->data, cblk->lengthinc);
-                cblk->length += cblk->lengthinc;
-                cblk->lengthinc = 0;
-            }
-        }
-    }
-    return 0;
-}
-
-static int decode_packets(J2kDecoderContext *s, J2kTile *tile)
-{
-    int layno, reslevelno, compno, precno, ok_reslevel;
-    s->bit_index = 8;
-    for (layno = 0; layno < tile->codsty[0].nlayers; layno++){
-        ok_reslevel = 1;
-        for (reslevelno = 0; ok_reslevel; reslevelno++){
-            ok_reslevel = 0;
-            for (compno = 0; compno < s->ncomponents; compno++){
-                J2kCodingStyle *codsty = tile->codsty + compno;
-                J2kQuantStyle  *qntsty = tile->qntsty + compno;
-                if (reslevelno < codsty->nreslevels){
-                    J2kResLevel *rlevel = tile->comp[compno].reslevel + reslevelno;
-                    ok_reslevel = 1;
-                    for (precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++){
-                        if (decode_packet(s, codsty, rlevel, precno, layno, qntsty->expn +
-                                          (reslevelno ? 3*(reslevelno-1)+1 : 0), qntsty->nguardbits))
-                            return -1;
-                    }
-                }
-            }
-        }
-    }
-    return 0;
-}
-
-/* TIER-1 routines */
-static void decode_sigpass(J2kT1Context *t1, int width, int height, int bpno, int bandno, int bpass_csty_symbol,
-                           int vert_causal_ctx_csty_symbol)
-{
-    int mask = 3 << (bpno - 1), y0, x, y;
-
-    for (y0 = 0; y0 < height; y0 += 4)
-        for (x = 0; x < width; x++)
-            for (y = y0; y < height && y < y0+4; y++){
-                if ((t1->flags[y+1][x+1] & J2K_T1_SIG_NB)
-                && !(t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS))){
-                    int vert_causal_ctx_csty_loc_symbol = vert_causal_ctx_csty_symbol && (x == 3 && y == 3);
-                    if (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_j2k_getnbctxno(t1->flags[y+1][x+1], bandno,
-                                      vert_causal_ctx_csty_loc_symbol))){
-                        int xorbit, ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit);
-                        if (bpass_csty_symbol)
-                             t1->data[y][x] = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ? -mask : mask;
-                        else
-                             t1->data[y][x] = (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ^ xorbit) ?
-                                               -mask : mask;
-
-                        ff_j2k_set_significant(t1, x, y, t1->data[y][x] < 0);
-                    }
-                    t1->flags[y+1][x+1] |= J2K_T1_VIS;
-                }
-            }
-}
-
-static void decode_refpass(J2kT1Context *t1, int width, int height, int bpno)
-{
-    int phalf, nhalf;
-    int y0, x, y;
-
-    phalf = 1 << (bpno - 1);
-    nhalf = -phalf;
-
-    for (y0 = 0; y0 < height; y0 += 4)
-        for (x = 0; x < width; x++)
-            for (y = y0; y < height && y < y0+4; y++){
-                if ((t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS)) == J2K_T1_SIG){
-                    int ctxno = ff_j2k_getrefctxno(t1->flags[y+1][x+1]);
-                    int r = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ? phalf : nhalf;
-                    t1->data[y][x] += t1->data[y][x] < 0 ? -r : r;
-                    t1->flags[y+1][x+1] |= J2K_T1_REF;
-                }
-            }
-}
-
-static void decode_clnpass(J2kDecoderContext *s, J2kT1Context *t1, int width, int height,
-                           int bpno, int bandno, int seg_symbols)
-{
-    int mask = 3 << (bpno - 1), y0, x, y, runlen, dec;
-
-    for (y0 = 0; y0 < height; y0 += 4) {
-        for (x = 0; x < width; x++){
-            if (y0 + 3 < height && !(
-            (t1->flags[y0+1][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) ||
-            (t1->flags[y0+2][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) ||
-            (t1->flags[y0+3][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) ||
-            (t1->flags[y0+4][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)))){
-                if (!ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_RL))
-                    continue;
-                runlen = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
-                runlen = (runlen << 1) | ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
-                dec = 1;
-            } else{
-                runlen = 0;
-                dec = 0;
-            }
-
-            for (y = y0 + runlen; y < y0 + 4 && y < height; y++){
-                if (!dec){
-                    if (!(t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS)))
-                        dec = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_j2k_getnbctxno(t1->flags[y+1][x+1],
-                                                                                             bandno, 0));
-                }
-                if (dec){
-                    int xorbit, ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit);
-                    t1->data[y][x] = (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ^ xorbit) ? -mask : mask;
-                    ff_j2k_set_significant(t1, x, y, t1->data[y][x] < 0);
-                }
-                dec = 0;
-                t1->flags[y+1][x+1] &= ~J2K_T1_VIS;
-            }
-        }
-    }
-    if (seg_symbols) {
-        int val;
-        val = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
-        val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
-        val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
-        val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
-        if (val != 0xa) {
-            av_log(s->avctx, AV_LOG_ERROR,"Segmentation symbol value incorrect\n");
-        }
-    }
-}
-
-static int decode_cblk(J2kDecoderContext *s, J2kCodingStyle *codsty, J2kT1Context *t1, J2kCblk *cblk,
-                       int width, int height, int bandpos)
-{
-    int passno = cblk->npasses, pass_t = 2, bpno = cblk->nonzerobits - 1, y, clnpass_cnt = 0;
-    int bpass_csty_symbol = J2K_CBLK_BYPASS & codsty->cblk_style;
-    int vert_causal_ctx_csty_symbol = J2K_CBLK_VSC & codsty->cblk_style;
-
-    for (y = 0; y < height+2; y++)
-        memset(t1->flags[y], 0, (width+2)*sizeof(int));
-
-    for (y = 0; y < height; y++)
-        memset(t1->data[y], 0, width*sizeof(int));
-
-    cblk->data[cblk->length] = 0xff;
-    cblk->data[cblk->length+1] = 0xff;
-    ff_mqc_initdec(&t1->mqc, cblk->data);
-
-    while(passno--){
-        switch(pass_t){
-            case 0: decode_sigpass(t1, width, height, bpno+1, bandpos,
-                                  bpass_csty_symbol && (clnpass_cnt >= 4), vert_causal_ctx_csty_symbol);
-                    break;
-            case 1: decode_refpass(t1, width, height, bpno+1);
-                    if (bpass_csty_symbol && clnpass_cnt >= 4)
-                        ff_mqc_initdec(&t1->mqc, cblk->data);
-                    break;
-            case 2: decode_clnpass(s, t1, width, height, bpno+1, bandpos,
-                                   codsty->cblk_style & J2K_CBLK_SEGSYM);
-                    clnpass_cnt = clnpass_cnt + 1;
-                    if (bpass_csty_symbol && clnpass_cnt >= 4)
-                       ff_mqc_initdec(&t1->mqc, cblk->data);
-                    break;
-        }
-
-        pass_t++;
-        if (pass_t == 3){
-            bpno--;
-            pass_t = 0;
-        }
-    }
-    return 0;
-}
-
-static void mct_decode(J2kDecoderContext *s, J2kTile *tile)
-{
-    int i, *src[3], i0, i1, i2, csize = 1;
-
-    for (i = 0; i < 3; i++)
-        src[i] = tile->comp[i].data;
-
-    for (i = 0; i < 2; i++)
-        csize *= tile->comp[0].coord[i][1] - tile->comp[0].coord[i][0];
-
-    if (tile->codsty[0].transform == FF_DWT97){
-        for (i = 0; i < csize; i++){
-            i0 = *src[0] + (*src[2] * 46802 >> 16);
-            i1 = *src[0] - (*src[1] * 22553 + *src[2] * 46802 >> 16);
-            i2 = *src[0] + (116130 * *src[1] >> 16);
-            *src[0]++ = i0;
-            *src[1]++ = i1;
-            *src[2]++ = i2;
-        }
-    } else{
-        for (i = 0; i < csize; i++){
-            i1 = *src[0] - (*src[2] + *src[1] >> 2);
-            i0 = i1 + *src[2];
-            i2 = i1 + *src[1];
-            *src[0]++ = i0;
-            *src[1]++ = i1;
-            *src[2]++ = i2;
-        }
-    }
-}
-
-static int decode_tile(J2kDecoderContext *s, J2kTile *tile)
-{
-    int compno, reslevelno, bandno;
-    int x, y, *src[4];
-    uint8_t *line;
-    J2kT1Context t1;
-
-    for (compno = 0; compno < s->ncomponents; compno++){
-        J2kComponent *comp = tile->comp + compno;
-        J2kCodingStyle *codsty = tile->codsty + compno;
-
-        for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){
-            J2kResLevel *rlevel = comp->reslevel + reslevelno;
-            for (bandno = 0; bandno < rlevel->nbands; bandno++){
-                J2kBand *band = rlevel->band + bandno;
-                int cblkx, cblky, cblkno=0, xx0, x0, xx1, y0, yy0, yy1, bandpos;
-
-                bandpos = bandno + (reslevelno > 0);
-
-                yy0 = bandno == 0 ? 0 : comp->reslevel[reslevelno-1].coord[1][1] - comp->reslevel[reslevelno-1].coord[1][0];
-                y0 = yy0;
-                yy1 = FFMIN(ff_j2k_ceildiv(band->coord[1][0] + 1, band->codeblock_height) * band->codeblock_height,
-                            band->coord[1][1]) - band->coord[1][0] + yy0;
-
-                if (band->coord[0][0] == band->coord[0][1] || band->coord[1][0] == band->coord[1][1])
-                    continue;
-
-                for (cblky = 0; cblky < band->cblkny; cblky++){
-                    if (reslevelno == 0 || bandno == 1)
-                        xx0 = 0;
-                    else
-                        xx0 = comp->reslevel[reslevelno-1].coord[0][1] - comp->reslevel[reslevelno-1].coord[0][0];
-                    x0 = xx0;
-                    xx1 = FFMIN(ff_j2k_ceildiv(band->coord[0][0] + 1, band->codeblock_width) * band->codeblock_width,
-                                band->coord[0][1]) - band->coord[0][0] + xx0;
-
-                    for (cblkx = 0; cblkx < band->cblknx; cblkx++, cblkno++){
-                        int y, x;
-                        decode_cblk(s, codsty, &t1, band->cblk + cblkno, xx1 - xx0, yy1 - yy0, bandpos);
-                        if (codsty->transform == FF_DWT53){
-                            for (y = yy0; y < yy1; y+=s->cdy[compno]){
-                                int *ptr = t1.data[y-yy0];
-                                for (x = xx0; x < xx1; x+=s->cdx[compno]){
-                                    comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y + x] = *ptr++ >> 1;
-                                }
-                            }
-                        } else{
-                            for (y = yy0; y < yy1; y+=s->cdy[compno]){
-                                int *ptr = t1.data[y-yy0];
-                                for (x = xx0; x < xx1; x+=s->cdx[compno]){
-                                    int tmp = ((int64_t)*ptr++) * ((int64_t)band->stepsize) >> 13, tmp2;
-                                    tmp2 = FFABS(tmp>>1) + (tmp&1);
-                                    comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y + x] = tmp < 0 ? -tmp2 : tmp2;
-                                }
-                            }
-                        }
-                        xx0 = xx1;
-                        xx1 = FFMIN(xx1 + band->codeblock_width, band->coord[0][1] - band->coord[0][0] + x0);
-                    }
-                    yy0 = yy1;
-                    yy1 = FFMIN(yy1 + band->codeblock_height, band->coord[1][1] - band->coord[1][0] + y0);
-                }
-            }
-        }
-        ff_j2k_dwt_decode(&comp->dwt, comp->data);
-        src[compno] = comp->data;
-    }
-    if (tile->codsty[0].mct)
-        mct_decode(s, tile);
-
-    if (s->precision <= 8) {
-        for (compno = 0; compno < s->ncomponents; compno++){
-            y = tile->comp[compno].coord[1][0] - s->image_offset_y;
-            line = s->picture->data[0] + y * s->picture->linesize[0];
-            for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y += s->cdy[compno]){
-                uint8_t *dst;
-
-                x = tile->comp[compno].coord[0][0] - s->image_offset_x;
-                dst = line + x * s->ncomponents + compno;
-
-                for (; x < tile->comp[compno].coord[0][1] - s->image_offset_x; x += s->cdx[compno]) {
-                    *src[compno] += 1 << (s->cbps[compno]-1);
-                    if (*src[compno] < 0)
-                        *src[compno] = 0;
-                    else if (*src[compno] >= (1 << s->cbps[compno]))
-                        *src[compno] = (1 << s->cbps[compno]) - 1;
-                    *dst = *src[compno]++;
-                    dst += s->ncomponents;
-                }
-                line += s->picture->linesize[0];
-            }
-        }
-    } else {
-        for (compno = 0; compno < s->ncomponents; compno++) {
-            y = tile->comp[compno].coord[1][0] - s->image_offset_y;
-            line = s->picture->data[0] + y * s->picture->linesize[0];
-            for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y += s->cdy[compno]) {
-                uint16_t *dst;
-
-                x = tile->comp[compno].coord[0][0] - s->image_offset_x;
-                dst = (uint16_t *)(line + (x * s->ncomponents + compno) * 2);
-                for (; x < tile->comp[compno].coord[0][1] - s->image_offset_x; x += s-> cdx[compno]) {
-                    int32_t val;
-
-                    val = *src[compno]++ << (16 - s->cbps[compno]);
-                    val += 1 << 15;
-                    val = av_clip(val, 0, (1 << 16) - 1);
-                    *dst = val;
-                    dst += s->ncomponents;
-                }
-                line += s->picture->linesize[0];
-            }
-        }
-    }
-    return 0;
-}
-
-static void cleanup(J2kDecoderContext *s)
-{
-    int tileno, compno;
-    for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){
-        for (compno = 0; compno < s->ncomponents; compno++){
-            J2kComponent *comp = s->tile[tileno].comp + compno;
-            J2kCodingStyle *codsty = s->tile[tileno].codsty + compno;
-
-            ff_j2k_cleanup(comp, codsty);
-        }
-        av_freep(&s->tile[tileno].comp);
-    }
-    av_freep(&s->tile);
-}
-
-static int decode_codestream(J2kDecoderContext *s)
-{
-    J2kCodingStyle *codsty = s->codsty;
-    J2kQuantStyle  *qntsty = s->qntsty;
-    uint8_t *properties = s->properties;
-
-    for (;;){
-        int oldpos, marker, len, ret = 0;
-
-        if (bytestream2_get_bytes_left(&s->g) < 2){
-            av_log(s->avctx, AV_LOG_ERROR, "Missing EOC\n");
-            break;
-        }
-
-        marker = bytestream2_get_be16u(&s->g);
-        av_dlog(s->avctx, "marker 0x%.4X at pos 0x%x\n", marker, bytestream2_tell(&s->g) - 4);
-        oldpos = bytestream2_tell(&s->g);
-
-        if (marker == J2K_SOD){
-            J2kTile *tile = s->tile + s->curtileno;
-            if (ret = init_tile(s, s->curtileno)) {
-                av_log(s->avctx, AV_LOG_ERROR, "tile initialization failed\n");
-                return ret;
-            }
-            if (ret = decode_packets(s, tile)) {
-                av_log(s->avctx, AV_LOG_ERROR, "packets decoding failed\n");
-                return ret;
-            }
-            continue;
-        }
-        if (marker == J2K_EOC)
-            break;
-
-        if (bytestream2_get_bytes_left(&s->g) < 2)
-            return AVERROR(EINVAL);
-        len = bytestream2_get_be16u(&s->g);
-        switch (marker){
-        case J2K_SIZ:
-            ret = get_siz(s);
-            break;
-        case J2K_COC:
-            ret = get_coc(s, codsty, properties);
-            break;
-        case J2K_COD:
-            ret = get_cod(s, codsty, properties);
-            break;
-        case J2K_QCC:
-            ret = get_qcc(s, len, qntsty, properties);
-            break;
-        case J2K_QCD:
-            ret = get_qcd(s, len, qntsty, properties);
-            break;
-        case J2K_SOT:
-            if (!(ret = get_sot(s))){
-                codsty = s->tile[s->curtileno].codsty;
-                qntsty = s->tile[s->curtileno].qntsty;
-                properties = s->tile[s->curtileno].properties;
-            }
-            break;
-        case J2K_COM:
-            // the comment is ignored
-            bytestream2_skip(&s->g, len - 2);
-            break;
-        default:
-            av_log(s->avctx, AV_LOG_ERROR, "unsupported marker 0x%.4X at pos 0x%x\n", marker, bytestream2_tell(&s->g) - 4);
-            bytestream2_skip(&s->g, len - 2);
-            break;
-        }
-        if (bytestream2_tell(&s->g) - oldpos != len || ret){
-            av_log(s->avctx, AV_LOG_ERROR, "error during processing marker segment %.4x\n", marker);
-            return ret ? ret : -1;
-        }
-    }
-    return 0;
-}
-
-static int jp2_find_codestream(J2kDecoderContext *s)
-{
-    uint32_t atom_size, atom;
-    int found_codestream = 0, search_range = 10;
-
-    while(!found_codestream && search_range && bytestream2_get_bytes_left(&s->g) >= 8) {
-        atom_size = bytestream2_get_be32u(&s->g);
-        atom      = bytestream2_get_be32u(&s->g);
-        if (atom == JP2_CODESTREAM) {
-            found_codestream = 1;
-        } else {
-            if (bytestream2_get_bytes_left(&s->g) < atom_size - 8)
-                return 0;
-            bytestream2_skipu(&s->g, atom_size - 8);
-            search_range--;
-        }
-    }
-
-    if (found_codestream)
-        return 1;
-    return 0;
-}
-
-static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *got_frame,
-                        AVPacket *avpkt)
-{
-    J2kDecoderContext *s = avctx->priv_data;
-    AVFrame *picture = data;
-    int tileno, ret;
-
-    s->picture = picture;
-
-    bytestream2_init(&s->g, avpkt->data, avpkt->size);
-    s->curtileno = -1;
-
-    if (bytestream2_get_bytes_left(&s->g) < 2) {
-        ret = AVERROR(EINVAL);
-        goto err_out;
-    }
-
-    // check if the image is in jp2 format
-    if (bytestream2_get_bytes_left(&s->g) >= 12 &&
-       (bytestream2_get_be32u(&s->g) == 12) &&
-       (bytestream2_get_be32u(&s->g) == JP2_SIG_TYPE) &&
-       (bytestream2_get_be32u(&s->g) == JP2_SIG_VALUE)) {
-        if(!jp2_find_codestream(s)) {
-            av_log(avctx, AV_LOG_ERROR, "couldn't find jpeg2k codestream atom\n");
-            ret = -1;
-            goto err_out;
-        }
-    } else {
-        bytestream2_seek(&s->g, 0, SEEK_SET);
-    }
-
-    if (bytestream2_get_be16u(&s->g) != J2K_SOC){
-        av_log(avctx, AV_LOG_ERROR, "SOC marker not present\n");
-        ret = -1;
-        goto err_out;
-    }
-    if (ret = decode_codestream(s))
-        goto err_out;
-
-    for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++)
-        if (ret = decode_tile(s, s->tile + tileno))
-            goto err_out;
-
-    cleanup(s);
-
-    *got_frame = 1;
-
-    return bytestream2_tell(&s->g);
-
-err_out:
-    cleanup(s);
-    return ret;
-}
-
-static av_cold int j2kdec_init(AVCodecContext *avctx)
-{
-    J2kDecoderContext *s = avctx->priv_data;
-
-    s->avctx = avctx;
-
-    ff_j2k_init_tier1_luts();
-
-    return 0;
-}
-
-AVCodec ff_j2k_decoder = {
-    .name           = "j2k",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_JPEG2000,
-    .priv_data_size = sizeof(J2kDecoderContext),
-    .init           = j2kdec_init,
-    .decode         = decode_frame,
-    .capabilities   = CODEC_CAP_EXPERIMENTAL,
-    .long_name      = NULL_IF_CONFIG_SMALL("JPEG 2000"),
-};
diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c
index ffbd503..fa15aad 100644
--- a/libavcodec/j2kenc.c
+++ b/libavcodec/j2kenc.c
@@ -29,7 +29,7 @@
 #include "avcodec.h"
 #include "internal.h"
 #include "bytestream.h"
-#include "j2k.h"
+#include "jpeg2000.h"
 #include "libavutil/common.h"
 
 #define NMSEDEC_BITS 7
@@ -55,8 +55,8 @@
 };
 
 typedef struct {
-   J2kComponent *comp;
-} J2kTile;
+   Jpeg2000Component *comp;
+} Jpeg2000Tile;
 
 typedef struct {
     AVCodecContext *avctx;
@@ -77,11 +77,11 @@
 
     int64_t lambda;
 
-    J2kCodingStyle codsty;
-    J2kQuantStyle  qntsty;
+    Jpeg2000CodingStyle codsty;
+    Jpeg2000QuantStyle  qntsty;
 
-    J2kTile *tile;
-} J2kEncoderContext;
+    Jpeg2000Tile *tile;
+} Jpeg2000EncoderContext;
 
 
 /* debug */
@@ -94,14 +94,14 @@
     while(n--) putc(' ', fd);
 }
 
-static void printcomp(J2kComponent *comp)
+static void printcomp(Jpeg2000Component *comp)
 {
     int i;
     for (i = 0; i < comp->y1 - comp->y0; i++)
-        ff_j2k_printv(comp->data + i * (comp->x1 - comp->x0), comp->x1 - comp->x0);
+        ff_jpeg2000_printv(comp->i_data + i * (comp->x1 - comp->x0), comp->x1 - comp->x0);
 }
 
-static void dump(J2kEncoderContext *s, FILE *fd)
+static void dump(Jpeg2000EncoderContext *s, FILE *fd)
 {
     int tileno, compno, reslevelno, bandno, precno;
     fprintf(fd, "XSiz = %d, YSiz = %d, tile_width = %d, tile_height = %d\n"
@@ -110,18 +110,18 @@
             s->width, s->height, s->tile_width, s->tile_height,
             s->numXtiles, s->numYtiles, s->ncomponents);
     for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){
-        J2kTile *tile = s->tile + tileno;
+        Jpeg2000Tile *tile = s->tile + tileno;
         nspaces(fd, 2);
         fprintf(fd, "tile %d:\n", tileno);
         for(compno = 0; compno < s->ncomponents; compno++){
-            J2kComponent *comp = tile->comp + compno;
+            Jpeg2000Component *comp = tile->comp + compno;
             nspaces(fd, 4);
             fprintf(fd, "component %d:\n", compno);
             nspaces(fd, 4);
             fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d\n",
                         comp->x0, comp->x1, comp->y0, comp->y1);
             for(reslevelno = 0; reslevelno < s->nreslevels; reslevelno++){
-                J2kResLevel *reslevel = comp->reslevel + reslevelno;
+                Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno;
                 nspaces(fd, 6);
                 fprintf(fd, "reslevel %d:\n", reslevelno);
                 nspaces(fd, 6);
@@ -129,7 +129,7 @@
                         reslevel->x0, reslevel->x1, reslevel->y0,
                         reslevel->y1, reslevel->nbands);
                 for(bandno = 0; bandno < reslevel->nbands; bandno++){
-                    J2kBand *band = reslevel->band + bandno;
+                    Jpeg2000Band *band = reslevel->band + bandno;
                     nspaces(fd, 8);
                     fprintf(fd, "band %d:\n", bandno);
                     nspaces(fd, 8);
@@ -140,7 +140,7 @@
                                 band->codeblock_width, band->codeblock_height,
                                 band->cblknx, band->cblkny);
                     for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){
-                        J2kPrec *prec = band->prec + precno;
+                        Jpeg2000Prec *prec = band->prec + precno;
                         nspaces(fd, 10);
                         fprintf(fd, "prec %d:\n", precno);
                         nspaces(fd, 10);
@@ -157,7 +157,7 @@
 /* bitstream routines */
 
 /** put n times val bit */
-static void put_bits(J2kEncoderContext *s, int val, int n) // TODO: optimize
+static void put_bits(Jpeg2000EncoderContext *s, int val, int n) // TODO: optimize
 {
     while (n-- > 0){
         if (s->bit_index == 8)
@@ -170,14 +170,14 @@
 }
 
 /** put n least significant bits of a number num */
-static void put_num(J2kEncoderContext *s, int num, int n)
+static void put_num(Jpeg2000EncoderContext *s, int num, int n)
 {
     while(--n >= 0)
         put_bits(s, (num >> n) & 1, 1);
 }
 
 /** flush the bitstream */
-static void j2k_flush(J2kEncoderContext *s)
+static void j2k_flush(Jpeg2000EncoderContext *s)
 {
     if (s->bit_index){
         s->bit_index = 0;
@@ -188,9 +188,9 @@
 /* tag tree routines */
 
 /** code the value stored in node */
-static void tag_tree_code(J2kEncoderContext *s, J2kTgtNode *node, int threshold)
+static void tag_tree_code(Jpeg2000EncoderContext *s, Jpeg2000TgtNode *node, int threshold)
 {
-    J2kTgtNode *stack[30];
+    Jpeg2000TgtNode *stack[30];
     int sp = 1, curval = 0;
     stack[0] = node;
 
@@ -216,7 +216,7 @@
 }
 
 /** update the value in node */
-static void tag_tree_update(J2kTgtNode *node)
+static void tag_tree_update(Jpeg2000TgtNode *node)
 {
     int lev = 0;
     while (node->parent){
@@ -228,14 +228,14 @@
     }
 }
 
-static int put_siz(J2kEncoderContext *s)
+static int put_siz(Jpeg2000EncoderContext *s)
 {
     int i;
 
     if (s->buf_end - s->buf < 40 + 3 * s->ncomponents)
         return -1;
 
-    bytestream_put_be16(&s->buf, J2K_SIZ);
+    bytestream_put_be16(&s->buf, JPEG2000_SIZ);
     bytestream_put_be16(&s->buf, 38 + 3 * s->ncomponents); // Lsiz
     bytestream_put_be16(&s->buf, 0); // Rsiz
     bytestream_put_be32(&s->buf, s->width); // width
@@ -257,14 +257,14 @@
     return 0;
 }
 
-static int put_cod(J2kEncoderContext *s)
+static int put_cod(Jpeg2000EncoderContext *s)
 {
-    J2kCodingStyle *codsty = &s->codsty;
+    Jpeg2000CodingStyle *codsty = &s->codsty;
 
     if (s->buf_end - s->buf < 14)
         return -1;
 
-    bytestream_put_be16(&s->buf, J2K_COD);
+    bytestream_put_be16(&s->buf, JPEG2000_COD);
     bytestream_put_be16(&s->buf, 12); // Lcod
     bytestream_put_byte(&s->buf, 0);  // Scod
     // SGcod
@@ -280,17 +280,17 @@
     bytestream_put_byte(&s->buf, codsty->log2_cblk_width-2); // cblk width
     bytestream_put_byte(&s->buf, codsty->log2_cblk_height-2); // cblk height
     bytestream_put_byte(&s->buf, 0); // cblk style
-    bytestream_put_byte(&s->buf, codsty->transform); // transformation
+    bytestream_put_byte(&s->buf, codsty->transform == FF_DWT53); // transformation
     return 0;
 }
 
-static int put_qcd(J2kEncoderContext *s, int compno)
+static int put_qcd(Jpeg2000EncoderContext *s, int compno)
 {
     int i, size;
-    J2kCodingStyle *codsty = &s->codsty;
-    J2kQuantStyle  *qntsty = &s->qntsty;
+    Jpeg2000CodingStyle *codsty = &s->codsty;
+    Jpeg2000QuantStyle  *qntsty = &s->qntsty;
 
-    if (qntsty->quantsty == J2K_QSTY_NONE)
+    if (qntsty->quantsty == JPEG2000_QSTY_NONE)
         size = 4 + 3 * (codsty->nreslevels-1);
     else // QSTY_SE
         size = 5 + 6 * (codsty->nreslevels-1);
@@ -298,10 +298,10 @@
     if (s->buf_end - s->buf < size + 2)
         return -1;
 
-    bytestream_put_be16(&s->buf, J2K_QCD);
+    bytestream_put_be16(&s->buf, JPEG2000_QCD);
     bytestream_put_be16(&s->buf, size);  // LQcd
     bytestream_put_byte(&s->buf, (qntsty->nguardbits << 5) | qntsty->quantsty);  // Sqcd
-    if (qntsty->quantsty == J2K_QSTY_NONE)
+    if (qntsty->quantsty == JPEG2000_QSTY_NONE)
         for (i = 0; i < codsty->nreslevels * 3 - 2; i++)
             bytestream_put_byte(&s->buf, qntsty->expn[i] << 3);
     else // QSTY_SE
@@ -310,14 +310,14 @@
     return 0;
 }
 
-static uint8_t *put_sot(J2kEncoderContext *s, int tileno)
+static uint8_t *put_sot(Jpeg2000EncoderContext *s, int tileno)
 {
     uint8_t *psotptr;
 
     if (s->buf_end - s->buf < 12)
         return NULL;
 
-    bytestream_put_be16(&s->buf, J2K_SOT);
+    bytestream_put_be16(&s->buf, JPEG2000_SOT);
     bytestream_put_be16(&s->buf, 10); // Lsot
     bytestream_put_be16(&s->buf, tileno); // Isot
 
@@ -334,55 +334,62 @@
  * allocate memory for them
  * divide the input image into tile-components
  */
-static int init_tiles(J2kEncoderContext *s)
+static int init_tiles(Jpeg2000EncoderContext *s)
 {
     int tileno, tilex, tiley, compno;
-    J2kCodingStyle *codsty = &s->codsty;
-    J2kQuantStyle  *qntsty = &s->qntsty;
+    Jpeg2000CodingStyle *codsty = &s->codsty;
+    Jpeg2000QuantStyle  *qntsty = &s->qntsty;
 
-    s->numXtiles = ff_j2k_ceildiv(s->width, s->tile_width);
-    s->numYtiles = ff_j2k_ceildiv(s->height, s->tile_height);
+    s->numXtiles = ff_jpeg2000_ceildiv(s->width, s->tile_width);
+    s->numYtiles = ff_jpeg2000_ceildiv(s->height, s->tile_height);
 
-    s->tile = av_malloc(s->numXtiles * s->numYtiles * sizeof(J2kTile));
+    s->tile = av_malloc(s->numXtiles * s->numYtiles * sizeof(Jpeg2000Tile));
     if (!s->tile)
         return AVERROR(ENOMEM);
     for (tileno = 0, tiley = 0; tiley < s->numYtiles; tiley++)
         for (tilex = 0; tilex < s->numXtiles; tilex++, tileno++){
-            J2kTile *tile = s->tile + tileno;
+            Jpeg2000Tile *tile = s->tile + tileno;
 
-            tile->comp = av_malloc(s->ncomponents * sizeof(J2kComponent));
+            tile->comp = av_mallocz(s->ncomponents * sizeof(Jpeg2000Component));
             if (!tile->comp)
                 return AVERROR(ENOMEM);
             for (compno = 0; compno < s->ncomponents; compno++){
-                J2kComponent *comp = tile->comp + compno;
+                Jpeg2000Component *comp = tile->comp + compno;
                 int ret, i, j;
 
-                comp->coord[0][0] = tilex * s->tile_width;
-                comp->coord[0][1] = FFMIN((tilex+1)*s->tile_width, s->width);
-                comp->coord[1][0] = tiley * s->tile_height;
-                comp->coord[1][1] = FFMIN((tiley+1)*s->tile_height, s->height);
+                comp->coord[0][0] = comp->coord_o[0][0] = tilex * s->tile_width;
+                comp->coord[0][1] = comp->coord_o[0][1] = FFMIN((tilex+1)*s->tile_width, s->width);
+                comp->coord[1][0] = comp->coord_o[1][0] = tiley * s->tile_height;
+                comp->coord[1][1] = comp->coord_o[1][1] = FFMIN((tiley+1)*s->tile_height, s->height);
                 if (compno > 0)
                     for (i = 0; i < 2; i++)
                         for (j = 0; j < 2; j++)
-                            comp->coord[i][j] = ff_j2k_ceildivpow2(comp->coord[i][j], s->chroma_shift[i]);
+                            comp->coord[i][j] = comp->coord_o[i][j] = ff_jpeg2000_ceildivpow2(comp->coord[i][j], s->chroma_shift[i]);
 
-                if (ret = ff_j2k_init_component(comp, codsty, qntsty, s->cbps[compno], compno?1<<s->chroma_shift[0]:1, compno?1<<s->chroma_shift[1]:1))
+                if (ret = ff_jpeg2000_init_component(comp,
+                                                codsty,
+                                                qntsty,
+                                                s->cbps[compno],
+                                                compno?1<<s->chroma_shift[0]:1,
+                                                compno?1<<s->chroma_shift[1]:1,
+                                                s->avctx
+                                               ))
                     return ret;
             }
         }
     return 0;
 }
 
-static void copy_frame(J2kEncoderContext *s)
+static void copy_frame(Jpeg2000EncoderContext *s)
 {
     int tileno, compno, i, y, x;
     uint8_t *line;
     for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){
-        J2kTile *tile = s->tile + tileno;
+        Jpeg2000Tile *tile = s->tile + tileno;
         if (s->planar){
             for (compno = 0; compno < s->ncomponents; compno++){
-                J2kComponent *comp = tile->comp + compno;
-                int *dst = comp->data;
+                Jpeg2000Component *comp = tile->comp + compno;
+                int *dst = comp->i_data;
                 line = s->picture.data[compno]
                        + comp->coord[1][0] * s->picture.linesize[compno]
                        + comp->coord[0][0];
@@ -402,7 +409,7 @@
                 uint8_t *ptr = line;
                 for (x = tile->comp[0].coord[0][0]; x < tile->comp[0].coord[0][1]; x++, i++){
                     for (compno = 0; compno < s->ncomponents; compno++){
-                        tile->comp[compno].data[i] = *ptr++  - (1 << 7);
+                        tile->comp[compno].i_data[i] = *ptr++  - (1 << 7);
                     }
                 }
                 line += s->picture.linesize[0];
@@ -411,11 +418,11 @@
     }
 }
 
-static void init_quantization(J2kEncoderContext *s)
+static void init_quantization(Jpeg2000EncoderContext *s)
 {
     int compno, reslevelno, bandno;
-    J2kQuantStyle  *qntsty = &s->qntsty;
-    J2kCodingStyle *codsty = &s->codsty;
+    Jpeg2000QuantStyle  *qntsty = &s->qntsty;
+    Jpeg2000CodingStyle *codsty = &s->codsty;
 
     for (compno = 0; compno < s->ncomponents; compno++){
         int gbandno = 0;
@@ -425,7 +432,7 @@
             for (bandno = 0; bandno < nbands; bandno++, gbandno++){
                 int expn, mant;
 
-                if (codsty->transform == FF_DWT97){
+                if (codsty->transform == FF_DWT97_INT){
                     int bandpos = bandno + (reslevelno>0),
                         ss = 81920000 / dwt_norms[0][bandpos][lev],
                         log = av_log2(ss);
@@ -473,54 +480,52 @@
     return lut_nmsedec_ref0[x & ((1 << NMSEDEC_BITS) - 1)];
 }
 
-static void encode_sigpass(J2kT1Context *t1, int width, int height, int bandno, int *nmsedec, int bpno)
+static void encode_sigpass(Jpeg2000T1Context *t1, int width, int height, int bandno, int *nmsedec, int bpno)
 {
     int y0, x, y, mask = 1 << (bpno + NMSEDEC_FRACBITS);
-    int vert_causal_ctx_csty_loc_symbol;
     for (y0 = 0; y0 < height; y0 += 4)
         for (x = 0; x < width; x++)
             for (y = y0; y < height && y < y0+4; y++){
-                if (!(t1->flags[y+1][x+1] & J2K_T1_SIG) && (t1->flags[y+1][x+1] & J2K_T1_SIG_NB)){
-                    int ctxno = ff_j2k_getnbctxno(t1->flags[y+1][x+1], bandno, vert_causal_ctx_csty_loc_symbol),
+                if (!(t1->flags[y+1][x+1] & JPEG2000_T1_SIG) && (t1->flags[y+1][x+1] & JPEG2000_T1_SIG_NB)){
+                    int ctxno = ff_jpeg2000_getsigctxno(t1->flags[y+1][x+1], bandno),
                         bit = t1->data[y][x] & mask ? 1 : 0;
                     ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, bit);
                     if (bit){
                         int xorbit;
-                        int ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit);
+                        int ctxno = ff_jpeg2000_getsgnctxno(t1->flags[y+1][x+1], &xorbit);
                         ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, (t1->flags[y+1][x+1] >> 15) ^ xorbit);
                         *nmsedec += getnmsedec_sig(t1->data[y][x], bpno + NMSEDEC_FRACBITS);
-                        ff_j2k_set_significant(t1, x, y, t1->flags[y+1][x+1] >> 15);
+                        ff_jpeg2000_set_significance(t1, x, y, t1->flags[y+1][x+1] >> 15);
                     }
-                    t1->flags[y+1][x+1] |= J2K_T1_VIS;
+                    t1->flags[y+1][x+1] |= JPEG2000_T1_VIS;
                 }
             }
 }
 
-static void encode_refpass(J2kT1Context *t1, int width, int height, int *nmsedec, int bpno)
+static void encode_refpass(Jpeg2000T1Context *t1, int width, int height, int *nmsedec, int bpno)
 {
     int y0, x, y, mask = 1 << (bpno + NMSEDEC_FRACBITS);
     for (y0 = 0; y0 < height; y0 += 4)
         for (x = 0; x < width; x++)
             for (y = y0; y < height && y < y0+4; y++)
-                if ((t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS)) == J2K_T1_SIG){
-                    int ctxno = ff_j2k_getrefctxno(t1->flags[y+1][x+1]);
+                if ((t1->flags[y+1][x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS)) == JPEG2000_T1_SIG){
+                    int ctxno = ff_jpeg2000_getrefctxno(t1->flags[y+1][x+1]);
                     *nmsedec += getnmsedec_ref(t1->data[y][x], bpno + NMSEDEC_FRACBITS);
                     ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, t1->data[y][x] & mask ? 1:0);
-                    t1->flags[y+1][x+1] |= J2K_T1_REF;
+                    t1->flags[y+1][x+1] |= JPEG2000_T1_REF;
                 }
 }
 
-static void encode_clnpass(J2kT1Context *t1, int width, int height, int bandno, int *nmsedec, int bpno)
+static void encode_clnpass(Jpeg2000T1Context *t1, int width, int height, int bandno, int *nmsedec, int bpno)
 {
     int y0, x, y, mask = 1 << (bpno + NMSEDEC_FRACBITS);
-    int vert_causal_ctx_csty_loc_symbol;
     for (y0 = 0; y0 < height; y0 += 4)
         for (x = 0; x < width; x++){
             if (y0 + 3 < height && !(
-            (t1->flags[y0+1][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) ||
-            (t1->flags[y0+2][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) ||
-            (t1->flags[y0+3][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) ||
-            (t1->flags[y0+4][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG))))
+            (t1->flags[y0+1][x+1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||
+            (t1->flags[y0+2][x+1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||
+            (t1->flags[y0+3][x+1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||
+            (t1->flags[y0+4][x+1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG))))
             {
                 // aggregation mode
                 int rlen;
@@ -533,40 +538,40 @@
                 ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI, rlen >> 1);
                 ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI, rlen & 1);
                 for (y = y0 + rlen; y < y0 + 4; y++){
-                    if (!(t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS))){
-                        int ctxno = ff_j2k_getnbctxno(t1->flags[y+1][x+1], bandno, vert_causal_ctx_csty_loc_symbol);
+                    if (!(t1->flags[y+1][x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))){
+                        int ctxno = ff_jpeg2000_getsigctxno(t1->flags[y+1][x+1], bandno);
                         if (y > y0 + rlen)
                             ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, t1->data[y][x] & mask ? 1:0);
                         if (t1->data[y][x] & mask){ // newly significant
                             int xorbit;
-                            int ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit);
+                            int ctxno = ff_jpeg2000_getsgnctxno(t1->flags[y+1][x+1], &xorbit);
                             *nmsedec += getnmsedec_sig(t1->data[y][x], bpno + NMSEDEC_FRACBITS);
                             ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, (t1->flags[y+1][x+1] >> 15) ^ xorbit);
-                            ff_j2k_set_significant(t1, x, y, t1->flags[y+1][x+1] >> 15);
+                            ff_jpeg2000_set_significance(t1, x, y, t1->flags[y+1][x+1] >> 15);
                         }
                     }
-                    t1->flags[y+1][x+1] &= ~J2K_T1_VIS;
+                    t1->flags[y+1][x+1] &= ~JPEG2000_T1_VIS;
                 }
             } else{
                 for (y = y0; y < y0 + 4 && y < height; y++){
-                    if (!(t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS))){
-                        int ctxno = ff_j2k_getnbctxno(t1->flags[y+1][x+1], bandno, vert_causal_ctx_csty_loc_symbol);
+                    if (!(t1->flags[y+1][x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))){
+                        int ctxno = ff_jpeg2000_getsigctxno(t1->flags[y+1][x+1], bandno);
                         ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, t1->data[y][x] & mask ? 1:0);
                         if (t1->data[y][x] & mask){ // newly significant
                             int xorbit;
-                            int ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit);
+                            int ctxno = ff_jpeg2000_getsgnctxno(t1->flags[y+1][x+1], &xorbit);
                             *nmsedec += getnmsedec_sig(t1->data[y][x], bpno + NMSEDEC_FRACBITS);
                             ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, (t1->flags[y+1][x+1] >> 15) ^ xorbit);
-                            ff_j2k_set_significant(t1, x, y, t1->flags[y+1][x+1] >> 15);
+                            ff_jpeg2000_set_significance(t1, x, y, t1->flags[y+1][x+1] >> 15);
                         }
                     }
-                    t1->flags[y+1][x+1] &= ~J2K_T1_VIS;
+                    t1->flags[y+1][x+1] &= ~JPEG2000_T1_VIS;
                 }
             }
         }
 }
 
-static void encode_cblk(J2kEncoderContext *s, J2kT1Context *t1, J2kCblk *cblk, J2kTile *tile,
+static void encode_cblk(Jpeg2000EncoderContext *s, Jpeg2000T1Context *t1, Jpeg2000Cblk *cblk, Jpeg2000Tile *tile,
                         int width, int height, int bandpos, int lev)
 {
     int pass_t = 2, passno, x, y, max=0, nmsedec, bpno;
@@ -578,7 +583,7 @@
     for (y = 0; y < height; y++){
         for (x = 0; x < width; x++){
             if (t1->data[y][x] < 0){
-                t1->flags[y+1][x+1] |= J2K_T1_SGN;
+                t1->flags[y+1][x+1] |= JPEG2000_T1_SGN;
                 t1->data[y][x] = -t1->data[y][x];
             }
             max = FFMAX(max, t1->data[y][x]);
@@ -625,7 +630,7 @@
 
 /* tier-2 routines: */
 
-static void putnumpasses(J2kEncoderContext *s, int n)
+static void putnumpasses(Jpeg2000EncoderContext *s, int n)
 {
     if (n == 1)
         put_num(s, 0, 1);
@@ -640,7 +645,7 @@
 }
 
 
-static int encode_packet(J2kEncoderContext *s, J2kResLevel *rlevel, int precno,
+static int encode_packet(Jpeg2000EncoderContext *s, Jpeg2000ResLevel *rlevel, int precno,
                           uint8_t *expn, int numgbits)
 {
     int bandno, empty = 1;
@@ -667,28 +672,28 @@
     }
 
     for (bandno = 0; bandno < rlevel->nbands; bandno++){
-        J2kBand *band = rlevel->band + bandno;
-        J2kPrec *prec = band->prec + precno;
+        Jpeg2000Band *band = rlevel->band + bandno;
+        Jpeg2000Prec *prec = band->prec + precno;
         int yi, xi, pos;
-        int cblknw = prec->xi1 - prec->xi0;
+        int cblknw = prec->nb_codeblocks_width;
 
         if (band->coord[0][0] == band->coord[0][1]
         ||  band->coord[1][0] == band->coord[1][1])
             continue;
 
-        for (pos=0, yi = prec->yi0; yi < prec->yi1; yi++){
-            for (xi = prec->xi0; xi < prec->xi1; xi++, pos++){
-                prec->cblkincl[pos].val = band->cblk[yi * cblknw + xi].ninclpasses == 0;
+        for (pos=0, yi = 0; yi < prec->nb_codeblocks_height; yi++){
+            for (xi = 0; xi < cblknw; xi++, pos++){
+                prec->cblkincl[pos].val = prec->cblk[yi * cblknw + xi].ninclpasses == 0;
                 tag_tree_update(prec->cblkincl + pos);
-                prec->zerobits[pos].val = expn[bandno] + numgbits - 1 - band->cblk[yi * cblknw + xi].nonzerobits;
+                prec->zerobits[pos].val = expn[bandno] + numgbits - 1 - prec->cblk[yi * cblknw + xi].nonzerobits;
                 tag_tree_update(prec->zerobits + pos);
             }
         }
 
-        for (pos=0, yi = prec->yi0; yi < prec->yi1; yi++){
-            for (xi = prec->xi0; xi < prec->xi1; xi++, pos++){
+        for (pos=0, yi = 0; yi < prec->nb_codeblocks_height; yi++){
+            for (xi = 0; xi < cblknw; xi++, pos++){
                 int pad = 0, llen, length;
-                J2kCblk *cblk = band->cblk + yi * cblknw + xi;
+                Jpeg2000Cblk *cblk = prec->cblk + yi * cblknw + xi;
 
                 if (s->buf_end - s->buf < 20) // approximately
                     return -1;
@@ -717,13 +722,13 @@
     }
     j2k_flush(s);
     for (bandno = 0; bandno < rlevel->nbands; bandno++){
-        J2kBand *band = rlevel->band + bandno;
-        J2kPrec *prec = band->prec + precno;
-        int yi, cblknw = prec->xi1 - prec->xi0;
-        for (yi = prec->yi0; yi < prec->yi1; yi++){
+        Jpeg2000Band *band = rlevel->band + bandno;
+        Jpeg2000Prec *prec = band->prec + precno;
+        int yi, cblknw = prec->nb_codeblocks_width;
+        for (yi =0; yi < prec->nb_codeblocks_height; yi++){
             int xi;
-            for (xi = prec->xi0; xi < prec->xi1; xi++){
-                J2kCblk *cblk = band->cblk + yi * cblknw + xi;
+            for (xi = 0; xi < cblknw; xi++){
+                Jpeg2000Cblk *cblk = prec->cblk + yi * cblknw + xi;
                 if (cblk->ninclpasses){
                     if (s->buf_end - s->buf < cblk->passes[cblk->ninclpasses-1].rate)
                         return -1;
@@ -735,18 +740,18 @@
     return 0;
 }
 
-static int encode_packets(J2kEncoderContext *s, J2kTile *tile, int tileno)
+static int encode_packets(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno)
 {
     int compno, reslevelno, ret;
-    J2kCodingStyle *codsty = &s->codsty;
-    J2kQuantStyle  *qntsty = &s->qntsty;
+    Jpeg2000CodingStyle *codsty = &s->codsty;
+    Jpeg2000QuantStyle  *qntsty = &s->qntsty;
 
     av_log(s->avctx, AV_LOG_DEBUG, "tier2\n");
     // lay-rlevel-comp-pos progression
     for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){
         for (compno = 0; compno < s->ncomponents; compno++){
             int precno;
-            J2kResLevel *reslevel = s->tile[tileno].comp[compno].reslevel + reslevelno;
+            Jpeg2000ResLevel *reslevel = s->tile[tileno].comp[compno].reslevel + reslevelno;
             for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){
                 if (ret = encode_packet(s, reslevel, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0),
                               qntsty->nguardbits))
@@ -758,7 +763,7 @@
     return 0;
 }
 
-static int getcut(J2kCblk *cblk, int64_t lambda, int dwt_norm)
+static int getcut(Jpeg2000Cblk *cblk, int64_t lambda, int dwt_norm)
 {
     int passno, res = 0;
     for (passno = 0; passno < cblk->npasses; passno++){
@@ -776,54 +781,58 @@
     return res;
 }
 
-static void truncpasses(J2kEncoderContext *s, J2kTile *tile)
+static void truncpasses(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile)
 {
-    int compno, reslevelno, bandno, cblkno, lev;
-    J2kCodingStyle *codsty = &s->codsty;
+    int precno, compno, reslevelno, bandno, cblkno, lev;
+    Jpeg2000CodingStyle *codsty = &s->codsty;
 
     for (compno = 0; compno < s->ncomponents; compno++){
-        J2kComponent *comp = tile->comp + compno;
+        Jpeg2000Component *comp = tile->comp + compno;
 
         for (reslevelno = 0, lev = codsty->nreslevels-1; reslevelno < codsty->nreslevels; reslevelno++, lev--){
-            J2kResLevel *reslevel = comp->reslevel + reslevelno;
+            Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno;
 
-            for (bandno = 0; bandno < reslevel->nbands ; bandno++){
-                int bandpos = bandno + (reslevelno > 0);
-                J2kBand *band = reslevel->band + bandno;
+            for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){
+                for (bandno = 0; bandno < reslevel->nbands ; bandno++){
+                    int bandpos = bandno + (reslevelno > 0);
+                    Jpeg2000Band *band = reslevel->band + bandno;
+                    Jpeg2000Prec *prec = band->prec + precno;
 
-                for (cblkno = 0; cblkno < band->cblknx * band->cblkny; cblkno++){
-                    J2kCblk *cblk = band->cblk + cblkno;
+                    for (cblkno = 0; cblkno < prec->nb_codeblocks_height * prec->nb_codeblocks_width; cblkno++){
+                        Jpeg2000Cblk *cblk = prec->cblk + cblkno;
 
-                    cblk->ninclpasses = getcut(cblk, s->lambda,
-                            (int64_t)dwt_norms[codsty->transform][bandpos][lev] * (int64_t)band->stepsize >> 13);
+                        cblk->ninclpasses = getcut(cblk, s->lambda,
+                                (int64_t)dwt_norms[codsty->transform == FF_DWT53][bandpos][lev] * (int64_t)band->i_stepsize >> 15);
+                    }
                 }
             }
         }
     }
 }
 
-static int encode_tile(J2kEncoderContext *s, J2kTile *tile, int tileno)
+static int encode_tile(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno)
 {
     int compno, reslevelno, bandno, ret;
-    J2kT1Context t1;
-    J2kCodingStyle *codsty = &s->codsty;
+    Jpeg2000T1Context t1;
+    Jpeg2000CodingStyle *codsty = &s->codsty;
     for (compno = 0; compno < s->ncomponents; compno++){
-        J2kComponent *comp = s->tile[tileno].comp + compno;
+        Jpeg2000Component *comp = s->tile[tileno].comp + compno;
 
         av_log(s->avctx, AV_LOG_DEBUG,"dwt\n");
-        if (ret = ff_j2k_dwt_encode(&comp->dwt, comp->data))
+        if (ret = ff_dwt_encode(&comp->dwt, comp->i_data))
             return ret;
         av_log(s->avctx, AV_LOG_DEBUG,"after dwt -> tier1\n");
 
         for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){
-            J2kResLevel *reslevel = comp->reslevel + reslevelno;
+            Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno;
 
             for (bandno = 0; bandno < reslevel->nbands ; bandno++){
-                J2kBand *band = reslevel->band + bandno;
+                Jpeg2000Band *band = reslevel->band + bandno;
+                Jpeg2000Prec *prec = band->prec; // we support only 1 precinct per band ATM in the encoder
                 int cblkx, cblky, cblkno=0, xx0, x0, xx1, y0, yy0, yy1, bandpos;
                 yy0 = bandno == 0 ? 0 : comp->reslevel[reslevelno-1].coord[1][1] - comp->reslevel[reslevelno-1].coord[1][0];
                 y0 = yy0;
-                yy1 = FFMIN(ff_j2k_ceildiv(band->coord[1][0] + 1, band->codeblock_height) * band->codeblock_height,
+                yy1 = FFMIN(ff_jpeg2000_ceildivpow2(band->coord[1][0] + 1, band->log2_cblk_height) << band->log2_cblk_height,
                             band->coord[1][1]) - band->coord[1][0] + yy0;
 
                 if (band->coord[0][0] == band->coord[0][1] || band->coord[1][0] == band->coord[1][1])
@@ -831,41 +840,41 @@
 
                 bandpos = bandno + (reslevelno > 0);
 
-                for (cblky = 0; cblky < band->cblkny; cblky++){
+                for (cblky = 0; cblky < prec->nb_codeblocks_height; cblky++){
                     if (reslevelno == 0 || bandno == 1)
                         xx0 = 0;
                     else
                         xx0 = comp->reslevel[reslevelno-1].coord[0][1] - comp->reslevel[reslevelno-1].coord[0][0];
                     x0 = xx0;
-                    xx1 = FFMIN(ff_j2k_ceildiv(band->coord[0][0] + 1, band->codeblock_width) * band->codeblock_width,
+                    xx1 = FFMIN(ff_jpeg2000_ceildivpow2(band->coord[0][0] + 1, band->log2_cblk_width) << band->log2_cblk_width,
                                 band->coord[0][1]) - band->coord[0][0] + xx0;
 
-                    for (cblkx = 0; cblkx < band->cblknx; cblkx++, cblkno++){
+                    for (cblkx = 0; cblkx < prec->nb_codeblocks_width; cblkx++, cblkno++){
                         int y, x;
                         if (codsty->transform == FF_DWT53){
                             for (y = yy0; y < yy1; y++){
                                 int *ptr = t1.data[y-yy0];
                                 for (x = xx0; x < xx1; x++){
-                                    *ptr++ = comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y + x] << NMSEDEC_FRACBITS;
+                                    *ptr++ = comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * y + x] << NMSEDEC_FRACBITS;
                                 }
                             }
                         } else{
                             for (y = yy0; y < yy1; y++){
                                 int *ptr = t1.data[y-yy0];
                                 for (x = xx0; x < xx1; x++){
-                                    *ptr = (comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y + x]);
-                                    *ptr = (int64_t)*ptr * (int64_t)(8192 * 8192 / band->stepsize) >> 13 - NMSEDEC_FRACBITS;
+                                    *ptr = (comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * y + x]);
+                                    *ptr = (int64_t)*ptr * (int64_t)(16384 * 65536 / band->i_stepsize) >> 15 - NMSEDEC_FRACBITS;
                                     ptr++;
                                 }
                             }
                         }
-                        encode_cblk(s, &t1, band->cblk + cblkno, tile, xx1 - xx0, yy1 - yy0,
+                        encode_cblk(s, &t1, prec->cblk + cblkno, tile, xx1 - xx0, yy1 - yy0,
                                     bandpos, codsty->nreslevels - reslevelno - 1);
                         xx0 = xx1;
-                        xx1 = FFMIN(xx1 + band->codeblock_width, band->coord[0][1] - band->coord[0][0] + x0);
+                        xx1 = FFMIN(xx1 + (1 << band->log2_cblk_width), band->coord[0][1] - band->coord[0][0] + x0);
                     }
                     yy0 = yy1;
-                    yy1 = FFMIN(yy1 + band->codeblock_height, band->coord[1][1] - band->coord[1][0] + y0);
+                    yy1 = FFMIN(yy1 + (1 << band->log2_cblk_height), band->coord[1][1] - band->coord[1][0] + y0);
                 }
             }
         }
@@ -880,28 +889,28 @@
     return 0;
 }
 
-static void cleanup(J2kEncoderContext *s)
+static void cleanup(Jpeg2000EncoderContext *s)
 {
     int tileno, compno;
-    J2kCodingStyle *codsty = &s->codsty;
+    Jpeg2000CodingStyle *codsty = &s->codsty;
 
     for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){
         for (compno = 0; compno < s->ncomponents; compno++){
-            J2kComponent *comp = s->tile[tileno].comp + compno;
-            ff_j2k_cleanup(comp, codsty);
+            Jpeg2000Component *comp = s->tile[tileno].comp + compno;
+            ff_jpeg2000_cleanup(comp, codsty);
         }
         av_freep(&s->tile[tileno].comp);
     }
     av_freep(&s->tile);
 }
 
-static void reinit(J2kEncoderContext *s)
+static void reinit(Jpeg2000EncoderContext *s)
 {
     int tileno, compno;
     for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){
-        J2kTile *tile = s->tile + tileno;
+        Jpeg2000Tile *tile = s->tile + tileno;
         for (compno = 0; compno < s->ncomponents; compno++)
-            ff_j2k_reinit(tile->comp + compno, &s->codsty);
+            ff_jpeg2000_reinit(tile->comp + compno, &s->codsty);
     }
 }
 
@@ -909,7 +918,7 @@
                         const AVFrame *pict, int *got_packet)
 {
     int tileno, ret;
-    J2kEncoderContext *s = avctx->priv_data;
+    Jpeg2000EncoderContext *s = avctx->priv_data;
 
     if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width*avctx->height*9 + FF_MIN_BUFFER_SIZE)) < 0)
         return ret;
@@ -928,7 +937,7 @@
 
     if (s->buf_end - s->buf < 2)
         return -1;
-    bytestream_put_be16(&s->buf, J2K_SOC);
+    bytestream_put_be16(&s->buf, JPEG2000_SOC);
     if (ret = put_siz(s))
         return ret;
     if (ret = put_cod(s))
@@ -942,14 +951,14 @@
             return -1;
         if (s->buf_end - s->buf < 2)
             return -1;
-        bytestream_put_be16(&s->buf, J2K_SOD);
+        bytestream_put_be16(&s->buf, JPEG2000_SOD);
         if (ret = encode_tile(s, s->tile + tileno, tileno))
             return ret;
         bytestream_put_be32(&psotptr, s->buf - psotptr + 6);
     }
     if (s->buf_end - s->buf < 2)
         return -1;
-    bytestream_put_be16(&s->buf, J2K_EOC);
+    bytestream_put_be16(&s->buf, JPEG2000_EOC);
 
     av_log(s->avctx, AV_LOG_DEBUG, "end\n");
     pkt->size = s->buf - s->buf_start;
@@ -962,21 +971,22 @@
 static av_cold int j2kenc_init(AVCodecContext *avctx)
 {
     int i, ret;
-    J2kEncoderContext *s = avctx->priv_data;
-    J2kCodingStyle *codsty = &s->codsty;
-    J2kQuantStyle  *qntsty = &s->qntsty;
+    Jpeg2000EncoderContext *s = avctx->priv_data;
+    Jpeg2000CodingStyle *codsty = &s->codsty;
+    Jpeg2000QuantStyle  *qntsty = &s->qntsty;
 
     s->avctx = avctx;
     av_log(s->avctx, AV_LOG_DEBUG, "init\n");
 
     // defaults:
     // TODO: implement setting non-standard precinct size
-    codsty->log2_prec_width  = 15;
-    codsty->log2_prec_height = 15;
+    memset(codsty->log2_prec_widths , 15, sizeof(codsty->log2_prec_widths ));
+    memset(codsty->log2_prec_heights, 15, sizeof(codsty->log2_prec_heights));
+    codsty->nreslevels2decode=
     codsty->nreslevels       = 7;
     codsty->log2_cblk_width  = 4;
     codsty->log2_cblk_height = 4;
-    codsty->transform        = 1;
+    codsty->transform        = avctx->prediction_method ? FF_DWT53 : FF_DWT97_INT;
 
     qntsty->nguardbits       = 1;
 
@@ -984,9 +994,9 @@
     s->tile_height           = 256;
 
     if (codsty->transform == FF_DWT53)
-        qntsty->quantsty = J2K_QSTY_NONE;
+        qntsty->quantsty = JPEG2000_QSTY_NONE;
     else
-        qntsty->quantsty = J2K_QSTY_SE;
+        qntsty->quantsty = JPEG2000_QSTY_SE;
 
     s->width = avctx->width;
     s->height = avctx->height;
@@ -1005,8 +1015,8 @@
                 s->chroma_shift, s->chroma_shift + 1);
     }
 
-    ff_j2k_init_tier1_luts();
-
+    ff_jpeg2000_init_tier1_luts();
+    ff_mqc_init_context_tables();
     init_luts();
 
     init_quantization(s);
@@ -1020,17 +1030,17 @@
 
 static int j2kenc_destroy(AVCodecContext *avctx)
 {
-    J2kEncoderContext *s = avctx->priv_data;
+    Jpeg2000EncoderContext *s = avctx->priv_data;
 
     cleanup(s);
     return 0;
 }
 
-AVCodec ff_j2k_encoder = {
-    .name           = "j2k",
+AVCodec ff_jpeg2000_encoder = {
+    .name           = "jpeg2000",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_JPEG2000,
-    .priv_data_size = sizeof(J2kEncoderContext),
+    .priv_data_size = sizeof(Jpeg2000EncoderContext),
     .init           = j2kenc_init,
     .encode2        = encode_frame,
     .close          = j2kenc_destroy,
diff --git a/libavcodec/jpeg2000.c b/libavcodec/jpeg2000.c
index 060b1fd..cb1a64d 100644
--- a/libavcodec/jpeg2000.c
+++ b/libavcodec/jpeg2000.c
@@ -25,6 +25,7 @@
  * JPEG 2000 image encoder and decoder common functions
  */
 
+#include "libavutil/avassert.h"
 #include "libavutil/common.h"
 #include "libavutil/mem.h"
 #include "avcodec.h"
@@ -40,8 +41,7 @@
     uint32_t res = 0;
     while (w > 1 || h > 1) {
         res += w * h;
-        if (res + 1 >= INT32_MAX)
-            return -1;
+        av_assert0(res + 1 < INT32_MAX);
         w = (w + 1) >> 1;
         h = (h + 1) >> 1;
     }
@@ -55,8 +55,6 @@
     int32_t tt_size;
 
     tt_size = tag_tree_size(w, h);
-    if (tt_size == -1)
-        return NULL;
 
     t = res = av_mallocz_array(tt_size, sizeof(*t));
     if (!res)
@@ -81,6 +79,16 @@
     return res;
 }
 
+static void tag_tree_zero(Jpeg2000TgtNode *t, int w, int h)
+{
+    int i, siz = tag_tree_size(w, h);
+
+    for (i = 0; i < siz; i++) {
+        t[i].val = 0;
+        t[i].vis = 0;
+    }
+}
+
 uint8_t ff_jpeg2000_sigctxno_lut[256][4];
 
 static int getsigctxno(int flag, int bandno)
@@ -95,47 +103,33 @@
         ((flag & JPEG2000_T1_SIG_NW) ? 1 : 0) +
         ((flag & JPEG2000_T1_SIG_SE) ? 1 : 0) +
         ((flag & JPEG2000_T1_SIG_SW) ? 1 : 0);
+
     if (bandno < 3) {
         if (bandno == 1)
             FFSWAP(int, h, v);
-        if (h == 2)
-            return 8;
+        if (h == 2) return 8;
         if (h == 1) {
-            if (v >= 1)
-                return 7;
-            if (d >= 1)
-                return 6;
+            if (v >= 1) return 7;
+            if (d >= 1) return 6;
             return 5;
         }
-        if (v == 2)
-            return 4;
-        if (v == 1)
-            return 3;
-        if (d >= 2)
-            return 2;
-        if (d == 1)
-            return 1;
-        return 0;
+        if (v == 2) return 4;
+        if (v == 1) return 3;
+        if (d >= 2) return 2;
+        if (d == 1) return 1;
     } else {
-        if (d >= 3)
-            return 8;
+        if (d >= 3) return 8;
         if (d == 2) {
-            if (h + v >= 1)
-                return 7;
+            if (h+v >= 1) return 7;
             return 6;
         }
         if (d == 1) {
-            if (h + v >= 2)
-                return 5;
-            if (h + v == 1)
-                return 4;
+            if (h+v >= 2) return 5;
+            if (h+v == 1) return 4;
             return 3;
         }
-        if (h + v >= 2)
-            return 2;
-        if (h + v == 1)
-            return 1;
-        return 0;
+        if (h+v >= 2) return 2;
+        if (h+v == 1) return 1;
     }
     return 0;
 }
@@ -204,7 +198,12 @@
 {
     uint8_t log2_band_prec_width, log2_band_prec_height;
     int reslevelno, bandno, gbandno = 0, ret, i, j;
-    uint32_t csize = 1;
+    uint32_t csize;
+
+    if (codsty->nreslevels2decode <= 0) {
+        av_log(avctx, AV_LOG_ERROR, "nreslevels2decode %d invalid or uninitialized\n", codsty->nreslevels2decode);
+        return AVERROR_INVALIDDATA;
+    }
 
     if (ret = ff_jpeg2000_dwt_init(&comp->dwt, comp->coord,
                                    codsty->nreslevels2decode - 1,
@@ -214,9 +213,17 @@
     csize = (comp->coord[0][1] - comp->coord[0][0]) *
             (comp->coord[1][1] - comp->coord[1][0]);
 
-    comp->data = av_malloc_array(csize, sizeof(*comp->data));
-    if (!comp->data)
-        return AVERROR(ENOMEM);
+    if (codsty->transform == FF_DWT97) {
+        comp->i_data = NULL;
+        comp->f_data = av_malloc_array(csize, sizeof(*comp->f_data));
+        if (!comp->f_data)
+            return AVERROR(ENOMEM);
+    } else {
+        comp->f_data = NULL;
+        comp->i_data = av_malloc_array(csize, sizeof(*comp->i_data));
+        if (!comp->i_data)
+            return AVERROR(ENOMEM);
+    }
     comp->reslevel = av_malloc_array(codsty->nreslevels, sizeof(*comp->reslevel));
     if (!comp->reslevel)
         return AVERROR(ENOMEM);
@@ -281,14 +288,14 @@
                 int numbps;
             case JPEG2000_QSTY_NONE:
                 /* TODO: to verify. No quantization in this case */
-                numbps = cbps +
-                         lut_gain[codsty->transform][bandno + reslevelno > 0];
-                band->stepsize = (float)SHL(2048 + qntsty->mant[gbandno],
-                                            2 + numbps - qntsty->expn[gbandno]);
+                band->f_stepsize = 1;
                 break;
             case JPEG2000_QSTY_SI:
                 /*TODO: Compute formula to implement. */
-                band->stepsize = (float) (1 << 13);
+                numbps = cbps +
+                         lut_gain[codsty->transform == FF_DWT53][bandno + (reslevelno > 0)];
+                band->f_stepsize = SHL(2048 + qntsty->mant[gbandno],
+                                       2 + numbps - qntsty->expn[gbandno]);
                 break;
             case JPEG2000_QSTY_SE:
                 /* Exponent quantization step.
@@ -300,20 +307,20 @@
                  * but it works (compared to OpenJPEG). Why?
                  * Further investigation needed. */
                 gain            = cbps;
-                band->stepsize  = pow(2.0, gain - qntsty->expn[gbandno]);
-                band->stepsize *= (float)qntsty->mant[gbandno] / 2048.0 + 1.0;
-                /* FIXME: In openjepg code stespize = stepsize * 0.5. Why?
-                 * If not set output of entropic decoder is not correct. */
-                band->stepsize *= 0.5;
+                band->f_stepsize  = pow(2.0, gain - qntsty->expn[gbandno]);
+                band->f_stepsize *= qntsty->mant[gbandno] / 2048.0 + 1.0;
                 break;
             default:
-                band->stepsize = 0;
+                band->f_stepsize = 0;
                 av_log(avctx, AV_LOG_ERROR, "Unknown quantization format\n");
                 break;
             }
-            /* BITEXACT computing case --> convert to int */
-            if (avctx->flags & CODEC_FLAG_BITEXACT)
-                band->stepsize = (int32_t)(band->stepsize * (1 << 16));
+            /* FIXME: In openjepg code stespize = stepsize * 0.5. Why?
+             * If not set output of entropic decoder is not correct. */
+            if (!av_codec_is_encoder(avctx->codec))
+                band->f_stepsize *= 0.5;
+
+            band->i_stepsize = band->f_stepsize * (1 << 15);
 
             /* computation of tbx_0, tbx_1, tby_0, tby_1
              * see ISO/IEC 15444-1:2002 B.5 eq. B-15 and tbl B.1
@@ -324,9 +331,8 @@
                 for (i = 0; i < 2; i++)
                     for (j = 0; j < 2; j++)
                         band->coord[i][j] =
-                            ff_jpeg2000_ceildivpow2(comp->coord_o[i][j],
+                            ff_jpeg2000_ceildivpow2(comp->coord_o[i][j] - comp->coord_o[i][0],
                                                     declvl - 1);
-
                 log2_band_prec_width  = reslevel->log2_prec_width;
                 log2_band_prec_height = reslevel->log2_prec_height;
                 /* see ISO/IEC 15444-1:2002 eq. B-17 and eq. B-15 */
@@ -341,7 +347,7 @@
                     for (j = 0; j < 2; j++)
                         /* Formula example for tbx_0 = ceildiv((tcx_0 - 2 ^ (declvl - 1) * x0_b) / declvl) */
                         band->coord[i][j] =
-                            ff_jpeg2000_ceildivpow2(comp->coord_o[i][j] -
+                            ff_jpeg2000_ceildivpow2(comp->coord_o[i][j] - comp->coord_o[i][0] -
                                                     (((bandno + 1 >> i) & 1) << declvl - 1),
                                                     declvl);
                 /* TODO: Manage case of 3 band offsets here or
@@ -357,8 +363,13 @@
                 log2_band_prec_height = reslevel->log2_prec_height - 1;
             }
 
+            for (j = 0; j < 2; j++)
+                band->coord[0][j] = ff_jpeg2000_ceildiv(band->coord[0][j], dx);
+            for (j = 0; j < 2; j++)
+                band->coord[1][j] = ff_jpeg2000_ceildiv(band->coord[1][j], dy);
+
             band->prec = av_malloc_array(reslevel->num_precincts_x *
-                                         reslevel->num_precincts_y,
+                                         (uint64_t)reslevel->num_precincts_y,
                                          sizeof(*band->prec));
             if (!band->prec)
                 return AVERROR(ENOMEM);
@@ -413,9 +424,9 @@
                 if (!prec->zerobits)
                     return AVERROR(ENOMEM);
 
-                prec->cblk = av_malloc_array(prec->nb_codeblocks_width *
-                                             prec->nb_codeblocks_height,
-                                             sizeof(*prec->cblk));
+                prec->cblk = av_mallocz_array(prec->nb_codeblocks_width *
+                                              (uint64_t)prec->nb_codeblocks_height,
+                                              sizeof(*prec->cblk));
                 if (!prec->cblk)
                     return AVERROR(ENOMEM);
                 for (cblkno = 0; cblkno < prec->nb_codeblocks_width * prec->nb_codeblocks_height; cblkno++) {
@@ -440,6 +451,20 @@
                     /* Compute Cy1 */
                     cblk->coord[1][1] = FFMIN(Cy0 + (1 << band->log2_cblk_height),
                                               prec->coord[1][1]);
+                    /* Update code-blocks coordinates according sub-band position */
+                    if ((bandno + !!reslevelno) & 1) {
+                        cblk->coord[0][0] += comp->reslevel[reslevelno-1].coord[0][1] -
+                                             comp->reslevel[reslevelno-1].coord[0][0];
+                        cblk->coord[0][1] += comp->reslevel[reslevelno-1].coord[0][1] -
+                                             comp->reslevel[reslevelno-1].coord[0][0];
+                    }
+                    if ((bandno + !!reslevelno) & 2) {
+                        cblk->coord[1][0] += comp->reslevel[reslevelno-1].coord[1][1] -
+                                             comp->reslevel[reslevelno-1].coord[1][0];
+                        cblk->coord[1][1] += comp->reslevel[reslevelno-1].coord[1][1] -
+                                             comp->reslevel[reslevelno-1].coord[1][0];
+                    }
+
                     cblk->zero      = 0;
                     cblk->lblock    = 3;
                     cblk->length    = 0;
@@ -452,10 +477,33 @@
     return 0;
 }
 
+void ff_jpeg2000_reinit(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty)
+{
+    int reslevelno, bandno, cblkno, precno;
+    for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++) {
+        Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno;
+        for (bandno = 0; bandno < rlevel->nbands; bandno++) {
+            Jpeg2000Band *band = rlevel->band + bandno;
+            for(precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++) {
+                Jpeg2000Prec *prec = band->prec + precno;
+                tag_tree_zero(prec->zerobits, prec->nb_codeblocks_width, prec->nb_codeblocks_height);
+                tag_tree_zero(prec->cblkincl, prec->nb_codeblocks_width, prec->nb_codeblocks_height);
+                for (cblkno = 0; cblkno < prec->nb_codeblocks_width * prec->nb_codeblocks_height; cblkno++) {
+                    Jpeg2000Cblk *cblk = prec->cblk + cblkno;
+                    cblk->length = 0;
+                    cblk->lblock = 3;
+                }
+            }
+        }
+    }
+}
+
 void ff_jpeg2000_cleanup(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty)
 {
     int reslevelno, bandno, precno;
-    for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++) {
+    for (reslevelno = 0;
+         comp->reslevel && reslevelno < codsty->nreslevels;
+         reslevelno++) {
         Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno;
 
         for (bandno = 0; bandno < reslevel->nbands; bandno++) {
@@ -474,5 +522,6 @@
 
     ff_dwt_destroy(&comp->dwt);
     av_freep(&comp->reslevel);
-    av_freep(&comp->data);
+    av_freep(&comp->i_data);
+    av_freep(&comp->f_data);
 }
diff --git a/libavcodec/jpeg2000.h b/libavcodec/jpeg2000.h
index c2d6d90..acdba62 100644
--- a/libavcodec/jpeg2000.h
+++ b/libavcodec/jpeg2000.h
@@ -67,7 +67,9 @@
 #define JPEG2000_MAX_CBLKW 64
 #define JPEG2000_MAX_CBLKH 64
 
-#define JPEG2000_MAX_RESLEVELS 33
+
+#define JPEG2000_MAX_DECLEVELS 32
+#define JPEG2000_MAX_RESLEVELS (JPEG2000_MAX_DECLEVELS + 1)
 
 // T1 flags
 // flags determining significance of neighbor coefficients
@@ -128,14 +130,12 @@
 } Jpeg2000TgtNode;
 
 typedef struct Jpeg2000CodingStyle {
-    uint8_t nreslevels;       // number of resolution levels
-    uint8_t nreslevels2decode; // number of resolution levels to decode
+    int nreslevels;           // number of resolution levels
+    int nreslevels2decode;    // number of resolution levels to decode
     uint8_t log2_cblk_width,
             log2_cblk_height; // exponent of codeblock size
     uint8_t transform;        // DWT type
     uint8_t csty;             // coding style
-    uint8_t log2_prec_width,
-            log2_prec_height; // precinct size
     uint8_t nlayers;          // number of layers
     uint8_t mct;              // multiple component transformation
     uint8_t cblk_style;       // codeblock coding style
@@ -145,8 +145,8 @@
 } Jpeg2000CodingStyle;
 
 typedef struct Jpeg2000QuantStyle {
-    uint8_t expn[32 * 3];  // quantization exponent
-    uint32_t mant[32 * 3]; // quantization mantissa
+    uint8_t expn[JPEG2000_MAX_DECLEVELS * 3];  // quantization exponent
+    uint16_t mant[JPEG2000_MAX_DECLEVELS * 3]; // quantization mantissa
     uint8_t quantsty;      // quantization style
     uint8_t nguardbits;    // number of guard bits
 } Jpeg2000QuantStyle;
@@ -170,7 +170,6 @@
 } Jpeg2000Cblk; // code block
 
 typedef struct Jpeg2000Prec {
-    uint16_t xi0, yi0; // codeblock indexes ([xi0, xi1))
     uint16_t nb_codeblocks_width;
     uint16_t nb_codeblocks_height;
     Jpeg2000TgtNode *zerobits;
@@ -179,13 +178,11 @@
     uint16_t coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
 } Jpeg2000Prec; // precinct
 
-/* TODO: stepsize can be float or integer depending on
- * reversible or irreversible transformation. */
 typedef struct Jpeg2000Band {
     uint16_t coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
     uint16_t log2_cblk_width, log2_cblk_height;
-    uint16_t cblknx, cblkny;
-    float stepsize; // quantization stepsize
+    int i_stepsize; // quantization stepsize
+    float f_stepsize; // quantization stepsize
     Jpeg2000Prec *prec;
 } Jpeg2000Band; // subband
 
@@ -197,13 +194,11 @@
     Jpeg2000Band *band;
 } Jpeg2000ResLevel; // resolution level
 
-/* TODO: data can be float of integer depending of reversible/irreversible
- * transformation.
- */
 typedef struct Jpeg2000Component {
     Jpeg2000ResLevel *reslevel;
     DWTContext dwt;
-    float *data;
+    float *f_data;
+    int *i_data;
     uint16_t coord[2][2];   // border coordinates {{x0, x1}, {y0, y1}} -- can be reduced with lowres option
     uint16_t coord_o[2][2]; // border coordinates {{x0, x1}, {y0, y1}} -- original values from jpeg2000 headers
 } Jpeg2000Component;
@@ -263,6 +258,8 @@
                                int cbps, int dx, int dy,
                                AVCodecContext *ctx);
 
+void ff_jpeg2000_reinit(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty);
+
 void ff_jpeg2000_cleanup(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty);
 
 #endif /* AVCODEC_JPEG2000_H */
diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c
index 20e5c9c..3c14a13 100644
--- a/libavcodec/jpeg2000dec.c
+++ b/libavcodec/jpeg2000dec.c
@@ -25,8 +25,10 @@
  * JPEG 2000 image decoder
  */
 
+#include "libavutil/avassert.h"
 #include "libavutil/common.h"
 #include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
 #include "avcodec.h"
 #include "bytestream.h"
 #include "internal.h"
@@ -36,16 +38,15 @@
 #define JP2_SIG_TYPE    0x6A502020
 #define JP2_SIG_VALUE   0x0D0A870A
 #define JP2_CODESTREAM  0x6A703263
+#define JP2_HEADER      0x6A703268
 
 #define HAD_COC 0x01
 #define HAD_QCC 0x02
 
 typedef struct Jpeg2000TilePart {
-    uint16_t tp_idx;                    // Tile-part index
     uint8_t tile_index;                 // Tile index who refers the tile-part
-    uint32_t tp_len;                    // Length of tile-part
-    const uint8_t *tp_start_bstrm;      // Start address bit stream in tile-part
-    const uint8_t *tp_end_bstrm;        // End address of the bit stream tile part
+    const uint8_t *tp_end;
+    GetByteContext tpg;                 // bit stream in tile-part
 } Jpeg2000TilePart;
 
 /* RMK: For JPEG2000 DCINEMA 3 tile-parts in a tile
@@ -55,12 +56,14 @@
     uint8_t             properties[4];
     Jpeg2000CodingStyle codsty[4];
     Jpeg2000QuantStyle  qntsty[4];
-    Jpeg2000TilePart    tile_part[3];
+    Jpeg2000TilePart    tile_part[4];
+    uint16_t tp_idx;                    // Tile-part index
 } Jpeg2000Tile;
 
 typedef struct Jpeg2000DecoderContext {
     AVClass         *class;
     AVCodecContext  *avctx;
+    GetByteContext  g;
 
     int             width, height;
     int             image_offset_x, image_offset_y;
@@ -71,24 +74,25 @@
     int             cdx[4], cdy[4];
     int             precision;
     int             ncomponents;
+    int             colour_space;
+    uint32_t        palette[256];
+    int8_t          pal8;
+    int             cdef[4];
     int             tile_width, tile_height;
-    int             numXtiles, numYtiles;
+    unsigned        numXtiles, numYtiles;
     int             maxtilelen;
 
     Jpeg2000CodingStyle codsty[4];
     Jpeg2000QuantStyle  qntsty[4];
 
-    const uint8_t   *buf_start;
-    const uint8_t   *buf;
-    const uint8_t   *buf_end;
     int             bit_index;
 
-    int16_t         curtileno;
+    int             curtileno;
+
     Jpeg2000Tile    *tile;
 
     /*options parameters*/
-    int16_t         lowres;
-    int16_t         reduction_factor;
+    int             reduction_factor;
 } Jpeg2000DecoderContext;
 
 /* get_bits functions for JPEG2000 packet bitstream
@@ -98,26 +102,23 @@
 static int get_bits(Jpeg2000DecoderContext *s, int n)
 {
     int res = 0;
-    if (s->buf_end - s->buf < ((n - s->bit_index) >> 8))
-        return AVERROR(EINVAL);
+
     while (--n >= 0) {
         res <<= 1;
         if (s->bit_index == 0) {
-            s->bit_index = 7 + (*s->buf != 0xff);
-            s->buf++;
+            s->bit_index = 7 + (bytestream2_get_byte(&s->g) != 0xFFu);
         }
         s->bit_index--;
-        res |= (*s->buf >> s->bit_index) & 1;
+        res |= (bytestream2_peek_byte(&s->g) >> s->bit_index) & 1;
     }
     return res;
 }
 
 static void jpeg2000_flush(Jpeg2000DecoderContext *s)
 {
-    if (*s->buf == 0xff)
-        s->buf++;
+    if (bytestream2_get_byte(&s->g) == 0xff)
+        bytestream2_skip(&s->g, 1);
     s->bit_index = 8;
-    s->buf++;
 }
 
 /* decode the value stored in node */
@@ -127,6 +128,9 @@
     Jpeg2000TgtNode *stack[30];
     int sp = -1, curval = 0;
 
+    if (!node)
+        return AVERROR_INVALIDDATA;
+
     while (node && !node->vis) {
         stack[++sp] = node;
         node        = node->parent;
@@ -156,44 +160,139 @@
     return curval;
 }
 
+static int pix_fmt_match(enum AVPixelFormat pix_fmt, int components,
+                         int bpc, uint32_t log2_chroma_wh, int pal8)
+{
+    int match = 1;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
+
+    if (desc->nb_components != components) {
+        return 0;
+    }
+
+    switch (components) {
+    case 4:
+        match = match && desc->comp[3].depth_minus1 + 1 >= bpc &&
+                         (log2_chroma_wh >> 14 & 3) == 0 &&
+                         (log2_chroma_wh >> 12 & 3) == 0;
+    case 3:
+        match = match && desc->comp[2].depth_minus1 + 1 >= bpc &&
+                         (log2_chroma_wh >> 10 & 3) == desc->log2_chroma_w &&
+                         (log2_chroma_wh >>  8 & 3) == desc->log2_chroma_h;
+    case 2:
+        match = match && desc->comp[1].depth_minus1 + 1 >= bpc &&
+                         (log2_chroma_wh >>  6 & 3) == desc->log2_chroma_w &&
+                         (log2_chroma_wh >>  4 & 3) == desc->log2_chroma_h;
+
+    case 1:
+        match = match && desc->comp[0].depth_minus1 + 1 >= bpc &&
+                         (log2_chroma_wh >>  2 & 3) == 0 &&
+                         (log2_chroma_wh       & 3) == 0 &&
+                         (desc->flags & AV_PIX_FMT_FLAG_PAL) == pal8 * AV_PIX_FMT_FLAG_PAL;
+    }
+    return match;
+}
+
+// pix_fmts with lower bpp have to be listed before
+// similar pix_fmts with higher bpp.
+#define RGB_PIXEL_FORMATS   AV_PIX_FMT_PAL8,AV_PIX_FMT_RGB24,AV_PIX_FMT_RGBA,AV_PIX_FMT_RGB48,AV_PIX_FMT_RGBA64
+#define GRAY_PIXEL_FORMATS  AV_PIX_FMT_GRAY8,AV_PIX_FMT_GRAY8A,AV_PIX_FMT_GRAY16
+#define YUV_PIXEL_FORMATS   AV_PIX_FMT_YUV410P,AV_PIX_FMT_YUV411P,AV_PIX_FMT_YUVA420P, \
+                            AV_PIX_FMT_YUV420P,AV_PIX_FMT_YUV422P,AV_PIX_FMT_YUVA422P, \
+                            AV_PIX_FMT_YUV440P,AV_PIX_FMT_YUV444P,AV_PIX_FMT_YUVA444P, \
+                            AV_PIX_FMT_YUV420P9,AV_PIX_FMT_YUV422P9,AV_PIX_FMT_YUV444P9, \
+                            AV_PIX_FMT_YUVA420P9,AV_PIX_FMT_YUVA422P9,AV_PIX_FMT_YUVA444P9, \
+                            AV_PIX_FMT_YUV420P10,AV_PIX_FMT_YUV422P10,AV_PIX_FMT_YUV444P10, \
+                            AV_PIX_FMT_YUVA420P10,AV_PIX_FMT_YUVA422P10,AV_PIX_FMT_YUVA444P10, \
+                            AV_PIX_FMT_YUV420P12,AV_PIX_FMT_YUV422P12,AV_PIX_FMT_YUV444P12, \
+                            AV_PIX_FMT_YUV420P14,AV_PIX_FMT_YUV422P14,AV_PIX_FMT_YUV444P14, \
+                            AV_PIX_FMT_YUV420P16,AV_PIX_FMT_YUV422P16,AV_PIX_FMT_YUV444P16, \
+                            AV_PIX_FMT_YUVA420P16,AV_PIX_FMT_YUVA422P16,AV_PIX_FMT_YUVA444P16
+#define XYZ_PIXEL_FORMATS   AV_PIX_FMT_XYZ12
+
+static const enum AVPixelFormat rgb_pix_fmts[]  = {RGB_PIXEL_FORMATS};
+static const enum AVPixelFormat gray_pix_fmts[] = {GRAY_PIXEL_FORMATS};
+static const enum AVPixelFormat yuv_pix_fmts[]  = {YUV_PIXEL_FORMATS};
+static const enum AVPixelFormat xyz_pix_fmts[]  = {XYZ_PIXEL_FORMATS};
+static const enum AVPixelFormat all_pix_fmts[]  = {RGB_PIXEL_FORMATS,
+                                                   GRAY_PIXEL_FORMATS,
+                                                   YUV_PIXEL_FORMATS,
+                                                   XYZ_PIXEL_FORMATS};
+
 /* marker segments */
 /* get sizes and offsets of image, tiles; number of components */
 static int get_siz(Jpeg2000DecoderContext *s)
 {
     int i;
+    int ncomponents;
+    uint32_t log2_chroma_wh = 0;
+    const enum AVPixelFormat *possible_fmts = NULL;
+    int possible_fmts_nb = 0;
 
-    if (s->buf_end - s->buf < 36)
-        return AVERROR(EINVAL);
+    if (bytestream2_get_bytes_left(&s->g) < 36)
+        return AVERROR_INVALIDDATA;
 
-    s->avctx->profile = bytestream_get_be16(&s->buf); // Rsiz
-    s->width          = bytestream_get_be32(&s->buf); // Width
-    s->height         = bytestream_get_be32(&s->buf); // Height
-    s->image_offset_x = bytestream_get_be32(&s->buf); // X0Siz
-    s->image_offset_y = bytestream_get_be32(&s->buf); // Y0Siz
-    s->tile_width     = bytestream_get_be32(&s->buf); // XTSiz
-    s->tile_height    = bytestream_get_be32(&s->buf); // YTSiz
-    s->tile_offset_x  = bytestream_get_be32(&s->buf); // XT0Siz
-    s->tile_offset_y  = bytestream_get_be32(&s->buf); // YT0Siz
-    s->ncomponents    = bytestream_get_be16(&s->buf); // CSiz
+    s->avctx->profile = bytestream2_get_be16u(&s->g); // Rsiz
+    s->width          = bytestream2_get_be32u(&s->g); // Width
+    s->height         = bytestream2_get_be32u(&s->g); // Height
+    s->image_offset_x = bytestream2_get_be32u(&s->g); // X0Siz
+    s->image_offset_y = bytestream2_get_be32u(&s->g); // Y0Siz
+    s->tile_width     = bytestream2_get_be32u(&s->g); // XTSiz
+    s->tile_height    = bytestream2_get_be32u(&s->g); // YTSiz
+    s->tile_offset_x  = bytestream2_get_be32u(&s->g); // XT0Siz
+    s->tile_offset_y  = bytestream2_get_be32u(&s->g); // YT0Siz
+    ncomponents       = bytestream2_get_be16u(&s->g); // CSiz
 
-    if (s->buf_end - s->buf < 2 * s->ncomponents)
-        return AVERROR(EINVAL);
+    if (ncomponents <= 0) {
+        av_log(s->avctx, AV_LOG_ERROR, "Invalid number of components: %d\n",
+               s->ncomponents);
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (ncomponents > 4) {
+        avpriv_request_sample(s->avctx, "Support for %d components",
+                              s->ncomponents);
+        return AVERROR_PATCHWELCOME;
+    }
+
+    s->ncomponents = ncomponents;
+
+    if (s->tile_width <= 0 || s->tile_height <= 0) {
+        av_log(s->avctx, AV_LOG_ERROR, "Invalid tile dimension %dx%d.\n",
+               s->tile_width, s->tile_height);
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (bytestream2_get_bytes_left(&s->g) < 3 * s->ncomponents)
+        return AVERROR_INVALIDDATA;
 
     for (i = 0; i < s->ncomponents; i++) { // Ssiz_i XRsiz_i, YRsiz_i
-        uint8_t x = bytestream_get_byte(&s->buf);
+        uint8_t x    = bytestream2_get_byteu(&s->g);
         s->cbps[i]   = (x & 0x7f) + 1;
         s->precision = FFMAX(s->cbps[i], s->precision);
-        s->sgnd[i]   = (x & 0x80) == 1;
-        s->cdx[i]    = bytestream_get_byte(&s->buf);
-        s->cdy[i]    = bytestream_get_byte(&s->buf);
+        s->sgnd[i]   = !!(x & 0x80);
+        s->cdx[i]    = bytestream2_get_byteu(&s->g);
+        s->cdy[i]    = bytestream2_get_byteu(&s->g);
+        if (!s->cdx[i] || !s->cdy[i]) {
+            av_log(s->avctx, AV_LOG_ERROR, "Invalid sample seperation\n");
+            return AVERROR_INVALIDDATA;
+        }
+        log2_chroma_wh |= s->cdy[i] >> 1 << i * 4 | s->cdx[i] >> 1 << i * 4 + 2;
     }
 
     s->numXtiles = ff_jpeg2000_ceildiv(s->width  - s->tile_offset_x, s->tile_width);
     s->numYtiles = ff_jpeg2000_ceildiv(s->height - s->tile_offset_y, s->tile_height);
 
-    s->tile = av_mallocz(s->numXtiles * s->numYtiles * sizeof(*s->tile));
-    if (!s->tile)
+    if (s->numXtiles * (uint64_t)s->numYtiles > INT_MAX/sizeof(*s->tile)) {
+        s->numXtiles = s->numYtiles = 0;
+        return AVERROR(EINVAL);
+    }
+
+    s->tile = av_mallocz_array(s->numXtiles * s->numYtiles, sizeof(*s->tile));
+    if (!s->tile) {
+        s->numXtiles = s->numYtiles = 0;
         return AVERROR(ENOMEM);
+    }
 
     for (i = 0; i < s->numXtiles * s->numYtiles; i++) {
         Jpeg2000Tile *tile = s->tile + i;
@@ -209,37 +308,46 @@
     s->avctx->height = ff_jpeg2000_ceildivpow2(s->height - s->image_offset_y,
                                                s->reduction_factor);
 
-    switch (s->avctx->profile) {
-    case FF_PROFILE_JPEG2000_DCINEMA_2K:
-    case FF_PROFILE_JPEG2000_DCINEMA_4K:
-        /* XYZ color-space for digital cinema profiles */
-        s->avctx->pix_fmt = AV_PIX_FMT_XYZ12;
-        break;
-    default:
-        /* For other profiles selects color-space according number of
-         * components and bit depth precision. */
-        switch (s->ncomponents) {
-        case 1:
-            if (s->precision > 8)
-                s->avctx->pix_fmt = AV_PIX_FMT_GRAY16;
-            else
-                s->avctx->pix_fmt = AV_PIX_FMT_GRAY8;
+    if (s->avctx->profile == FF_PROFILE_JPEG2000_DCINEMA_2K ||
+        s->avctx->profile == FF_PROFILE_JPEG2000_DCINEMA_4K) {
+        possible_fmts = xyz_pix_fmts;
+        possible_fmts_nb = FF_ARRAY_ELEMS(xyz_pix_fmts);
+    } else {
+        switch (s->colour_space) {
+        case 16:
+            possible_fmts = rgb_pix_fmts;
+            possible_fmts_nb = FF_ARRAY_ELEMS(rgb_pix_fmts);
             break;
-        case 3:
-            if (s->precision > 8)
-                s->avctx->pix_fmt = AV_PIX_FMT_RGB48;
-            else
-                s->avctx->pix_fmt = AV_PIX_FMT_RGB24;
+        case 17:
+            possible_fmts = gray_pix_fmts;
+            possible_fmts_nb = FF_ARRAY_ELEMS(gray_pix_fmts);
             break;
-        case 4:
-            s->avctx->pix_fmt = AV_PIX_FMT_BGRA;
+        case 18:
+            possible_fmts = yuv_pix_fmts;
+            possible_fmts_nb = FF_ARRAY_ELEMS(yuv_pix_fmts);
             break;
         default:
-            /* pixel format can not be identified */
-            s->avctx->pix_fmt = AV_PIX_FMT_NONE;
+            possible_fmts = all_pix_fmts;
+            possible_fmts_nb = FF_ARRAY_ELEMS(all_pix_fmts);
             break;
         }
-        break;
+    }
+    for (i = 0; i < possible_fmts_nb; ++i) {
+        if (pix_fmt_match(possible_fmts[i], ncomponents, s->precision, log2_chroma_wh, s->pal8)) {
+            s->avctx->pix_fmt = possible_fmts[i];
+            break;
+        }
+    }
+    if (s->avctx->pix_fmt == AV_PIX_FMT_NONE) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "Unknown pix_fmt, profile: %d, colour_space: %d, "
+               "components: %d, precision: %d, "
+               "cdx[1]: %d, cdy[1]: %d, cdx[2]: %d, cdy[2]: %d\n",
+               s->avctx->profile, s->colour_space, ncomponents, s->precision,
+               ncomponents > 2 ? s->cdx[1] : 0,
+               ncomponents > 2 ? s->cdy[1] : 0,
+               ncomponents > 2 ? s->cdx[2] : 0,
+               ncomponents > 2 ? s->cdy[2] : 0);
     }
     return 0;
 }
@@ -249,9 +357,16 @@
 {
     uint8_t byte;
 
-    if (s->buf_end - s->buf < 5)
-        return AVERROR(EINVAL);
-    c->nreslevels = bytestream_get_byte(&s->buf) + 1; // num of resolution levels - 1
+    if (bytestream2_get_bytes_left(&s->g) < 5)
+        return AVERROR_INVALIDDATA;
+
+    /*  nreslevels = number of resolution levels
+                   = number of decomposition level +1 */
+    c->nreslevels = bytestream2_get_byteu(&s->g) + 1;
+    if (c->nreslevels >= JPEG2000_MAX_RESLEVELS) {
+        av_log(s->avctx, AV_LOG_ERROR, "nreslevels %d is invalid\n", c->nreslevels);
+        return AVERROR_INVALIDDATA;
+    }
 
     /* compute number of resolution levels to decode */
     if (c->nreslevels < s->reduction_factor)
@@ -259,15 +374,20 @@
     else
         c->nreslevels2decode = c->nreslevels - s->reduction_factor;
 
-    c->log2_cblk_width  = bytestream_get_byte(&s->buf) + 2; // cblk width
-    c->log2_cblk_height = bytestream_get_byte(&s->buf) + 2; // cblk height
+    c->log2_cblk_width  = (bytestream2_get_byteu(&s->g) & 15) + 2; // cblk width
+    c->log2_cblk_height = (bytestream2_get_byteu(&s->g) & 15) + 2; // cblk height
 
-    c->cblk_style = bytestream_get_byte(&s->buf);
-    if (c->cblk_style != 0) { // cblk style
-        av_log(s->avctx, AV_LOG_ERROR, "no extra cblk styles supported\n");
-        return -1;
+    if (c->log2_cblk_width > 10 || c->log2_cblk_height > 10 ||
+        c->log2_cblk_width + c->log2_cblk_height > 12) {
+        av_log(s->avctx, AV_LOG_ERROR, "cblk size invalid\n");
+        return AVERROR_INVALIDDATA;
     }
-    c->transform = bytestream_get_byte(&s->buf); // DWT transformation type
+
+    c->cblk_style = bytestream2_get_byteu(&s->g);
+    if (c->cblk_style != 0) { // cblk style
+        av_log(s->avctx, AV_LOG_WARNING, "extra cblk styles %X\n", c->cblk_style);
+    }
+    c->transform = bytestream2_get_byteu(&s->g); // DWT transformation type
     /* set integer 9/7 DWT in case of BITEXACT flag */
     if ((s->avctx->flags & CODEC_FLAG_BITEXACT) && (c->transform == FF_DWT97))
         c->transform = FF_DWT97_INT;
@@ -275,10 +395,13 @@
     if (c->csty & JPEG2000_CSTY_PREC) {
         int i;
         for (i = 0; i < c->nreslevels; i++) {
-            byte = bytestream_get_byte(&s->buf);
+            byte = bytestream2_get_byte(&s->g);
             c->log2_prec_widths[i]  =  byte       & 0x0F;    // precinct PPx
             c->log2_prec_heights[i] = (byte >> 4) & 0x0F;    // precinct PPy
         }
+    } else {
+        memset(c->log2_prec_widths , 15, sizeof(c->log2_prec_widths ));
+        memset(c->log2_prec_heights, 15, sizeof(c->log2_prec_heights));
     }
     return 0;
 }
@@ -288,23 +411,29 @@
                    uint8_t *properties)
 {
     Jpeg2000CodingStyle tmp;
-    int compno;
+    int compno, ret;
 
-    if (s->buf_end - s->buf < 5)
-        return AVERROR(EINVAL);
+    if (bytestream2_get_bytes_left(&s->g) < 5)
+        return AVERROR_INVALIDDATA;
 
-    tmp.log2_prec_width  =
-    tmp.log2_prec_height = 15;
-
-    tmp.csty = bytestream_get_byte(&s->buf);
+    tmp.csty = bytestream2_get_byteu(&s->g);
 
     // get progression order
-    tmp.prog_order = bytestream_get_byte(&s->buf);
+    tmp.prog_order = bytestream2_get_byteu(&s->g);
 
-    tmp.nlayers = bytestream_get_be16(&s->buf);
-    tmp.mct     = bytestream_get_byte(&s->buf); // multiple component transformation
+    tmp.nlayers    = bytestream2_get_be16u(&s->g);
+    tmp.mct        = bytestream2_get_byteu(&s->g); // multiple component transformation
 
-    get_cox(s, &tmp);
+    if (tmp.mct && s->ncomponents < 3) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "MCT %d with too few components (%d)\n",
+               tmp.mct, s->ncomponents);
+        return AVERROR_INVALIDDATA;
+    }
+
+    if ((ret = get_cox(s, &tmp)) < 0)
+        return ret;
+
     for (compno = 0; compno < s->ncomponents; compno++)
         if (!(properties[compno] & HAD_COC))
             memcpy(c + compno, &tmp, sizeof(tmp));
@@ -316,16 +445,25 @@
 static int get_coc(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c,
                    uint8_t *properties)
 {
-    int compno;
+    int compno, ret;
 
-    if (s->buf_end - s->buf < 2)
-        return AVERROR(EINVAL);
+    if (bytestream2_get_bytes_left(&s->g) < 2)
+        return AVERROR_INVALIDDATA;
 
-    compno = bytestream_get_byte(&s->buf);
+    compno = bytestream2_get_byteu(&s->g);
+
+    if (compno >= s->ncomponents) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "Invalid compno %d. There are %d components in the image.\n",
+               compno, s->ncomponents);
+        return AVERROR_INVALIDDATA;
+    }
 
     c      += compno;
-    c->csty = bytestream_get_byte(&s->buf);
-    get_cox(s, c);
+    c->csty = bytestream2_get_byteu(&s->g);
+
+    if ((ret = get_cox(s, c)) < 0)
+        return ret;
 
     properties[compno] |= HAD_COC;
     return 0;
@@ -336,37 +474,39 @@
 {
     int i, x;
 
-    if (s->buf_end - s->buf < 1)
-        return AVERROR(EINVAL);
+    if (bytestream2_get_bytes_left(&s->g) < 1)
+        return AVERROR_INVALIDDATA;
 
-    x = bytestream_get_byte(&s->buf); // Sqcd
+    x = bytestream2_get_byteu(&s->g); // Sqcd
 
     q->nguardbits = x >> 5;
     q->quantsty   = x & 0x1f;
 
     if (q->quantsty == JPEG2000_QSTY_NONE) {
         n -= 3;
-        if (s->buf_end - s->buf < n)
-            return AVERROR(EINVAL);
+        if (bytestream2_get_bytes_left(&s->g) < n ||
+            n > JPEG2000_MAX_DECLEVELS*3)
+            return AVERROR_INVALIDDATA;
         for (i = 0; i < n; i++)
-            q->expn[i] = bytestream_get_byte(&s->buf) >> 3;
+            q->expn[i] = bytestream2_get_byteu(&s->g) >> 3;
     } else if (q->quantsty == JPEG2000_QSTY_SI) {
-        if (s->buf_end - s->buf < 2)
-            return AVERROR(EINVAL);
-        x          = bytestream_get_be16(&s->buf);
+        if (bytestream2_get_bytes_left(&s->g) < 2)
+            return AVERROR_INVALIDDATA;
+        x          = bytestream2_get_be16u(&s->g);
         q->expn[0] = x >> 11;
         q->mant[0] = x & 0x7ff;
-        for (i = 1; i < 32 * 3; i++) {
+        for (i = 1; i < JPEG2000_MAX_DECLEVELS * 3; i++) {
             int curexpn = FFMAX(0, q->expn[0] - (i - 1) / 3);
             q->expn[i] = curexpn;
             q->mant[i] = q->mant[0];
         }
     } else {
         n = (n - 3) >> 1;
-        if (s->buf_end - s->buf < n)
-            return AVERROR(EINVAL);
+        if (bytestream2_get_bytes_left(&s->g) < 2 * n ||
+            n > JPEG2000_MAX_DECLEVELS*3)
+            return AVERROR_INVALIDDATA;
         for (i = 0; i < n; i++) {
-            x          = bytestream_get_be16(&s->buf);
+            x          = bytestream2_get_be16u(&s->g);
             q->expn[i] = x >> 11;
             q->mant[i] = x & 0x7ff;
         }
@@ -379,10 +519,10 @@
                    uint8_t *properties)
 {
     Jpeg2000QuantStyle tmp;
-    int compno;
+    int compno, ret;
 
-    if (get_qcx(s, n, &tmp))
-        return -1;
+    if ((ret = get_qcx(s, n, &tmp)) < 0)
+        return ret;
     for (compno = 0; compno < s->ncomponents; compno++)
         if (!(properties[compno] & HAD_QCC))
             memcpy(q + compno, &tmp, sizeof(tmp));
@@ -396,58 +536,67 @@
 {
     int compno;
 
-    if (s->buf_end - s->buf < 1)
-        return AVERROR(EINVAL);
+    if (bytestream2_get_bytes_left(&s->g) < 1)
+        return AVERROR_INVALIDDATA;
 
-    compno              = bytestream_get_byte(&s->buf);
+    compno = bytestream2_get_byteu(&s->g);
+
+    if (compno >= s->ncomponents) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "Invalid compno %d. There are %d components in the image.\n",
+               compno, s->ncomponents);
+        return AVERROR_INVALIDDATA;
+    }
+
     properties[compno] |= HAD_QCC;
     return get_qcx(s, n - 1, q + compno);
 }
 
 /* Get start of tile segment. */
-static uint8_t get_sot(Jpeg2000DecoderContext *s, int n)
+static int get_sot(Jpeg2000DecoderContext *s, int n)
 {
     Jpeg2000TilePart *tp;
     uint16_t Isot;
     uint32_t Psot;
     uint8_t TPsot;
 
-    if (s->buf_end - s->buf < 4)
-        return AVERROR(EINVAL);
+    if (bytestream2_get_bytes_left(&s->g) < 8)
+        return AVERROR_INVALIDDATA;
 
-    Isot = bytestream_get_be16(&s->buf);        // Isot
-    if (Isot) {
-        av_log(s->avctx, AV_LOG_ERROR,
-               "Not a DCINEMA JP2K file: more than one tile\n");
-        return -1;
-    }
-    Psot  = bytestream_get_be32(&s->buf);       // Psot
-    TPsot = bytestream_get_byte(&s->buf);       // TPsot
+    s->curtileno = 0;
+    Isot = bytestream2_get_be16u(&s->g);        // Isot
+    if (Isot >= s->numXtiles * s->numYtiles)
+        return AVERROR_INVALIDDATA;
+
+    s->curtileno = Isot;
+    Psot  = bytestream2_get_be32u(&s->g);       // Psot
+    TPsot = bytestream2_get_byteu(&s->g);       // TPsot
 
     /* Read TNSot but not used */
-    bytestream_get_byte(&s->buf);               // TNsot
+    bytestream2_get_byteu(&s->g);               // TNsot
 
-    tp             = s->tile[s->curtileno].tile_part + TPsot;
-    tp->tile_index = Isot;
-    tp->tp_len     = Psot;
-    tp->tp_idx     = TPsot;
-
-    /* Start of bit stream. Pointer to SOD marker
-     * Check SOD marker is present. */
-    if (JPEG2000_SOD == bytestream_get_be16(&s->buf))
-        tp->tp_start_bstrm = s->buf;
-    else {
-        av_log(s->avctx, AV_LOG_ERROR, "SOD marker not found \n");
-        return -1;
+    if (Psot > bytestream2_get_bytes_left(&s->g) + n + 2) {
+        av_log(s->avctx, AV_LOG_ERROR, "Psot %d too big\n", Psot);
+        return AVERROR_INVALIDDATA;
     }
 
-    /* End address of bit stream =
-     *     start address + (Psot - size of SOT HEADER(n)
-     *     - size of SOT MARKER(2)  - size of SOD marker(2) */
-    tp->tp_end_bstrm = s->buf + (tp->tp_len - n - 4);
+    if (TPsot >= FF_ARRAY_ELEMS(s->tile[Isot].tile_part)) {
+        avpriv_request_sample(s->avctx, "Support for %d components", TPsot);
+        return AVERROR_PATCHWELCOME;
+    }
 
-    // set buffer pointer to end of tile part header
-    s->buf = tp->tp_end_bstrm;
+    s->tile[Isot].tp_idx = TPsot;
+    tp             = s->tile[Isot].tile_part + TPsot;
+    tp->tile_index = Isot;
+    tp->tp_end     = s->g.buffer + Psot - n - 2;
+
+    if (!TPsot) {
+        Jpeg2000Tile *tile = s->tile + s->curtileno;
+
+        /* copy defaults */
+        memcpy(tile->codsty, s->codsty, s->ncomponents * sizeof(Jpeg2000CodingStyle));
+        memcpy(tile->qntsty, s->qntsty, s->ncomponents * sizeof(Jpeg2000QuantStyle));
+    }
 
     return 0;
 }
@@ -463,8 +612,8 @@
 static uint8_t get_tlm(Jpeg2000DecoderContext *s, int n)
 {
     uint8_t Stlm, ST, SP, tile_tlm, i;
-    bytestream_get_byte(&s->buf);               /* Ztlm: skipped */
-    Stlm = bytestream_get_byte(&s->buf);
+    bytestream2_get_byte(&s->g);               /* Ztlm: skipped */
+    Stlm = bytestream2_get_byte(&s->g);
 
     // too complex ? ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02);
     ST = (Stlm >> 4) & 0x03;
@@ -476,19 +625,19 @@
         case 0:
             break;
         case 1:
-            bytestream_get_byte(&s->buf);
+            bytestream2_get_byte(&s->g);
             break;
         case 2:
-            bytestream_get_be16(&s->buf);
+            bytestream2_get_be16(&s->g);
             break;
         case 3:
-            bytestream_get_be32(&s->buf);
+            bytestream2_get_be32(&s->g);
             break;
         }
         if (SP == 0) {
-            bytestream_get_be16(&s->buf);
+            bytestream2_get_be16(&s->g);
         } else {
-            bytestream_get_be32(&s->buf);
+            bytestream2_get_be32(&s->g);
         }
     }
     return 0;
@@ -500,35 +649,25 @@
     int tilex = tileno % s->numXtiles;
     int tiley = tileno / s->numXtiles;
     Jpeg2000Tile *tile = s->tile + tileno;
-    Jpeg2000CodingStyle *codsty;
-    Jpeg2000QuantStyle  *qntsty;
 
     if (!tile->comp)
         return AVERROR(ENOMEM);
 
-    /* copy codsty, qnsty to tile. TODO: Is it the best way?
-     * codsty, qnsty is an array of 4 structs Jpeg2000CodingStyle
-     * and Jpeg2000QuantStyle */
-    memcpy(tile->codsty, s->codsty, s->ncomponents * sizeof(*codsty));
-    memcpy(tile->qntsty, s->qntsty, s->ncomponents * sizeof(*qntsty));
-
     for (compno = 0; compno < s->ncomponents; compno++) {
         Jpeg2000Component *comp = tile->comp + compno;
+        Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+        Jpeg2000QuantStyle  *qntsty = tile->qntsty + compno;
         int ret; // global bandno
-        codsty = tile->codsty + compno;
-        qntsty = tile->qntsty + compno;
 
         comp->coord_o[0][0] = FFMAX(tilex       * s->tile_width  + s->tile_offset_x, s->image_offset_x);
         comp->coord_o[0][1] = FFMIN((tilex + 1) * s->tile_width  + s->tile_offset_x, s->width);
         comp->coord_o[1][0] = FFMAX(tiley       * s->tile_height + s->tile_offset_y, s->image_offset_y);
         comp->coord_o[1][1] = FFMIN((tiley + 1) * s->tile_height + s->tile_offset_y, s->height);
 
-        // FIXME: add a dcinema profile check ?
-        // value is guaranteed by profile (orig=0, 1 tile)
-        comp->coord[0][0] = 0;
-        comp->coord[0][1] = s->avctx->width;
-        comp->coord[1][0] = 0;
-        comp->coord[1][1] = s->avctx->height;
+        comp->coord[0][0] = ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], s->reduction_factor);
+        comp->coord[0][1] = ff_jpeg2000_ceildivpow2(comp->coord_o[0][1], s->reduction_factor);
+        comp->coord[1][0] = ff_jpeg2000_ceildivpow2(comp->coord_o[1][0], s->reduction_factor);
+        comp->coord[1][1] = ff_jpeg2000_ceildivpow2(comp->coord_o[1][1], s->reduction_factor);
 
         if (ret = ff_jpeg2000_init_component(comp, codsty, qntsty,
                                              s->cbps[compno], s->cdx[compno],
@@ -585,8 +724,6 @@
         if (band->coord[0][0] == band->coord[0][1] ||
             band->coord[1][0] == band->coord[1][1])
             continue;
-        prec->yi0 = 0;
-        prec->xi0 = 0;
         nb_code_blocks =  prec->nb_codeblocks_height *
                           prec->nb_codeblocks_width;
         for (cblkno = 0; cblkno < nb_code_blocks; cblkno++) {
@@ -602,10 +739,16 @@
             else if (incl < 0)
                 return incl;
 
-            if (!cblk->npasses)
-                cblk->nonzerobits = expn[bandno] + numgbits - 1 -
-                                    tag_tree_decode(s, prec->zerobits + cblkno,
-                                                    100);
+            if (!cblk->npasses) {
+                int v = expn[bandno] + numgbits - 1 -
+                        tag_tree_decode(s, prec->zerobits + cblkno, 100);
+                if (v < 0) {
+                    av_log(s->avctx, AV_LOG_ERROR,
+                           "nonzerobits %d invalid\n", v);
+                    return AVERROR_INVALIDDATA;
+                }
+                cblk->nonzerobits = v;
+            }
             if ((newpasses = getnpasses(s)) < 0)
                 return newpasses;
             if ((llen = getlblockinc(s)) < 0)
@@ -613,6 +756,12 @@
             cblk->lblock += llen;
             if ((ret = get_bits(s, av_log2(newpasses) + cblk->lblock)) < 0)
                 return ret;
+            if (ret > sizeof(cblk->data)) {
+                avpriv_request_sample(s->avctx,
+                                      "Block with lengthinc greater than %zu",
+                                      sizeof(cblk->data));
+                return AVERROR_PATCHWELCOME;
+            }
             cblk->lengthinc = ret;
             cblk->npasses  += newpasses;
         }
@@ -620,8 +769,8 @@
     jpeg2000_flush(s);
 
     if (codsty->csty & JPEG2000_CSTY_EPH) {
-        if (AV_RB16(s->buf) == JPEG2000_EPH)
-            s->buf += 2;
+        if (bytestream2_peek_be16(&s->g) == JPEG2000_EPH)
+            bytestream2_skip(&s->g, 2);
         else
             av_log(s->avctx, AV_LOG_ERROR, "EPH marker not found.\n");
     }
@@ -633,9 +782,12 @@
         nb_code_blocks = prec->nb_codeblocks_height * prec->nb_codeblocks_width;
         for (cblkno = 0; cblkno < nb_code_blocks; cblkno++) {
             Jpeg2000Cblk *cblk = prec->cblk + cblkno;
-            if (s->buf_end - s->buf < cblk->lengthinc)
-                return AVERROR(EINVAL);
-            bytestream_get_buffer(&s->buf, cblk->data, cblk->lengthinc);
+            if (   bytestream2_get_bytes_left(&s->g) < cblk->lengthinc
+                || sizeof(cblk->data) < cblk->length + cblk->lengthinc + 2
+            )
+                return AVERROR_INVALIDDATA;
+
+            bytestream2_get_bufferu(&s->g, cblk->data + cblk->length, cblk->lengthinc);
             cblk->length   += cblk->lengthinc;
             cblk->lengthinc = 0;
         }
@@ -645,13 +797,15 @@
 
 static int jpeg2000_decode_packets(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
 {
+    int ret = 0;
     int layno, reslevelno, compno, precno, ok_reslevel;
-    uint8_t prog_order = tile->codsty[0].prog_order;
-    uint16_t x;
-    uint16_t y;
+    int x, y;
 
     s->bit_index = 8;
-    switch (prog_order) {
+    switch (tile->codsty[0].prog_order) {
+    case JPEG2000_PGOD_RLCP:
+        avpriv_request_sample(s->avctx, "Progression order RLCP");
+
     case JPEG2000_PGOD_LRCP:
         for (layno = 0; layno < tile->codsty[0].nlayers; layno++) {
             ok_reslevel = 1;
@@ -662,15 +816,15 @@
                     Jpeg2000QuantStyle *qntsty  = tile->qntsty + compno;
                     if (reslevelno < codsty->nreslevels) {
                         Jpeg2000ResLevel *rlevel = tile->comp[compno].reslevel +
-                                                   reslevelno;
+                                                reslevelno;
                         ok_reslevel = 1;
                         for (precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++)
-                            if (jpeg2000_decode_packet(s,
-                                                       codsty, rlevel,
-                                                       precno, layno,
-                                                       qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
-                                                       qntsty->nguardbits))
-                                return -1;
+                            if ((ret = jpeg2000_decode_packet(s,
+                                                              codsty, rlevel,
+                                                              precno, layno,
+                                                              qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
+                                                              qntsty->nguardbits)) < 0)
+                                return ret;
                     }
                 }
             }
@@ -685,7 +839,7 @@
             /* Set bit stream buffer address according to tile-part.
              * For DCinema one tile-part per component, so can be
              * indexed by component. */
-            s->buf = tile->tile_part[compno].tp_start_bstrm;
+            s->g = tile->tile_part[compno].tpg;
 
             /* Position loop (y axis)
              * TODO: Automate computing of step 256.
@@ -713,11 +867,11 @@
                         prcy   = ff_jpeg2000_ceildivpow2(y, reducedresno) >> rlevel->log2_prec_height;
                         precno = prcx + rlevel->num_precincts_x * prcy;
                         for (layno = 0; layno < tile->codsty[0].nlayers; layno++) {
-                            if (jpeg2000_decode_packet(s, codsty, rlevel,
-                                                       precno, layno,
-                                                       qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
-                                                       qntsty->nguardbits))
-                                return -1;
+                            if ((ret = jpeg2000_decode_packet(s, codsty, rlevel,
+                                                              precno, layno,
+                                                              qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
+                                                              qntsty->nguardbits)) < 0)
+                                return ret;
                         }
                     }
                 }
@@ -725,44 +879,55 @@
         }
         break;
 
+    case JPEG2000_PGOD_RPCL:
+        avpriv_request_sample(s->avctx, "Progression order RPCL");
+        ret = AVERROR_PATCHWELCOME;
+        break;
+
+    case JPEG2000_PGOD_PCRL:
+        avpriv_request_sample(s->avctx, "Progression order PCRL");
+        ret = AVERROR_PATCHWELCOME;
+        break;
+
     default:
         break;
     }
 
     /* EOC marker reached */
-    s->buf += 2;
+    bytestream2_skip(&s->g, 2);
 
-    return 0;
+    return ret;
 }
 
 /* TIER-1 routines */
 static void decode_sigpass(Jpeg2000T1Context *t1, int width, int height,
-                           int bpno, int bandno)
+                           int bpno, int bandno, int bpass_csty_symbol,
+                           int vert_causal_ctx_csty_symbol)
 {
     int mask = 3 << (bpno - 1), y0, x, y;
 
     for (y0 = 0; y0 < height; y0 += 4)
         for (x = 0; x < width; x++)
-            for (y = y0; y < height && y < y0 + 4; y++)
-                if ((t1->flags[y + 1][x + 1] & JPEG2000_T1_SIG_NB)
-                    && !(t1->flags[y + 1][x + 1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))) {
-                    if (ff_mqc_decode(&t1->mqc,
-                                      t1->mqc.cx_states +
-                                      ff_jpeg2000_getsigctxno(t1->flags[y + 1][x + 1],
-                                                             bandno))) {
-                        int xorbit, ctxno = ff_jpeg2000_getsgnctxno(t1->flags[y + 1][x + 1],
-                                                                    &xorbit);
-
-                        t1->data[y][x] =
-                            (ff_mqc_decode(&t1->mqc,
-                                           t1->mqc.cx_states + ctxno) ^ xorbit)
-                            ? -mask : mask;
+            for (y = y0; y < height && y < y0 + 4; y++) {
+                if ((t1->flags[y+1][x+1] & JPEG2000_T1_SIG_NB)
+                && !(t1->flags[y+1][x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))) {
+                    int flags_mask = -1;
+                    if (vert_causal_ctx_csty_symbol && y == y0 + 3)
+                        flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE);
+                    if (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_jpeg2000_getsigctxno(t1->flags[y+1][x+1] & flags_mask, bandno))) {
+                        int xorbit, ctxno = ff_jpeg2000_getsgnctxno(t1->flags[y+1][x+1], &xorbit);
+                        if (bpass_csty_symbol)
+                             t1->data[y][x] = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ? -mask : mask;
+                        else
+                             t1->data[y][x] = (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ^ xorbit) ?
+                                               -mask : mask;
 
                         ff_jpeg2000_set_significance(t1, x, y,
                                                      t1->data[y][x] < 0);
                     }
                     t1->flags[y + 1][x + 1] |= JPEG2000_T1_VIS;
                 }
+            }
 }
 
 static void decode_refpass(Jpeg2000T1Context *t1, int width, int height,
@@ -789,11 +954,11 @@
 
 static void decode_clnpass(Jpeg2000DecoderContext *s, Jpeg2000T1Context *t1,
                            int width, int height, int bpno, int bandno,
-                           int seg_symbols)
+                           int seg_symbols, int vert_causal_ctx_csty_symbol)
 {
     int mask = 3 << (bpno - 1), y0, x, y, runlen, dec;
 
-    for (y0 = 0; y0 < height; y0 += 4)
+    for (y0 = 0; y0 < height; y0 += 4) {
         for (x = 0; x < width; x++) {
             if (y0 + 3 < height &&
                 !((t1->flags[y0 + 1][x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||
@@ -815,11 +980,13 @@
 
             for (y = y0 + runlen; y < y0 + 4 && y < height; y++) {
                 if (!dec) {
-                    if (!(t1->flags[y + 1][x + 1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS)))
-                        dec = ff_mqc_decode(&t1->mqc,
-                                            t1->mqc.cx_states +
-                                            ff_jpeg2000_getsigctxno(t1->flags[y + 1][x + 1],
-                                                                   bandno));
+                    if (!(t1->flags[y+1][x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))) {
+                        int flags_mask = -1;
+                        if (vert_causal_ctx_csty_symbol && y == y0 + 3)
+                            flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE);
+                        dec = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_jpeg2000_getsigctxno(t1->flags[y+1][x+1] & flags_mask,
+                                                                                             bandno));
+                    }
                 }
                 if (dec) {
                     int xorbit;
@@ -835,6 +1002,7 @@
                 t1->flags[y + 1][x + 1] &= ~JPEG2000_T1_VIS;
             }
         }
+    }
     if (seg_symbols) {
         int val;
         val = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
@@ -852,28 +1020,43 @@
                        int width, int height, int bandpos)
 {
     int passno = cblk->npasses, pass_t = 2, bpno = cblk->nonzerobits - 1, y;
-
-    for (y = 0; y < height + 2; y++)
-        memset(t1->flags[y], 0, (width + 2) * sizeof(width));
+    int clnpass_cnt = 0;
+    int bpass_csty_symbol           = codsty->cblk_style & JPEG2000_CBLK_BYPASS;
+    int vert_causal_ctx_csty_symbol = codsty->cblk_style & JPEG2000_CBLK_VSC;
 
     for (y = 0; y < height; y++)
-        memset(t1->data[y], 0, width * sizeof(width));
+        memset(t1->data[y], 0, width * sizeof(**t1->data));
 
+    /* If code-block contains no compressed data: nothing to do. */
+    if (!cblk->length)
+        return 0;
+
+    for (y = 0; y < height + 2; y++)
+        memset(t1->flags[y], 0, (width + 2) * sizeof(**t1->flags));
+
+    cblk->data[cblk->length] = 0xff;
+    cblk->data[cblk->length+1] = 0xff;
     ff_mqc_initdec(&t1->mqc, cblk->data);
-    cblk->data[cblk->length]     = 0xff;
-    cblk->data[cblk->length + 1] = 0xff;
 
     while (passno--) {
-        switch (pass_t) {
+        switch(pass_t) {
         case 0:
-            decode_sigpass(t1, width, height, bpno + 1, bandpos);
+            decode_sigpass(t1, width, height, bpno + 1, bandpos,
+                           bpass_csty_symbol && (clnpass_cnt >= 4),
+                           vert_causal_ctx_csty_symbol);
             break;
         case 1:
             decode_refpass(t1, width, height, bpno + 1);
+            if (bpass_csty_symbol && clnpass_cnt >= 4)
+                ff_mqc_initdec(&t1->mqc, cblk->data);
             break;
         case 2:
             decode_clnpass(s, t1, width, height, bpno + 1, bandpos,
-                           codsty->cblk_style & JPEG2000_CBLK_SEGSYM);
+                           codsty->cblk_style & JPEG2000_CBLK_SEGSYM,
+                           vert_causal_ctx_csty_symbol);
+            clnpass_cnt = clnpass_cnt + 1;
+            if (bpass_csty_symbol && clnpass_cnt >= 4)
+                ff_mqc_initdec(&t1->mqc, cblk->data);
             break;
         }
 
@@ -897,14 +1080,14 @@
                                  Jpeg2000Component *comp,
                                  Jpeg2000T1Context *t1, Jpeg2000Band *band)
 {
-    int i, j, idx;
-    float *datap = &comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y + x];
-    for (j = 0; j < (cblk->coord[1][1] - cblk->coord[1][0]); ++j)
-        for (i = 0; i < (cblk->coord[0][1] - cblk->coord[0][0]); ++i) {
-            idx        = (comp->coord[0][1] - comp->coord[0][0]) * j + i;
-            datap[idx] = (float)(t1->data[j][i]) * ((float)band->stepsize);
-        }
-    return;
+    int i, j;
+    int w = cblk->coord[0][1] - cblk->coord[0][0];
+    for (j = 0; j < (cblk->coord[1][1] - cblk->coord[1][0]); ++j) {
+        float *datap = &comp->f_data[(comp->coord[0][1] - comp->coord[0][0]) * (y + j) + x];
+        int *src = t1->data[j];
+        for (i = 0; i < w; ++i)
+            datap[i] = src[i] * band->f_stepsize;
+    }
 }
 
 /* Integer dequantization of a codeblock.*/
@@ -912,16 +1095,14 @@
                                Jpeg2000Component *comp,
                                Jpeg2000T1Context *t1, Jpeg2000Band *band)
 {
-    int i, j, idx;
-    int32_t *datap =
-        (int32_t *) &comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y + x];
-    for (j = 0; j < (cblk->coord[1][1] - cblk->coord[1][0]); ++j)
-        for (i = 0; i < (cblk->coord[0][1] - cblk->coord[0][0]); ++i) {
-            idx        = (comp->coord[0][1] - comp->coord[0][0]) * j + i;
-            datap[idx] =
-                ((int32_t)(t1->data[j][i]) * ((int32_t)band->stepsize) + (1 << 15)) >> 16;
-        }
-    return;
+    int i, j;
+    int w = cblk->coord[0][1] - cblk->coord[0][0];
+    for (j = 0; j < (cblk->coord[1][1] - cblk->coord[1][0]); ++j) {
+        int32_t *datap = &comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * (y + j) + x];
+        int *src = t1->data[j];
+        for (i = 0; i < w; ++i)
+            datap[i] = (src[i] * band->i_stepsize + (1 << 14)) >> 15;
+    }
 }
 
 /* Inverse ICT parameters in float and integer.
@@ -939,21 +1120,21 @@
     116130
 };
 
-static int mct_decode(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
+static void mct_decode(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
 {
     int i, csize = 1;
-    int ret = 0;
     int32_t *src[3],  i0,  i1,  i2;
     float   *srcf[3], i0f, i1f, i2f;
 
     for (i = 0; i < 3; i++)
         if (tile->codsty[0].transform == FF_DWT97)
-            srcf[i] = tile->comp[i].data;
+            srcf[i] = tile->comp[i].f_data;
         else
-            src[i] = (int32_t *)tile->comp[i].data;
+            src [i] = tile->comp[i].i_data;
 
     for (i = 0; i < 2; i++)
         csize *= tile->comp[0].coord[i][1] - tile->comp[0].coord[i][0];
+
     switch (tile->codsty[0].transform) {
     case FF_DWT97:
         for (i = 0; i < csize; i++) {
@@ -988,7 +1169,6 @@
         }
         break;
     }
-    return ret;
 }
 
 static int jpeg2000_decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
@@ -999,21 +1179,27 @@
 
     uint8_t *line;
     Jpeg2000T1Context t1;
-    /* Loop on tile components */
 
+    /* Loop on tile components */
     for (compno = 0; compno < s->ncomponents; compno++) {
         Jpeg2000Component *comp     = tile->comp + compno;
         Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+
         /* Loop on resolution levels */
         for (reslevelno = 0; reslevelno < codsty->nreslevels2decode; reslevelno++) {
             Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno;
             /* Loop on bands */
             for (bandno = 0; bandno < rlevel->nbands; bandno++) {
-                uint16_t nb_precincts, precno;
+                int nb_precincts, precno;
                 Jpeg2000Band *band = rlevel->band + bandno;
                 int cblkno = 0, bandpos;
+
                 bandpos = bandno + (reslevelno > 0);
 
+                if (band->coord[0][0] == band->coord[0][1] ||
+                    band->coord[1][0] == band->coord[1][1])
+                    continue;
+
                 nb_precincts = rlevel->num_precincts_x * rlevel->num_precincts_y;
                 /* Loop on precincts */
                 for (precno = 0; precno < nb_precincts; precno++) {
@@ -1028,93 +1214,128 @@
                                     cblk->coord[1][1] - cblk->coord[1][0],
                                     bandpos);
 
-                        /* Manage band offsets */
                         x = cblk->coord[0][0];
                         y = cblk->coord[1][0];
-                        if ((reslevelno > 0) && ((bandno + 1) & 1)) {
-                            Jpeg2000ResLevel *pres = comp->reslevel + (reslevelno - 1);
-                            x += pres->coord[0][1] - pres->coord[0][0];
-                        }
-                        if ((reslevelno > 0) && ((bandno + 1) & 2)) {
-                            Jpeg2000ResLevel *pres = comp->reslevel + (reslevelno - 1);
-                            y += pres->coord[1][1] - pres->coord[1][0];
-                        }
 
-                        if (s->avctx->flags & CODEC_FLAG_BITEXACT)
-                            dequantization_int(x, y, cblk, comp, &t1, band);
-                        else
+                        if (codsty->transform == FF_DWT97)
                             dequantization_float(x, y, cblk, comp, &t1, band);
+                        else
+                            dequantization_int(x, y, cblk, comp, &t1, band);
                    } /* end cblk */
                 } /*end prec */
             } /* end band */
         } /* end reslevel */
 
         /* inverse DWT */
-        ff_dwt_decode(&comp->dwt, comp->data);
+        ff_dwt_decode(&comp->dwt, codsty->transform == FF_DWT97 ? (void*)comp->f_data : (void*)comp->i_data);
     } /*end comp */
 
     /* inverse MCT transformation */
     if (tile->codsty[0].mct)
         mct_decode(s, tile);
 
-    if (s->avctx->pix_fmt == PIX_FMT_BGRA) // RGBA -> BGRA
-        FFSWAP(float *, tile->comp[0].data, tile->comp[2].data);
+    if (s->cdef[0] < 0) {
+        for (x = 0; x < s->ncomponents; x++)
+            s->cdef[x] = x + 1;
+        if ((s->ncomponents & 1) == 0)
+            s->cdef[s->ncomponents-1] = 0;
+    }
 
     if (s->precision <= 8) {
         for (compno = 0; compno < s->ncomponents; compno++) {
             Jpeg2000Component *comp = tile->comp + compno;
-            int32_t *datap = (int32_t *)comp->data;
+            Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+            float *datap = comp->f_data;
+            int32_t *i_datap = comp->i_data;
+            int cbps = s->cbps[compno];
+            int w = tile->comp[compno].coord[0][1] - s->image_offset_x;
+            int planar = !!picture->data[2];
+            int pixelsize = planar ? 1 : s->ncomponents;
+            int plane = 0;
+
+            if (planar)
+                plane = s->cdef[compno] ? s->cdef[compno]-1 : (s->ncomponents-1);
+
+
             y    = tile->comp[compno].coord[1][0] - s->image_offset_y;
-            line = picture->data[0] + y * picture->linesize[0];
+            line = picture->data[plane] + y * picture->linesize[plane];
             for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y += s->cdy[compno]) {
                 uint8_t *dst;
 
                 x   = tile->comp[compno].coord[0][0] - s->image_offset_x;
-                dst = line + x * s->ncomponents + compno;
+                dst = line + x * pixelsize + compno*!planar;
 
-                for (; x < tile->comp[compno].coord[0][1] - s->image_offset_x; x += s->cdx[compno]) {
-                    *datap += 1 << (s->cbps[compno] - 1);
-                    if (*datap < 0)
-                        *datap = 0;
-                    else if (*datap >= (1 << s->cbps[compno]))
-                        *datap = (1 << s->cbps[compno]) - 1;
-                    *dst = *datap++;
-                    dst += s->ncomponents;
+                if (codsty->transform == FF_DWT97) {
+                    for (; x < w; x += s->cdx[compno]) {
+                        int val = lrintf(*datap) + (1 << (cbps - 1));
+                        /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
+                        val = av_clip(val, 0, (1 << cbps) - 1);
+                        *dst = val << (8 - cbps);
+                        datap++;
+                        dst += pixelsize;
+                    }
+                } else {
+                    for (; x < w; x += s->cdx[compno]) {
+                        int val = *i_datap + (1 << (cbps - 1));
+                        /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
+                        val = av_clip(val, 0, (1 << cbps) - 1);
+                        *dst = val << (8 - cbps);
+                        i_datap++;
+                        dst += pixelsize;
+                    }
                 }
-                line += picture->linesize[0];
+                line += picture->linesize[plane];
             }
         }
     } else {
         for (compno = 0; compno < s->ncomponents; compno++) {
             Jpeg2000Component *comp = tile->comp + compno;
-            float *datap = comp->data;
-            int32_t *i_datap = (int32_t *) comp->data;
+            Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+            float *datap = comp->f_data;
+            int32_t *i_datap = comp->i_data;
             uint16_t *linel;
+            int cbps = s->cbps[compno];
+            int w = tile->comp[compno].coord[0][1] - s->image_offset_x;
+            int planar = !!picture->data[2];
+            int pixelsize = planar ? 1 : s->ncomponents;
+            int plane = 0;
+
+            if (planar)
+                plane = s->cdef[compno] ? s->cdef[compno]-1 : (s->ncomponents-1);
 
             y     = tile->comp[compno].coord[1][0] - s->image_offset_y;
-            linel = (uint16_t *)picture->data[0] + y * (picture->linesize[0] >> 1);
+            linel = (uint16_t *)picture->data[plane] + y * (picture->linesize[plane] >> 1);
             for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y += s->cdy[compno]) {
                 uint16_t *dst;
+
                 x   = tile->comp[compno].coord[0][0] - s->image_offset_x;
-                dst = linel + (x * s->ncomponents + compno);
-                for (; x < s->avctx->width; x += s->cdx[compno]) {
-                    int16_t val;
-                    /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
-                    if (s->avctx->flags & CODEC_FLAG_BITEXACT)
-                        val = *i_datap + (1 << (s->cbps[compno] - 1));
-                    else
-                        val = lrintf(*datap) + (1 << (s->cbps[compno] - 1));
-                    val = av_clip(val, 0, (1 << s->cbps[compno]) - 1);
-                    /* align 12 bit values in little-endian mode */
-                    *dst = val << 4;
-                    datap++;
-                    i_datap++;
-                    dst += s->ncomponents;
+                dst = linel + (x * pixelsize + compno*!planar);
+                if (codsty->transform == FF_DWT97) {
+                    for (; x < w; x += s-> cdx[compno]) {
+                        int  val = lrintf(*datap) + (1 << (cbps - 1));
+                        /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
+                        val = av_clip(val, 0, (1 << cbps) - 1);
+                        /* align 12 bit values in little-endian mode */
+                        *dst = val << (16 - cbps);
+                        datap++;
+                        dst += pixelsize;
+                    }
+                } else {
+                    for (; x < w; x += s-> cdx[compno]) {
+                        int val = *i_datap + (1 << (cbps - 1));
+                        /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
+                        val = av_clip(val, 0, (1 << cbps) - 1);
+                        /* align 12 bit values in little-endian mode */
+                        *dst = val << (16 - cbps);
+                        i_datap++;
+                        dst += pixelsize;
+                    }
                 }
-                linel += picture->linesize[0] >> 1;
+                linel += picture->linesize[plane] >> 1;
             }
         }
     }
+
     return 0;
 }
 
@@ -1122,15 +1343,18 @@
 {
     int tileno, compno;
     for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++) {
-        for (compno = 0; compno < s->ncomponents; compno++) {
-            Jpeg2000Component *comp     = s->tile[tileno].comp   + compno;
-            Jpeg2000CodingStyle *codsty = s->tile[tileno].codsty + compno;
+        if (s->tile[tileno].comp) {
+            for (compno = 0; compno < s->ncomponents; compno++) {
+                Jpeg2000Component *comp     = s->tile[tileno].comp   + compno;
+                Jpeg2000CodingStyle *codsty = s->tile[tileno].codsty + compno;
 
-            ff_jpeg2000_cleanup(comp, codsty);
+                ff_jpeg2000_cleanup(comp, codsty);
+            }
+            av_freep(&s->tile[tileno].comp);
         }
-        av_freep(&s->tile[tileno].comp);
     }
     av_freep(&s->tile);
+    s->numXtiles = s->numYtiles = 0;
 }
 
 static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
@@ -1142,25 +1366,48 @@
     for (;;) {
         int len, ret = 0;
         uint16_t marker;
-        const uint8_t *oldbuf;
+        int oldpos;
 
-        if (s->buf_end - s->buf < 2) {
+        if (bytestream2_get_bytes_left(&s->g) < 2) {
             av_log(s->avctx, AV_LOG_ERROR, "Missing EOC\n");
             break;
         }
 
-        marker = bytestream_get_be16(&s->buf);
-        oldbuf = s->buf;
+        marker = bytestream2_get_be16u(&s->g);
+        oldpos = bytestream2_tell(&s->g);
 
+        if (marker == JPEG2000_SOD) {
+            Jpeg2000Tile *tile;
+            Jpeg2000TilePart *tp;
+
+            if (s->curtileno < 0) {
+                av_log(s->avctx, AV_LOG_ERROR, "Missing SOT\n");
+                return AVERROR_INVALIDDATA;
+            }
+
+            tile = s->tile + s->curtileno;
+            tp = tile->tile_part + tile->tp_idx;
+            if (tp->tp_end < s->g.buffer) {
+                av_log(s->avctx, AV_LOG_ERROR, "Invalid tpend\n");
+                return AVERROR_INVALIDDATA;
+            }
+            bytestream2_init(&tp->tpg, s->g.buffer, tp->tp_end - s->g.buffer);
+            bytestream2_skip(&s->g, tp->tp_end - s->g.buffer);
+
+            continue;
+        }
         if (marker == JPEG2000_EOC)
             break;
 
-        if (s->buf_end - s->buf < 2)
-            return AVERROR(EINVAL);
-        len = bytestream_get_be16(&s->buf);
+        len = bytestream2_get_be16(&s->g);
+        if (len < 2 || bytestream2_get_bytes_left(&s->g) < len - 2)
+            return AVERROR_INVALIDDATA;
+
         switch (marker) {
         case JPEG2000_SIZ:
             ret = get_siz(s);
+            if (!s->tile)
+                s->numXtiles = s->numYtiles = 0;
             break;
         case JPEG2000_COC:
             ret = get_coc(s, codsty, properties);
@@ -1175,11 +1422,16 @@
             ret = get_qcd(s, len, qntsty, properties);
             break;
         case JPEG2000_SOT:
-            ret = get_sot(s, len);
+            if (!(ret = get_sot(s, len))) {
+                av_assert1(s->curtileno >= 0);
+                codsty = s->tile[s->curtileno].codsty;
+                qntsty = s->tile[s->curtileno].qntsty;
+                properties = s->tile[s->curtileno].properties;
+            }
             break;
         case JPEG2000_COM:
             // the comment is ignored
-            s->buf += len - 2;
+            bytestream2_skip(&s->g, len - 2);
             break;
         case JPEG2000_TLM:
             // Tile-part lengths
@@ -1187,12 +1439,12 @@
             break;
         default:
             av_log(s->avctx, AV_LOG_ERROR,
-                   "unsupported marker 0x%.4X at pos 0x%lX\n",
-                   marker, (uint64_t)(s->buf - s->buf_start - 4));
-            s->buf += len - 2;
+                   "unsupported marker 0x%.4X at pos 0x%X\n",
+                   marker, bytestream2_tell(&s->g) - 4);
+            bytestream2_skip(&s->g, len - 2);
             break;
         }
-        if (((s->buf - oldbuf != len) && (marker != JPEG2000_SOT)) || ret) {
+        if (bytestream2_tell(&s->g) - oldpos != len || ret) {
             av_log(s->avctx, AV_LOG_ERROR,
                    "error during processing marker segment %.4x\n", marker);
             return ret ? ret : -1;
@@ -1205,37 +1457,119 @@
 static int jpeg2000_read_bitstream_packets(Jpeg2000DecoderContext *s)
 {
     int ret = 0;
-    Jpeg2000Tile *tile = s->tile + s->curtileno;
+    int tileno;
 
-    if (ret = init_tile(s, s->curtileno))
-        return ret;
-    if (ret = jpeg2000_decode_packets(s, tile))
-        return ret;
+    for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++) {
+        Jpeg2000Tile *tile = s->tile + tileno;
+
+        if (ret = init_tile(s, tileno))
+            return ret;
+
+        s->g = tile->tile_part[0].tpg;
+        if (ret = jpeg2000_decode_packets(s, tile))
+            return ret;
+    }
 
     return 0;
 }
 
 static int jp2_find_codestream(Jpeg2000DecoderContext *s)
 {
-    int32_t atom_size;
-    int found_codestream = 0, search_range = 10;
+    uint32_t atom_size, atom, atom_end;
+    int search_range = 10;
 
-    // Skip JPEG 2000 signature atom.
-    s->buf += 12;
+    while (search_range
+           &&
+           bytestream2_get_bytes_left(&s->g) >= 8) {
+        atom_size = bytestream2_get_be32u(&s->g);
+        atom      = bytestream2_get_be32u(&s->g);
+        atom_end  = bytestream2_tell(&s->g) + atom_size - 8;
 
-    while (!found_codestream && search_range) {
-        atom_size = AV_RB32(s->buf);
-        if (AV_RB32(s->buf + 4) == JP2_CODESTREAM) {
-            found_codestream = 1;
-            s->buf += 8;
+        if (atom == JP2_CODESTREAM)
+            return 1;
+
+        if (bytestream2_get_bytes_left(&s->g) < atom_size || atom_end < atom_size)
+            return 0;
+
+        if (atom == JP2_HEADER &&
+                   atom_size >= 16) {
+            uint32_t atom2_size, atom2, atom2_end;
+            do {
+                atom2_size = bytestream2_get_be32u(&s->g);
+                atom2      = bytestream2_get_be32u(&s->g);
+                atom2_end  = bytestream2_tell(&s->g) + atom2_size - 8;
+                if (atom2_size < 8 || atom2_end > atom_end || atom2_end < atom2_size)
+                    break;
+                if (atom2 == JP2_CODESTREAM) {
+                    return 1;
+                } else if (atom2 == MKBETAG('c','o','l','r') && atom2_size >= 7) {
+                    int method = bytestream2_get_byteu(&s->g);
+                    bytestream2_skipu(&s->g, 2);
+                    if (method == 1) {
+                        s->colour_space = bytestream2_get_be32u(&s->g);
+                    }
+                } else if (atom2 == MKBETAG('p','c','l','r') && atom2_size >= 6) {
+                    int i, size, colour_count, colour_channels, colour_depth[3];
+                    uint32_t r, g, b;
+                    colour_count = bytestream2_get_be16u(&s->g);
+                    colour_channels = bytestream2_get_byteu(&s->g);
+                    // FIXME: Do not ignore channel_sign
+                    colour_depth[0] = (bytestream2_get_byteu(&s->g) & 0x7f) + 1;
+                    colour_depth[1] = (bytestream2_get_byteu(&s->g) & 0x7f) + 1;
+                    colour_depth[2] = (bytestream2_get_byteu(&s->g) & 0x7f) + 1;
+                    size = (colour_depth[0] + 7 >> 3) * colour_count +
+                           (colour_depth[1] + 7 >> 3) * colour_count +
+                           (colour_depth[2] + 7 >> 3) * colour_count;
+                    if (colour_count > 256   ||
+                        colour_channels != 3 ||
+                        colour_depth[0] > 16 ||
+                        colour_depth[1] > 16 ||
+                        colour_depth[2] > 16 ||
+                        atom2_size < size) {
+                        avpriv_request_sample(s->avctx, "Unknown palette");
+                        bytestream2_seek(&s->g, atom2_end, SEEK_SET);
+                        continue;
+                    }
+                    s->pal8 = 1;
+                    for (i = 0; i < colour_count; i++) {
+                        if (colour_depth[0] <= 8) {
+                            r = bytestream2_get_byteu(&s->g) << 8 - colour_depth[0];
+                            r |= r >> colour_depth[0];
+                        } else {
+                            r = bytestream2_get_be16u(&s->g) >> colour_depth[0] - 8;
+                        }
+                        if (colour_depth[1] <= 8) {
+                            g = bytestream2_get_byteu(&s->g) << 8 - colour_depth[1];
+                            r |= r >> colour_depth[1];
+                        } else {
+                            g = bytestream2_get_be16u(&s->g) >> colour_depth[1] - 8;
+                        }
+                        if (colour_depth[2] <= 8) {
+                            b = bytestream2_get_byteu(&s->g) << 8 - colour_depth[2];
+                            r |= r >> colour_depth[2];
+                        } else {
+                            b = bytestream2_get_be16u(&s->g) >> colour_depth[2] - 8;
+                        }
+                        s->palette[i] = 0xffu << 24 | r << 16 | g << 8 | b;
+                    }
+                } else if (atom2 == MKBETAG('c','d','e','f') && atom2_size >= 2) {
+                    int n = bytestream2_get_be16u(&s->g);
+                    for (; n>0; n--) {
+                        int cn   = bytestream2_get_be16(&s->g);
+                        int av_unused typ  = bytestream2_get_be16(&s->g);
+                        int asoc = bytestream2_get_be16(&s->g);
+                        if (cn < 4 || asoc < 4)
+                            s->cdef[cn] = asoc;
+                    }
+                }
+                bytestream2_seek(&s->g, atom2_end, SEEK_SET);
+            } while (atom_end - atom2_end >= 8);
         } else {
-            s->buf += atom_size;
             search_range--;
         }
+        bytestream2_seek(&s->g, atom_end, SEEK_SET);
     }
 
-    if (found_codestream)
-        return 1;
     return 0;
 }
 
@@ -1248,54 +1582,69 @@
     int tileno, ret;
 
     s->avctx     = avctx;
-    s->buf       = s->buf_start = avpkt->data;
-    s->buf_end   = s->buf_start + avpkt->size;
-    s->curtileno = 0; // TODO: only one tile in DCI JP2K. to implement for more tiles
+    bytestream2_init(&s->g, avpkt->data, avpkt->size);
+    s->curtileno = -1;
+    memset(s->cdef, -1, sizeof(s->cdef));
 
-    // reduction factor, i.e number of resolution levels to skip
-    s->reduction_factor = s->lowres;
-
-    ff_jpeg2000_init_tier1_luts();
-
-    if (s->buf_end - s->buf < 2)
-        return AVERROR(EINVAL);
+    if (bytestream2_get_bytes_left(&s->g) < 2) {
+        ret = AVERROR_INVALIDDATA;
+        goto end;
+    }
 
     // check if the image is in jp2 format
-    if ((AV_RB32(s->buf) == 12) &&
-        (AV_RB32(s->buf + 4) == JP2_SIG_TYPE) &&
-        (AV_RB32(s->buf + 8) == JP2_SIG_VALUE)) {
+    if (bytestream2_get_bytes_left(&s->g) >= 12 &&
+       (bytestream2_get_be32u(&s->g) == 12) &&
+       (bytestream2_get_be32u(&s->g) == JP2_SIG_TYPE) &&
+       (bytestream2_get_be32u(&s->g) == JP2_SIG_VALUE)) {
         if (!jp2_find_codestream(s)) {
             av_log(avctx, AV_LOG_ERROR,
-                   "couldn't find jpeg2k codestream atom\n");
-            return -1;
+                   "Could not find Jpeg2000 codestream atom.\n");
+            ret = AVERROR_INVALIDDATA;
+            goto end;
         }
+    } else {
+        bytestream2_seek(&s->g, 0, SEEK_SET);
     }
 
-    if (bytestream_get_be16(&s->buf) != JPEG2000_SOC) {
+    if (bytestream2_get_be16u(&s->g) != JPEG2000_SOC) {
         av_log(avctx, AV_LOG_ERROR, "SOC marker not present\n");
-        return -1;
+        ret = AVERROR_INVALIDDATA;
+        goto end;
     }
     if (ret = jpeg2000_read_main_headers(s))
-        return ret;
+        goto end;
 
     /* get picture buffer */
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "ff_thread_get_buffer() failed.\n");
-        return ret;
-    }
+    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+        goto end;
     picture->pict_type = AV_PICTURE_TYPE_I;
     picture->key_frame = 1;
 
     if (ret = jpeg2000_read_bitstream_packets(s))
-        return ret;
+        goto end;
+
     for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++)
         if (ret = jpeg2000_decode_tile(s, s->tile + tileno, picture))
-            return ret;
+            goto end;
+
     jpeg2000_dec_cleanup(s);
 
     *got_frame = 1;
 
-    return s->buf - s->buf_start;
+    if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
+        memcpy(picture->data[1], s->palette, 256 * sizeof(uint32_t));
+
+    return bytestream2_tell(&s->g);
+
+end:
+    jpeg2000_dec_cleanup(s);
+    return ret;
+}
+
+static void jpeg2000_init_static_data(AVCodec *codec)
+{
+    ff_jpeg2000_init_tier1_luts();
+    ff_mqc_init_context_tables();
 }
 
 #define OFFSET(x) offsetof(Jpeg2000DecoderContext, x)
@@ -1303,7 +1652,7 @@
 
 static const AVOption options[] = {
     { "lowres",  "Lower the decoding resolution by a power of two",
-        OFFSET(lowres), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, JPEG2000_MAX_RESLEVELS - 1, VD },
+        OFFSET(reduction_factor), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, JPEG2000_MAX_RESLEVELS - 1, VD },
     { NULL },
 };
 
@@ -1316,7 +1665,7 @@
     { FF_PROFILE_UNKNOWN },
 };
 
-static const AVClass class = {
+static const AVClass jpeg2000_class = {
     .class_name = "jpeg2000",
     .item_name  = av_default_item_name,
     .option     = options,
@@ -1324,16 +1673,15 @@
 };
 
 AVCodec ff_jpeg2000_decoder = {
-    .name           = "jpeg2000",
-    .long_name      = NULL_IF_CONFIG_SMALL("JPEG 2000"),
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_JPEG2000,
-    .capabilities   = CODEC_CAP_FRAME_THREADS,
-    .priv_data_size = sizeof(Jpeg2000DecoderContext),
-    .decode         = jpeg2000_decode_frame,
-    .priv_class     = &class,
-    .pix_fmts       = (enum PixelFormat[]) { AV_PIX_FMT_XYZ12,
-                                             AV_PIX_FMT_GRAY8,
-                                             -1 },
-    .profiles       = NULL_IF_CONFIG_SMALL(profiles)
+    .name             = "jpeg2000",
+    .long_name        = NULL_IF_CONFIG_SMALL("JPEG 2000"),
+    .type             = AVMEDIA_TYPE_VIDEO,
+    .id               = AV_CODEC_ID_JPEG2000,
+    .capabilities     = CODEC_CAP_FRAME_THREADS,
+    .priv_data_size   = sizeof(Jpeg2000DecoderContext),
+    .init_static_data = jpeg2000_init_static_data,
+    .decode           = jpeg2000_decode_frame,
+    .priv_class       = &jpeg2000_class,
+    .max_lowres       = 5,
+    .profiles         = NULL_IF_CONFIG_SMALL(profiles)
 };
diff --git a/libavcodec/jpeg2000dwt.c b/libavcodec/jpeg2000dwt.c
index 080b0a0..266edec 100644
--- a/libavcodec/jpeg2000dwt.c
+++ b/libavcodec/jpeg2000dwt.c
@@ -51,7 +51,6 @@
 #define I_LFTG_K       80621
 #define I_LFTG_X      106544
 
-
 static inline void extend53(int *p, int i0, int i1)
 {
     p[i0 - 1] = p[i0 + 1];
@@ -80,6 +79,213 @@
     }
 }
 
+static void sd_1d53(int *p, int i0, int i1)
+{
+    int i;
+
+    if (i1 == i0 + 1)
+        return;
+
+    extend53(p, i0, i1);
+
+    for (i = (i0+1)/2 - 1; i < (i1+1)/2; i++)
+        p[2*i+1] -= (p[2*i] + p[2*i+2]) >> 1;
+    for (i = (i0+1)/2; i < (i1+1)/2; i++)
+        p[2*i] += (p[2*i-1] + p[2*i+1] + 2) >> 2;
+}
+
+static void dwt_encode53(DWTContext *s, int *t)
+{
+    int lev,
+        w = s->linelen[s->ndeclevels-1][0];
+    int *line = s->i_linebuf;
+    line += 3;
+
+    for (lev = s->ndeclevels-1; lev >= 0; lev--){
+        int lh = s->linelen[lev][0],
+            lv = s->linelen[lev][1],
+            mh = s->mod[lev][0],
+            mv = s->mod[lev][1],
+            lp;
+        int *l;
+
+        // HOR_SD
+        l = line + mh;
+        for (lp = 0; lp < lv; lp++){
+            int i, j = 0;
+
+            for (i = 0; i < lh; i++)
+                l[i] = t[w*lp + i];
+
+            sd_1d53(line, mh, mh + lh);
+
+            // copy back and deinterleave
+            for (i =   mh; i < lh; i+=2, j++)
+                t[w*lp + j] = l[i];
+            for (i = 1-mh; i < lh; i+=2, j++)
+                t[w*lp + j] = l[i];
+        }
+
+        // VER_SD
+        l = line + mv;
+        for (lp = 0; lp < lh; lp++) {
+            int i, j = 0;
+
+            for (i = 0; i < lv; i++)
+                l[i] = t[w*i + lp];
+
+            sd_1d53(line, mv, mv + lv);
+
+            // copy back and deinterleave
+            for (i =   mv; i < lv; i+=2, j++)
+                t[w*j + lp] = l[i];
+            for (i = 1-mv; i < lv; i+=2, j++)
+                t[w*j + lp] = l[i];
+        }
+    }
+}
+static void sd_1d97_float(float *p, int i0, int i1)
+{
+    int i;
+
+    if (i1 == i0 + 1)
+        return;
+
+    extend97_float(p, i0, i1);
+    i0++; i1++;
+
+    for (i = i0/2 - 2; i < i1/2 + 1; i++)
+        p[2*i+1] -= 1.586134 * (p[2*i] + p[2*i+2]);
+    for (i = i0/2 - 1; i < i1/2 + 1; i++)
+        p[2*i] -= 0.052980 * (p[2*i-1] + p[2*i+1]);
+    for (i = i0/2 - 1; i < i1/2; i++)
+        p[2*i+1] += 0.882911 * (p[2*i] + p[2*i+2]);
+    for (i = i0/2; i < i1/2; i++)
+        p[2*i] += 0.443506 * (p[2*i-1] + p[2*i+1]);
+}
+
+static void dwt_encode97_float(DWTContext *s, float *t)
+{
+    int lev,
+        w = s->linelen[s->ndeclevels-1][0];
+    float *line = s->f_linebuf;
+    line += 5;
+
+    for (lev = s->ndeclevels-1; lev >= 0; lev--){
+        int lh = s->linelen[lev][0],
+            lv = s->linelen[lev][1],
+            mh = s->mod[lev][0],
+            mv = s->mod[lev][1],
+            lp;
+        float *l;
+
+        // HOR_SD
+        l = line + mh;
+        for (lp = 0; lp < lv; lp++){
+            int i, j = 0;
+
+            for (i = 0; i < lh; i++)
+                l[i] = t[w*lp + i];
+
+            sd_1d97_float(line, mh, mh + lh);
+
+            // copy back and deinterleave
+            for (i =   mh; i < lh; i+=2, j++)
+                t[w*lp + j] = F_LFTG_X * l[i] / 2;
+            for (i = 1-mh; i < lh; i+=2, j++)
+                t[w*lp + j] = F_LFTG_K * l[i] / 2;
+        }
+
+        // VER_SD
+        l = line + mv;
+        for (lp = 0; lp < lh; lp++) {
+            int i, j = 0;
+
+            for (i = 0; i < lv; i++)
+                l[i] = t[w*i + lp];
+
+            sd_1d97_float(line, mv, mv + lv);
+
+            // copy back and deinterleave
+            for (i =   mv; i < lv; i+=2, j++)
+                t[w*j + lp] = F_LFTG_X * l[i] / 2;
+            for (i = 1-mv; i < lv; i+=2, j++)
+                t[w*j + lp] = F_LFTG_K * l[i] / 2;
+        }
+    }
+}
+
+static void sd_1d97_int(int *p, int i0, int i1)
+{
+    int i;
+
+    if (i1 == i0 + 1)
+        return;
+
+    extend97_int(p, i0, i1);
+    i0++; i1++;
+
+    for (i = i0/2 - 2; i < i1/2 + 1; i++)
+        p[2 * i + 1] -= (I_LFTG_ALPHA * (p[2 * i]     + p[2 * i + 2]) + (1 << 15)) >> 16;
+    for (i = i0/2 - 1; i < i1/2 + 1; i++)
+        p[2 * i]     -= (I_LFTG_BETA  * (p[2 * i - 1] + p[2 * i + 1]) + (1 << 15)) >> 16;
+    for (i = i0/2 - 1; i < i1/2; i++)
+        p[2 * i + 1] += (I_LFTG_GAMMA * (p[2 * i]     + p[2 * i + 2]) + (1 << 15)) >> 16;
+    for (i = i0/2; i < i1/2; i++)
+        p[2 * i]     += (I_LFTG_DELTA * (p[2 * i - 1] + p[2 * i + 1]) + (1 << 15)) >> 16;
+}
+
+static void dwt_encode97_int(DWTContext *s, int *t)
+{
+    int lev,
+        w = s->linelen[s->ndeclevels-1][0];
+    int *line = s->i_linebuf;
+    line += 5;
+
+    for (lev = s->ndeclevels-1; lev >= 0; lev--){
+        int lh = s->linelen[lev][0],
+            lv = s->linelen[lev][1],
+            mh = s->mod[lev][0],
+            mv = s->mod[lev][1],
+            lp;
+        int *l;
+
+        // HOR_SD
+        l = line + mh;
+        for (lp = 0; lp < lv; lp++){
+            int i, j = 0;
+
+            for (i = 0; i < lh; i++)
+                l[i] = t[w*lp + i];
+
+            sd_1d97_int(line, mh, mh + lh);
+
+            // copy back and deinterleave
+            for (i =   mh; i < lh; i+=2, j++)
+                t[w*lp + j] = ((l[i] * I_LFTG_X) + (1 << 16)) >> 17;
+            for (i = 1-mh; i < lh; i+=2, j++)
+                t[w*lp + j] = ((l[i] * I_LFTG_K) + (1 << 16)) >> 17;
+        }
+
+        // VER_SD
+        l = line + mv;
+        for (lp = 0; lp < lh; lp++) {
+            int i, j = 0;
+
+            for (i = 0; i < lv; i++)
+                l[i] = t[w*i + lp];
+
+            sd_1d97_int(line, mv, mv + lv);
+
+            // copy back and deinterleave
+            for (i =   mv; i < lv; i+=2, j++)
+                t[w*j + lp] = ((l[i] * I_LFTG_X) + (1 << 16)) >> 17;
+            for (i = 1-mv; i < lv; i+=2, j++)
+                t[w*j + lp] = ((l[i] * I_LFTG_K) + (1 << 16)) >> 17;
+        }
+    }
+}
+
 static void sr_1d53(int *p, int i0, int i1)
 {
     int i;
@@ -153,13 +359,6 @@
 
     extend97_float(p, i0, i1);
 
-    /*step 1*/
-    for (i = i0 / 2 - 1; i < i1 / 2 + 2; i++)
-        p[2 * i]     *= F_LFTG_K;
-    /* step 2*/
-    for (i = i0 / 2 - 2; i < i1 / 2 + 2; i++)
-        p[2 * i + 1] *= F_LFTG_X;
-    /* step 3*/
     for (i = i0 / 2 - 1; i < i1 / 2 + 2; i++)
         p[2 * i]     -= F_LFTG_DELTA * (p[2 * i - 1] + p[2 * i + 1]);
     /* step 4 */
@@ -195,9 +394,9 @@
             int i, j = 0;
             // copy with interleaving
             for (i = mh; i < lh; i += 2, j++)
-                l[i] = data[w * lp + j];
+                l[i] = data[w * lp + j] * F_LFTG_K;
             for (i = 1 - mh; i < lh; i += 2, j++)
-                l[i] = data[w * lp + j];
+                l[i] = data[w * lp + j] * F_LFTG_X;
 
             sr_1d97_float(line, mh, mh + lh);
 
@@ -211,9 +410,9 @@
             int i, j = 0;
             // copy with interleaving
             for (i = mv; i < lv; i += 2, j++)
-                l[i] = data[w * j + lp];
+                l[i] = data[w * j + lp] * F_LFTG_K;
             for (i = 1 - mv; i < lv; i += 2, j++)
-                l[i] = data[w * j + lp];
+                l[i] = data[w * j + lp] * F_LFTG_X;
 
             sr_1d97_float(line, mv, mv + lv);
 
@@ -232,13 +431,6 @@
 
     extend97_int(p, i0, i1);
 
-    /*step 1*/
-    for (i = i0 / 2 - 1; i < i1 / 2 + 2; i++)
-        p[2 * i]      = ((p[2 * i] * I_LFTG_K)     + (1 << 15)) >> 16;
-    /* step 2*/
-    for (i = i0 / 2 - 2; i < i1 / 2 + 2; i++)
-        p[2 * i + 1]  = ((p[2 * i + 1] * I_LFTG_X) + (1 << 15)) >> 16;
-    /* step 3*/
     for (i = i0 / 2 - 1; i < i1 / 2 + 2; i++)
         p[2 * i]     -= (I_LFTG_DELTA * (p[2 * i - 1] + p[2 * i + 1]) + (1 << 15)) >> 16;
     /* step 4 */
@@ -272,11 +464,11 @@
         l = line + mh;
         for (lp = 0; lp < lv; lp++) {
             int i, j = 0;
-            // copy with interleaving
+            // rescale with interleaving
             for (i = mh; i < lh; i += 2, j++)
-                l[i] = data[w * lp + j];
+                l[i] = ((data[w * lp + j] * I_LFTG_K) + (1 << 15)) >> 16;
             for (i = 1 - mh; i < lh; i += 2, j++)
-                l[i] = data[w * lp + j];
+                l[i] = ((data[w * lp + j] * I_LFTG_X) + (1 << 15)) >> 16;
 
             sr_1d97_int(line, mh, mh + lh);
 
@@ -288,11 +480,11 @@
         l = line + mv;
         for (lp = 0; lp < lh; lp++) {
             int i, j = 0;
-            // copy with interleaving
+            // rescale with interleaving
             for (i = mv; i < lv; i += 2, j++)
-                l[i] = data[w * j + lp];
+                l[i] = ((data[w * j + lp] * I_LFTG_K) + (1 << 15)) >> 16;
             for (i = 1 - mv; i < lv; i += 2, j++)
-                l[i] = data[w * j + lp];
+                l[i] = ((data[w * j + lp] * I_LFTG_X) + (1 << 15)) >> 16;
 
             sr_1d97_int(line, mv, mv + lv);
 
@@ -346,6 +538,21 @@
     return 0;
 }
 
+int ff_dwt_encode(DWTContext *s, void *t)
+{
+    switch(s->type){
+        case FF_DWT97:
+            dwt_encode97_float(s, t); break;
+        case FF_DWT97_INT:
+            dwt_encode97_int(s, t); break;
+        case FF_DWT53:
+            dwt_encode53(s, t); break;
+        default:
+            return -1;
+    }
+    return 0;
+}
+
 int ff_dwt_decode(DWTContext *s, void *t)
 {
     switch (s->type) {
diff --git a/libavcodec/jpeg2000dwt.h b/libavcodec/jpeg2000dwt.h
index 2abfd15..b5be812 100644
--- a/libavcodec/jpeg2000dwt.h
+++ b/libavcodec/jpeg2000dwt.h
@@ -57,6 +57,7 @@
 int ff_jpeg2000_dwt_init(DWTContext *s, uint16_t border[2][2],
                          int decomp_levels, int type);
 
+int ff_dwt_encode(DWTContext *s, void *t);
 int ff_dwt_decode(DWTContext *s, void *t);
 
 void ff_dwt_destroy(DWTContext *s);
diff --git a/libavcodec/jpegls.c b/libavcodec/jpegls.c
index dc5c9cf..216c486 100644
--- a/libavcodec/jpegls.c
+++ b/libavcodec/jpegls.c
@@ -27,61 +27,74 @@
 
 #include "jpegls.h"
 
-void ff_jpegls_init_state(JLSState *state){
+void ff_jpegls_init_state(JLSState *state)
+{
     int i;
 
     state->twonear = state->near * 2 + 1;
-    state->range = ((state->maxval + state->twonear - 1) / state->twonear) + 1;
+    state->range   = (state->maxval + state->twonear - 1) / state->twonear + 1;
 
     // QBPP = ceil(log2(RANGE))
-    for(state->qbpp = 0; (1 << state->qbpp) < state->range; state->qbpp++);
+    for (state->qbpp = 0; (1 << state->qbpp) < state->range; state->qbpp++)
+        ;
 
-    state->bpp = FFMAX(av_log2(state->maxval)+1, 2);
+    state->bpp   = FFMAX(av_log2(state->maxval) + 1, 2);
     state->limit = 2*(state->bpp + FFMAX(state->bpp, 8)) - state->qbpp;
 
-    for(i = 0; i < 367; i++) {
-        state->A[i] = FFMAX((state->range + 32) >> 6, 2);
+    for (i = 0; i < 367; i++) {
+        state->A[i] = FFMAX(state->range + 32 >> 6, 2);
         state->N[i] = 1;
     }
-
 }
 
 /**
  * Custom value clipping function used in T1, T2, T3 calculation
  */
-static inline int iso_clip(int v, int vmin, int vmax){
-    if(v > vmax || v < vmin) return vmin;
-    else                     return v;
+static inline int iso_clip(int v, int vmin, int vmax)
+{
+    if (v > vmax || v < vmin)
+        return vmin;
+    else
+        return v;
 }
 
-void ff_jpegls_reset_coding_parameters(JLSState *s, int reset_all){
-    const int basic_t1= 3;
-    const int basic_t2= 7;
-    const int basic_t3= 21;
+void ff_jpegls_reset_coding_parameters(JLSState *s, int reset_all)
+{
+    const int basic_t1 = 3;
+    const int basic_t2 = 7;
+    const int basic_t3 = 21;
     int factor;
 
-    if(s->maxval==0 || reset_all) s->maxval= (1 << s->bpp) - 1;
+    if (s->maxval == 0 || reset_all)
+        s->maxval = (1 << s->bpp) - 1;
 
-    if(s->maxval >=128){
-        factor= (FFMIN(s->maxval, 4095) + 128)>>8;
+    if (s->maxval >= 128) {
+        factor = FFMIN(s->maxval, 4095) + 128 >> 8;
 
-        if(s->T1==0     || reset_all)
-            s->T1= iso_clip(factor*(basic_t1-2) + 2 + 3*s->near, s->near+1, s->maxval);
-        if(s->T2==0     || reset_all)
-            s->T2= iso_clip(factor*(basic_t2-3) + 3 + 5*s->near, s->T1, s->maxval);
-        if(s->T3==0     || reset_all)
-            s->T3= iso_clip(factor*(basic_t3-4) + 4 + 7*s->near, s->T2, s->maxval);
-    }else{
-        factor= 256 / (s->maxval + 1);
+        if (s->T1 == 0 || reset_all)
+            s->T1 = iso_clip(factor * (basic_t1 - 2) + 2 + 3 * s->near,
+                             s->near + 1, s->maxval);
+        if (s->T2 == 0 || reset_all)
+            s->T2 = iso_clip(factor * (basic_t2 - 3) + 3 + 5 * s->near,
+                             s->T1, s->maxval);
+        if (s->T3 == 0 || reset_all)
+            s->T3 = iso_clip(factor * (basic_t3 - 4) + 4 + 7 * s->near,
+                             s->T2, s->maxval);
+    } else {
+        factor = 256 / (s->maxval + 1);
 
-        if(s->T1==0     || reset_all)
-            s->T1= iso_clip(FFMAX(2, basic_t1/factor + 3*s->near), s->near+1, s->maxval);
-        if(s->T2==0     || reset_all)
-            s->T2= iso_clip(FFMAX(3, basic_t2/factor + 5*s->near), s->T1, s->maxval);
-        if(s->T3==0     || reset_all)
-            s->T3= iso_clip(FFMAX(4, basic_t3/factor + 7*s->near), s->T2, s->maxval);
+        if (s->T1 == 0 || reset_all)
+            s->T1 = iso_clip(FFMAX(2, basic_t1 / factor + 3 * s->near),
+                             s->near + 1, s->maxval);
+        if (s->T2 == 0 || reset_all)
+            s->T2 = iso_clip(FFMAX(3, basic_t2 / factor + 5 * s->near),
+                             s->T1, s->maxval);
+        if (s->T3 == 0 || reset_all)
+            s->T3 = iso_clip(FFMAX(4, basic_t3 / factor + 7 * s->near),
+                             s->T2, s->maxval);
     }
 
-    if(s->reset==0  || reset_all) s->reset= 64;
+    if (s->reset == 0 || reset_all)
+        s->reset = 64;
     av_dlog(NULL, "[JPEG-LS RESET] T=%i,%i,%i\n", s->T1, s->T2, s->T3);
 }
diff --git a/libavcodec/jpegls.h b/libavcodec/jpegls.h
index 0a6ead3..2dc3832 100644
--- a/libavcodec/jpegls.h
+++ b/libavcodec/jpegls.h
@@ -28,21 +28,21 @@
 #ifndef AVCODEC_JPEGLS_H
 #define AVCODEC_JPEGLS_H
 
-#include "avcodec.h"
 #include "libavutil/common.h"
+#include "avcodec.h"
 
-typedef struct JpeglsContext{
+typedef struct JpeglsContext {
     AVCodecContext *avctx;
     AVFrame picture;
-}JpeglsContext;
+} JpeglsContext;
 
-typedef struct JLSState{
+typedef struct JLSState {
     int T1, T2, T3;
     int A[367], B[367], C[365], N[367];
     int limit, reset, bpp, qbpp, maxval, range;
     int near, twonear;
     int run_index[4];
-}JLSState;
+} JLSState;
 
 extern const uint8_t ff_log2_run[32];
 
@@ -54,19 +54,29 @@
 /**
  * Calculate quantized gradient value, used for context determination
  */
-static inline int ff_jpegls_quantize(JLSState *s, int v){ //FIXME optimize
-    if(v==0) return 0;
-    if(v < 0){
-        if(v <= -s->T3) return -4;
-        if(v <= -s->T2) return -3;
-        if(v <= -s->T1) return -2;
-        if(v <  -s->near) return -1;
+static inline int ff_jpegls_quantize(JLSState *s, int v)
+{
+    if (v == 0)
         return 0;
-    }else{
-        if(v <= s->near) return 0;
-        if(v <  s->T1) return 1;
-        if(v <  s->T2) return 2;
-        if(v <  s->T3) return 3;
+    if (v < 0) {
+        if (v <= -s->T3)
+            return -4;
+        if (v <= -s->T2)
+            return -3;
+        if (v <= -s->T1)
+            return -2;
+        if (v < -s->near)
+            return -1;
+        return 0;
+    } else {
+        if (v <= s->near)
+            return 0;
+        if (v < s->T1)
+            return 1;
+        if (v < s->T2)
+            return 2;
+        if (v < s->T3)
+            return 3;
         return 4;
     }
 }
@@ -76,39 +86,41 @@
  */
 void ff_jpegls_reset_coding_parameters(JLSState *s, int reset_all);
 
-
-static inline void ff_jpegls_downscale_state(JLSState *state, int Q){
-    if(state->N[Q] == state->reset){
-        state->A[Q] >>=1;
-        state->B[Q] >>=1;
-        state->N[Q] >>=1;
+static inline void ff_jpegls_downscale_state(JLSState *state, int Q)
+{
+    if (state->N[Q] == state->reset) {
+        state->A[Q] >>= 1;
+        state->B[Q] >>= 1;
+        state->N[Q] >>= 1;
     }
     state->N[Q]++;
 }
 
-static inline int ff_jpegls_update_state_regular(JLSState *state, int Q, int err){
+static inline int ff_jpegls_update_state_regular(JLSState *state,
+                                                 int Q, int err)
+{
     if(FFABS(err) > 0xFFFF)
         return -0x10000;
     state->A[Q] += FFABS(err);
-    err *= state->twonear;
+    err         *= state->twonear;
     state->B[Q] += err;
 
     ff_jpegls_downscale_state(state, Q);
 
-    if(state->B[Q] <= -state->N[Q]) {
-        state->B[Q]= FFMAX(state->B[Q] + state->N[Q], 1-state->N[Q]);
-        if(state->C[Q] > -128)
+    if (state->B[Q] <= -state->N[Q]) {
+        state->B[Q] = FFMAX(state->B[Q] + state->N[Q], 1 - state->N[Q]);
+        if (state->C[Q] > -128)
             state->C[Q]--;
-    }else if(state->B[Q] > 0){
-        state->B[Q]= FFMIN(state->B[Q] - state->N[Q], 0);
-        if(state->C[Q] < 127)
+    } else if (state->B[Q] > 0) {
+        state->B[Q] = FFMIN(state->B[Q] - state->N[Q], 0);
+        if (state->C[Q] < 127)
             state->C[Q]++;
     }
 
     return err;
 }
 
-#define R(a, i   ) (bits == 8 ?  ((uint8_t*)(a))[i]    :  ((uint16_t*)(a))[i]  )
-#define W(a, i, v) (bits == 8 ? (((uint8_t*)(a))[i]=v) : (((uint16_t*)(a))[i]=v))
+#define R(a, i)    (bits == 8 ?  ((uint8_t *)(a))[i]      :  ((uint16_t *)(a))[i])
+#define W(a, i, v) (bits == 8 ? (((uint8_t *)(a))[i] = v) : (((uint16_t *)(a))[i] = v))
 
 #endif /* AVCODEC_JPEGLS_H */
diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c
index 516a82f..0e344f5 100644
--- a/libavcodec/jpeglsdec.c
+++ b/libavcodec/jpeglsdec.c
@@ -34,18 +34,16 @@
 #include "jpegls.h"
 #include "jpeglsdec.h"
 
-
 /*
-* Uncomment this to significantly speed up decoding of broken JPEG-LS
-* (or test broken JPEG-LS decoder) and slow down ordinary decoding a bit.
-*
-* There is no Golomb code with length >= 32 bits possible, so check and
-* avoid situation of 32 zeros, FFmpeg Golomb decoder is painfully slow
-* on this errors.
-*/
+ * Uncomment this to significantly speed up decoding of broken JPEG-LS
+ * (or test broken JPEG-LS decoder) and slow down ordinary decoding a bit.
+ *
+ * There is no Golomb code with length >= 32 bits possible, so check and
+ * avoid situation of 32 zeros, FFmpeg Golomb decoder is painfully slow
+ * on this errors.
+ */
 //#define JLS_BROKEN
 
-
 /**
  * Decode LSE block with initialization parameters
  */
@@ -56,13 +54,13 @@
     skip_bits(&s->gb, 16);  /* length: FIXME: verify field validity */
     id = get_bits(&s->gb, 8);
 
-    switch(id){
+    switch (id) {
     case 1:
-        s->maxval= get_bits(&s->gb, 16);
-        s->t1= get_bits(&s->gb, 16);
-        s->t2= get_bits(&s->gb, 16);
-        s->t3= get_bits(&s->gb, 16);
-        s->reset= get_bits(&s->gb, 16);
+        s->maxval = get_bits(&s->gb, 16);
+        s->t1     = get_bits(&s->gb, 16);
+        s->t2     = get_bits(&s->gb, 16);
+        s->t3     = get_bits(&s->gb, 16);
+        s->reset  = get_bits(&s->gb, 16);
 
 //        ff_jpegls_reset_coding_parameters(s, 0);
         //FIXME quant table?
@@ -70,13 +68,13 @@
     case 2:
     case 3:
         av_log(s->avctx, AV_LOG_ERROR, "palette not supported\n");
-        return -1;
+        return AVERROR(ENOSYS);
     case 4:
         av_log(s->avctx, AV_LOG_ERROR, "oversize image not supported\n");
-        return -1;
+        return AVERROR(ENOSYS);
     default:
         av_log(s->avctx, AV_LOG_ERROR, "invalid id %d\n", id);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     av_dlog(s->avctx, "ID=%i, T=%i,%i,%i\n", id, s->t1, s->t2, s->t3);
 
@@ -86,27 +84,30 @@
 /**
  * Get context-dependent Golomb code, decode it and update context
  */
-static inline int ls_get_code_regular(GetBitContext *gb, JLSState *state, int Q){
+static inline int ls_get_code_regular(GetBitContext *gb, JLSState *state, int Q)
+{
     int k, ret;
 
-    for(k = 0; (state->N[Q] << k) < state->A[Q]; k++);
+    for (k = 0; (state->N[Q] << k) < state->A[Q]; k++)
+        ;
 
 #ifdef JLS_BROKEN
-    if(!show_bits_long(gb, 32))return -1;
+    if (!show_bits_long(gb, 32))
+        return -1;
 #endif
     ret = get_ur_golomb_jpegls(gb, k, state->limit, state->qbpp);
 
     /* decode mapped error */
-    if(ret & 1)
-        ret = -((ret + 1) >> 1);
+    if (ret & 1)
+        ret = -(ret + 1 >> 1);
     else
         ret >>= 1;
 
     /* for NEAR=0, k=0 and 2*B[Q] <= - N[Q] mapping is reversed */
-    if(!state->near && !k && (2 * state->B[Q] <= -state->N[Q]))
+    if (!state->near && !k && (2 * state->B[Q] <= -state->N[Q]))
         ret = -(ret + 1);
 
-    ret= ff_jpegls_update_state_regular(state, Q, ret);
+    ret = ff_jpegls_update_state_regular(state, Q, ret);
 
     return ret;
 }
@@ -114,29 +115,34 @@
 /**
  * Get Golomb code, decode it and update state for run termination
  */
-static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state, int RItype, int limit_add){
+static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state,
+                                      int RItype, int limit_add)
+{
     int k, ret, temp, map;
     int Q = 365 + RItype;
 
-    temp=  state->A[Q];
-    if(RItype)
+    temp = state->A[Q];
+    if (RItype)
         temp += state->N[Q] >> 1;
 
-    for(k = 0; (state->N[Q] << k) < temp; k++);
+    for (k = 0; (state->N[Q] << k) < temp; k++)
+        ;
 
 #ifdef JLS_BROKEN
-    if(!show_bits_long(gb, 32))return -1;
+    if (!show_bits_long(gb, 32))
+        return -1;
 #endif
-    ret = get_ur_golomb_jpegls(gb, k, state->limit - limit_add - 1, state->qbpp);
+    ret = get_ur_golomb_jpegls(gb, k, state->limit - limit_add - 1,
+                               state->qbpp);
 
     /* decode mapped error */
     map = 0;
-    if(!k && (RItype || ret) && (2 * state->B[Q] < state->N[Q]))
+    if (!k && (RItype || ret) && (2 * state->B[Q] < state->N[Q]))
         map = 1;
     ret += RItype + map;
 
-    if(ret & 1){
-        ret = map - ((ret + 1) >> 1);
+    if (ret & 1) {
+        ret = map - (ret + 1 >> 1);
         state->B[Q]++;
     } else {
         ret = ret >> 1;
@@ -144,7 +150,7 @@
 
     /* update state */
     state->A[Q] += FFABS(ret) - RItype;
-    ret *= state->twonear;
+    ret         *= state->twonear;
     ff_jpegls_downscale_state(state, Q);
 
     return ret;
@@ -153,12 +159,15 @@
 /**
  * Decode one line of image
  */
-static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, void *last, void *dst, int last2, int w, int stride, int comp, int bits){
+static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s,
+                                  void *last, void *dst, int last2, int w,
+                                  int stride, int comp, int bits)
+{
     int i, x = 0;
     int Ra, Rb, Rc, Rd;
     int D0, D1, D2;
 
-    while(x < w) {
+    while (x < w) {
         int err, pred;
 
         /* compute gradients */
@@ -170,52 +179,54 @@
         D1 = Rb - Rc;
         D2 = Rc - Ra;
         /* run mode */
-        if((FFABS(D0) <= state->near) && (FFABS(D1) <= state->near) && (FFABS(D2) <= state->near)) {
+        if ((FFABS(D0) <= state->near) &&
+            (FFABS(D1) <= state->near) &&
+            (FFABS(D2) <= state->near)) {
             int r;
             int RItype;
 
             /* decode full runs while available */
-            while(get_bits1(&s->gb)) {
+            while (get_bits1(&s->gb)) {
                 int r;
                 r = 1 << ff_log2_run[state->run_index[comp]];
-                if(x + r * stride > w) {
+                if (x + r * stride > w)
                     r = (w - x) / stride;
-                }
-                for(i = 0; i < r; i++) {
+                for (i = 0; i < r; i++) {
                     W(dst, x, Ra);
                     x += stride;
                 }
                 /* if EOL reached, we stop decoding */
-                if(r != (1 << ff_log2_run[state->run_index[comp]]))
+                if (r != 1 << ff_log2_run[state->run_index[comp]])
                     return;
-                if(state->run_index[comp] < 31)
+                if (state->run_index[comp] < 31)
                     state->run_index[comp]++;
-                if(x + stride > w)
+                if (x + stride > w)
                     return;
             }
             /* decode aborted run */
             r = ff_log2_run[state->run_index[comp]];
-            if(r)
+            if (r)
                 r = get_bits_long(&s->gb, r);
-            if(x + r * stride > w) {
+            if (x + r * stride > w) {
                 r = (w - x) / stride;
             }
-            for(i = 0; i < r; i++) {
+            for (i = 0; i < r; i++) {
                 W(dst, x, Ra);
                 x += stride;
             }
 
             /* decode run termination value */
-            Rb = R(last, x);
+            Rb     = R(last, x);
             RItype = (FFABS(Ra - Rb) <= state->near) ? 1 : 0;
-            err = ls_get_code_runterm(&s->gb, state, RItype, ff_log2_run[state->run_index[comp]]);
-            if(state->run_index[comp])
+            err    = ls_get_code_runterm(&s->gb, state, RItype,
+                                         ff_log2_run[state->run_index[comp]]);
+            if (state->run_index[comp])
                 state->run_index[comp]--;
 
-            if(state->near && RItype){
+            if (state->near && RItype) {
                 pred = Ra + err;
             } else {
-                if(Rb < Ra)
+                if (Rb < Ra)
                     pred = Rb - err;
                 else
                     pred = Rb + err;
@@ -223,31 +234,33 @@
         } else { /* regular mode */
             int context, sign;
 
-            context = ff_jpegls_quantize(state, D0) * 81 + ff_jpegls_quantize(state, D1) * 9 + ff_jpegls_quantize(state, D2);
-            pred = mid_pred(Ra, Ra + Rb - Rc, Rb);
+            context = ff_jpegls_quantize(state, D0) * 81 +
+                      ff_jpegls_quantize(state, D1) *  9 +
+                      ff_jpegls_quantize(state, D2);
+            pred    = mid_pred(Ra, Ra + Rb - Rc, Rb);
 
-            if(context < 0){
+            if (context < 0) {
                 context = -context;
-                sign = 1;
-            }else{
+                sign    = 1;
+            } else {
                 sign = 0;
             }
 
-            if(sign){
+            if (sign) {
                 pred = av_clip(pred - state->C[context], 0, state->maxval);
-                err = -ls_get_code_regular(&s->gb, state, context);
+                err  = -ls_get_code_regular(&s->gb, state, context);
             } else {
                 pred = av_clip(pred + state->C[context], 0, state->maxval);
-                err = ls_get_code_regular(&s->gb, state, context);
+                err  = ls_get_code_regular(&s->gb, state, context);
             }
 
             /* we have to do something more for near-lossless coding */
             pred += err;
         }
-        if(state->near){
-            if(pred < -state->near)
+        if (state->near) {
+            if (pred < -state->near)
                 pred += state->range * state->twonear;
-            else if(pred > state->maxval + state->near)
+            else if (pred > state->maxval + state->near)
                 pred -= state->range * state->twonear;
             pred = av_clip(pred, 0, state->maxval);
         }
@@ -258,53 +271,61 @@
     }
 }
 
-int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transform, int ilv){
+int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near,
+                             int point_transform, int ilv)
+{
     int i, t = 0;
     uint8_t *zero, *last, *cur;
     JLSState *state;
-    int off = 0, stride = 1, width, shift;
+    int off = 0, stride = 1, width, shift, ret = 0;
 
     zero = av_mallocz(s->picture.linesize[0]);
     last = zero;
-    cur = s->picture.data[0];
+    cur  = s->picture.data[0];
 
     state = av_mallocz(sizeof(JLSState));
     /* initialize JPEG-LS state from JPEG parameters */
-    state->near = near;
-    state->bpp = (s->bits < 2) ? 2 : s->bits;
+    state->near   = near;
+    state->bpp    = (s->bits < 2) ? 2 : s->bits;
     state->maxval = s->maxval;
-    state->T1 = s->t1;
-    state->T2 = s->t2;
-    state->T3 = s->t3;
-    state->reset = s->reset;
+    state->T1     = s->t1;
+    state->T2     = s->t2;
+    state->T3     = s->t3;
+    state->reset  = s->reset;
     ff_jpegls_reset_coding_parameters(state, 0);
     ff_jpegls_init_state(state);
 
-    if(s->bits <= 8)
+    if (s->bits <= 8)
         shift = point_transform + (8 - s->bits);
     else
         shift = point_transform + (16 - s->bits);
 
     if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
-        av_log(s->avctx, AV_LOG_DEBUG, "JPEG-LS params: %ix%i NEAR=%i MV=%i T(%i,%i,%i) RESET=%i, LIMIT=%i, qbpp=%i, RANGE=%i\n",
+        av_log(s->avctx, AV_LOG_DEBUG,
+               "JPEG-LS params: %ix%i NEAR=%i MV=%i T(%i,%i,%i) "
+               "RESET=%i, LIMIT=%i, qbpp=%i, RANGE=%i\n",
                 s->width, s->height, state->near, state->maxval,
                 state->T1, state->T2, state->T3,
                 state->reset, state->limit, state->qbpp, state->range);
         av_log(s->avctx, AV_LOG_DEBUG, "JPEG params: ILV=%i Pt=%i BPP=%i, scan = %i\n",
                 ilv, point_transform, s->bits, s->cur_scan);
     }
-    if(ilv == 0) { /* separate planes */
+    if (ilv == 0) { /* separate planes */
+        if (s->cur_scan > s->nb_components) {
+            ret = AVERROR_INVALIDDATA;
+            goto end;
+        }
         stride = (s->nb_components > 1) ? 3 : 1;
-        off = av_clip(s->cur_scan - 1, 0, stride - 1);
-        width = s->width * stride;
-        cur += off;
-        for(i = 0; i < s->height; i++) {
-            if(s->bits <= 8){
-                ls_decode_line(state, s, last, cur, t, width, stride, off,  8);
+        off    = av_clip(s->cur_scan - 1, 0, stride - 1);
+        width  = s->width * stride;
+        cur   += off;
+        for (i = 0; i < s->height; i++) {
+            if (s->bits <= 8) {
+                ls_decode_line(state, s, last, cur, t, width, stride, off, 8);
                 t = last[0];
-            }else{
+            } else {
                 ls_decode_line(state, s, last, cur, t, width, stride, off, 16);
-                t = *((uint16_t*)last);
+                t = *((uint16_t *)last);
             }
             last = cur;
             cur += s->picture.linesize[0];
@@ -314,15 +335,16 @@
                 skip_bits(&s->gb, 16); /* skip RSTn */
             }
         }
-    } else if(ilv == 1) { /* line interleaving */
+    } else if (ilv == 1) { /* line interleaving */
         int j;
-        int Rc[3] = {0, 0, 0};
+        int Rc[3] = { 0, 0, 0 };
         stride = (s->nb_components > 1) ? 3 : 1;
         memset(cur, 0, s->picture.linesize[0]);
         width = s->width * stride;
-        for(i = 0; i < s->height; i++) {
-            for(j = 0; j < stride; j++) {
-                ls_decode_line(state, s, last + j, cur + j, Rc[j], width, stride, j, 8);
+        for (i = 0; i < s->height; i++) {
+            for (j = 0; j < stride; j++) {
+                ls_decode_line(state, s, last + j, cur + j,
+                               Rc[j], width, stride, j, 8);
                 Rc[j] = last[j];
 
                 if (s->restart_interval && !--s->restart_count) {
@@ -333,47 +355,93 @@
             last = cur;
             cur += s->picture.linesize[0];
         }
-    } else if(ilv == 2) { /* sample interleaving */
-        av_log(s->avctx, AV_LOG_ERROR, "Sample interleaved images are not supported.\n");
-        av_free(state);
-        av_free(zero);
-        return -1;
+    } else if (ilv == 2) { /* sample interleaving */
+        avpriv_report_missing_feature(s->avctx, "Sample interleaved images");
+        ret = AVERROR_PATCHWELCOME;
+        goto end;
     }
 
-    if(shift){ /* we need to do point transform or normalize samples */
+    if (s->xfrm && s->nb_components == 3) {
         int x, w;
 
         w = s->width * s->nb_components;
 
-        if(s->bits <= 8){
+        if (s->bits <= 8) {
             uint8_t *src = s->picture.data[0];
 
-            for(i = 0; i < s->height; i++){
-                for(x = off; x < w; x+= stride){
-                    src[x] <<= shift;
+            for (i = 0; i < s->height; i++) {
+                switch(s->xfrm) {
+                case 1:
+                    for (x = off; x < w; x += 3) {
+                        src[x  ] += src[x+1] + 128;
+                        src[x+2] += src[x+1] + 128;
+                    }
+                    break;
+                case 2:
+                    for (x = off; x < w; x += 3) {
+                        src[x  ] += src[x+1] + 128;
+                        src[x+2] += ((src[x  ] + src[x+1])>>1) + 128;
+                    }
+                    break;
+                case 3:
+                    for (x = off; x < w; x += 3) {
+                        int g = src[x+0] - ((src[x+2]+src[x+1])>>2) + 64;
+                        src[x+0] = src[x+2] + g + 128;
+                        src[x+2] = src[x+1] + g + 128;
+                        src[x+1] = g;
+                    }
+                    break;
+                case 4:
+                    for (x = off; x < w; x += 3) {
+                        int r    = src[x+0] - ((                       359 * (src[x+2]-128) + 490) >> 8);
+                        int g    = src[x+0] - (( 88 * (src[x+1]-128) - 183 * (src[x+2]-128) +  30) >> 8);
+                        int b    = src[x+0] + ((454 * (src[x+1]-128)                        + 574) >> 8);
+                        src[x+0] = av_clip_uint8(r);
+                        src[x+1] = av_clip_uint8(g);
+                        src[x+2] = av_clip_uint8(b);
+                    }
+                    break;
                 }
                 src += s->picture.linesize[0];
             }
-        }else{
-            uint16_t *src = (uint16_t*) s->picture.data[0];
+        }else
+            avpriv_report_missing_feature(s->avctx, "16bit xfrm");
+    }
 
-            for(i = 0; i < s->height; i++){
-                for(x = 0; x < w; x++){
+    if (shift) { /* we need to do point transform or normalize samples */
+        int x, w;
+
+        w = s->width * s->nb_components;
+
+        if (s->bits <= 8) {
+            uint8_t *src = s->picture.data[0];
+
+            for (i = 0; i < s->height; i++) {
+                for (x = off; x < w; x += stride)
                     src[x] <<= shift;
-                }
-                src += s->picture.linesize[0]/2;
+                src += s->picture.linesize[0];
+            }
+        } else {
+            uint16_t *src = (uint16_t *)s->picture.data[0];
+
+            for (i = 0; i < s->height; i++) {
+                for (x = 0; x < w; x++)
+                    src[x] <<= shift;
+                src += s->picture.linesize[0] / 2;
             }
         }
     }
+
+end:
     av_free(state);
     av_free(zero);
 
-    return 0;
+    return ret;
 }
 
-
 AVCodec ff_jpegls_decoder = {
     .name           = "jpegls",
+    .long_name      = NULL_IF_CONFIG_SMALL("JPEG-LS"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_JPEGLS,
     .priv_data_size = sizeof(MJpegDecodeContext),
@@ -381,5 +449,4 @@
     .close          = ff_mjpeg_decode_end,
     .decode         = ff_mjpeg_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("JPEG-LS"),
 };
diff --git a/libavcodec/jpeglsdec.h b/libavcodec/jpeglsdec.h
index 5204ecb..0cafaba 100644
--- a/libavcodec/jpeglsdec.h
+++ b/libavcodec/jpeglsdec.h
@@ -36,6 +36,7 @@
  */
 int ff_jpegls_decode_lse(MJpegDecodeContext *s);
 
-int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transform, int ilv);
+int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near,
+                             int point_transform, int ilv);
 
 #endif /* AVCODEC_JPEGLSDEC_H */
diff --git a/libavcodec/jpeglsenc.c b/libavcodec/jpeglsenc.c
index be979aa..308d6d3 100644
--- a/libavcodec/jpeglsenc.c
+++ b/libavcodec/jpeglsenc.c
@@ -34,24 +34,26 @@
 #include "mjpeg.h"
 #include "jpegls.h"
 
-
 /**
  * Encode error from regular symbol
  */
-static inline void ls_encode_regular(JLSState *state, PutBitContext *pb, int Q, int err){
+static inline void ls_encode_regular(JLSState *state, PutBitContext *pb, int Q,
+                                     int err)
+{
     int k;
     int val;
     int map;
 
-    for(k = 0; (state->N[Q] << k) < state->A[Q]; k++);
+    for (k = 0; (state->N[Q] << k) < state->A[Q]; k++)
+        ;
 
     map = !state->near && !k && (2 * state->B[Q] <= -state->N[Q]);
 
-    if(err < 0)
+    if (err < 0)
         err += state->range;
-    if(err >= ((state->range + 1) >> 1)) {
+    if (err >= (state->range + 1 >> 1)) {
         err -= state->range;
-        val = 2 * FFABS(err) - 1 - map;
+        val  = 2 * FFABS(err) - 1 - map;
     } else
         val = 2 * err + map;
 
@@ -63,27 +65,30 @@
 /**
  * Encode error from run termination
  */
-static inline void ls_encode_runterm(JLSState *state, PutBitContext *pb, int RItype, int err, int limit_add){
+static inline void ls_encode_runterm(JLSState *state, PutBitContext *pb,
+                                     int RItype, int err, int limit_add)
+{
     int k;
     int val, map;
     int Q = 365 + RItype;
     int temp;
 
     temp = state->A[Q];
-    if(RItype)
+    if (RItype)
         temp += state->N[Q] >> 1;
-    for(k = 0; (state->N[Q] << k) < temp; k++);
+    for (k = 0; (state->N[Q] << k) < temp; k++)
+        ;
     map = 0;
-    if(!k && err && (2 * state->B[Q] < state->N[Q]))
+    if (!k && err && (2 * state->B[Q] < state->N[Q]))
         map = 1;
 
-    if(err < 0)
-        val = - (2 * err) - 1 - RItype + map;
+    if (err < 0)
+        val = -(2 * err) - 1 - RItype + map;
     else
         val = 2 * err - RItype - map;
     set_ur_golomb_jpegls(pb, val, k, state->limit - limit_add - 1, state->qbpp);
 
-    if(err < 0)
+    if (err < 0)
         state->B[Q]++;
     state->A[Q] += (val + 1 - RItype) >> 1;
 
@@ -93,19 +98,21 @@
 /**
  * Encode run value as specified by JPEG-LS standard
  */
-static inline void ls_encode_run(JLSState *state, PutBitContext *pb, int run, int comp, int trail){
-    while(run >= (1 << ff_log2_run[state->run_index[comp]])){
+static inline void ls_encode_run(JLSState *state, PutBitContext *pb, int run,
+                                 int comp, int trail)
+{
+    while (run >= (1 << ff_log2_run[state->run_index[comp]])) {
         put_bits(pb, 1, 1);
         run -= 1 << ff_log2_run[state->run_index[comp]];
-        if(state->run_index[comp] < 31)
+        if (state->run_index[comp] < 31)
             state->run_index[comp]++;
     }
     /* if hit EOL, encode another full run, else encode aborted run */
-    if(!trail && run) {
+    if (!trail && run) {
         put_bits(pb, 1, 1);
-    }else if(trail){
+    } else if (trail) {
         put_bits(pb, 1, 0);
-        if(ff_log2_run[state->run_index[comp]])
+        if (ff_log2_run[state->run_index[comp]])
             put_bits(pb, ff_log2_run[state->run_index[comp]], run);
     }
 }
@@ -113,12 +120,15 @@
 /**
  * Encode one line of image
  */
-static inline void ls_encode_line(JLSState *state, PutBitContext *pb, void *last, void *cur, int last2, int w, int stride, int comp, int bits){
+static inline void ls_encode_line(JLSState *state, PutBitContext *pb,
+                                  void *last, void *cur, int last2, int w,
+                                  int stride, int comp, int bits)
+{
     int x = 0;
     int Ra, Rb, Rc, Rd;
     int D0, D1, D2;
 
-    while(x < w) {
+    while (x < w) {
         int err, pred, sign;
 
         /* compute gradients */
@@ -131,71 +141,76 @@
         D2 = Rc - Ra;
 
         /* run mode */
-        if((FFABS(D0) <= state->near) && (FFABS(D1) <= state->near) && (FFABS(D2) <= state->near)) {
+        if ((FFABS(D0) <= state->near) &&
+            (FFABS(D1) <= state->near) &&
+            (FFABS(D2) <= state->near)) {
             int RUNval, RItype, run;
 
-            run = 0;
+            run    = 0;
             RUNval = Ra;
-            while(x < w && (FFABS(R(cur, x) - RUNval) <= state->near)){
+            while (x < w && (FFABS(R(cur, x) - RUNval) <= state->near)) {
                 run++;
                 W(cur, x, Ra);
                 x += stride;
             }
             ls_encode_run(state, pb, run, comp, x < w);
-            if(x >= w)
+            if (x >= w)
                 return;
-            Rb = R(last, x);
-            RItype = (FFABS(Ra - Rb) <= state->near);
-            pred = RItype ? Ra : Rb;
-            err = R(cur, x) - pred;
+            Rb     = R(last, x);
+            RItype = FFABS(Ra - Rb) <= state->near;
+            pred   = RItype ? Ra : Rb;
+            err    = R(cur, x) - pred;
 
-            if(!RItype && Ra > Rb)
+            if (!RItype && Ra > Rb)
                 err = -err;
 
-            if(state->near){
-                if(err > 0)
-                    err = (state->near + err) / state->twonear;
+            if (state->near) {
+                if (err > 0)
+                    err =  (state->near + err) / state->twonear;
                 else
                     err = -(state->near - err) / state->twonear;
 
-                if(RItype || (Rb >= Ra))
+                if (RItype || (Rb >= Ra))
                     Ra = av_clip(pred + err * state->twonear, 0, state->maxval);
                 else
                     Ra = av_clip(pred - err * state->twonear, 0, state->maxval);
                 W(cur, x, Ra);
             }
-            if(err < 0)
+            if (err < 0)
                 err += state->range;
-            if(err >= ((state->range + 1) >> 1))
+            if (err >= state->range + 1 >> 1)
                 err -= state->range;
 
-            ls_encode_runterm(state, pb, RItype, err, ff_log2_run[state->run_index[comp]]);
+            ls_encode_runterm(state, pb, RItype, err,
+                              ff_log2_run[state->run_index[comp]]);
 
-            if(state->run_index[comp] > 0)
+            if (state->run_index[comp] > 0)
                 state->run_index[comp]--;
         } else { /* regular mode */
             int context;
 
-            context = ff_jpegls_quantize(state, D0) * 81 + ff_jpegls_quantize(state, D1) * 9 + ff_jpegls_quantize(state, D2);
-            pred = mid_pred(Ra, Ra + Rb - Rc, Rb);
+            context = ff_jpegls_quantize(state, D0) * 81 +
+                      ff_jpegls_quantize(state, D1) *  9 +
+                      ff_jpegls_quantize(state, D2);
+            pred    = mid_pred(Ra, Ra + Rb - Rc, Rb);
 
-            if(context < 0){
+            if (context < 0) {
                 context = -context;
-                sign = 1;
-                pred = av_clip(pred - state->C[context], 0, state->maxval);
-                err = pred - R(cur, x);
-            }else{
+                sign    = 1;
+                pred    = av_clip(pred - state->C[context], 0, state->maxval);
+                err     = pred - R(cur, x);
+            } else {
                 sign = 0;
                 pred = av_clip(pred + state->C[context], 0, state->maxval);
-                err = R(cur, x) - pred;
+                err  = R(cur, x) - pred;
             }
 
-            if(state->near){
-                if(err > 0)
-                    err = (state->near + err) / state->twonear;
+            if (state->near) {
+                if (err > 0)
+                    err =  (state->near + err) / state->twonear;
                 else
                     err = -(state->near - err) / state->twonear;
-                if(!sign)
+                if (!sign)
                     Ra = av_clip(pred + err * state->twonear, 0, state->maxval);
                 else
                     Ra = av_clip(pred - err * state->twonear, 0, state->maxval);
@@ -208,18 +223,22 @@
     }
 }
 
-static void ls_store_lse(JLSState *state, PutBitContext *pb){
+static void ls_store_lse(JLSState *state, PutBitContext *pb)
+{
     /* Test if we have default params and don't need to store LSE */
     JLSState state2 = { 0 };
-    state2.bpp = state->bpp;
+    state2.bpp  = state->bpp;
     state2.near = state->near;
     ff_jpegls_reset_coding_parameters(&state2, 1);
-    if(state->T1 == state2.T1 && state->T2 == state2.T2 && state->T3 == state2.T3 && state->reset == state2.reset)
+    if (state->T1 == state2.T1 &&
+        state->T2 == state2.T2 &&
+        state->T3 == state2.T3 &&
+        state->reset == state2.reset)
         return;
     /* store LSE type 1 */
     put_marker(pb, LSE);
     put_bits(pb, 16, 13);
-    put_bits(pb, 8,   1);
+    put_bits(pb, 8, 1);
     put_bits(pb, 16, state->maxval);
     put_bits(pb, 16, state->T1);
     put_bits(pb, 16, state->T2);
@@ -230,9 +249,9 @@
 static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt,
                              const AVFrame *pict, int *got_packet)
 {
-    JpeglsContext * const s = avctx->priv_data;
-    AVFrame * const p = &s->picture;
-    const int near = avctx->prediction_method;
+    JpeglsContext *const s = avctx->priv_data;
+    AVFrame *const p       = &s->picture;
+    const int near         = avctx->prediction_method;
     PutBitContext pb, pb2;
     GetBitContext gb;
     uint8_t *buf2, *zero, *cur, *last;
@@ -240,17 +259,18 @@
     int i, size, ret;
     int comps;
 
-    *p = *pict;
-    p->pict_type= AV_PICTURE_TYPE_I;
-    p->key_frame= 1;
+    *p           = *pict;
+    p->pict_type = AV_PICTURE_TYPE_I;
+    p->key_frame = 1;
 
-    if(avctx->pix_fmt == AV_PIX_FMT_GRAY8 || avctx->pix_fmt == AV_PIX_FMT_GRAY16)
+    if (avctx->pix_fmt == AV_PIX_FMT_GRAY8 ||
+        avctx->pix_fmt == AV_PIX_FMT_GRAY16)
         comps = 1;
     else
         comps = 3;
 
-    if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width*avctx->height*comps*4 +
-                                    FF_MIN_BUFFER_SIZE)) < 0)
+    if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width  *avctx->height * comps * 4 +
+                                FF_MIN_BUFFER_SIZE)) < 0)
         return ret;
 
     buf2 = av_malloc(pkt->size);
@@ -262,31 +282,31 @@
     put_marker(&pb, SOI);
     put_marker(&pb, SOF48);
     put_bits(&pb, 16, 8 + comps * 3); // header size depends on components
-    put_bits(&pb,  8, (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8); // bpp
+    put_bits(&pb, 8, (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8);  // bpp
     put_bits(&pb, 16, avctx->height);
     put_bits(&pb, 16, avctx->width);
-    put_bits(&pb,  8, comps);         // components
-    for(i = 1; i <= comps; i++) {
-        put_bits(&pb,  8, i);    // component ID
-        put_bits(&pb,  8, 0x11); // subsampling: none
-        put_bits(&pb,  8, 0);    // Tiq, used by JPEG-LS ext
+    put_bits(&pb, 8, comps);          // components
+    for (i = 1; i <= comps; i++) {
+        put_bits(&pb, 8, i);     // component ID
+        put_bits(&pb, 8, 0x11);  // subsampling: none
+        put_bits(&pb, 8, 0);     // Tiq, used by JPEG-LS ext
     }
 
     put_marker(&pb, SOS);
     put_bits(&pb, 16, 6 + comps * 2);
-    put_bits(&pb,  8, comps);
-    for(i = 1; i <= comps; i++) {
-        put_bits(&pb,  8, i);  // component ID
-        put_bits(&pb,  8, 0);  // mapping index: none
+    put_bits(&pb, 8, comps);
+    for (i = 1; i <= comps; i++) {
+        put_bits(&pb, 8, i);   // component ID
+        put_bits(&pb, 8, 0);   // mapping index: none
     }
-    put_bits(&pb,  8, near);
-    put_bits(&pb,  8, (comps > 1) ? 1 : 0); // interleaving: 0 - plane, 1 - line
-    put_bits(&pb,  8, 0); // point transform: none
+    put_bits(&pb, 8, near);
+    put_bits(&pb, 8, (comps > 1) ? 1 : 0);  // interleaving: 0 - plane, 1 - line
+    put_bits(&pb, 8, 0);  // point transform: none
 
     state = av_mallocz(sizeof(JLSState));
     /* initialize JPEG-LS state from JPEG parameters */
     state->near = near;
-    state->bpp = (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8;
+    state->bpp  = (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8;
     ff_jpegls_reset_coding_parameters(state, 0);
     ff_jpegls_init_state(state);
 
@@ -298,46 +318,48 @@
         return AVERROR(ENOMEM);
     }
     last = zero;
-    cur = p->data[0];
-    if(avctx->pix_fmt == AV_PIX_FMT_GRAY8){
+    cur  = p->data[0];
+    if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
         int t = 0;
 
-        for(i = 0; i < avctx->height; i++) {
-            ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0,  8);
-            t = last[0];
+        for (i = 0; i < avctx->height; i++) {
+            ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0, 8);
+            t    = last[0];
             last = cur;
             cur += p->linesize[0];
         }
-    }else if(avctx->pix_fmt == AV_PIX_FMT_GRAY16){
+    } else if (avctx->pix_fmt == AV_PIX_FMT_GRAY16) {
         int t = 0;
 
-        for(i = 0; i < avctx->height; i++) {
+        for (i = 0; i < avctx->height; i++) {
             ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0, 16);
-            t = *((uint16_t*)last);
+            t    = *((uint16_t *)last);
             last = cur;
             cur += p->linesize[0];
         }
-    }else if(avctx->pix_fmt == AV_PIX_FMT_RGB24){
+    } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) {
         int j, width;
-        int Rc[3] = {0, 0, 0};
+        int Rc[3] = { 0, 0, 0 };
 
         width = avctx->width * 3;
-        for(i = 0; i < avctx->height; i++) {
-            for(j = 0; j < 3; j++) {
-                ls_encode_line(state, &pb2, last + j, cur + j, Rc[j], width, 3, j, 8);
+        for (i = 0; i < avctx->height; i++) {
+            for (j = 0; j < 3; j++) {
+                ls_encode_line(state, &pb2, last + j, cur + j, Rc[j],
+                               width, 3, j, 8);
                 Rc[j] = last[j];
             }
             last = cur;
             cur += s->picture.linesize[0];
         }
-    }else if(avctx->pix_fmt == AV_PIX_FMT_BGR24){
+    } else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
         int j, width;
-        int Rc[3] = {0, 0, 0};
+        int Rc[3] = { 0, 0, 0 };
 
         width = avctx->width * 3;
-        for(i = 0; i < avctx->height; i++) {
-            for(j = 2; j >= 0; j--) {
-                ls_encode_line(state, &pb2, last + j, cur + j, Rc[j], width, 3, j, 8);
+        for (i = 0; i < avctx->height; i++) {
+            for (j = 2; j >= 0; j--) {
+                ls_encode_line(state, &pb2, last + j, cur + j, Rc[j],
+                               width, 3, j, 8);
                 Rc[j] = last[j];
             }
             last = cur;
@@ -348,20 +370,20 @@
     av_freep(&zero);
     av_freep(&state);
 
-    // the specification says that after doing 0xff escaping unused bits in the
-    // last byte must be set to 0, so just append 7 "optional" zero-bits to
-    // avoid special-casing.
+    /* the specification says that after doing 0xff escaping unused bits in
+     * the last byte must be set to 0, so just append 7 "optional" zero-bits
+     * to avoid special-casing. */
     put_bits(&pb2, 7, 0);
     size = put_bits_count(&pb2);
     flush_put_bits(&pb2);
     /* do escape coding */
     init_get_bits(&gb, buf2, size);
     size -= 7;
-    while(get_bits_count(&gb) < size){
+    while (get_bits_count(&gb) < size) {
         int v;
         v = get_bits(&gb, 8);
         put_bits(&pb, 8, v);
-        if(v == 0xFF){
+        if (v == 0xFF) {
             v = get_bits(&gb, 7);
             put_bits(&pb, 8, v);
         }
@@ -381,14 +403,19 @@
     return 0;
 }
 
-static av_cold int encode_init_ls(AVCodecContext *ctx) {
-    JpeglsContext *c = (JpeglsContext*)ctx->priv_data;
+static av_cold int encode_init_ls(AVCodecContext *ctx)
+{
+    JpeglsContext *c = (JpeglsContext *)ctx->priv_data;
 
-    c->avctx = ctx;
+    c->avctx         = ctx;
     ctx->coded_frame = &c->picture;
 
-    if(ctx->pix_fmt != AV_PIX_FMT_GRAY8 && ctx->pix_fmt != AV_PIX_FMT_GRAY16 && ctx->pix_fmt != AV_PIX_FMT_RGB24 && ctx->pix_fmt != AV_PIX_FMT_BGR24){
-        av_log(ctx, AV_LOG_ERROR, "Only grayscale and RGB24/BGR24 images are supported\n");
+    if (ctx->pix_fmt != AV_PIX_FMT_GRAY8  &&
+        ctx->pix_fmt != AV_PIX_FMT_GRAY16 &&
+        ctx->pix_fmt != AV_PIX_FMT_RGB24  &&
+        ctx->pix_fmt != AV_PIX_FMT_BGR24) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Only grayscale and RGB24/BGR24 images are supported\n");
         return -1;
     }
     return 0;
@@ -396,14 +423,15 @@
 
 AVCodec ff_jpegls_encoder = {
     .name           = "jpegls",
+    .long_name      = NULL_IF_CONFIG_SMALL("JPEG-LS"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_JPEGLS,
     .priv_data_size = sizeof(JpeglsContext),
     .init           = encode_init_ls,
     .encode2        = encode_picture_ls,
-    .pix_fmts       = (const enum AVPixelFormat[]){
-        AV_PIX_FMT_BGR24, AV_PIX_FMT_RGB24, AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16,
+    .pix_fmts       = (const enum AVPixelFormat[]) {
+        AV_PIX_FMT_BGR24, AV_PIX_FMT_RGB24,
+        AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16,
         AV_PIX_FMT_NONE
     },
-    .long_name      = NULL_IF_CONFIG_SMALL("JPEG-LS"),
 };
diff --git a/libavcodec/jvdec.c b/libavcodec/jvdec.c
index 18cc73f..740884a 100644
--- a/libavcodec/jvdec.c
+++ b/libavcodec/jvdec.c
@@ -33,7 +33,7 @@
 
 typedef struct JvContext {
     DSPContext dsp;
-    AVFrame    frame;
+    AVFrame   *frame;
     uint32_t   palette[AVPALETTE_COUNT];
     int        palette_has_changed;
 } JvContext;
@@ -43,7 +43,9 @@
     JvContext *s = avctx->priv_data;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
     ff_dsputil_init(&s->dsp, avctx);
-    avcodec_get_frame_defaults(&s->frame);
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
     return 0;
 }
 
@@ -151,7 +153,7 @@
             av_log(avctx, AV_LOG_ERROR, "video size %d invalid\n", video_size);
             return AVERROR_INVALIDDATA;
         }
-        if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0)
+        if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
             return ret;
 
         if (video_type == 0 || video_type == 1) {
@@ -160,14 +162,14 @@
 
             for (j = 0; j < avctx->height; j += 8)
                 for (i = 0; i < avctx->width; i += 8)
-                    decode8x8(&gb, s->frame.data[0] + j*s->frame.linesize[0] + i,
-                              s->frame.linesize[0], &s->dsp);
+                    decode8x8(&gb, s->frame->data[0] + j * s->frame->linesize[0] + i,
+                              s->frame->linesize[0], &s->dsp);
 
             buf += video_size;
         } else if (video_type == 2) {
             int v = *buf++;
             for (j = 0; j < avctx->height; j++)
-                memset(s->frame.data[0] + j*s->frame.linesize[0], v, avctx->width);
+                memset(s->frame->data[0] + j * s->frame->linesize[0], v, avctx->width);
         } else {
             av_log(avctx, AV_LOG_WARNING, "unsupported frame type %i\n", video_type);
             return AVERROR_INVALIDDATA;
@@ -184,13 +186,13 @@
     }
 
     if (video_size) {
-        s->frame.key_frame           = 1;
-        s->frame.pict_type           = AV_PICTURE_TYPE_I;
-        s->frame.palette_has_changed = s->palette_has_changed;
+        s->frame->key_frame           = 1;
+        s->frame->pict_type           = AV_PICTURE_TYPE_I;
+        s->frame->palette_has_changed = s->palette_has_changed;
         s->palette_has_changed       = 0;
-        memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
+        memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE);
 
-        if ((ret = av_frame_ref(data, &s->frame)) < 0)
+        if ((ret = av_frame_ref(data, s->frame)) < 0)
             return ret;
         *got_frame = 1;
     }
@@ -202,7 +204,7 @@
 {
     JvContext *s = avctx->priv_data;
 
-    av_frame_unref(&s->frame);
+    av_frame_free(&s->frame);
 
     return 0;
 }
diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c
index 20aae67..0560c6e 100644
--- a/libavcodec/kmvc.c
+++ b/libavcodec/kmvc.c
@@ -30,6 +30,7 @@
 #include "avcodec.h"
 #include "bytestream.h"
 #include "internal.h"
+#include "libavutil/common.h"
 
 #define KMVC_KEYFRAME 0x80
 #define KMVC_PALETTE  0x40
@@ -46,7 +47,7 @@
     int palsize;
     uint32_t pal[MAX_PALSIZE];
     uint8_t *cur, *prev;
-    uint8_t *frm0, *frm1;
+    uint8_t frm0[320 * 200], frm1[320 * 200];
     GetByteContext g;
 } KmvcContext;
 
@@ -55,7 +56,7 @@
     int bitbuf;
 } BitBuf;
 
-#define BLK(data, x, y)  data[(x) + (y) * 320]
+#define BLK(data, x, y)  data[av_clip((x) + (y) * 320, 0, 320 * 200 -1)]
 
 #define kmvc_init_getbits(bb, g)  bb.bits = 7; bb.bitbuf = bytestream2_get_byte(g);
 
@@ -106,7 +107,7 @@
                             val = bytestream2_get_byte(&ctx->g);
                             mx = val & 0xF;
                             my = val >> 4;
-                            if ((l0x-mx) + 320*(l0y-my) < 0 || (l0x-mx) + 320*(l0y-my) > 316*196) {
+                            if ((l0x-mx) + 320*(l0y-my) < 0 || (l0x-mx) + 320*(l0y-my) > 320*197 - 4) {
                                 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
                                 return AVERROR_INVALIDDATA;
                             }
@@ -131,7 +132,7 @@
                                     val = bytestream2_get_byte(&ctx->g);
                                     mx = val & 0xF;
                                     my = val >> 4;
-                                    if ((l1x-mx) + 320*(l1y-my) < 0 || (l1x-mx) + 320*(l1y-my) > 318*198) {
+                                    if ((l1x-mx) + 320*(l1y-my) < 0 || (l1x-mx) + 320*(l1y-my) > 320*199 - 2) {
                                         av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
                                         return AVERROR_INVALIDDATA;
                                     }
@@ -206,7 +207,7 @@
                             val = bytestream2_get_byte(&ctx->g);
                             mx = (val & 0xF) - 8;
                             my = (val >> 4) - 8;
-                            if ((l0x+mx) + 320*(l0y+my) < 0 || (l0x+mx) + 320*(l0y+my) > 318*198) {
+                            if ((l0x+mx) + 320*(l0y+my) < 0 || (l0x+mx) + 320*(l0y+my) > 320*197 - 4) {
                                 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
                                 return AVERROR_INVALIDDATA;
                             }
@@ -231,7 +232,7 @@
                                     val = bytestream2_get_byte(&ctx->g);
                                     mx = (val & 0xF) - 8;
                                     my = (val >> 4) - 8;
-                                    if ((l1x+mx) + 320*(l1y+my) < 0 || (l1x+mx) + 320*(l1y+my) > 318*198) {
+                                    if ((l1x+mx) + 320*(l1y+my) < 0 || (l1x+mx) + 320*(l1y+my) > 320*199 - 2) {
                                         av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
                                         return AVERROR_INVALIDDATA;
                                     }
@@ -378,8 +379,6 @@
         return AVERROR(EINVAL);
     }
 
-    c->frm0 = av_mallocz(320 * 200);
-    c->frm1 = av_mallocz(320 * 200);
     c->cur = c->frm0;
     c->prev = c->frm1;
 
@@ -414,28 +413,12 @@
     return 0;
 }
 
-
-
-/*
- * Uninit kmvc decoder
- */
-static av_cold int decode_end(AVCodecContext * avctx)
-{
-    KmvcContext *const c = avctx->priv_data;
-
-    av_freep(&c->frm0);
-    av_freep(&c->frm1);
-
-    return 0;
-}
-
 AVCodec ff_kmvc_decoder = {
     .name           = "kmvc",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_KMVC,
     .priv_data_size = sizeof(KmvcContext),
     .init           = decode_init,
-    .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Karl Morton's video codec"),
diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c
index 8599784..4285644 100644
--- a/libavcodec/lagarith.c
+++ b/libavcodec/lagarith.c
@@ -556,6 +556,28 @@
             }
         }
         break;
+    case FRAME_SOLID_COLOR:
+        if (avctx->bits_per_coded_sample == 24) {
+            avctx->pix_fmt = AV_PIX_FMT_RGB24;
+        } else {
+            avctx->pix_fmt = AV_PIX_FMT_RGB32;
+            offset_gu |= 0xFFU << 24;
+        }
+
+        if ((ret = ff_thread_get_buffer(avctx, &frame,0)) < 0)
+            return ret;
+
+        dst = p->data[0];
+        for (j = 0; j < avctx->height; j++) {
+            for (i = 0; i < avctx->width; i++)
+                if (avctx->bits_per_coded_sample == 24) {
+                    AV_WB24(dst + i * 3, offset_gu);
+                } else {
+                    AV_WN32(dst + i * 4, offset_gu);
+                }
+            dst += p->linesize[0];
+        }
+        break;
     case FRAME_ARITH_RGBA:
         avctx->pix_fmt = AV_PIX_FMT_RGB32;
         planes = 4;
diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c
index 7948199..ad7ef91 100644
--- a/libavcodec/lcldec.c
+++ b/libavcodec/lcldec.c
@@ -42,6 +42,7 @@
 #include <stdlib.h>
 
 #include "libavutil/mem.h"
+#include "libavutil/pixdesc.h"
 #include "avcodec.h"
 #include "bytestream.h"
 #include "internal.h"
@@ -482,6 +483,7 @@
     unsigned int max_basesize = FFALIGN(avctx->width,  4) *
                                 FFALIGN(avctx->height, 4);
     unsigned int max_decomp_size;
+    int subsample_h, subsample_v;
 
     if (avctx->extradata_size < 8) {
         av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n");
@@ -507,6 +509,10 @@
         max_decomp_size = max_basesize * 2;
         avctx->pix_fmt = AV_PIX_FMT_YUV422P;
         av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:2.\n");
+        if (avctx->width % 4) {
+            avpriv_request_sample(avctx, "Unsupported dimensions\n");
+            return AVERROR_INVALIDDATA;
+        }
         break;
     case IMGTYPE_RGB24:
         c->decomp_size = basesize * 3;
@@ -537,6 +543,12 @@
         return AVERROR_INVALIDDATA;
     }
 
+    av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &subsample_h, &subsample_v);
+    if (avctx->width % (1<<subsample_h) || avctx->height % (1<<subsample_v)) {
+        avpriv_request_sample(avctx, "Unsupported dimensions\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     /* Detect compression method */
     c->compression = (int8_t)avctx->extradata[5];
     switch (avctx->codec_id) {
diff --git a/libavcodec/lclenc.c b/libavcodec/lclenc.c
index 09beb98..07f4d39 100644
--- a/libavcodec/lclenc.c
+++ b/libavcodec/lclenc.c
@@ -56,7 +56,6 @@
 typedef struct LclEncContext {
 
     AVCodecContext *avctx;
-    AVFrame pic;
 
     // Image type
     int imgtype;
@@ -73,20 +72,15 @@
  *
  */
 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
-                        const AVFrame *pict, int *got_packet)
+                        const AVFrame *p, int *got_packet)
 {
     LclEncContext *c = avctx->priv_data;
-    AVFrame * const p = &c->pic;
     int i, ret;
     int zret; // Zlib return code
     int max_size = deflateBound(&c->zstream, avctx->width * avctx->height * 3);
 
     if ((ret = ff_alloc_packet2(avctx, pkt, max_size)) < 0)
-            return ret;
-
-    *p = *pict;
-    p->pict_type= AV_PICTURE_TYPE_I;
-    p->key_frame= 1;
+        return ret;
 
     if(avctx->pix_fmt != AV_PIX_FMT_BGR24){
         av_log(avctx, AV_LOG_ERROR, "Format not supported!\n");
@@ -137,8 +131,9 @@
 
     av_assert0(avctx->width && avctx->height);
 
-    avctx->extradata= av_mallocz(8);
-    avctx->coded_frame= &c->pic;
+    avctx->extradata = av_mallocz(8 + FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!avctx->extradata)
+        return AVERROR(ENOMEM);
 
     c->compression = avctx->compression_level == FF_COMPRESSION_DEFAULT ?
                             COMP_ZLIB_NORMAL :
diff --git a/libavcodec/libaacplus.c b/libavcodec/libaacplus.c
index 68850c5..9c874fb 100644
--- a/libavcodec/libaacplus.c
+++ b/libavcodec/libaacplus.c
@@ -43,33 +43,31 @@
     /* number of channels */
     if (avctx->channels < 1 || avctx->channels > 2) {
         av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed\n", avctx->channels);
-        return -1;
+        return AVERROR(EINVAL);
+    }
+
+    if (avctx->profile != FF_PROFILE_AAC_LOW && avctx->profile != FF_PROFILE_UNKNOWN) {
+        av_log(avctx, AV_LOG_ERROR, "invalid AAC profile: %d, only LC supported\n", avctx->profile);
+        return AVERROR(EINVAL);
     }
 
     s->aacplus_handle = aacplusEncOpen(avctx->sample_rate, avctx->channels,
                                        &s->samples_input, &s->max_output_bytes);
-    if(!s->aacplus_handle) {
-            av_log(avctx, AV_LOG_ERROR, "can't open encoder\n");
-            return -1;
+    if (!s->aacplus_handle) {
+        av_log(avctx, AV_LOG_ERROR, "can't open encoder\n");
+        return AVERROR(EINVAL);
     }
 
     /* check aacplus version */
     aacplus_cfg = aacplusEncGetCurrentConfiguration(s->aacplus_handle);
 
-    /* put the options in the configuration struct */
-    if(avctx->profile != FF_PROFILE_AAC_LOW && avctx->profile != FF_PROFILE_UNKNOWN) {
-            av_log(avctx, AV_LOG_ERROR, "invalid AAC profile: %d, only LC supported\n", avctx->profile);
-            aacplusEncClose(s->aacplus_handle);
-            return -1;
-    }
-
     aacplus_cfg->bitRate = avctx->bit_rate;
     aacplus_cfg->bandWidth = avctx->cutoff;
     aacplus_cfg->outputFormat = !(avctx->flags & CODEC_FLAG_GLOBAL_HEADER);
     aacplus_cfg->inputFormat = avctx->sample_fmt == AV_SAMPLE_FMT_FLT ? AACPLUS_INPUT_FLOAT : AACPLUS_INPUT_16BIT;
     if (!aacplusEncSetConfiguration(s->aacplus_handle, aacplus_cfg)) {
         av_log(avctx, AV_LOG_ERROR, "libaacplus doesn't support this output format!\n");
-        return -1;
+        return AVERROR(EINVAL);
     }
 
     avctx->frame_size = s->samples_input / avctx->channels;
@@ -114,8 +112,8 @@
     aacPlusAudioContext *s = avctx->priv_data;
 
     av_freep(&avctx->extradata);
-
     aacplusEncClose(s->aacplus_handle);
+
     return 0;
 }
 
diff --git a/libavcodec/libfaac.c b/libavcodec/libfaac.c
index ac18fe2..f37e03a 100644
--- a/libavcodec/libfaac.c
+++ b/libavcodec/libfaac.c
@@ -151,9 +151,20 @@
     }
 
     if (!faacEncSetConfiguration(s->faac_handle, faac_cfg)) {
-        av_log(avctx, AV_LOG_ERROR, "libfaac doesn't support this output format!\n");
-        ret = AVERROR(EINVAL);
-        goto error;
+        int i;
+        for (i = avctx->bit_rate/1000; i ; i--) {
+            faac_cfg->bitRate = 1000*i / avctx->channels;
+            if (faacEncSetConfiguration(s->faac_handle, faac_cfg))
+                break;
+        }
+        if (!i) {
+            av_log(avctx, AV_LOG_ERROR, "libfaac doesn't support this output format!\n");
+            ret = AVERROR(EINVAL);
+            goto error;
+        } else {
+            avctx->bit_rate = 1000*i;
+            av_log(avctx, AV_LOG_WARNING, "libfaac doesn't support the specified bitrate, using %dkbit/s instead\n", i);
+        }
     }
 
     avctx->delay = FAAC_DELAY_SAMPLES;
diff --git a/libavcodec/libfdk-aacdec.c b/libavcodec/libfdk-aacdec.c
new file mode 100644
index 0000000..7b695e8
--- /dev/null
+++ b/libavcodec/libfdk-aacdec.c
@@ -0,0 +1,299 @@
+/*
+ * AAC decoder wrapper
+ * Copyright (c) 2012 Martin Storsjo
+ *
+ * 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
+ */
+
+#include <fdk-aac/aacdecoder_lib.h>
+
+#include "libavutil/channel_layout.h"
+#include "libavutil/common.h"
+#include "libavutil/opt.h"
+#include "avcodec.h"
+#include "internal.h"
+
+enum ConcealMethod {
+    CONCEAL_METHOD_DEFAULT              = -1,
+    CONCEAL_METHOD_SPECTRAL_MUTING      =  0,
+    CONCEAL_METHOD_NOISE_SUBSTITUTION   =  1,
+    CONCEAL_METHOD_ENERGY_INTERPOLATION =  2,
+    CONCEAL_METHOD_NB,
+};
+
+typedef struct FDKAACDecContext {
+    const AVClass *class;
+    HANDLE_AACDECODER handle;
+    int initialized;
+    enum ConcealMethod conceal_method;
+} FDKAACDecContext;
+
+#define OFFSET(x) offsetof(FDKAACDecContext, x)
+#define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+static const AVOption fdk_aac_dec_options[] = {
+    { "conceal", "Error concealment method", OFFSET(conceal_method), AV_OPT_TYPE_INT, { .i64 = CONCEAL_METHOD_DEFAULT }, CONCEAL_METHOD_DEFAULT, CONCEAL_METHOD_NB - 1, AD, "conceal" },
+    { "default",  "Default",              0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_DEFAULT },              INT_MIN, INT_MAX, AD, "conceal" },
+    { "spectral", "Spectral muting",      0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_SPECTRAL_MUTING },      INT_MIN, INT_MAX, AD, "conceal" },
+    { "noise",    "Noise Substitution",   0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_NOISE_SUBSTITUTION },   INT_MIN, INT_MAX, AD, "conceal" },
+    { "energy",   "Energy Interpolation", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_ENERGY_INTERPOLATION }, INT_MIN, INT_MAX, AD, "conceal" },
+    { NULL }
+};
+
+static const AVClass fdk_aac_dec_class = {
+    "libfdk-aac decoder", av_default_item_name, fdk_aac_dec_options, LIBAVUTIL_VERSION_INT
+};
+
+static int get_stream_info(AVCodecContext *avctx)
+{
+    FDKAACDecContext *s   = avctx->priv_data;
+    CStreamInfo *info     = aacDecoder_GetStreamInfo(s->handle);
+    int channel_counts[9] = { 0 };
+    int i, ch_error       = 0;
+    uint64_t ch_layout    = 0;
+
+    if (!info) {
+        av_log(avctx, AV_LOG_ERROR, "Unable to get stream info\n");
+        return AVERROR_UNKNOWN;
+    }
+
+    if (info->sampleRate <= 0) {
+        av_log(avctx, AV_LOG_ERROR, "Stream info not initialized\n");
+        return AVERROR_UNKNOWN;
+    }
+    avctx->sample_rate = info->sampleRate;
+    avctx->frame_size  = info->frameSize;
+
+    for (i = 0; i < info->numChannels; i++) {
+        AUDIO_CHANNEL_TYPE ctype = info->pChannelType[i];
+        if (ctype <= ACT_NONE || ctype > ACT_TOP) {
+            av_log(avctx, AV_LOG_WARNING, "unknown channel type\n");
+            break;
+        }
+        channel_counts[ctype]++;
+    }
+    av_log(avctx, AV_LOG_DEBUG, "%d channels - front:%d side:%d back:%d lfe:%d top:%d\n",
+           info->numChannels,
+           channel_counts[ACT_FRONT], channel_counts[ACT_SIDE],
+           channel_counts[ACT_BACK],  channel_counts[ACT_LFE],
+           channel_counts[ACT_FRONT_TOP] + channel_counts[ACT_SIDE_TOP] +
+           channel_counts[ACT_BACK_TOP] +  channel_counts[ACT_TOP]);
+
+    switch (channel_counts[ACT_FRONT]) {
+    case 4:
+        ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER;
+        break;
+    case 3:
+        ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER;
+        break;
+    case 2:
+        ch_layout |= AV_CH_LAYOUT_STEREO;
+        break;
+    case 1:
+        ch_layout |= AV_CH_FRONT_CENTER;
+        break;
+    default:
+        av_log(avctx, AV_LOG_WARNING, "unsupported number of front channels: %d\n",
+                channel_counts[ACT_FRONT]);
+        ch_error = 1;
+        break;
+    }
+    if (channel_counts[ACT_SIDE] > 0) {
+        if (channel_counts[ACT_SIDE] == 2) {
+            ch_layout |= AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT;
+        } else {
+            av_log(avctx, AV_LOG_WARNING, "unsupported number of side channels: %d\n",
+                   channel_counts[ACT_SIDE]);
+            ch_error = 1;
+        }
+    }
+    if (channel_counts[ACT_BACK] > 0) {
+        switch (channel_counts[ACT_BACK]) {
+        case 3:
+            ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_BACK_CENTER;
+            break;
+        case 2:
+            ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT;
+            break;
+        case 1:
+            ch_layout |= AV_CH_BACK_CENTER;
+            break;
+        default:
+            av_log(avctx, AV_LOG_WARNING, "unsupported number of back channels: %d\n",
+                    channel_counts[ACT_BACK]);
+            ch_error = 1;
+            break;
+        }
+    }
+    if (channel_counts[ACT_LFE] > 0) {
+        if (channel_counts[ACT_LFE] == 1) {
+            ch_layout |= AV_CH_LOW_FREQUENCY;
+        } else {
+            av_log(avctx, AV_LOG_WARNING, "unsupported number of LFE channels: %d\n",
+                   channel_counts[ACT_LFE]);
+            ch_error = 1;
+        }
+    }
+    if (!ch_error &&
+        av_get_channel_layout_nb_channels(ch_layout) != info->numChannels) {
+        av_log(avctx, AV_LOG_WARNING, "unsupported channel configuration\n");
+        ch_error = 1;
+    }
+    if (ch_error)
+        avctx->channel_layout = 0;
+    else
+        avctx->channel_layout = ch_layout;
+
+    avctx->channels = info->numChannels;
+
+    return 0;
+}
+
+static av_cold int fdk_aac_decode_close(AVCodecContext *avctx)
+{
+    FDKAACDecContext *s = avctx->priv_data;
+
+    if (s->handle)
+        aacDecoder_Close(s->handle);
+
+    return 0;
+}
+
+static av_cold int fdk_aac_decode_init(AVCodecContext *avctx)
+{
+    FDKAACDecContext *s = avctx->priv_data;
+    AAC_DECODER_ERROR err;
+
+    s->handle = aacDecoder_Open(avctx->extradata_size ? TT_MP4_RAW : TT_MP4_ADTS, 1);
+    if (!s->handle) {
+        av_log(avctx, AV_LOG_ERROR, "Error opening decoder\n");
+        return AVERROR_UNKNOWN;
+    }
+
+    if (avctx->extradata_size) {
+        if ((err = aacDecoder_ConfigRaw(s->handle, &avctx->extradata, &avctx->extradata_size)) != AAC_DEC_OK) {
+            av_log(avctx, AV_LOG_ERROR, "Unable to set extradata\n");
+            return AVERROR_INVALIDDATA;
+        }
+    }
+
+    if (s->conceal_method != CONCEAL_METHOD_DEFAULT) {
+        if ((err = aacDecoder_SetParam(s->handle, AAC_CONCEAL_METHOD, s->conceal_method)) != AAC_DEC_OK) {
+            av_log(avctx, AV_LOG_ERROR, "Unable to set error concealment method\n");
+            return AVERROR_UNKNOWN;
+        }
+    }
+
+    avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+    return 0;
+}
+
+static int fdk_aac_decode_frame(AVCodecContext *avctx, void *data,
+                                int *got_frame_ptr, AVPacket *avpkt)
+{
+    FDKAACDecContext *s = avctx->priv_data;
+    AVFrame *frame = data;
+    int ret;
+    AAC_DECODER_ERROR err;
+    UINT valid = avpkt->size;
+    uint8_t *buf, *tmpptr = NULL;
+    int buf_size;
+
+    err = aacDecoder_Fill(s->handle, &avpkt->data, &avpkt->size, &valid);
+    if (err != AAC_DEC_OK) {
+        av_log(avctx, AV_LOG_ERROR, "aacDecoder_Fill() failed: %x\n", err);
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (s->initialized) {
+        frame->nb_samples = avctx->frame_size;
+        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
+            av_log(avctx, AV_LOG_ERROR, "ff_get_buffer() failed\n");
+            return ret;
+        }
+        buf = frame->extended_data[0];
+        buf_size = avctx->channels * frame->nb_samples *
+                   av_get_bytes_per_sample(avctx->sample_fmt);
+    } else {
+        buf_size = 50 * 1024;
+        buf = tmpptr = av_malloc(buf_size);
+        if (!buf)
+            return AVERROR(ENOMEM);
+    }
+
+    err = aacDecoder_DecodeFrame(s->handle, (INT_PCM *) buf, buf_size, 0);
+    if (err == AAC_DEC_NOT_ENOUGH_BITS) {
+        ret = avpkt->size - valid;
+        goto end;
+    }
+    if (err != AAC_DEC_OK) {
+        av_log(avctx, AV_LOG_ERROR, "aacDecoder_DecodeFrame() failed: %x\n", err);
+        ret = AVERROR_UNKNOWN;
+        goto end;
+    }
+
+    if (!s->initialized) {
+        if ((ret = get_stream_info(avctx)) < 0)
+            goto end;
+        s->initialized = 1;
+        frame->nb_samples = avctx->frame_size;
+    }
+
+    if (tmpptr) {
+        frame->nb_samples = avctx->frame_size;
+        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
+            av_log(avctx, AV_LOG_ERROR, "ff_get_buffer() failed\n");
+            goto end;
+        }
+        memcpy(frame->extended_data[0], tmpptr,
+               avctx->channels * avctx->frame_size *
+               av_get_bytes_per_sample(avctx->sample_fmt));
+    }
+
+    *got_frame_ptr = 1;
+    ret = avpkt->size - valid;
+
+end:
+    av_free(tmpptr);
+    return ret;
+}
+
+static av_cold void fdk_aac_decode_flush(AVCodecContext *avctx)
+{
+    FDKAACDecContext *s = avctx->priv_data;
+    AAC_DECODER_ERROR err;
+
+    if (!s->handle)
+        return;
+
+    if ((err = aacDecoder_SetParam(s->handle, AAC_TPDEC_CLEAR_BUFFER, 1)) != AAC_DEC_OK)
+        av_log(avctx, AV_LOG_WARNING, "failed to clear buffer when flushing\n");
+}
+
+AVCodec ff_libfdk_aac_decoder = {
+    .name           = "libfdk_aac",
+    .long_name      = NULL_IF_CONFIG_SMALL("Fraunhofer FDK AAC"),
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_AAC,
+    .priv_data_size = sizeof(FDKAACDecContext),
+    .init           = fdk_aac_decode_init,
+    .decode         = fdk_aac_decode_frame,
+    .close          = fdk_aac_decode_close,
+    .flush          = fdk_aac_decode_flush,
+    .capabilities   = CODEC_CAP_DR1,
+    .priv_class     = &fdk_aac_dec_class,
+};
diff --git a/libavcodec/libfdk-aacenc.c b/libavcodec/libfdk-aacenc.c
index e3992e1..034701a 100644
--- a/libavcodec/libfdk-aacenc.c
+++ b/libavcodec/libfdk-aacenc.c
@@ -197,6 +197,7 @@
             avctx->bit_rate = (96*sce + 128*cpe) * avctx->sample_rate / 44;
             if (avctx->profile == FF_PROFILE_AAC_HE ||
                 avctx->profile == FF_PROFILE_AAC_HE_V2 ||
+                avctx->profile == FF_PROFILE_MPEG2_AAC_HE ||
                 s->eld_sbr)
                 avctx->bit_rate /= 2;
         }
diff --git a/libavcodec/libopencore-amr.c b/libavcodec/libopencore-amr.c
index c991106..391ac25 100644
--- a/libavcodec/libopencore-amr.c
+++ b/libavcodec/libopencore-amr.c
@@ -180,7 +180,7 @@
     { NULL }
 };
 
-static const AVClass class = {
+static const AVClass amrnb_class = {
     "libopencore_amrnb", av_default_item_name, options, LIBAVUTIL_VERSION_INT
 };
 
@@ -291,7 +291,7 @@
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("OpenCORE AMR-NB (Adaptive Multi-Rate Narrow-Band)"),
-    .priv_class     = &class,
+    .priv_class     = &amrnb_class,
 };
 #endif /* CONFIG_LIBOPENCORE_AMRNB_ENCODER */
 
diff --git a/libavcodec/libopenjpegdec.c b/libavcodec/libopenjpegdec.c
index ec6e275..c331b59 100644
--- a/libavcodec/libopenjpegdec.c
+++ b/libavcodec/libopenjpegdec.c
@@ -392,7 +392,7 @@
     { NULL },
 };
 
-static const AVClass class = {
+static const AVClass openjpeg_class = {
     .class_name = "libopenjpeg",
     .item_name  = av_default_item_name,
     .option     = options,
@@ -409,5 +409,5 @@
     .capabilities     = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
     .max_lowres       = 31,
     .long_name        = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"),
-    .priv_class       = &class,
+    .priv_class       = &openjpeg_class,
 };
diff --git a/libavcodec/libopenjpegenc.c b/libavcodec/libopenjpegenc.c
index c355083..957cabf 100644
--- a/libavcodec/libopenjpegenc.c
+++ b/libavcodec/libopenjpegenc.c
@@ -106,6 +106,7 @@
     case AV_PIX_FMT_GBRP12:
     case AV_PIX_FMT_GBRP14:
     case AV_PIX_FMT_GBRP16:
+    case AV_PIX_FMT_XYZ12:
         color_space = CLRSPC_SRGB;
         break;
     case AV_PIX_FMT_YUV410P:
@@ -280,6 +281,38 @@
     return 1;
 }
 
+// for XYZ 12 bit
+static int libopenjpeg_copy_packed12(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
+{
+    int compno;
+    int x;
+    int y;
+    int image_index;
+    int frame_index;
+    const int numcomps = image->numcomps;
+    uint16_t *frame_ptr = (uint16_t*)frame->data[0];
+
+    for (compno = 0; compno < numcomps; ++compno) {
+        if (image->comps[compno].w > frame->linesize[0] / numcomps) {
+            av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
+            return 0;
+        }
+    }
+
+    for (compno = 0; compno < numcomps; ++compno) {
+        for (y = 0; y < avctx->height; ++y) {
+            image_index = y * avctx->width;
+            frame_index = y * (frame->linesize[0] / 2) + compno;
+            for (x = 0; x < avctx->width; ++x) {
+                image->comps[compno].data[image_index++] = frame_ptr[frame_index] >> 4;
+                frame_index += numcomps;
+            }
+        }
+    }
+
+    return 1;
+}
+
 static int libopenjpeg_copy_packed16(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
 {
     int compno;
@@ -401,6 +434,9 @@
     case AV_PIX_FMT_GRAY8A:
         cpyresult = libopenjpeg_copy_packed8(avctx, frame, image);
         break;
+    case AV_PIX_FMT_XYZ12:
+        cpyresult = libopenjpeg_copy_packed12(avctx, frame, image);
+        break;
     case AV_PIX_FMT_RGB48:
     case AV_PIX_FMT_RGBA64:
         cpyresult = libopenjpeg_copy_packed16(avctx, frame, image);
@@ -542,7 +578,7 @@
     { NULL },
 };
 
-static const AVClass class = {
+static const AVClass openjpeg_class = {
     .class_name = "libopenjpeg",
     .item_name  = av_default_item_name,
     .option     = options,
@@ -574,8 +610,9 @@
         AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14,
         AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16,
         AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16,
+        AV_PIX_FMT_XYZ12,
         AV_PIX_FMT_NONE
     },
     .long_name      = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"),
-    .priv_class     = &class,
+    .priv_class     = &openjpeg_class,
 };
diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c
index 04c297d..59caac7 100644
--- a/libavcodec/libopusenc.c
+++ b/libavcodec/libopusenc.c
@@ -156,7 +156,7 @@
     return OPUS_OK;
 }
 
-static int av_cold libopus_encode_init(AVCodecContext *avctx)
+static av_cold int libopus_encode_init(AVCodecContext *avctx)
 {
     LibopusEncContext *opus = avctx->priv_data;
     const uint8_t *channel_mapping;
@@ -359,7 +359,7 @@
     return 0;
 }
 
-static int av_cold libopus_encode_close(AVCodecContext *avctx)
+static av_cold int libopus_encode_close(AVCodecContext *avctx)
 {
     LibopusEncContext *opus = avctx->priv_data;
 
diff --git a/libavcodec/libschroedinger.c b/libavcodec/libschroedinger.c
index f452d70..9f0b25c 100644
--- a/libavcodec/libschroedinger.c
+++ b/libavcodec/libschroedinger.c
@@ -23,8 +23,9 @@
 * function definitions common to libschroedinger decoder and encoder
 */
 
-#include "libschroedinger.h"
+#include "libavutil/attributes.h"
 #include "libavutil/mem.h"
+#include "libschroedinger.h"
 
 static const SchroVideoFormatInfo ff_schro_video_format_info[] = {
     { 640,  480,  24000, 1001},
@@ -66,7 +67,7 @@
     return ret_idx;
 }
 
-void ff_schro_queue_init(FFSchroQueue *queue)
+av_cold void ff_schro_queue_init(FFSchroQueue *queue)
 {
     queue->p_head = queue->p_tail = NULL;
     queue->size = 0;
diff --git a/libavcodec/libschroedingerenc.c b/libavcodec/libschroedingerenc.c
index 297c6c5..21af65e 100644
--- a/libavcodec/libschroedingerenc.c
+++ b/libavcodec/libschroedingerenc.c
@@ -31,6 +31,7 @@
 #include <schroedinger/schrodebug.h>
 #include <schroedinger/schrovideoformat.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "internal.h"
@@ -100,7 +101,7 @@
     return -1;
 }
 
-static int libschroedinger_encode_init(AVCodecContext *avctx)
+static av_cold int libschroedinger_encode_init(AVCodecContext *avctx)
 {
     SchroEncoderParams *p_schro_params = avctx->priv_data;
     SchroVideoFormatEnum preset;
diff --git a/libavcodec/libshine.c b/libavcodec/libshine.c
index 521ac17..cf8b1bb 100644
--- a/libavcodec/libshine.c
+++ b/libavcodec/libshine.c
@@ -50,17 +50,17 @@
     shine_set_config_mpeg_defaults(&s->config.mpeg);
     if (avctx->bit_rate)
         s->config.mpeg.bitr = avctx->bit_rate / 1000;
-    if (shine_find_bitrate_index(s->config.mpeg.bitr) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "invalid bitrate\n");
-        return AVERROR(EINVAL);
-    }
     s->config.mpeg.mode = avctx->channels == 2 ? STEREO : MONO;
     s->config.wave.samplerate = avctx->sample_rate;
     s->config.wave.channels   = avctx->channels == 2 ? PCM_STEREO : PCM_MONO;
+    if (shine_check_config(s->config.wave.samplerate, s->config.mpeg.bitr) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "invalid configuration\n");
+        return AVERROR(EINVAL);
+    }
     s->shine = shine_initialise(&s->config);
     if (!s->shine)
         return AVERROR(ENOMEM);
-    avctx->frame_size = samp_per_frame;
+    avctx->frame_size = shine_samples_per_pass(s->shine);
     ff_af_queue_init(avctx, &s->afq);
     return 0;
 }
@@ -75,7 +75,7 @@
     int ret, len;
 
     if (frame)
-        data = shine_encode_frame(s->shine, frame->data[0], &written);
+        data = shine_encode_buffer(s->shine, (int16_t **)frame->data, &written);
     else
         data = shine_flush(s->shine, &written);
     if (written < 0)
diff --git a/libavcodec/libspeexenc.c b/libavcodec/libspeexenc.c
index b96ca1b..5be5d69 100644
--- a/libavcodec/libspeexenc.c
+++ b/libavcodec/libspeexenc.c
@@ -334,7 +334,7 @@
     { NULL },
 };
 
-static const AVClass class = {
+static const AVClass speex_class = {
     .class_name = "libspeex",
     .item_name  = av_default_item_name,
     .option     = options,
@@ -363,6 +363,6 @@
                                            0 },
     .supported_samplerates = (const int[]){ 8000, 16000, 32000, 0 },
     .long_name      = NULL_IF_CONFIG_SMALL("libspeex Speex"),
-    .priv_class     = &class,
+    .priv_class     = &speex_class,
     .defaults       = defaults,
 };
diff --git a/libavcodec/libstagefright.cpp b/libavcodec/libstagefright.cpp
index a6fd1b9..bb49d8a 100644
--- a/libavcodec/libstagefright.cpp
+++ b/libavcodec/libstagefright.cpp
@@ -36,6 +36,7 @@
 extern "C" {
 #include "avcodec.h"
 #include "libavutil/imgutils.h"
+#include "internal.h"
 }
 
 #define OMX_QCOM_COLOR_FormatYVU420SemiPlanar 0x7FA30C00
@@ -185,7 +186,7 @@
                 buffer->release();
                 goto push_frame;
             }
-            ret = ff_get_buffer(avctx, frame->vframe);
+            ret = ff_get_buffer(avctx, frame->vframe, AV_GET_BUFFER_FLAG_REF);
             if (ret < 0) {
                 frame->status = ret;
                 decode_done   = 1;
@@ -456,10 +457,8 @@
         return -1;
     }
 
-    if (s->prev_frame) {
-        avctx->release_buffer(avctx, s->prev_frame);
-        av_freep(&s->prev_frame);
-    }
+    if (s->prev_frame)
+        av_frame_free(&s->prev_frame);
     s->prev_frame = ret_frame;
 
     *got_frame = 1;
@@ -481,10 +480,8 @@
             while (!s->out_queue->empty()) {
                 frame = *s->out_queue->begin();
                 s->out_queue->erase(s->out_queue->begin());
-                if (frame->vframe) {
-                    avctx->release_buffer(avctx, frame->vframe);
-                    av_freep(&frame->vframe);
-                }
+                if (frame->vframe)
+                    av_frame_free(&frame->vframe);
                 av_freep(&frame);
             }
             pthread_mutex_unlock(&s->out_mutex);
@@ -514,10 +511,8 @@
 
         pthread_join(s->decode_thread_id, NULL);
 
-        if (s->prev_frame) {
-            avctx->release_buffer(avctx, s->prev_frame);
-            av_freep(&s->prev_frame);
-        }
+        if (s->prev_frame)
+            av_frame_free(&s->prev_frame);
 
         s->thread_started = false;
     }
@@ -533,10 +528,8 @@
     while (!s->out_queue->empty()) {
         frame = *s->out_queue->begin();
         s->out_queue->erase(s->out_queue->begin());
-        if (frame->vframe) {
-            avctx->release_buffer(avctx, frame->vframe);
-            av_freep(&frame->vframe);
-        }
+        if (frame->vframe)
+            av_frame_free(&frame->vframe);
         av_freep(&frame);
     }
 
diff --git a/libavcodec/libtwolame.c b/libavcodec/libtwolame.c
index 8858714..bc93433 100644
--- a/libavcodec/libtwolame.c
+++ b/libavcodec/libtwolame.c
@@ -67,6 +67,8 @@
     twolame_set_psymodel(s->glopts, s->psymodel);
     twolame_set_energy_levels(s->glopts, s->energy);
     twolame_set_error_protection(s->glopts, s->error_protection);
+    twolame_set_copyright(s->glopts, s->copyright);
+    twolame_set_original(s->glopts, s->original);
 
     twolame_set_num_channels(s->glopts, avctx->channels);
     twolame_set_in_samplerate(s->glopts, avctx->sample_rate);
diff --git a/libavcodec/libutvideo.h b/libavcodec/libutvideo.h
index b35d19c..5fb1174 100644
--- a/libavcodec/libutvideo.h
+++ b/libavcodec/libutvideo.h
@@ -21,7 +21,8 @@
 /**
  * @file
  * Known FOURCCs:
- *     'ULY0' (YCbCr 4:2:0), 'ULY2' (YCbCr 4:2:2), 'ULRG' (RGB), 'ULRA' (RGBA)
+ *     'ULY0' (YCbCr 4:2:0), 'ULY2' (YCbCr 4:2:2), 'ULRG' (RGB), 'ULRA' (RGBA),
+ *     'ULH0' (YCbCr 4:2:0 BT.709), 'ULH2' (YCbCr 4:2:2 BT.709)
  */
 
 #ifndef AVCODEC_LIBUTVIDEO_H
@@ -45,6 +46,14 @@
 #define UTVF_NFCC_BGRA_BU UTVF_RGB32_WIN
 #endif
 
+/*
+ * Ut Video version 13.0.1 introduced new BT.709 variants.
+ * Special-case these and only use them if v13 is detected.
+ */
+#if defined(UTVF_HDYC)
+#define UTV_BT709
+#endif
+
 typedef struct {
     uint32_t version;
     uint32_t original_format;
diff --git a/libavcodec/libutvideodec.cpp b/libavcodec/libutvideodec.cpp
index bc491e2..0fae9f7 100644
--- a/libavcodec/libutvideodec.cpp
+++ b/libavcodec/libutvideodec.cpp
@@ -21,7 +21,8 @@
 /**
  * @file
  * Known FOURCCs:
- *     'ULY0' (YCbCr 4:2:0), 'ULY2' (YCbCr 4:2:2), 'ULRG' (RGB), 'ULRA' (RGBA)
+ *     'ULY0' (YCbCr 4:2:0), 'ULY2' (YCbCr 4:2:2), 'ULRG' (RGB), 'ULRA' (RGBA),
+ *     'ULH0' (YCbCr 4:2:0 BT.709), 'ULH2' (YCbCr 4:2:2 BT.709)
  */
 
 extern "C" {
@@ -51,6 +52,18 @@
 
     /* Pick format based on FOURCC */
     switch (avctx->codec_tag) {
+#ifdef UTV_BT709
+    case MKTAG('U', 'L', 'H', '0'):
+        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+        avctx->colorspace = AVCOL_SPC_BT709;
+        format = UTVF_YV12;
+        break;
+    case MKTAG('U', 'L', 'H', '2'):
+        avctx->pix_fmt = AV_PIX_FMT_YUYV422;
+        avctx->colorspace = AVCOL_SPC_BT709;
+        format = UTVF_YUY2;
+        break;
+#endif
     case MKTAG('U', 'L', 'Y', '0'):
         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
         format = UTVF_YV12;
diff --git a/libavcodec/libutvideoenc.cpp b/libavcodec/libutvideoenc.cpp
index 07205f7..44cd42f 100644
--- a/libavcodec/libutvideoenc.cpp
+++ b/libavcodec/libutvideoenc.cpp
@@ -21,7 +21,8 @@
 /**
  * @file
  * Known FOURCCs:
- *     'ULY0' (YCbCr 4:2:0), 'ULY2' (YCbCr 4:2:2), 'ULRG' (RGB), 'ULRA' (RGBA)
+ *     'ULY0' (YCbCr 4:2:0), 'ULY2' (YCbCr 4:2:2), 'ULRG' (RGB), 'ULRA' (RGBA),
+ *     'ULH0' (YCbCr 4:2:0 BT.709), 'ULH2' (YCbCr 4:2:2 BT.709)
  */
 
 extern "C" {
diff --git a/libavcodec/libvo-amrwbenc.c b/libavcodec/libvo-amrwbenc.c
index a068cd0..f12cfb6 100644
--- a/libavcodec/libvo-amrwbenc.c
+++ b/libavcodec/libvo-amrwbenc.c
@@ -45,7 +45,7 @@
     { NULL }
 };
 
-static const AVClass class = {
+static const AVClass amrwb_class = {
     "libvo_amrwbenc", av_default_item_name, options, LIBAVUTIL_VERSION_INT
 };
 
@@ -148,5 +148,5 @@
                                                      AV_SAMPLE_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("Android VisualOn AMR-WB "
                                            "(Adaptive Multi-Rate Wide-Band)"),
-    .priv_class     = &class,
+    .priv_class     = &amrwb_class,
 };
diff --git a/libavcodec/libvorbisenc.c b/libavcodec/libvorbisenc.c
index d3f86cc..d7fded8 100644
--- a/libavcodec/libvorbisenc.c
+++ b/libavcodec/libvorbisenc.c
@@ -64,7 +64,7 @@
     { NULL },
 };
 
-static const AVClass class = {
+static const AVClass vorbis_class = {
     .class_name = "libvorbis",
     .item_name  = av_default_item_name,
     .option     = options,
@@ -373,6 +373,6 @@
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("libvorbis"),
-    .priv_class     = &class,
+    .priv_class     = &vorbis_class,
     .defaults       = defaults,
 };
diff --git a/libavcodec/libvpxdec.c b/libavcodec/libvpxdec.c
index 5e80a9f..be97428 100644
--- a/libavcodec/libvpxdec.c
+++ b/libavcodec/libvpxdec.c
@@ -96,7 +96,7 @@
         }
         if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
             return ret;
-        av_image_copy(picture->data, picture->linesize, img->planes,
+        av_image_copy(picture->data, picture->linesize, (const uint8_t **)img->planes,
                       img->stride, avctx->pix_fmt, img->d_w, img->d_h);
         *got_frame           = 1;
     }
diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index 4f1adb8..5f3c32a 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -33,6 +33,7 @@
 #include "libavutil/avassert.h"
 #include "libavutil/base64.h"
 #include "libavutil/common.h"
+#include "libavutil/intreadwrite.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
 
@@ -43,6 +44,8 @@
 struct FrameListData {
     void *buf;                       /**< compressed data buffer */
     size_t sz;                       /**< length of compressed data */
+    void *buf_alpha;
+    size_t sz_alpha;
     int64_t pts;                     /**< time stamp to show frame
                                           (in timebase units) */
     unsigned long duration;          /**< duration to show frame
@@ -58,6 +61,9 @@
     AVClass *class;
     struct vpx_codec_ctx encoder;
     struct vpx_image rawimg;
+    struct vpx_codec_ctx encoder_alpha;
+    struct vpx_image rawimg_alpha;
+    uint8_t is_alpha;
     struct vpx_fixed_buf twopass_stats;
     int deadline; //i.e., RT/GOOD/BEST
     uint64_t sse[4];
@@ -186,6 +192,8 @@
 static av_cold void free_coded_frame(struct FrameListData *cx_frame)
 {
     av_freep(&cx_frame->buf);
+    if (cx_frame->buf_alpha)
+        av_freep(&cx_frame->buf_alpha);
     av_freep(&cx_frame);
 }
 
@@ -226,6 +234,8 @@
     VP8Context *ctx = avctx->priv_data;
 
     vpx_codec_destroy(&ctx->encoder);
+    if (ctx->is_alpha)
+        vpx_codec_destroy(&ctx->encoder_alpha);
     av_freep(&ctx->twopass_stats.buf);
     av_freep(&avctx->coded_frame);
     av_freep(&avctx->stats_out);
@@ -238,12 +248,16 @@
 {
     VP8Context *ctx = avctx->priv_data;
     struct vpx_codec_enc_cfg enccfg;
+    struct vpx_codec_enc_cfg enccfg_alpha;
     vpx_codec_flags_t flags = (avctx->flags & CODEC_FLAG_PSNR) ? VPX_CODEC_USE_PSNR : 0;
     int res;
 
     av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str());
     av_log(avctx, AV_LOG_VERBOSE, "%s\n", vpx_codec_build_config());
 
+    if (avctx->pix_fmt == AV_PIX_FMT_YUVA420P)
+        ctx->is_alpha = 1;
+
     if ((res = vpx_codec_enc_config_default(iface, &enccfg, 0)) != VPX_CODEC_OK) {
         av_log(avctx, AV_LOG_ERROR, "Failed to get config: %s\n",
                vpx_codec_err_to_string(res));
@@ -377,6 +391,15 @@
         return AVERROR(EINVAL);
     }
 
+    if (ctx->is_alpha) {
+        enccfg_alpha = enccfg;
+        res = vpx_codec_enc_init(&ctx->encoder_alpha, iface, &enccfg_alpha, flags);
+        if (res != VPX_CODEC_OK) {
+            log_encoder_error(avctx, "Failed to initialize alpha encoder");
+            return AVERROR(EINVAL);
+        }
+    }
+
     //codec control failures are currently treated only as warnings
     av_log(avctx, AV_LOG_DEBUG, "vpx_codec_control\n");
     if (ctx->cpu_used != INT_MIN)
@@ -404,6 +427,10 @@
     vpx_img_wrap(&ctx->rawimg, VPX_IMG_FMT_I420, avctx->width, avctx->height, 1,
                  (unsigned char*)1);
 
+    if (ctx->is_alpha)
+        vpx_img_wrap(&ctx->rawimg_alpha, VPX_IMG_FMT_I420, avctx->width, avctx->height, 1,
+                     (unsigned char*)1);
+
     avctx->coded_frame = avcodec_alloc_frame();
     if (!avctx->coded_frame) {
         av_log(avctx, AV_LOG_ERROR, "Error allocating coded frame\n");
@@ -415,6 +442,7 @@
 
 static inline void cx_pktcpy(struct FrameListData *dst,
                              const struct vpx_codec_cx_pkt *src,
+                             const struct vpx_codec_cx_pkt *src_alpha,
                              VP8Context *ctx)
 {
     dst->pts      = src->data.frame.pts;
@@ -438,6 +466,14 @@
     } else {
         dst->frame_number = -1;   /* sanity marker */
     }
+    if (src_alpha) {
+        dst->buf_alpha = src_alpha->data.frame.buf;
+        dst->sz_alpha = src_alpha->data.frame.sz;
+    }
+    else {
+        dst->buf_alpha = NULL;
+        dst->sz_alpha = 0;
+    }
 }
 
 /**
@@ -451,6 +487,7 @@
                       AVPacket *pkt, AVFrame *coded_frame)
 {
     int ret = ff_alloc_packet2(avctx, pkt, cx_frame->sz);
+    uint8_t *side_data;
     if (ret >= 0) {
         memcpy(pkt->data, cx_frame->buf, pkt->size);
         pkt->pts = pkt->dts    = cx_frame->pts;
@@ -475,6 +512,18 @@
             }
             cx_frame->have_sse = 0;
         }
+        if (cx_frame->sz_alpha > 0) {
+            side_data = av_packet_new_side_data(pkt,
+                                                AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
+                                                cx_frame->sz_alpha + 8);
+            if(side_data == NULL) {
+                av_free_packet(pkt);
+                av_free(pkt);
+                return AVERROR(ENOMEM);
+            }
+            AV_WB64(side_data, 1);
+            memcpy(side_data + 8, cx_frame->buf_alpha, cx_frame->sz_alpha);
+        }
     } else {
         return ret;
     }
@@ -494,7 +543,9 @@
 {
     VP8Context *ctx = avctx->priv_data;
     const struct vpx_codec_cx_pkt *pkt;
+    const struct vpx_codec_cx_pkt *pkt_alpha = NULL;
     const void *iter = NULL;
+    const void *iter_alpha = NULL;
     int size = 0;
 
     if (ctx->coded_frame_list) {
@@ -509,7 +560,9 @@
 
     /* consume all available output from the encoder before returning. buffers
        are only good through the next vpx_codec call */
-    while ((pkt = vpx_codec_get_cx_data(&ctx->encoder, &iter))) {
+    while ((pkt = vpx_codec_get_cx_data(&ctx->encoder, &iter)) &&
+            (!ctx->is_alpha ||
+             (ctx->is_alpha && (pkt_alpha = vpx_codec_get_cx_data(&ctx->encoder_alpha, &iter_alpha))))) {
         switch (pkt->kind) {
         case VPX_CODEC_CX_FRAME_PKT:
             if (!size) {
@@ -518,7 +571,7 @@
                 /* avoid storing the frame when the list is empty and we haven't yet
                    provided a frame for output */
                 av_assert0(!ctx->coded_frame_list);
-                cx_pktcpy(&cx_frame, pkt, ctx);
+                cx_pktcpy(&cx_frame, pkt, pkt_alpha, ctx);
                 size = storeframe(avctx, &cx_frame, pkt_out, coded_frame);
                 if (size < 0)
                     return size;
@@ -531,7 +584,7 @@
                            "Frame queue element alloc failed\n");
                     return AVERROR(ENOMEM);
                 }
-                cx_pktcpy(cx_frame, pkt, ctx);
+                cx_pktcpy(cx_frame, pkt, pkt_alpha, ctx);
                 cx_frame->buf = av_malloc(cx_frame->sz);
 
                 if (!cx_frame->buf) {
@@ -542,6 +595,17 @@
                     return AVERROR(ENOMEM);
                 }
                 memcpy(cx_frame->buf, pkt->data.frame.buf, pkt->data.frame.sz);
+                if (ctx->is_alpha) {
+                    cx_frame->buf_alpha = av_malloc(cx_frame->sz_alpha);
+                    if (!cx_frame->buf_alpha) {
+                        av_log(avctx, AV_LOG_ERROR,
+                               "Data buffer alloc (%zu bytes) failed\n",
+                               cx_frame->sz_alpha);
+                        av_free(cx_frame);
+                        return AVERROR(ENOMEM);
+                    }
+                    memcpy(cx_frame->buf_alpha, pkt_alpha->data.frame.buf, pkt_alpha->data.frame.sz);
+                }
                 coded_frame_add(&ctx->coded_frame_list, cx_frame);
             }
             break;
@@ -580,6 +644,7 @@
 {
     VP8Context *ctx = avctx->priv_data;
     struct vpx_image *rawimg = NULL;
+    struct vpx_image *rawimg_alpha = NULL;
     int64_t timestamp = 0;
     int res, coded_size;
     vpx_enc_frame_flags_t flags = 0;
@@ -592,6 +657,20 @@
         rawimg->stride[VPX_PLANE_Y] = frame->linesize[0];
         rawimg->stride[VPX_PLANE_U] = frame->linesize[1];
         rawimg->stride[VPX_PLANE_V] = frame->linesize[2];
+        if (ctx->is_alpha) {
+            uint8_t *u_plane, *v_plane;
+            rawimg_alpha = &ctx->rawimg_alpha;
+            rawimg_alpha->planes[VPX_PLANE_Y] = frame->data[3];
+            u_plane = av_malloc(frame->linesize[1] * frame->height);
+            memset(u_plane, 0x80, frame->linesize[1] * frame->height);
+            rawimg_alpha->planes[VPX_PLANE_U] = u_plane;
+            v_plane = av_malloc(frame->linesize[2] * frame->height);
+            memset(v_plane, 0x80, frame->linesize[2] * frame->height);
+            rawimg_alpha->planes[VPX_PLANE_V] = v_plane;
+            rawimg_alpha->stride[VPX_PLANE_Y] = frame->linesize[0];
+            rawimg_alpha->stride[VPX_PLANE_U] = frame->linesize[1];
+            rawimg_alpha->stride[VPX_PLANE_V] = frame->linesize[2];
+        }
         timestamp                   = frame->pts;
         if (frame->pict_type == AV_PICTURE_TYPE_I)
             flags |= VPX_EFLAG_FORCE_KF;
@@ -603,6 +682,16 @@
         log_encoder_error(avctx, "Error encoding frame");
         return AVERROR_INVALIDDATA;
     }
+
+    if (ctx->is_alpha) {
+        res = vpx_codec_encode(&ctx->encoder_alpha, rawimg_alpha, timestamp,
+                               avctx->ticks_per_frame, flags, ctx->deadline);
+        if (res != VPX_CODEC_OK) {
+            log_encoder_error(avctx, "Error encoding alpha frame");
+            return AVERROR_INVALIDDATA;
+        }
+    }
+
     coded_size = queue_frames(avctx, pkt, avctx->coded_frame);
 
     if (!frame && avctx->flags & CODEC_FLAG_PASS1) {
@@ -618,6 +707,11 @@
                          ctx->twopass_stats.sz);
     }
 
+    if (rawimg_alpha) {
+        av_free(rawimg_alpha->planes[VPX_PLANE_U]);
+        av_free(rawimg_alpha->planes[VPX_PLANE_V]);
+    }
+
     *got_packet = !!coded_size;
     return 0;
 }
@@ -677,7 +771,7 @@
 }
 
 static const AVClass class_vp8 = {
-    .class_name = "libvpx encoder",
+    .class_name = "libvpx-vp8 encoder",
     .item_name  = av_default_item_name,
     .option     = options,
     .version    = LIBAVUTIL_VERSION_INT,
@@ -692,7 +786,7 @@
     .encode2        = vp8_encode,
     .close          = vp8_free,
     .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS,
-    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
+    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("libvpx VP8"),
     .priv_class     = &class_vp8,
     .defaults       = defaults,
@@ -706,7 +800,7 @@
 }
 
 static const AVClass class_vp9 = {
-    .class_name = "libvpx encoder",
+    .class_name = "libvpx-vp9 encoder",
     .item_name  = av_default_item_name,
     .option     = options,
     .version    = LIBAVUTIL_VERSION_INT,
diff --git a/libavcodec/libwavpackenc.c b/libavcodec/libwavpackenc.c
new file mode 100644
index 0000000..77d98a2
--- /dev/null
+++ b/libavcodec/libwavpackenc.c
@@ -0,0 +1,194 @@
+/*
+ * 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
+ */
+
+#include <wavpack/wavpack.h>
+#include <string.h>
+
+#include "libavutil/attributes.h"
+#include "libavutil/opt.h"
+#include "libavutil/samplefmt.h"
+
+#include "audio_frame_queue.h"
+#include "avcodec.h"
+#include "internal.h"
+
+#define WV_DEFAULT_BLOCK_SIZE 32768
+
+typedef struct LibWavpackContext {
+    const AVClass *class;
+    WavpackContext *wv;
+    AudioFrameQueue afq;
+
+    AVPacket *pkt;
+    int user_size;
+
+    int got_output;
+} LibWavpackContext;
+
+static int wavpack_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+                                const AVFrame *frame, int *got_output)
+{
+    LibWavpackContext *s = avctx->priv_data;
+    int ret;
+
+    s->got_output = 0;
+    s->pkt        = pkt;
+    s->user_size  = pkt->size;
+
+    if (frame) {
+        ret = ff_af_queue_add(&s->afq, frame);
+        if (ret < 0)
+            return ret;
+
+        ret = WavpackPackSamples(s->wv, (int32_t*)frame->data[0], frame->nb_samples);
+        if (!ret) {
+            av_log(avctx, AV_LOG_ERROR, "Error encoding a frame: %s\n",
+                   WavpackGetErrorMessage(s->wv));
+            return AVERROR_UNKNOWN;
+        }
+    }
+
+    if (!s->got_output &&
+        (!frame || frame->nb_samples < avctx->frame_size)) {
+        ret = WavpackFlushSamples(s->wv);
+        if (!ret) {
+            av_log(avctx, AV_LOG_ERROR, "Error flushing the encoder: %s\n",
+                   WavpackGetErrorMessage(s->wv));
+            return AVERROR_UNKNOWN;
+        }
+    }
+
+    if (s->got_output) {
+        ff_af_queue_remove(&s->afq, avctx->frame_size, &pkt->pts, &pkt->duration);
+        *got_output = 1;
+    }
+
+    return 0;
+}
+
+static int encode_callback(void *id, void *data, int32_t count)
+{
+    AVCodecContext *avctx = id;
+    LibWavpackContext *s  = avctx->priv_data;
+    int ret, offset = s->pkt->size;
+
+    if (s->user_size) {
+        if (s->user_size - count < s->pkt->size) {
+            av_log(avctx, AV_LOG_ERROR, "Provided packet too small.\n");
+            return 0;
+        }
+        s->pkt->size += count;
+    } else {
+        ret = av_grow_packet(s->pkt, count);
+        if (ret < 0) {
+            av_log(avctx, AV_LOG_ERROR, "Error allocating output packet.\n");
+            return 0;
+        }
+    }
+
+    memcpy(s->pkt->data + offset, data, count);
+
+    s->got_output = 1;
+
+    return 1;
+}
+
+static av_cold int wavpack_encode_init(AVCodecContext *avctx)
+{
+    LibWavpackContext *s = avctx->priv_data;
+    WavpackConfig config = { 0 };
+    int ret;
+
+    s->wv = WavpackOpenFileOutput(encode_callback, avctx, NULL);
+    if (!s->wv) {
+        av_log(avctx, AV_LOG_ERROR, "Error allocating the encoder.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    if (!avctx->frame_size)
+        avctx->frame_size = WV_DEFAULT_BLOCK_SIZE;
+
+    config.bytes_per_sample = 4;
+    config.bits_per_sample  = 32;
+    config.block_samples    = avctx->frame_size;
+    config.channel_mask     = avctx->channel_layout;
+    config.num_channels     = avctx->channels;
+    config.sample_rate      = avctx->sample_rate;
+
+    if (avctx->compression_level != FF_COMPRESSION_DEFAULT) {
+        if (avctx->compression_level >= 3) {
+            config.flags |= CONFIG_VERY_HIGH_FLAG;
+
+            if      (avctx->compression_level >= 8)
+                config.xmode = 6;
+            else if (avctx->compression_level >= 7)
+                config.xmode = 5;
+            else if (avctx->compression_level >= 6)
+                config.xmode = 4;
+            else if (avctx->compression_level >= 5)
+                config.xmode = 3;
+            else if (avctx->compression_level >= 4)
+                config.xmode = 2;
+        } else if (avctx->compression_level >= 2)
+            config.flags |= CONFIG_HIGH_FLAG;
+        else if (avctx->compression_level < 1)
+            config.flags |= CONFIG_FAST_FLAG;
+    }
+
+    ret = WavpackSetConfiguration(s->wv, &config, -1);
+    if (!ret)
+        goto fail;
+
+    ret = WavpackPackInit(s->wv);
+    if (!ret)
+        goto fail;
+
+    ff_af_queue_init(avctx, &s->afq);
+
+    return 0;
+
+fail:
+    av_log(avctx, AV_LOG_ERROR, "Error configuring the encoder: %s.\n",
+           WavpackGetErrorMessage(s->wv));
+    WavpackCloseFile(s->wv);
+    return AVERROR_UNKNOWN;
+}
+
+static av_cold int wavpack_encode_close(AVCodecContext *avctx)
+{
+    LibWavpackContext *s = avctx->priv_data;
+
+    WavpackCloseFile(s->wv);
+
+    ff_af_queue_close(&s->afq);
+
+    return 0;
+}
+
+AVCodec ff_libwavpack_encoder = {
+    .name           = "libwavpack",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_WAVPACK,
+    .priv_data_size = sizeof(LibWavpackContext),
+    .init           = wavpack_encode_init,
+    .encode2        = wavpack_encode_frame,
+    .close          = wavpack_encode_close,
+    .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_SMALL_LAST_FRAME,
+    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32,
+                                                     AV_SAMPLE_FMT_NONE },
+};
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 7e8fa65..ea7e905 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -25,6 +25,11 @@
 #include "libavutil/pixdesc.h"
 #include "avcodec.h"
 #include "internal.h"
+
+#if defined(_MSC_VER)
+#define X264_API_IMPORTS 1
+#endif
+
 #include <x264.h>
 #include <float.h>
 #include <math.h>
@@ -59,6 +64,7 @@
     int weightb;
     int ssim;
     int intra_refresh;
+    int bluray_compat;
     int b_bias;
     int b_pyramid;
     int mixed_refs;
@@ -155,7 +161,7 @@
     X264Context *x4 = ctx->priv_data;
     x264_nal_t *nal;
     int nnal, i, ret;
-    x264_picture_t pic_out;
+    x264_picture_t pic_out = {0};
 
     x264_picture_init( &x4->pic );
     x4->pic.img.i_csp   = x4->params.i_csp;
@@ -237,7 +243,7 @@
 #define OPT_STR(opt, param)                                                   \
     do {                                                                      \
         int ret;                                                              \
-        if (param && (ret = x264_param_parse(&x4->params, opt, param)) < 0) { \
+        if (param!=NULL && (ret = x264_param_parse(&x4->params, opt, param)) < 0) { \
             if(ret == X264_PARAM_BAD_NAME)                                    \
                 av_log(avctx, AV_LOG_ERROR,                                   \
                         "bad option '%s': '%s'\n", opt, param);               \
@@ -428,6 +434,10 @@
         x4->params.analyse.b_ssim = x4->ssim;
     if (x4->intra_refresh >= 0)
         x4->params.b_intra_refresh = x4->intra_refresh;
+    if (x4->bluray_compat >= 0) {
+        x4->params.b_bluray_compat = x4->bluray_compat;
+        x4->params.b_vfr_input = 0;
+    }
     if (x4->b_bias != INT_MIN)
         x4->params.i_bframe_bias              = x4->b_bias;
     if (x4->b_pyramid >= 0)
@@ -646,6 +656,7 @@
     { "smart",         NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_WEIGHTP_SMART},  INT_MIN, INT_MAX, VE, "weightp" },
     { "ssim",          "Calculate and print SSIM stats.",                 OFFSET(ssim),          AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, 1, VE },
     { "intra-refresh", "Use Periodic Intra Refresh instead of IDR frames.",OFFSET(intra_refresh),AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, 1, VE },
+    { "bluray-compat", "Bluray compatibility workarounds.",               OFFSET(bluray_compat) ,AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, 1, VE },
     { "b-bias",        "Influences how often B-frames are used",          OFFSET(b_bias),        AV_OPT_TYPE_INT,    { .i64 = INT_MIN}, INT_MIN, INT_MAX, VE },
     { "b-pyramid",     "Keep some B-frames as references.",               OFFSET(b_pyramid),     AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, INT_MAX, VE, "b_pyramid" },
     { "none",          NULL,                                  0, AV_OPT_TYPE_CONST, {.i64 = X264_B_PYRAMID_NONE},   INT_MIN, INT_MAX, VE, "b_pyramid" },
@@ -676,7 +687,7 @@
     { NULL },
 };
 
-static const AVClass class = {
+static const AVClass x264_class = {
     .class_name = "libx264",
     .item_name  = av_default_item_name,
     .option     = options,
@@ -730,7 +741,7 @@
     .close            = X264_close,
     .capabilities     = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS,
     .long_name        = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
-    .priv_class       = &class,
+    .priv_class       = &x264_class,
     .defaults         = x264_defaults,
     .init_static_data = X264_init_static,
 };
@@ -743,7 +754,7 @@
     .init           = X264_init,
     .encode2        = X264_frame,
     .close          = X264_close,
-    .capabilities   = CODEC_CAP_DELAY,
+    .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS,
     .long_name      = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 RGB"),
     .priv_class     = &rgbclass,
     .defaults       = x264_defaults,
diff --git a/libavcodec/libxavs.c b/libavcodec/libxavs.c
index 442fc0ee..fad0a54 100644
--- a/libavcodec/libxavs.c
+++ b/libavcodec/libxavs.c
@@ -404,7 +404,7 @@
     { NULL },
 };
 
-static const AVClass class = {
+static const AVClass xavs_class = {
     .class_name = "libxavs",
     .item_name  = av_default_item_name,
     .option     = options,
@@ -427,6 +427,6 @@
     .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS,
     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("libxavs Chinese AVS (Audio Video Standard)"),
-    .priv_class     = &class,
+    .priv_class     = &xavs_class,
     .defaults       = xavs_defaults,
 };
diff --git a/libavcodec/libxvid.c b/libavcodec/libxvid.c
index 05a12db..d2190c8 100644
--- a/libavcodec/libxvid.c
+++ b/libavcodec/libxvid.c
@@ -63,6 +63,10 @@
     int twopassfd;
     unsigned char *intra_matrix;   /**< P-Frame Quant Matrix */
     unsigned char *inter_matrix;   /**< I-Frame Quant Matrix */
+    int lumi_aq;                   /**< Lumi masking as an aq method */
+    int variance_aq;               /**< Variance adaptive quantization */
+    int ssim;                      /**< SSIM information display mode */
+    int ssim_acc;                  /**< SSIM accuracy. 0: accurate. 4: fast. */
 };
 
 /**
@@ -352,45 +356,47 @@
     uint16_t *intra, *inter;
     int fd;
 
-    xvid_plugin_single_t single       = { 0 };
-    struct xvid_ff_pass1 rc2pass1     = { 0 };
-    xvid_plugin_2pass2_t rc2pass2     = { 0 };
-    xvid_gbl_init_t xvid_gbl_init     = { 0 };
-    xvid_enc_create_t xvid_enc_create = { 0 };
-    xvid_enc_plugin_t plugins[7];
+    xvid_plugin_single_t      single          = { 0 };
+    struct xvid_ff_pass1      rc2pass1        = { 0 };
+    xvid_plugin_2pass2_t      rc2pass2        = { 0 };
+    xvid_plugin_lumimasking_t masking_l       = { 0 }; /* For lumi masking */
+    xvid_plugin_lumimasking_t masking_v       = { 0 }; /* For variance AQ */
+    xvid_plugin_ssim_t        ssim            = { 0 };
+    xvid_gbl_init_t           xvid_gbl_init   = { 0 };
+    xvid_enc_create_t         xvid_enc_create = { 0 };
+    xvid_enc_plugin_t         plugins[4];
 
     x->twopassfd = -1;
 
     /* Bring in VOP flags from ffmpeg command-line */
-    x->vop_flags = XVID_VOP_HALFPEL; /* Bare minimum quality */
+    x->vop_flags = XVID_VOP_HALFPEL;              /* Bare minimum quality */
     if( xvid_flags & CODEC_FLAG_4MV )
-        x->vop_flags |= XVID_VOP_INTER4V; /* Level 3 */
-    if( avctx->trellis
-        )
-        x->vop_flags |= XVID_VOP_TRELLISQUANT; /* Level 5 */
+        x->vop_flags    |= XVID_VOP_INTER4V;      /* Level 3 */
+    if( avctx->trellis)
+        x->vop_flags    |= XVID_VOP_TRELLISQUANT; /* Level 5 */
     if( xvid_flags & CODEC_FLAG_AC_PRED )
-        x->vop_flags |= XVID_VOP_HQACPRED; /* Level 6 */
+        x->vop_flags    |= XVID_VOP_HQACPRED;     /* Level 6 */
     if( xvid_flags & CODEC_FLAG_GRAY )
-        x->vop_flags |= XVID_VOP_GREYSCALE;
+        x->vop_flags    |= XVID_VOP_GREYSCALE;
 
     /* Decide which ME quality setting to use */
     x->me_flags = 0;
     switch( avctx->me_method ) {
        case ME_FULL:   /* Quality 6 */
-           x->me_flags |=  XVID_ME_EXTSEARCH16
-                       |   XVID_ME_EXTSEARCH8;
+           x->me_flags  |=  XVID_ME_EXTSEARCH16
+                        |   XVID_ME_EXTSEARCH8;
 
        case ME_EPZS:   /* Quality 4 */
-           x->me_flags |=  XVID_ME_ADVANCEDDIAMOND8
-                       |   XVID_ME_HALFPELREFINE8
-                       |   XVID_ME_CHROMA_PVOP
-                       |   XVID_ME_CHROMA_BVOP;
+           x->me_flags  |=  XVID_ME_ADVANCEDDIAMOND8
+                        |   XVID_ME_HALFPELREFINE8
+                        |   XVID_ME_CHROMA_PVOP
+                        |   XVID_ME_CHROMA_BVOP;
 
        case ME_LOG:    /* Quality 2 */
        case ME_PHODS:
        case ME_X1:
-           x->me_flags |=  XVID_ME_ADVANCEDDIAMOND16
-                       |   XVID_ME_HALFPELREFINE16;
+           x->me_flags  |=  XVID_ME_ADVANCEDDIAMOND16
+                        |   XVID_ME_HALFPELREFINE16;
 
        case ME_ZERO:   /* Quality 0 */
        default:
@@ -401,15 +407,15 @@
     switch( avctx->mb_decision ) {
        case 2:
            x->vop_flags |= XVID_VOP_MODEDECISION_RD;
-           x->me_flags |=  XVID_ME_HALFPELREFINE8_RD
-                       |   XVID_ME_QUARTERPELREFINE8_RD
-                       |   XVID_ME_EXTSEARCH_RD
-                       |   XVID_ME_CHECKPREDICTION_RD;
+           x->me_flags  |=  XVID_ME_HALFPELREFINE8_RD
+                        |   XVID_ME_QUARTERPELREFINE8_RD
+                        |   XVID_ME_EXTSEARCH_RD
+                        |   XVID_ME_CHECKPREDICTION_RD;
        case 1:
            if( !(x->vop_flags & XVID_VOP_MODEDECISION_RD) )
                x->vop_flags |= XVID_VOP_FAST_MODEDECISION_RD;
-           x->me_flags |=  XVID_ME_HALFPELREFINE16_RD
-                       |   XVID_ME_QUARTERPELREFINE16_RD;
+           x->me_flags  |=  XVID_ME_HALFPELREFINE16_RD
+                        |   XVID_ME_QUARTERPELREFINE16_RD;
 
        default:
            break;
@@ -418,12 +424,12 @@
     /* Bring in VOL flags from ffmpeg command-line */
     x->vol_flags = 0;
     if( xvid_flags & CODEC_FLAG_GMC ) {
-        x->vol_flags |= XVID_VOL_GMC;
-        x->me_flags |= XVID_ME_GME_REFINE;
+        x->vol_flags    |= XVID_VOL_GMC;
+        x->me_flags     |= XVID_ME_GME_REFINE;
     }
     if( xvid_flags & CODEC_FLAG_QPEL ) {
-        x->vol_flags |= XVID_VOL_QUARTERPEL;
-        x->me_flags |= XVID_ME_QUARTERPELREFINE16;
+        x->vol_flags    |= XVID_VOL_QUARTERPEL;
+        x->me_flags     |= XVID_ME_QUARTERPELREFINE16;
         if( x->vop_flags & XVID_VOP_INTER4V )
             x->me_flags |= XVID_ME_QUARTERPELREFINE8;
     }
@@ -525,10 +531,41 @@
         xvid_enc_create.num_plugins++;
     }
 
+    if ( avctx->lumi_masking != 0.0)
+        x->lumi_aq = 1;
+
     /* Luminance Masking */
-    if( 0.0 != avctx->lumi_masking ) {
+    if( x->lumi_aq ) {
+        masking_l.method = 0;
         plugins[xvid_enc_create.num_plugins].func = xvid_plugin_lumimasking;
-        plugins[xvid_enc_create.num_plugins].param = NULL;
+
+        /* The old behavior is that when avctx->lumi_masking is specified,
+         * plugins[...].param = NULL. Trying to keep the old behavior here. */
+        plugins[xvid_enc_create.num_plugins].param = avctx->lumi_masking ? NULL : &masking_l ;
+        xvid_enc_create.num_plugins++;
+    }
+
+    /* Variance AQ */
+    if( x->variance_aq ) {
+        masking_v.method = 1;
+        plugins[xvid_enc_create.num_plugins].func  = xvid_plugin_lumimasking;
+        plugins[xvid_enc_create.num_plugins].param = &masking_v ;
+        xvid_enc_create.num_plugins++;
+    }
+
+    if( x->lumi_aq && x->variance_aq )
+        av_log(avctx, AV_LOG_INFO,
+               "Both lumi_aq and variance_aq are enabled. The resulting quality"
+               "will be the worse one of the two effects made by the AQ.\n");
+
+    /* SSIM */
+    if( x->ssim ) {
+        plugins[xvid_enc_create.num_plugins].func = xvid_plugin_ssim;
+        ssim.b_printstat = ( x->ssim == 2 );
+        ssim.acc         = x->ssim_acc;
+        ssim.cpu_flags   = xvid_gbl_init.cpu_flags;
+        ssim.b_visualize = 0;
+        plugins[xvid_enc_create.num_plugins].param = &ssim;
         xvid_enc_create.num_plugins++;
     }
 
@@ -604,6 +641,8 @@
     xvid_enc_create.bquant_ratio = 100 * avctx->b_quant_factor;
     if( avctx->max_b_frames > 0  && !x->quicktime_format ) xvid_enc_create.global |= XVID_GLOBAL_PACKED;
 
+    av_assert0(xvid_enc_create.num_plugins + (!!x->ssim) + (!!x->variance_aq) + (!!x->lumi_aq) <= FF_ARRAY_ELEMS(plugins));
+
     /* Create encoder context */
     xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL);
     if( xerr ) {
@@ -762,6 +801,26 @@
     return 0;
 }
 
+#define OFFSET(x) offsetof(struct xvid_context, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    { "lumi_aq",     "Luminance masking AQ", OFFSET(lumi_aq),     AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
+    { "variance_aq", "Variance AQ",          OFFSET(variance_aq), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
+    { "ssim",        "Show SSIM information to stdout",       OFFSET(ssim),              AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, VE, "ssim" },
+        { "off",     NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "ssim" },
+        { "avg",     NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "ssim" },
+        { "frame",   NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "ssim" },
+    { "ssim_acc",    "SSIM accuracy",                         OFFSET(ssim_acc),          AV_OPT_TYPE_INT, { .i64 = 2 }, 0, 4, VE },
+    { NULL },
+};
+
+static const AVClass xvid_class = {
+    .class_name = "libxvid",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_libxvid_encoder = {
     .name           = "libxvid",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -772,4 +831,5 @@
     .close          = xvid_encode_close,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("libxvidcore MPEG-4 part 2"),
+    .priv_class     = &xvid_class,
 };
diff --git a/libavcodec/libxvid_rc.c b/libavcodec/libxvid_rc.c
index 4a5842f..5da435b 100644
--- a/libavcodec/libxvid_rc.c
+++ b/libavcodec/libxvid_rc.c
@@ -23,6 +23,7 @@
 #include "config.h"
 #include <xvid.h>
 #include <unistd.h>
+#include "libavutil/attributes.h"
 #include "libavutil/file.h"
 #include "avcodec.h"
 #include "libxvid.h"
@@ -31,7 +32,8 @@
 #undef NDEBUG
 #include <assert.h>
 
-int ff_xvid_rate_control_init(MpegEncContext *s){
+av_cold int ff_xvid_rate_control_init(MpegEncContext *s)
+{
     char *tmp_name;
     int fd, i;
     xvid_plg_create_t xvid_plg_create = { 0 };
@@ -134,7 +136,8 @@
         return xvid_plg_data.quant * FF_QP2LAMBDA;
 }
 
-void ff_xvid_rate_control_uninit(MpegEncContext *s){
+av_cold void ff_xvid_rate_control_uninit(MpegEncContext *s)
+{
     xvid_plg_destroy_t xvid_plg_destroy;
 
     xvid_plugin_2pass2(s->rc_context.non_lavc_opaque, XVID_PLG_DESTROY, &xvid_plg_destroy, NULL);
diff --git a/libavcodec/loco.c b/libavcodec/loco.c
index ffb9742..81a93c8 100644
--- a/libavcodec/loco.c
+++ b/libavcodec/loco.c
@@ -135,7 +135,7 @@
     if(buf_size<=0)
         return -1;
 
-    init_get_bits(&rc.gb, buf, buf_size*8);
+    init_get_bits8(&rc.gb, buf, buf_size);
     rc.save  = 0;
     rc.run   = 0;
     rc.run2  = 0;
diff --git a/libavcodec/lpc.c b/libavcodec/lpc.c
index 4149135..1d52edf 100644
--- a/libavcodec/lpc.c
+++ b/libavcodec/lpc.c
@@ -177,11 +177,12 @@
     double autoc[MAX_LPC_ORDER+1];
     double ref[MAX_LPC_ORDER];
     double lpc[MAX_LPC_ORDER][MAX_LPC_ORDER];
-    int i, j, pass;
+    int i, j, pass = 0;
     int opt_order;
 
     av_assert2(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER &&
            lpc_type > FF_LPC_TYPE_FIXED);
+    av_assert0(lpc_type == FF_LPC_TYPE_CHOLESKY || lpc_type == FF_LPC_TYPE_LEVINSON);
 
     /* reinit LPC context if parameters have changed */
     if (blocksize != s->blocksize || max_order != s->max_order ||
@@ -190,7 +191,10 @@
         ff_lpc_init(s, blocksize, max_order, lpc_type);
     }
 
-    if (lpc_type == FF_LPC_TYPE_LEVINSON) {
+    if(lpc_passes <= 0)
+        lpc_passes = 2;
+
+    if (lpc_type == FF_LPC_TYPE_LEVINSON || (lpc_type == FF_LPC_TYPE_CHOLESKY && lpc_passes > 1)) {
         s->lpc_apply_welch_window(samples, blocksize, s->windowed_samples);
 
         s->lpc_compute_autocorr(s->windowed_samples, blocksize, max_order, autoc);
@@ -199,14 +203,20 @@
 
         for(i=0; i<max_order; i++)
             ref[i] = fabs(lpc[i][i]);
-    } else if (lpc_type == FF_LPC_TYPE_CHOLESKY) {
+
+        pass++;
+    }
+
+    if (lpc_type == FF_LPC_TYPE_CHOLESKY) {
         LLSModel m[2];
-        double var[MAX_LPC_ORDER+1], av_uninit(weight);
+        LOCAL_ALIGNED(32, double, var, [FFALIGN(MAX_LPC_ORDER+1,4)]);
+        double av_uninit(weight);
+        memset(var, 0, FFALIGN(MAX_LPC_ORDER+1,4)*sizeof(*var));
 
-        if(lpc_passes <= 0)
-            lpc_passes = 2;
+        for(j=0; j<max_order; j++)
+            m[0].coeff[max_order-1][j] = -lpc[max_order-1][j];
 
-        for(pass=0; pass<lpc_passes; pass++){
+        for(; pass<lpc_passes; pass++){
             avpriv_init_lls(&m[pass&1], max_order);
 
             weight=0;
@@ -216,7 +226,7 @@
 
                 if(pass){
                     double eval, inv, rinv;
-                    eval= avpriv_evaluate_lls(&m[(pass-1)&1], var+1, max_order-1);
+                    eval= m[pass&1].evaluate_lls(&m[(pass-1)&1], var+1, max_order-1);
                     eval= (512>>pass) + fabs(eval - var[0]);
                     inv = 1/eval;
                     rinv = sqrt(inv);
@@ -226,7 +236,7 @@
                 }else
                     weight++;
 
-                avpriv_update_lls(&m[pass&1], var, 1.0);
+                m[pass&1].update_lls(&m[pass&1], var);
             }
             avpriv_solve_lls(&m[pass&1], 0.001, 0);
         }
@@ -238,8 +248,8 @@
         }
         for(i=max_order-1; i>0; i--)
             ref[i] = ref[i-1] - ref[i];
-    } else
-        av_assert0(0);
+    }
+
     opt_order = max_order;
 
     if(omethod == ORDER_METHOD_EST) {
@@ -262,15 +272,11 @@
     s->max_order = max_order;
     s->lpc_type  = lpc_type;
 
-    if (lpc_type == FF_LPC_TYPE_LEVINSON) {
-        s->windowed_buffer = av_mallocz((blocksize + 2 + FFALIGN(max_order, 4)) *
-                                        sizeof(*s->windowed_samples));
-        if (!s->windowed_buffer)
-            return AVERROR(ENOMEM);
-        s->windowed_samples = s->windowed_buffer + FFALIGN(max_order, 4);
-    } else {
-        s->windowed_samples = NULL;
-    }
+    s->windowed_buffer = av_mallocz((blocksize + 2 + FFALIGN(max_order, 4)) *
+                                    sizeof(*s->windowed_samples));
+    if (!s->windowed_buffer)
+        return AVERROR(ENOMEM);
+    s->windowed_samples = s->windowed_buffer + FFALIGN(max_order, 4);
 
     s->lpc_apply_welch_window = lpc_apply_welch_window_c;
     s->lpc_compute_autocorr   = lpc_compute_autocorr_c;
diff --git a/libavcodec/lpc.h b/libavcodec/lpc.h
index 8fa56ad..c323230 100644
--- a/libavcodec/lpc.h
+++ b/libavcodec/lpc.h
@@ -67,7 +67,7 @@
     /**
      * Perform autocorrelation on input samples with delay of 0 to lag.
      * @param data  input samples.
-     *              constraints: no alignment needed, but must have have at
+     *              constraints: no alignment needed, but must have at
      *              least lag*sizeof(double) valid bytes preceding it, and
      *              size must be at least (len+1)*sizeof(double) if data is
      *              16-byte aligned or (len+2)*sizeof(double) if data is
diff --git a/libavcodec/lzwenc.c b/libavcodec/lzwenc.c
index 7e30765..d5a07bc 100644
--- a/libavcodec/lzwenc.c
+++ b/libavcodec/lzwenc.c
@@ -111,7 +111,7 @@
  */
 static inline void writeCode(LZWEncodeState * s, int c)
 {
-    assert(0 <= c && c < 1 << s->bits);
+    av_assert2(0 <= c && c < 1 << s->bits);
     s->put_bits(&s->pb, s->bits, c);
 }
 
@@ -207,7 +207,7 @@
     s->maxbits = maxbits;
     init_put_bits(&s->pb, outbuf, outsize);
     s->bufsize = outsize;
-    assert(s->maxbits >= 9 && s->maxbits <= LZW_MAXBITS);
+    av_assert0(s->maxbits >= 9 && s->maxbits <= LZW_MAXBITS);
     s->maxcode = 1 << s->maxbits;
     s->output_bytes = 0;
     s->last_code = LZW_PREFIX_EMPTY;
@@ -262,6 +262,9 @@
     if (s->last_code != -1)
         writeCode(s, s->last_code);
     writeCode(s, s->end_code);
+    if (s->mode == FF_LZW_GIF)
+        s->put_bits(&s->pb, 1, 0);
+
     lzw_flush_put_bits(&s->pb);
     s->last_code = -1;
 
diff --git a/libavcodec/mathops.h b/libavcodec/mathops.h
index 592f5a5..1d57342 100644
--- a/libavcodec/mathops.h
+++ b/libavcodec/mathops.h
@@ -195,6 +195,15 @@
 #   define FASTDIV(a,b) ((uint32_t)((((uint64_t)a) * ff_inverse[b]) >> 32))
 #endif /* FASTDIV */
 
+#ifndef MOD_UNLIKELY
+#   define MOD_UNLIKELY(modulus, dividend, divisor, prev_dividend) \
+    do { \
+        if ((prev_dividend) == 0 || (dividend) - (prev_dividend) != (divisor)) \
+            (modulus) = (dividend) % (divisor); \
+        (prev_dividend) = (dividend); \
+    } while (0)
+#endif
+
 static inline av_const unsigned int ff_sqrt(unsigned int a)
 {
     unsigned int b;
diff --git a/libavcodec/mdct.c b/libavcodec/mdct.c
index 2232024..922d577 100644
--- a/libavcodec/mdct.c
+++ b/libavcodec/mdct.c
@@ -34,7 +34,11 @@
 #if CONFIG_FFT_FLOAT
 #   define RSCALE(x) (x)
 #else
+#if CONFIG_FFT_FIXED_32
+#   define RSCALE(x) (((x) + 32) >> 6)
+#else /* CONFIG_FFT_FIXED_32 */
 #   define RSCALE(x) ((x) >> 1)
+#endif /* CONFIG_FFT_FIXED_32 */
 #endif
 
 /**
diff --git a/libavcodec/mdct_fixed.c b/libavcodec/mdct_fixed.c
index 794a3e0..33a266d 100644
--- a/libavcodec/mdct_fixed.c
+++ b/libavcodec/mdct_fixed.c
@@ -17,6 +17,7 @@
  */
 
 #define CONFIG_FFT_FLOAT 0
+#define CONFIG_FFT_FIXED_32 0
 #include "mdct.c"
 
 /* same as ff_mdct_calcw_c with double-width unscaled output */
diff --git a/libavcodec/mips/fft_table.h b/libavcodec/mdct_fixed_32.c
similarity index 83%
copy from libavcodec/mips/fft_table.h
copy to libavcodec/mdct_fixed_32.c
index dd52eaf..66226f3 100644
--- a/libavcodec/mips/fft_table.h
+++ b/libavcodec/mdct_fixed_32.c
@@ -26,7 +26,9 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * Author:  Stanislav Ocovaj (socovaj@mips.com)
+ * Authors:  Stanislav Ocovaj (socovaj@mips.com)
+ *           Goran Cordasic   (goran@mips.com)
+ *           Djordje Pesut    (djordje@mips.com)
  *
  * This file is part of FFmpeg.
  *
@@ -45,19 +47,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-/**
- * @file
- * definitions and LUT table for MIPS FFT
- */
-#ifndef AVCODEC_MIPS_FFT_TABLE_H
-#define AVCODEC_MIPS_FFT_TABLE_H
-
-#include "libavcodec/fft.h"
-
-#define MAX_LOG2_NFFT 16 //!< Specifies maxiumum allowed fft size
-#define MAX_FFT_SIZE (1 << MAX_LOG2_NFFT)
-
-extern uint16_t fft_offsets_lut[];
-void ff_fft_lut_init(uint16_t *table, int off, int size, int *index);
-
-#endif /* AVCODEC_MIPS_FFT_TABLE_H */
+#define CONFIG_FFT_FLOAT 0
+#define CONFIG_FFT_FIXED_32 1
+#include "mdct.c"
diff --git a/libavcodec/mdct_float.c b/libavcodec/mdct_float.c
index ec4f486..fec18ba 100644
--- a/libavcodec/mdct_float.c
+++ b/libavcodec/mdct_float.c
@@ -17,4 +17,5 @@
  */
 
 #define CONFIG_FFT_FLOAT 1
+#define CONFIG_FFT_FIXED_32 0
 #include "mdct.c"
diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c
index 8fb29ce..9211fe7 100644
--- a/libavcodec/mdec.c
+++ b/libavcodec/mdec.c
@@ -121,7 +121,7 @@
 static inline int decode_mb(MDECContext *a, int16_t block[6][64])
 {
     int i, ret;
-    const int block_index[6] = { 5, 4, 0, 1, 2, 3 };
+    static const int block_index[6] = { 5, 4, 0, 1, 2, 3 };
 
     a->dsp.clear_blocks(block[0]);
 
@@ -177,7 +177,8 @@
         a->bitstream_buffer[i]     = buf[i + 1];
         a->bitstream_buffer[i + 1] = buf[i];
     }
-    init_get_bits(&a->gb, a->bitstream_buffer, buf_size * 8);
+    if ((ret = init_get_bits8(&a->gb, a->bitstream_buffer, buf_size)) < 0)
+        return ret;
 
     /* skip over 4 preamble bytes in stream (typically 0xXX 0xXX 0x00 0x38) */
     skip_bits(&a->gb, 32);
diff --git a/libavcodec/metasound.c b/libavcodec/metasound.c
new file mode 100644
index 0000000..cc221cc
--- /dev/null
+++ b/libavcodec/metasound.c
@@ -0,0 +1,346 @@
+/*
+ * Voxware MetaSound decoder
+ * Copyright (c) 2013 Konstantin Shishkov
+ * based on TwinVQ decoder
+ * Copyright (c) 2009 Vitor Sessak
+ *
+ * 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
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+#define BITSTREAM_READER_LE
+#include "libavutil/channel_layout.h"
+#include "libavutil/float_dsp.h"
+#include "avcodec.h"
+#include "get_bits.h"
+#include "fft.h"
+#include "internal.h"
+#include "lsp.h"
+#include "sinewin.h"
+
+#include "twinvq.h"
+#include "metasound_data.h"
+
+static void add_peak(float period, int width, const float *shape,
+                     float ppc_gain, float *speech, int len)
+{
+    int i, j, center;
+    const float *shape_end = shape + len;
+
+    // First peak centered around zero
+    for (i = 0; i < width / 2; i++)
+        speech[i] += ppc_gain * *shape++;
+
+    for (i = 1; i < ROUNDED_DIV(len, width); i++) {
+        center = (int)(i * period + 0.5);
+        for (j = -width / 2; j < (width + 1) / 2; j++)
+            speech[j + center] += ppc_gain * *shape++;
+    }
+
+    // For the last block, be careful not to go beyond the end of the buffer
+    center = (int)(i * period + 0.5);
+    for (j = -width / 2; j < (width + 1) / 2 && shape < shape_end; j++)
+        speech[j + center] += ppc_gain * *shape++;
+}
+
+static void decode_ppc(TwinVQContext *tctx, int period_coef, int g_coef,
+                       const float *shape, float *speech)
+{
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int isampf       = tctx->avctx->sample_rate / 1000;
+    int ibps         = tctx->avctx->bit_rate / (1000 * tctx->avctx->channels);
+    int width;
+
+    float ratio = (float)mtab->size / isampf;
+    float min_period, max_period, period_range, period;
+    float some_mult;
+
+    float pgain_base, pgain_step, ppc_gain;
+
+    if (tctx->avctx->channels == 1) {
+        min_period = log2(ratio * 0.2);
+        max_period = min_period + log2(6);
+    } else {
+        min_period = (int)(ratio * 0.2 * 400     + 0.5) / 400.0;
+        max_period = (int)(ratio * 0.2 * 400 * 6 + 0.5) / 400.0;
+    }
+    period_range = max_period - min_period;
+    period       = min_period + period_coef * period_range /
+                   ((1 << mtab->ppc_period_bit) - 1);
+    if (tctx->avctx->channels == 1)
+        period = powf(2.0, period);
+    else
+        period = (int)(period * 400 + 0.5) / 400.0;
+
+    switch (isampf) {
+    case  8: some_mult = 2.0; break;
+    case 11: some_mult = 3.0; break;
+    case 16: some_mult = 3.0; break;
+    case 22: some_mult = ibps == 32 ? 2.0 : 4.0; break;
+    case 44: some_mult = 8.0; break;
+    default: some_mult = 4.0;
+    }
+
+    width = (int)(some_mult / (mtab->size / period) * mtab->ppc_shape_len);
+    if (isampf == 22 && ibps == 32)
+        width = (int)((2.0 / period + 1) * width + 0.5);
+
+    pgain_base = tctx->avctx->channels == 2 ? 25000.0 : 20000.0;
+    pgain_step = pgain_base / ((1 << mtab->pgain_bit) - 1);
+    ppc_gain   = 1.0 / 8192 *
+                 twinvq_mulawinv(pgain_step * g_coef + pgain_step / 2,
+                                 pgain_base, TWINVQ_PGAIN_MU);
+
+    add_peak(period, width, shape, ppc_gain, speech, mtab->ppc_shape_len);
+}
+
+static void dec_bark_env(TwinVQContext *tctx, const uint8_t *in, int use_hist,
+                         int ch, float *out, float gain,
+                         enum TwinVQFrameType ftype)
+{
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int i, j;
+    float *hist     = tctx->bark_hist[ftype][ch];
+    float val       = ((const float []) { 0.4, 0.35, 0.28 })[ftype];
+    int bark_n_coef = mtab->fmode[ftype].bark_n_coef;
+    int fw_cb_len   = mtab->fmode[ftype].bark_env_size / bark_n_coef;
+    int idx         = 0;
+
+    if (tctx->avctx->channels == 1)
+        val = 0.5;
+    for (i = 0; i < fw_cb_len; i++)
+        for (j = 0; j < bark_n_coef; j++, idx++) {
+            float tmp2 = mtab->fmode[ftype].bark_cb[fw_cb_len * in[j] + i] *
+                         (1.0 / 2048);
+            float st;
+
+            if (tctx->avctx->channels == 1)
+                st = use_hist ?
+                    tmp2 + val * hist[idx] + 1.0 : tmp2 + 1.0;
+            else
+                st = use_hist ? (1.0 - val) * tmp2 + val * hist[idx] + 1.0
+                              : tmp2 + 1.0;
+
+            hist[idx] = tmp2;
+            if (st < 0.1)
+                st = 0.1;
+
+            twinvq_memset_float(out, st * gain,
+                                mtab->fmode[ftype].bark_tab[idx]);
+            out += mtab->fmode[ftype].bark_tab[idx];
+        }
+}
+
+static void read_cb_data(TwinVQContext *tctx, GetBitContext *gb,
+                         uint8_t *dst, enum TwinVQFrameType ftype)
+{
+    int i;
+
+    for (i = 0; i < tctx->n_div[ftype]; i++) {
+        int bs_second_part = (i >= tctx->bits_main_spec_change[ftype]);
+
+        *dst++ = get_bits(gb, tctx->bits_main_spec[0][ftype][bs_second_part]);
+        *dst++ = get_bits(gb, tctx->bits_main_spec[1][ftype][bs_second_part]);
+    }
+}
+
+static int metasound_read_bitstream(AVCodecContext *avctx, TwinVQContext *tctx,
+                                    const uint8_t *buf, int buf_size)
+{
+    TwinVQFrameData     *bits = &tctx->bits;
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int channels              = tctx->avctx->channels;
+    int sub;
+    GetBitContext gb;
+    int i, j, k;
+
+    if (buf_size * 8 < avctx->bit_rate * mtab->size / avctx->sample_rate) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Frame too small (%d bytes). Truncated file?\n", buf_size);
+        return AVERROR(EINVAL);
+    }
+
+    init_get_bits(&gb, buf, buf_size * 8);
+
+    bits->window_type = get_bits(&gb, TWINVQ_WINDOW_TYPE_BITS);
+
+    if (bits->window_type > 8) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid window type, broken sample?\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    bits->ftype = ff_twinvq_wtype_to_ftype_table[tctx->bits.window_type];
+
+    sub = mtab->fmode[bits->ftype].sub;
+
+    if (bits->ftype != TWINVQ_FT_SHORT)
+        get_bits(&gb, 2);
+
+    read_cb_data(tctx, &gb, bits->main_coeffs, bits->ftype);
+
+    for (i = 0; i < channels; i++)
+        for (j = 0; j < sub; j++)
+            for (k = 0; k < mtab->fmode[bits->ftype].bark_n_coef; k++)
+                bits->bark1[i][j][k] =
+                    get_bits(&gb, mtab->fmode[bits->ftype].bark_n_bit);
+
+    for (i = 0; i < channels; i++)
+        for (j = 0; j < sub; j++)
+            bits->bark_use_hist[i][j] = get_bits1(&gb);
+
+    if (bits->ftype == TWINVQ_FT_LONG) {
+        for (i = 0; i < channels; i++)
+            bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
+    } else {
+        for (i = 0; i < channels; i++) {
+            bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
+            for (j = 0; j < sub; j++)
+                bits->sub_gain_bits[i * sub + j] =
+                    get_bits(&gb, TWINVQ_SUB_GAIN_BITS);
+        }
+    }
+
+    for (i = 0; i < channels; i++) {
+        bits->lpc_hist_idx[i] = get_bits(&gb, mtab->lsp_bit0);
+        bits->lpc_idx1[i]     = get_bits(&gb, mtab->lsp_bit1);
+
+        for (j = 0; j < mtab->lsp_split; j++)
+            bits->lpc_idx2[i][j] = get_bits(&gb, mtab->lsp_bit2);
+    }
+
+    if (bits->ftype == TWINVQ_FT_LONG) {
+        read_cb_data(tctx, &gb, bits->ppc_coeffs, 3);
+        for (i = 0; i < channels; i++) {
+            bits->p_coef[i] = get_bits(&gb, mtab->ppc_period_bit);
+            bits->g_coef[i] = get_bits(&gb, mtab->pgain_bit);
+        }
+    }
+
+    return 0;
+}
+
+typedef struct MetasoundProps {
+    uint32_t tag;
+    int      bit_rate;
+    int      channels;
+    int      sample_rate;
+} MetasoundProps;
+
+static const MetasoundProps codec_props[] = {
+    { MKTAG('V','X','0','3'),  6, 1,  8000 },
+    { MKTAG('V','X','0','4'), 12, 2,  8000 },
+
+    { MKTAG('V','O','X','i'),  8, 1,  8000 },
+    { MKTAG('V','O','X','j'), 10, 1, 11025 },
+    { MKTAG('V','O','X','k'), 16, 1, 16000 },
+    { MKTAG('V','O','X','L'), 24, 1, 22050 },
+    { MKTAG('V','O','X','q'), 32, 1, 44100 },
+    { MKTAG('V','O','X','r'), 40, 1, 44100 },
+    { MKTAG('V','O','X','s'), 48, 1, 44100 },
+    { MKTAG('V','O','X','t'), 16, 2,  8000 },
+    { MKTAG('V','O','X','u'), 20, 2, 11025 },
+    { MKTAG('V','O','X','v'), 32, 2, 16000 },
+    { MKTAG('V','O','X','w'), 48, 2, 22050 },
+    { MKTAG('V','O','X','x'), 64, 2, 44100 },
+    { MKTAG('V','O','X','y'), 80, 2, 44100 },
+    { MKTAG('V','O','X','z'), 96, 2, 44100 },
+
+    { 0, 0, 0, 0 }
+};
+
+static av_cold int metasound_decode_init(AVCodecContext *avctx)
+{
+    int isampf, ibps;
+    TwinVQContext *tctx = avctx->priv_data;
+    uint32_t tag;
+    const MetasoundProps *props = codec_props;
+
+    if (!avctx->extradata || avctx->extradata_size < 16) {
+        av_log(avctx, AV_LOG_ERROR, "Missing or incomplete extradata\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    tag = AV_RL32(avctx->extradata + 12);
+
+    for (;;) {
+        if (!props->tag) {
+            av_log(avctx, AV_LOG_ERROR, "Could not find tag %08X\n", tag);
+            return AVERROR_INVALIDDATA;
+        }
+        if (props->tag == tag) {
+            avctx->sample_rate = props->sample_rate;
+            avctx->channels    = props->channels;
+            avctx->bit_rate    = props->bit_rate * 1000;
+            isampf             = avctx->sample_rate / 1000;
+            break;
+        }
+        props++;
+    }
+
+    if (avctx->channels <= 0 || avctx->channels > TWINVQ_CHANNELS_MAX) {
+        av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %i\n",
+               avctx->channels);
+        return AVERROR_INVALIDDATA;
+    }
+    avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO
+                                                 : AV_CH_LAYOUT_STEREO;
+
+    ibps = avctx->bit_rate / (1000 * avctx->channels);
+
+    switch ((avctx->channels << 16) + (isampf << 8) + ibps) {
+    case (1 << 16) + ( 8 << 8) +  8:
+        tctx->mtab = &ff_metasound_mode0808;
+        break;
+    case (1 << 16) + (16 << 8) + 16:
+        tctx->mtab = &ff_metasound_mode1616;
+        break;
+    case (1 << 16) + (44 << 8) + 32:
+        tctx->mtab = &ff_metasound_mode4432;
+        break;
+    case (2 << 16) + (44 << 8) + 48:
+        tctx->mtab = &ff_metasound_mode4448s;
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR,
+               "This version does not support %d kHz - %d kbit/s/ch mode.\n",
+               isampf, isampf);
+        return AVERROR(ENOSYS);
+    }
+
+    tctx->codec          = TWINVQ_CODEC_METASOUND;
+    tctx->read_bitstream = metasound_read_bitstream;
+    tctx->dec_bark_env   = dec_bark_env;
+    tctx->decode_ppc     = decode_ppc;
+
+    return ff_twinvq_decode_init(avctx);
+}
+
+AVCodec ff_metasound_decoder = {
+    .name           = "metasound",
+    .long_name      = NULL_IF_CONFIG_SMALL("Voxware MetaSound"),
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_METASOUND,
+    .priv_data_size = sizeof(TwinVQContext),
+    .init           = metasound_decode_init,
+    .close          = ff_twinvq_decode_close,
+    .decode         = ff_twinvq_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
+                                                      AV_SAMPLE_FMT_NONE },
+};
diff --git a/libavcodec/metasound_data.c b/libavcodec/metasound_data.c
new file mode 100644
index 0000000..3465499
--- /dev/null
+++ b/libavcodec/metasound_data.c
@@ -0,0 +1,5081 @@
+/*
+ * MetaSound decoder
+ * Copyright (c) 2013 Konstantin Shishkov
+ *
+ * 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
+ */
+
+#include "metasound_data.h"
+
+static const int16_t cb0808l0[] = {
+       164,  -3637,  -3563,   -243,   -123,    -47,    -87,    -32,
+        62,    129,     -2,    131,    -36,   -202,   -197,     37,
+       -35,   -442,   -139,    -69,    -59,     29,    -62,    -67,
+       -17,    -42,     74,     10,    107,     74,   -109,     40,
+    -10210,    -33,  -3210,   -410,   -106,    512,     40,    -17,
+       109,     67,     99,    170,     53,     34,    -68,    -16,
+      3895,    -71,   -116,      1,    608,     66,   -215,     34,
+        77,     50,    -45,    -73,      3,     11,    -33,     18,
+       -34,     58,     25,   4420,     96,     77,    -67,     23,
+       -83,  -6724,    226,    -32,   -150,   -154,     30,    -12,
+        -8,     -7,     89,     42,    173,    -51,     38,  -1852,
+        40,    -48,    -40,     81,     34,     81,     66,     16,
+        20,      3,     99,     41,    123,     52,    154,     20,
+       -38,      6,  10889,    -44,     22,    -39,     55,    -34,
+        25,    -45,    -22,    139,     19,    -20,    -64,  -2242,
+      -473,   -113,    316,    127,    -31,    128,   -363,   -124,
+       196,    259,    -60,  -3792,    -41,   -103,    104,    -80,
+      -389,    179,    110,     83,   3174,     60,   -197,    101,
+        66,    -47,   -107,     96,    -27,     45,    -21,      6,
+       116,    -51,     -8,   -594,    377,   -279,    158,   -159,
+      4595,   -163,   -210,     19,      3,   -292,    -67,     14,
+       115,    -41,   -125,   -154,   -263,   -101,      4,    -11,
+       -89,    130,     58,     32,     92,     16,    126,    -93,
+       -99,  -4239,    -69,     88,      5,   -113,    -18,     35,
+        31,    -48,    -16,     35,     62,  -2839,     14,    121,
+        19,     41,    125,   -102,     26, -13144,      6,    -30,
+        -7,     60,      4,     36,    -40,    -26,     54,    -57,
+        -9,    -30,     13,     -1,     73,   -131,     29,    256,
+        39,    -51,    -12,   1788,      4,     10,    -58,     17,
+       -36,     -2,     13,     59,    -20,    -21,    173,    129,
+      -435,   -107,   -214,     33,   3078,     13,     31,    148,
+     -2975,   -311,     38,     25,   -247,   -542,     34,    106,
+      -392,     85,   -203,    182,   -232,    423,    629,   -183,
+       800,   -466,   3145,  -2498,   -305,     39,     22,     41,
+         0,    -14,    671,   -181,   3197,    109,   2900,     72,
+       -64,      8,    414,    133,    244,   -263,     53,    -69,
+        70, -13756,    -13,     21,     50,     12,    -14,    -12,
+        -7,     97,    -32,     24,     51,    -24,    -29,     53,
+        34,    -19,  -2341,    976,     25,    -58,     18,    -48,
+     -2490,    -55,    -31,   -165,    -36,     28,    -26,     92,
+        60,    137,     69,  -5341,   -125,   1966,   -154,    -66,
+       -13,    -84,    -13,     81,    -46,    -96,     50,    -50,
+      -114,     15,     30,   -211,   -147,   -555,   3998,     88,
+       358,   -159,   -105,    -51,   -109,    -16,     70,     91,
+       268,    125,    -95,    -62,     38,  -3227,   3591,    -15,
+        92,    -72,    115,    144,    -40,    142,    172,     72,
+       -17,     23,      1,     28,    -38,   -135,    220,    -80,
+      -179,      9,    -32,     -6,     37,    -33,     -3,    -89,
+      7314,      5,    194,    -13,     23,     31,     42,     84,
+       197,   -163,   -251,   -273,    193,    206,   -613,    394,
+      3469,   2587,   -701,     62,    301,   -104,    200,    164,
+      -201,   -473,     52,   -473,    128,   -381,    404,    -69,
+      -230,   -537,    157,    389,     -7,   2783,   3058,     95,
+       -59,   1618,      1,      4,     53,     -6,     28,     10,
+         2,     82,     28,     -8,    -14,     25,     59,     10,
+        -4,     36,   -777,  -4984,     29,      8,     85,    -43,
+      -137,    -34,     53,    -58,      1,    -27,     91,     15,
+        80,    -19,   -186,    467,     94,   -382,    129,    327,
+      3053,   -221,    399,  -2821,   1090,    278,     -2,   -163,
+      -398,    126,   -266,    180,   -235,     70,    -18,    -34,
+       -45,    159,    -32,     66,     11,   3177,   -188,     27,
+        35,    -52,    114,    -28,   -136,    186,   2146,    100,
+        92,      6,     58,    -70,    159,    -14,    -32,      9,
+         6,    -27,    -73,     28,     23,    -24,    101,    148,
+        80,    -52,    -27,    -53,    -36,      4,    -74,     47,
+       -30,   -108,     34,   7213,     12,     31,    -17,   -185,
+      3318,    199,    192,   3450,    -87,      3,     47,     46,
+      -141,     49,     83,    -82,   -132,    -82,     68,    138,
+     -1031,   -236,    390,    -37,     23,    -94,     -7,      9,
+     -2958,  -1846,    -43,     23,     25,    -79,   -193,    -77,
+     -3332,  -3355,   -139,     56,    163,  -3302,    -82,    -25,
+        35,     96,     73,    166,   -154,    174,   -121,     14,
+       -89,    101,  -3751,   -344,   -240,    -35,    401,    -14,
+        47,    -49,     24,    -78,     24,      6,     68,     51,
+      -145,     20,     83,     57,    147,   -100,     60,     33,
+       -53,     11,     37,  -5793,    -93,    -67,     -9,    117,
+       112,    -51,     60,     48,     49,    328,    293,    127,
+      -314,  -3022,    374,   3283,    -86,    588,   -346,    436,
+        -7,    -26,    -88,    104,    205,    150,    147,     34,
+       126,     85,     46,   -125,   -119,     75,     13,    144,
+      3721,    275,    -71,     43,    163,    -73,   -292,   -381,
+       -79,     33,     79,    -79,     34,    -94,     18,    229,
+        63,     28,    -44,     97,  -3606,     77,    -95,   -162,
+       163,     62,   6180,     81,    -51,    -19,     -5,    109,
+        71,      7,    -37,   -100,    -31,    -94,    188,    169,
+       -14,   2606,   -417,     18,  -4371,    -25,    180,    108,
+        17,     33,     48,    -46,    -93,    -77,     32,    -37,
+       -71,   -271,    -48,   -273,    -14,    115,    -59,   -312,
+     -3334,  -3046,     71,   -166,    379,    209,   -142,     22,
+        89,    -41,    -40,     -7,    -50,      8,    -15,     12,
+       -70,    -27,    -27,     25,    -31,     38,     -5,   2831,
+       -89,     -8,    -50,   -110,   1368,    -59,  -2307,      6,
+       179,     75,    189,    170,    -55,    330,    -70,    172,
+        67,   -492,    -57,  -3408,      9,    -93, -11400,     14,
+        -1,    -21,     65,    -15,     45,    -22,     40,    -10,
+       -41,     23,    -29,    -96,    -55,    -66,    -57,    -61,
+       -29,    -15,   -101,  -9831,     33,     42,    -35,     42,
+       -44,    -58,     11,    -40,     27,     21,    715,   -315,
+      -255,   -115,   1736,      4,     41,    -70,    -51,   -108,
+       160,     -9,     87,     -6,     36,    -20,    -68,     10,
+        82,    -33,    -42,     15,    -57,    -40,    -31,     21,
+     10023,     62,    -41,    -10,     85,    -65,    -12,    -61,
+       -72,   -610,    128,    -76,    198,    367,  -4564,     60,
+       158,    -13,   -134,    -45,    -33,    -11,    -51,    -72,
+       111,   -188,    232,   -494,    -27,     42,     46,    -23,
+       137,   3174,  -3598,    211,    152,    155,   -299,     56,
+       -23,   -123,    132,     50,     28,    -64,     28,      9,
+       -17,     31,    112,    -19,      4,     45,  -7175,     54,
+       -61,     -7,     87,    164,    195,    -29,    -48,     28,
+       -60,     70,    -69,    112,   -295,      5,    -89,     38,
+        36, -11501,     17,    -26,    -64,   -222,     91,    -23,
+       -89,      0,    -94,   2191,    -74,    -84,    -61,    -41,
+        57,     24,    -35,    -28,    -37,    486,    131,   3699,
+      -277,     64,   -125,   -243,    270,    313,   -112,    145,
+        47,  -2862,   -254,   -110,    -27,    -69,   -342,   -120,
+       216,     35,     24,     62,    -39,    -29,   2402,     -7,
+        -3,     14,    -47,    -27,      4,     27,     20,     81,
+       138,     75,    178,    421,  -2943,  -3080,    -84,    -40,
+       -58,   -195,   -182,    101,   -187,      6,    -83,    269,
+       -32,    -99,     51,    -38,     44,     82,    -14,    -35,
+         0,      8,    -23,  10754,    -73,    -57,     68,    107,
+        85,     77,    101,      1,    -28,    103,    -10,     48,
+        55,     33,    -93,    -18,      8,     28,    -14,   -575,
+        28, -11712,     90,   -186,     58,     38,    -42,   2156,
+       -82,     28,    -23,     43,     43,      8,     25,     65,
+         0,    -53,     28,    -88,    388,    -36,    363,     64,
+      3068,     56,    320,   -202,  -3433,     73,   -339,   -157,
+       373,   -216,    -43,    171,    140,   -437,   -143,  -2820,
+      -101,     53,   -111,     65,    -39,     65,    -30,     69,
+       -55,     49,     45,    126,    174,    220,     73,   -101,
+       -60,   -151,    -13,    -41,    -48,     -9,     25,   -122,
+       -80,  -2450,     19,     94,     14,    -18,    -19,     60,
+     -3252,    -10,   3390,    -15,   -365,    -15,    -73,   -222,
+       307,     70,    -95,    237,   -142,   -163,    -44,   -138,
+        -7,      6,    -36,    -67,      9,    -22,  10235,    -56,
+        -8,     44,   -155,   -117,    -22,    -32,    -74,    -14,
+};
+
+static const int16_t cb0808l1[] = {
+       -58,    222,   -154,    -74,    -53,   4939,    421,     67,
+        26,    132,     60,    -97,     -1,    -43,    328,      2,
+       460,    -66,    -11,    -45,    -56,    -86, -10569,   -129,
+        58,    -25,     39,     28,     26,     45,    -61,   -139,
+       -22,   -135,   -282,   -517,   -368,     55,    -47,     30,
+      -110,     47,     75,    -13,     65,    -41,    104,   4745,
+      -149,    -99,     28,    421,    517,    -56,     81,   -309,
+        67,    -42,     -6,     17,    -60,   -151,     50,    -84,
+        -9,     29,    -72,  -3019,     82,   -195,     41,    -14,
+      -206,    -34,    -58,    -18,     30,   2154,    -20,      2,
+        -1,     41,    -10,      7,     86,    494,    123,    328,
+        73,    213,    -29,     17,     43,    -92,    -61,     -9,
+      -130,   -113,     33,    -28,  -6677,   -198,   -185,   -236,
+       183,   -108,    739,     60,     98,   -314,     66,     10,
+     -3161,   -159,  -2850,    118,     37,    -41,   -119,   3087,
+        43,    -36,     42,    106,   -174,  -3379,    -92,   -142,
+      -237,     94,    -59,   -123,   -117,    144,    -75,    146,
+      -268,    561,  -1160,    336,   1477,    207,     89,    130,
+       127,   3763,   -372,     48,     99,    204,     84,    209,
+       103,    118,    125,    326,    -29,   -206,    139,    -61,
+        94,     77,   6624,   -163,     23,     27,   -104,    150,
+       -76,   -205,   -186,    -30,   -227,    -58,     17,     25,
+     -6536,    -19,    -66,    -45,    -72,     41,     49,    -79,
+       105,     -4,   -117,    -37,   -183,    216,    -27,    -23,
+       -31,  -2720,     53,    -23,    -46,     -9,    -10,     50,
+       -12,    -50,    -56,     35,   5498,   -110,     -2,     44,
+        -1,     13,     52,    -18,    -61,    -80,    -29,     25,
+        61,    -37,     93,    -19,     67,     75,    -41,    254,
+       161,    118,  -3379,    398,     -9,   -208,   -143,    207,
+      -135,    -32,    171,    187,   -194,    466,    -55,    158,
+        34,    105,   4986,     27,    -41,     20,     87,   -110,
+        39,     80,    -37,      8,    -25,    -44,   -108,   -171,
+      -366,    208,   -225,      1,   -124,     21,     81, -10349,
+       -51,     33,    -51,    141,    -36,    106,   -100,    320,
+       122,      3,    266,     72,     -8,   -112,     55,   -107,
+     -4154,    -69,      0,     71,   -153,    -80,    -50,     20,
+      -112,    225,  -1982,    273,    -19,   -127,    109,    -25,
+        47,     57,    -98,    -10,     42,    -25,     10,     24,
+        41,    -73,     45,  -3523,   -370,   3213,     54,    -87,
+        67,   -185,    100,    -33,    -41,      3,    -38,     70,
+      -108,   -120,    -67,   -144,   -181,    -33,   -104,    429,
+        89,    849,   3022,  -2765,   -341,    184,   -248,    610,
+       408,   -222,    184,     84,    -64,    479,   -146,     47,
+      -100,     13,     17,     -7,     58,    -13,    -36,    -23,
+        -1,    -25,     10,   2666,   -113,    -41,   -140,   3064,
+       105,     31,   3042,    -75,   -132,   -113,     80,   -100,
+       -39,    216,     -4,      7,    -43,    242,     19,  -1031,
+       731,  -3659,    -24,    -20,    109,    126,   2980,     19,
+       -11,    -48,     57,   -138,    -11,   -211,   -151,    540,
+      -113,   -110,      0,   -415,    150,    -80,    -80,    209,
+       -82,  -5212,   -125,    376,      8,    131,   -138,     30,
+      -922,   -320,    181,    -75,    138,   -112,    146,    -72,
+        64,    -75,   -262,   4872,    -11,    -61,     37,   -205,
+        48,  -2257,     82,    106,     93,    -66,     48,     71,
+        29,     72,     32,     29,     17,      5,     34,     29,
+       -29,    -72,     50,  -7702,   -114,   -117,     47,     11,
+        19,    100,     48,    -28,     -8,     53,     21,     80,
+       -43,     37,    164,     22,    -15,  -5258,    -23,    -32,
+       108,     52,      7,   -161,     11,     84,    141,     -8,
+       -12,    -25,    111,    146,    -96,     66,   7388,     54,
+        17,    -54,     62,     44,    -66,    -13,     26,     13,
+        85,    -79,    -21,     98,    156,    181,   -103,   -188,
+       -35,   -179,     83,    117,    -92,     49,   -185,   3800,
+       -90,     14,     42,     94,    -83,   -178,   -156,     -8,
+        33,     42,    204,     42,      1,    -85,     47,     10,
+     10804,     36,      8,     26,    -47,    -51,   -189,     83,
+       -47,    -23,    104,  -7142,    -67,     55,     21,     68,
+         8,    -84,    -60,    -43,    142,    -41,     27,    -72,
+       -70,   -170,   -141,    202,   -198,   -105,     41,  -3553,
+       -34,   -148,     34,    -62,   -161,    -20,    -73,    128,
+       162,  -8343,      4,    -71,    -46,     12,     27,     48,
+       -41,     50,    -19,    -88,      7,     79,     29,    -19,
+       -31,    -49,   -147,  -1886,   -103,   -213,     28,   -183,
+      4119,     87,      6,     -6,     51,   -190,   -167,   -116,
+        23,    -26,      7,    -38,   5442,  -1869,    -81,    197,
+       105,   -122,     65,    220,     32,    -57,    -39,    -15,
+         4,    112,    -55,   -139,   -825,    985,   -109,   2558,
+       218,     94,     65,   -184,   3269,    101,    -65,     42,
+       372,    -38,     58,      8,   -143,   -544,   -268,    121,
+        38,     61,    -63,    -10,    -30,    -52,    -76,    -74,
+     -6690,     -5,   -160,     76,    -77,     74,    374,   -917,
+       239,   -203,    550,    -84,   -305,    292,    -51,     36,
+       135,    -79,     27,    -69,   -309,   4561,    -67,     11,
+       -60,     43,     18,     -2,      8,    -15,     20,     22,
+        -2,    -41,  -2396,     37,    -79,     67,     27,    -84,
+       353,   -213,  -2336,     58,     39,    126,    -78,    -98,
+       -90,     -3,     -9,    -43,     -2,    -29,     -5,   -149,
+        42,     98,   -109,    137,     58,    -83,    -38,     51,
+      6525,     50,     97,    -31,      8,    132,    -71,    -55,
+        11,    120,      2,    -43,    136,    -37,    -85,    150,
+       133,     67,    -41,   -452,   -104,      4,    126,    100,
+     -2660,   -108,   -109,    -64,    615,    -75,     45,     10,
+       -57,    -57,   -108,    167,   -218,    -10,   -331,    -26,
+       -21,   6561,     73,   -599,    126,    -23,    250,   -103,
+        -4,    -28,    -20,    -35,    -19,     51,      9,    -25,
+       -40, -11220,     -2,     28,    -12,     23,   3481,    169,
+       159,   -217,    -48,    114,    -93,    -34,   -191,    -63,
+        31,    182,     79,     90,     55,     67,   -145,    409,
+       190,  -7791,    -26,     18,     71,   -113,    -80,     69,
+       -21,    -27,   -121,     51,   -148,    103,    196,   2726,
+       -67,   3022,    -28,     26,    -99,     51,     24,     61,
+       104,     89,    -57,    -23,   -112,     43,      6,     13,
+      -184,   -168,    117,    -29,   1865,     -3,     20,      8,
+        30,     32,    -81,     80,    -20,    -59,     37,     19,
+      -107,  -3920,   -259,     44,     23,   -129,     24,    -66,
+       -27,  -3071,    116,      9,    -76,     56,    -83,     25,
+        54,    -20,      2,    230,     56,    -41,    131,    -15,
+       -62,     61,     56,     74,    -34,    110,   4606,     -4,
+        18,    -47,    331,   -106,    -78,     70,     53,     70,
+       -22,     77,    -71,    -60,   -101,     70,      7,    104,
+        -7,     39,    -27,   7210,    253,    -15,      0,    -96,
+        32,     50,    -10,     33,   2058,     11,    -15,     42,
+       -14,     51,      4,     -3,    -11,    -86,     10,     33,
+        21,    -18,    -31,     -7,     53,     -7,     95,      7,
+        75, -11314,      7,     17,    -16,    -83,   -475,   -887,
+     -1141,      1,   -101,      5,    -46,    110,    -90,    -47,
+       -15,     19,     66,  -4078,    104,     43,    105,   -126,
+       181,     43,  -1655,    -81,    -11,     33,    -33,     33,
+        28,    -44,     35,     -6,    -38,     68,    -40,     67,
+        73,    -29,    171,  11982,     42,     -8,    -66,    -66,
+        40,    -19,     14,     33,    -63,     24,     94,    -94,
+      -106,    584,    330,   -108,  -3841,    782,   -300,    -11,
+      -303,   -174,   -217,     -3,     24,    168,    187,   -166,
+        54,    238,   -269,    -27,    182,     -4,    -72,    -47,
+        32,     39,   7622,    -46,    -67,    -53,     56,    123,
+       -50,     69,    -36,   -275,    628,    -55,    195,    -56,
+      -265,   -132,    -39,     -4,    169,    113,   -180,    -19,
+        88,  -6427,     42,   -257,   1180,    359,    335,   3821,
+       116,     79,      3,    -93,     67,    -44,     58,    -16,
+       265,    172,    -39,    -44,     18,     92,      4,    218,
+       122,  -2993,    150,    138,    618,     66,   -618,    402,
+      2227,     10,     38,    308,    338,    -70,    265,   1047,
+      -104,   -182,    305,   -162,    -99,    510,    -20,   -114,
+       529,    -42,  -3569,     52,    -80,   -314,    716,    -31,
+       259,     59,    -73,   -117,     38,    -44,    -16,    -74,
+     -5060,     35,     10,    -30,     54,    217,     36,   -205,
+};
+
+static const int16_t cb0808s0[] = {
+     -2191,   -865,  -1906,   -251,    274,    594,  -1214,    677,
+       482,  -1176,     43,  -1098,   -203,   -537,   1834,   1332,
+       308,    432,   -191,   3091,   1892,    926,   -446,  -1206,
+      -613,    198,    575,    -38,    264,    375,    278,   -691,
+      -107,     17,   -239,    261,    848,   -620,    183,    624,
+       122,   -358,    -50,   1017,  -1075,   -705,   -346,    337,
+      -121,    100,   -218,  -1051,   -463,  -4728,   -513,  -1151,
+       737,   4356,    684,  -1374,   1630,    521,   -520,    -52,
+        90,    119,    -43,   -131,     24,     -2,   -184,    -65,
+       614,    371,   -448,   -414,   1415,   -687,   -224,    584,
+      -768,  -1210,   2941,  -3057,    132,    406,   -952,    291,
+       295,   -798,    608,  -1476,   -516,     21,   -302,   2085,
+     -1700,  -2655,   -355,    175,   -409,    662,     46,   -247,
+      -201,   -580,    179,    -54,    458,    836,   1543,   1829,
+      -282,   -278,    412,   2422,   2077,    197,   -897,    451,
+       595,   1547,    538,    825,    563,    443,   -576,   -854,
+      -572,    241,   -471,    201,   -311,   -529,    112,  -5128,
+      -173,   -233,   -435,    340,    158,    -41,    273,   -224,
+       919,  -1570,   1075,    265,   -282,   1256,   1007,    231,
+       720,    417,   -401,  -4589,   -747,   -453,  -1112,     54,
+       156,   -561,   2746,   -422,    -83,    -91,   -381,   -270,
+     -1226,    987,   -965,    625,   -474,    565,   2890,    -85,
+      1291,   -280,    626,    -26,    840,   1122,  -1915,    780,
+      -702,    792,   -578,   -122,     -9,   1175,   -194,   -571,
+      2940,    540,     31,   1817,   -352,    264,    953,  -2035,
+       238,   3250,  -1561,    653,   -331,   -393,    827,   -382,
+       323,    281,  -1339,   -819,    545,    207,     14,    338,
+       432,    860,   1691,    142,    711,    381,  -1151,   4164,
+      -867,   -241,    111,   -513,   -863,     78,   1453,   -363,
+      -128,   -232,  -1853,   2373,  -1156,    210,    698,   1134,
+      -869,   -177,   -352,   1514,  -1370,   -789,  -1193,    819,
+       348,     80,    492,    179,   -909,    591,   -600,   -377,
+     -1709,     59,   -539,    557,    -45,   -362,    778,  -4919,
+      -647,    203,    865,   -313,   -257,    173,  -2415,   1005,
+     -1771,    843,   -474,   1619,   1193,   -186,    305,    636,
+      -662,   1976,    546,    -82,   -108,   -751,    850,    521,
+     -1625,  -3135,   -388,     64,    249,  -1189,  -1552,   2629,
+         2,   -221,   -105,    754,    251,    219,   -270,   -202,
+       545,    147,   1019,    108,  -1358,  -1317,   1362,  -1323,
+     -3322,   -405,   -371,   -554,   -334,    296,    493,    248,
+        -4,   1340,    123,   -584,   -804,   -766,   -164,   -470,
+       295,    218,     -3,     62,   -194,   -657,   5016,    280,
+        -4,    -69,   -281,   -994,    209,    307,   8648,    -37,
+      -138,     45,   -329,   -101,    -65,     98,     58,    714,
+        56,   -170,     60,   -203,   -248,    103,    107,   -408,
+       596,    170,     61,    584,    727,   -434,   -181,  -5116,
+      -502,    494,     52,     83,   -105,    325,     68,   -561,
+      -274,    371,  -1833,    -78,  -2990,    320,    141,   -748,
+      1764,   1157,   -538,   -276,  -1594,   -152,    838,    -45,
+      1137,     13,   -803,   -162,   -838,  -1199,   2003,    580,
+      3687,   -844,   -552,   -271,   -462,  -1034,    -29,    273,
+       862,    269,     95,    186,   -222,   -124,     79,    -34,
+      -684,    808,  -1061,   -916,    610,    539,   1289,    782,
+      1216,   3213,    -38,   -546,  -1209,   -398,     98,    -39,
+        58,  -1271,   -611,    573,    499,  -2170,   -157,   -943,
+      -595,    436,   1203,    487,  -1419,   -570,   1468,    711,
+      -589,   -101,   3299,    -45,  -1432,   -453,   1820,    677,
+      1052,  -1793,   1071,   -400,    268,   -464,    443,    508,
+      -273,   -736,   -233,    270,  -1187,  -1931,  -1208,   -519,
+      -879,    325,   1032,    280,    565,    294,   2588,   -303,
+       640,  -1398,   1070,    674,     57,   -165,    -46,    512,
+       757,  -3471,   -812,   -854,     45,    101,   3195,   -786,
+       -61,    122,  -1234,    -74,    119,   -389,    254,    -84,
+       829,   1465,   -930,    171,   -248,    201,    939,      1,
+        52,  -3517,  -1854,    147,   -843,    310,    502,    729,
+       191,    525,    333,   -669,  -3358,    215,    552,    156,
+     -1771,    982,   -746,    523,   -187,   -684,    456,    123,
+     -1544,   -145,     58,  -1083,  -1646,  -1309,    775,   1436,
+      1409,  -1114,   -171,     26,  -1775,   1103,   -392,  -2053,
+     -1221,    100,  -1120,     25,   -295,    306,   -105,   -514,
+     -4362,    156,  -2172,   -191,    -90,      7,    -62,    244,
+      -107,    521,    309,     22,   -663,    239,   -213,   -226,
+       100,   2228,   -330,   -197,  -1247,   -876,   1561,     -1,
+      -354,    439,   -163,   -318,    -61,  -1184,  -3022,   1434,
+        65,     87,    806,  -2093,   3016,   1022,   -779,   -391,
+       -18,  -1371,   -548,    910,   -910,   -438,    673,     48,
+      1028,    548,    153,   -337,    554,    353,   1686,    468,
+      -190,   -113,   -560,    542,     94,   -140,   -194,    -58,
+       165,   -154,   -311,   4744,   -148,     49,   -253,    180,
+       -65,   -125,   -139,    -49,   -115,   -270,    439,    139,
+       210,    202,   -207,    -65,   -477,    168,  -4720,    -96,
+     -1091,  -2071,   -567,  -1330,    237,    411,   -123,   1197,
+      2625,   1348,   -230,    362,   -147,   -139,   -699,   1210,
+      -299,     92,   2835,    -36,   -296,    287,   2426,  -1171,
+      -218,    884,   -320,   1130,  -1085,   1177,   -953,   -776,
+       609,    827,    -90,    131,  -2757,    567,    885,  -2359,
+       955,   -200,  -1883,    131,    282,    -80,    141,     -8,
+       -33,    333,    809,    357,    -13,    499,    597,    923,
+     -1725,  -1533,    465,    -93,   2187,   -841,    751,     74,
+     -2158,     99,  -1078,   -459,    648,   -258,    349,   -917,
+      1200,    374,  -1741,  -1013,    724,    -61,    182,   4032,
+      -581,   1123,   -400,   -459,   -443,   -316,      3,   -271,
+      -248,    -17,    595,    206,  -1188,   2869,   1338,   -253,
+       316,   -474,   1680,   -856,  -1487,    547,    679,    425,
+      -258,     92,     -4,    -24,    117,   -157,    385,   -257,
+      -332,  -5597,    -68,   -329,    -65,   -108,   -277,    202,
+      -400,    124,    -51,      5,     71,     90,   -927,    966,
+       780,    305,    703,    802,  -1661,  -1415,    -66,    437,
+      -610,    317,    795,    599,   -189,    322,   -519,  -4010,
+       729,   -620,  -2127,    351,    506,    -68,    162,   -983,
+      -288,   3167,   -140,    991,   -599,    128,   1868,     64,
+       -63,     -1,   2047,    155,   -871,   -130,    226,    508,
+       499,    882,   3762,   -383,    -23,      0,   -345,   -488,
+       167,    648,    395,    114,   1121,    343,    232,   -538,
+        15,    342,   -820,     38,    435,   -468,   -282,   -415,
+     -5021,   -293,    147,    533,   -128,    -70,    503,    844,
+       -86,   1836,  -2103,  -1143,    -70,   -510,    576,   -689,
+       410,  -2101,    433,    339,   -417,    820,    157,    173,
+       454,   -586,   1219,    -73,  -5123,    344,    397,     53,
+       105,    501,    -59,    515,    194,    356,     78,    706,
+       303,    332,   4532,    739,    961,   -521,   -392,     20,
+      -697,    823,    607,   -243,    332,    365,   -330,    307,
+       429,   -865,     -8,    545,     -3,   6041,   -310,    272,
+       464,     22,   -156,    142,    -63,    -87,    297,    -24,
+       562,     -9,    147,    341,    -21,    119,   1386,    947,
+     -1738,   -500,   -655,     95,     32,     32,    187,    518,
+      1330,     95,   -324,   3620,    737,    -54,     55,    670,
+     -1252,    995,    484,   1347,   -745,    244,    262,    -83,
+      -122,   1194,   -653,  -1111,   -327,   -325,   3579,   -214,
+       -37,   -412,   -267,   -377,    -62,    131,    360,    203,
+     -5713,    -42,     94,    279,    406,   -355,     34,   -144,
+       156,   -256,    -48,    -98,  -1392,   1273,    202,  -1249,
+     -3457,   -710,   1007,     37,  -1788,     86,   -570,    535,
+        17,   -369,   1640,    816,   -117,    128,   -969,  -1381,
+       224,   1519,   -996,   -833,    931,    185,    804,    465,
+        82,     69,   -247,   3312,   -430,    -23,    173,   -223,
+      3080,   1848,  -1187,  -1494,   -485,  -1131,    496,   -517,
+      -596,    320,   -853,  -1303,    240,   -298,    159,    527,
+      -257,    412,    839,  -1020,    706,  -3499,   -175,  -1089,
+      -717,   -325,    261,    310,  -1740,  -1035,   -403,   -229,
+      -861,   -970,    -62,   -192,    535,  -2154,   -364,  -1133,
+       979,  -3299,    353,    982,   -517,   1144,   -563,    675,
+       285,     63,     17,  -1957,     82,     28,   -513,    501,
+     -1183,   1476,   -813,   -254,  -1584,  -1181,   -426,    -56,
+      -916,    203,  -2693,    209,  -1066,  -1174,    279,    439,
+       201,   1179,    797,    407,    851,    927,    316,   -640,
+      1398,   -128,   2741,    563,  -1789,    989,    932,    247,
+         6,   -617,    268,   -691,   1112,   -569,    883,    298,
+        37,   -362,   -661,    -17,   -154,   -574,    721,   4578,
+       205,    507,     77,    -90,   -433,  -1613,    270,   -500,
+     -1061,   1634,   -388,   -432,   -648,  -1985,    629,   2887,
+      -201,    -32,    223,    621,    143,    446,   1384,   1109,
+       299,    329,  -1002,   -356,   1504,    -77,     49,    952,
+      4166,   -544,    -85,   -412,   -249,    474,     27,   -107,
+};
+
+static const int16_t cb0808s1[] = {
+      2632,   1511,    944,   -180,  -2377,     54,   -470,   -187,
+      -710,   -998,   -516,   -916,   -440,   -842,    285,     22,
+      -282,   -459,   -299,  -2769,  -2285,   -380,  -2194,    801,
+      -595,   -252,    504,    -69,   -752,    972,    639,    277,
+       502,    117,  -1072,   -145,   1462,   -528,   2165,    880,
+      -182,  -2953,    750,  -1090,    596,    105,    187,    555,
+      -153,   -113,    830,    161,    308,    -44,   -250,    -58,
+      -507,   -406,   -626,   1453,   1357,    116,   -456,   3242,
+      -607,     94,    390,    393,    114,   1069,     -2,      2,
+      2497,   1405,   -755,   1353,    192,   1288,   -187,    262,
+      1722,     91,    885,   -622,   -321,    246,  -1835,     17,
+       213,    -80,   -658,  -1940,    275,    845,   -365,    276,
+      2142,   -216,  -3402,   -646,    549,    -78,   -176,    -52,
+       785,  -1335,     44,    163,   -409,   1273,    679,   -377,
+       788,  -1355,  -1721,    332,    223,   1409,   -104,    165,
+       354,    322,   2414,  -1611,    216,     -6,   -232,  -1770,
+     -1931,   2496,   -530,    228,   -924,   -173,   -329,   -575,
+     -1709,   -900,    199,    223,    690,   -636,     73,   -367,
+       460,   -823,  -5105,    435,    957,    224,    246,    406,
+      -673,    752,    412,   -158,   -267,      4,    694,     10,
+       -45,    219,   1040,    778,  -1910,   1886,   -691,    674,
+      1085,   -537,    376,   1048,    858,   -161,    613,    376,
+       535,  -1349,  -1913,   -518,   -850,    665,    772,  -2985,
+       -66,    -42,   2142,   -848,  -1151,    237,   -211,   -161,
+     -2753,    603,    507,     39,   -575,    -61,  -1053,   -273,
+       290,   -258,   -162,    139,     95,    -12,   -201,   -236,
+       709,   -328,   -314,   -130,  -5337,    100,    -18,    -97,
+      -206,   1827,   1722,    302,    924,   -203,    761,   -715,
+       -24,    372,   -600,   2115,   1197,  -1406,    676,  -2068,
+      -167,   -221,   -936,   1419,    353,   -317,    245,  -2890,
+       623,    265,   -622,    204,   2549,    596,    239,    -25,
+      -672,    583,    117,    -13,  -2251,  -1325,   1984,   1431,
+     -1335,  -1268,    735,    245,    105,    593,   -193,   -614,
+       909,   -339,  -1033,    383,    102,    363,    732,   1439,
+      1028,   1275,    442,    987,  -3901,   -257,    -36,    224,
+      -116,   -402,    200,   -596,   -125,    372,   -572,    398,
+      -543,   1024,   1746,   -736,  -1056,  -1736,    953,   1026,
+      -965,    442,  -1565,   -448,    -96,   1498,     30,   -231,
+      -483,     73,  -3185,   1765,   1313,   -100,    477,   -198,
+       782,    316,    364,   -107,   -431,  -1795,   -244,    122,
+      -423,   -385,    457,   -872,   -535,  -1098,     80,   -110,
+      1420,    646,     33,  -3226,    648,    861,    328,  -1269,
+      -558,    495,    881,    112,    479,    170,   -309,   1904,
+     -1412,   -768,  -1220,    -34,    995,   -649,    162,      1,
+       153,    985,    762,   -263,   -188,     77,    760,  -2346,
+      3430,   -450,   1677,   1090,   1771,   2109,    -14,   -119,
+      -995,    268,    141,     33,     35,     31,    537,     65,
+      -345,     69,    192,    763,    -18,   1078,   3829,    274,
+       442,   -173,   -412,    434,   -695,    924,      2,   1551,
+       566,    -85,    217,    976,   2196,   -503,  -1401,    759,
+       922,  -3024,   -963,     -3,    600,   -452,   -193,   -787,
+         7,    186,    828,    515,    148,   -225,  -1250,   -985,
+       443,   -511,   2037,   1560,   3230,    647,   1418,   -165,
+      -261,   -369,    224,    450,   -100,   -271,   -122,   -511,
+      -691,  -1444,    906,   -144,    248,    452,    957,    -70,
+      -517,    116,  -3559,   -877,   -399,    418,  -1300,   -415,
+      -177,    770,  -2566,   -371,  -1673,  -1042,   -500,   -290,
+      -708,   -631,    193,   2494,    319,    545,    767,    102,
+       231,    -43,   -139,    -97,   -700,  -1592,    282,   1325,
+     -1419,   -647,    449,   1995,   -737,    661,   1617,    725,
+     -1464,    615,    906,    202,   -154,   -228,  -2194,   -231,
+       299,    110,   1318,   1053,   -312,    843,   -937,  -1697,
+      -592,  -1224,   -633,    -50,    792,   1600,  -1187,   -171,
+       211,   -744,   -306,    186,   1914,  -3119,   -904,   -159,
+       178,   -596,   -654,    817,     94,   -242,  -2376,   -218,
+      -421,   -365,   -699,    177,   -427,    -32,    265,    -33,
+       245,    -34,   5309,   -307,   -262,   -299,     86,    278,
+        33,   -200,   -180,    -56,    337,   1034,   -229,   4952,
+       306,   -609,    189,    -22,    280,   -160,   -507,    135,
+     -1265,   -252,    434,   -427,    158,   -546,   -130,  -2500,
+       597,    908,    918,    706,   1227,   3390,    995,    298,
+      -558,   1307,    765,   -144,    -37,   -286,    122,    215,
+     -1251,   1090,     85,   -914,    522,    316,   1829,   -701,
+      -365,  -3311,    312,     22,    680,  -1351,    220,    243,
+       166,    -36,    780,   2395,    -64,    836,   1037,    735,
+       966,    173,   1114,    192,    510,  -1054,   1341,   -616,
+      1559,    897,    338,     -3,   -194,   -214,   -573,   -265,
+       328,   -365,    433,   -505,    -86,     33,   -156,   -129,
+      -137,    119,    143,   5773,    -76,     68,    820,   1215,
+      1315,    713,     12,   1590,    131,   -193,   -881,   -227,
+       736,    581,    736,    -37,   -434,   -449,   -348,   4189,
+      2180,  -1360,  -1663,    -74,   1215,    278,   2092,    -66,
+       313,    388,  -1373,     25,    599,    888,    -87,    293,
+        30,    367,   1010,   -883,    818,   -910,  -1918,    864,
+       482,   -968,  -1249,    222,   1100,     23,    -87,   2493,
+      -248,   -622,    240,    151,    873,  -2735,   1325,   -700,
+      -411,    282,  -2361,  -1843,   -631,   -208,    103,   -411,
+       831,   -446,   -292,    450,    184,   -158,    484,  -1964,
+      4663,    123,     18,    174,    621,    158,   -788,    233,
+       302,    441,   -339,    200,    -62,   -197,     -9,   -236,
+       984,    584,   -521,   -373,   -205,    910,    392,    850,
+     -2968,     68,   -727,   1330,    578,     36,   -385,    754,
+      -538,    -36,    271,    418,   -548,   1775,  -1045,   -879,
+     -1407,    524,  -1085,  -1479,    371,     19,    873,    171,
+      2932,   -216,     42,     71,  -1187,   -570,   -524,    344,
+      -770,  -4086,   -735,   -515,   1055,   -551,    945,  -1408,
+       913,  -1005,   -222,   -443,     60,   -194,   -734,   1908,
+      -534,  -1351,     72,   -938,    -66,  -2756,   1313,   -169,
+     -1550,    450,   -610,    893,   1100,   -583,     87,   -145,
+      -210,    281,   1402,    674,      0,    -38,    874,   -363,
+      2436,   2156,  -1659,   -481,   -130,    -63,   -669,   -316,
+      -761,   -413,    108,   2362,    354,     76,  -1725,   -924,
+     -1443,   1251,    871,  -2058,    518,    955,   -283,    680,
+       -85,   -560,   -464,    127,   -216,  -1382,   1908,    238,
+      -182,    459,  -1227,   1144,   2266,    -96,    595,   -750,
+       912,   -198,   1786,  -1423,   -618,   -450,    185,  -1212,
+       706,   -689,   -154,   -365,   -681,  -1378,    914,  -1200,
+      -253,   -532,   3244,    444,      1,    -96,   -404,    -64,
+      -412,  -1400,  -2830,   -785,    940,   -217,    358,    618,
+       208,  -2974,   -365,    -32,    -63,   -233,   -868,   -413,
+       358,   -451,   1310,   -751,  -1329,  -2480,     63,    458,
+      -273,   1270,    316,     93,   -453,   -463,  -1258,    -57,
+     -1073,  -2037,     46,   -160,   4609,  -1193,    192,   -355,
+      -963,    -92,    752,    593,    102,    -80,   -121,    166,
+      -606,   -274,     28,    258,     45,    -45,    928,   -949,
+      -134,   -268,    -77,    242,   1623,  -1290,    739,    109,
+       285,    175,    -92,  -4053,   -482,    366,    217,   -126,
+      -843,    950,  -1068,    777,   1818,    550,   -891,    -34,
+      -995,   1976,   2677,   -764,     45,    -40,  -1800,    569,
+      -323,   -102,  -1064,   4000,   -109,   -423,   -289,    738,
+      -872,    808,   -977,    504,   -901,     41,    -45,   -287,
+      -140,   -444,    477,   -271,   -876,    301,  -2421,   1633,
+      -918,   -660,   -149,  -2542,   -503,   -265,   -107,   -623,
+      -447,   -782,   -858,   -535,   -220,    442,    661,   -209,
+       878,  -1601,   3610,    149,   -331,    190,    102,    270,
+      1451,    237,     13,  -1026,    178,   1290,   -281,   -217,
+        11,  -1728,   1043,  -2992,   -718,   -776,    357,   -615,
+      -231,    813,   -473,   1634,    539,   -513,    240,   1158,
+       144,     57,   1249,   1479,   -481,   -733,   1663,   -757,
+       641,    680,   -468,  -2697,    -29,    -62,   1253,   1142,
+       292,    245,    -96,    295,   -664,   -264,   -308,   -670,
+      -705,    155,  -4024,    330,    191,    -77,  -1502,    326,
+         9,    295,   -567,     34,   -104,   -123,   -320,   -255,
+      1124,    320,     98,   1299,   -436,   1491,   -341,    908,
+        11,      8,    988,  -1921,      5,  -1391,    859,  -1291,
+      -581,    546,    -95,    272,   -441,    185,   -256,    313,
+       466,   -393,    -50,   4430,   -940,     87,   -224,    390,
+      -539,   -290,  -1046,    531,  -2329,   1275,   -586,  -1046,
+     -1682,   1159,    908,   2023,    951,   -273,    -68,    713,
+      -556,    770,    783,    223,     60,   -881,    -97,    760,
+       556,   -237,   -263,   -246,   -240,    165,    526,    832,
+     -4761,    432,   -339,    186,    492,     81,   -136,   -827,
+      -390,  -1026,   -371,   -292,    937,   -243,   -136,      6,
+        49,   -223,   -600,   -355,   5306,    140,     34,    -84,
+};
+
+static const int16_t cb0808m0[] = {
+     -3555,   -106,   -131,    -53,   -156,    196,   -206,   -104,
+        18,  -2948,    122,    146,   -520,      2,    294,   -419,
+        -1,    -25,   -257,   9334,     87,    -55,    -42,     30,
+        92,     35,    195,     31,     59,     88,     47,     47,
+      -220,    564,  -1686,    426,    106,    396,     97,   1315,
+      2331,    167,  -1261,   1003,    732,   -300,   -342,    418,
+        87,    236,   -245,   2235,     11,    725,    -24,   -169,
+      -480,   2845,     96,    -34,     67,    857,     28,     50,
+        92,   2100,    -84,   -600,  -1990,  -2208,   -163,    299,
+       431,   -825,   -283,    299,    -98,    391,    -65,    -92,
+      -200,   -689,   2236,    -82,    -81,    -52,    127,     86,
+      -137,   -319,  -2561,    -90,    547,   -198,     10,    195,
+      -366,  -2688,    -77,   -234,   -112,   -245,    270,    199,
+      2674,    -57,   -673,     -9,   1029,    -31,    311,    -50,
+      -160,   -175,   2371,   2711,    409,    -19,     22,   -244,
+       312,   -158,    270,   -125,   -247,    118,    -91,   -602,
+        86,    174,   -216,     18,   3048,  -1953,    171,  -1985,
+      -297,    295,    -38,   -198,   -229,    363,    -13,    127,
+        13,   -202,   -117,     65,     74,     63,    125,    -62,
+        -2,   -543,   -680,  -4269,   -130,    325,    -49,   -245,
+       -50,   -509,   -151,    -19,      3,    152,   -980,   -129,
+      -234,    399,    349,    171,   -196,   4952,     -2,     36,
+       288,    771,   2313,    231,    -39,    572,  -3012,     77,
+      -501,   -215,   -228,   -444,    830,    200,   -188,   -157,
+      3248,    279,  -3319,      0,     76,     10,    160,    -80,
+       135,    102,   -349,    174,    -30,    -88,   -145,   -205,
+        10,   -185,    177,    -34,     25,     31,    218,     -4,
+       191,    172,    228,   -136,   -178,    268,    638,   3559,
+        55,    198,    145,    342,    -25,  -1940,   2866,   -334,
+      -921,   1941,   -464,    273,   -181,   -506,    -21,   -410,
+       116,   -179,    -49,   -273,    -22,    -36,  -1298,    274,
+     -1831,    321,   -382,    238,  -3464,    -68,   -194,     32,
+       -95,   -506,     72,     64,   -329,     19,    -39,    347,
+      -302,    204,    145,    -72,    855,   -112,  -3596,    989,
+     -2801,    386,  -2623,   -471,    101,   -155,    257,    291,
+        30,   -153,    185,    172,    511,     20,    166,    274,
+        29,  -3023,    129,     33,   -219,   -205,      6,     47,
+      -407,    137,    563,   -106,  -2065,     76,    201,    -99,
+      -170,    -77,    170,  -4536,   -440,    -96,   -940,  -1066,
+        81,    205,    358,    435,    -78,   -148,   -201,    -85,
+      -307,   -306,     14,    -47,   -101,   -187,   -136,    380,
+        -4,    -32,    -34,    -54,    528,    -58,   6389,    302,
+       -79,     52,    -28,    -65,    -77,    -12,   9024,   -100,
+       262,     20,    -67,    -31,     50,    -33,    -30,   -140,
+       326,  -1170,   -304,   -136,   -233,    170,     60,    314,
+      -166,   -208,   -105,   -245,   -169,    -72,    137,  -7173,
+        -2,    375,    152,    226,   -206,   -341,    303,     47,
+      1010,   -188,    577,   -292,  -3581,    -12,   -195,     20,
+      2165,   -206,    -88,    -83,   -132,    -40,   -443,    236,
+      -333,    179,   -211,    -56,    318,   -409,   3106,     95,
+     11636,    340,    204,   -323,    167,     76,     61,     65,
+      -157,     71,    -21,     38,     66,    391,    -52,     20,
+       -17,     11,    259,     45,   -194,    440,   3432,    122,
+       468,   -595,  -1856,     94,   -427,   -133,    149,   -273,
+        61,  -6622,     48,     97,   -162,     93,    402,   -104,
+      -207,     64,   -278,     92,    387,      3,     96,     -2,
+       -27,    -30,     84,     64,     35,    -65,     98,     85,
+       -16,   -248,   7930,     74,      4,   -104,     83,    -48,
+        40,  -2104,    -86,    -89,     99,   -142,     65,  -2713,
+        63,   -431,    523,    687,    212,  -1515,      3,     59,
+        55,     -6,     22,     -8,   -148,    180,     78,   7833,
+       -63,    -83,     13,   -187,   -116,    156,    -29,   -186,
+      -160,    148,    -82,   -303,   -166,    112,   -103,    -39,
+      -165,   2827,    -54,    -26,     24,  -3055,     78,     21,
+       128,    -81,    -25,   -122,     51,    -54,    -19,    188,
+       -18,     -1,   -140,    -18,  -8085,    124,    -46,     45,
+      -574,     12,   -150,    147,     65,   -209,   -396,   -444,
+     -3882,   -291,   -231,    296,    244,     76,    180,     36,
+     -2575,    659,    -63,   3277,    -85,     48,   -518,   -353,
+       130,     50,     13,    338,   -343,   -276,    -16,    353,
+     -6036,    -77,     18,    139,     43,    335,    294,     99,
+       219,    442,    -25,    -53,     40,    271,    175,   -282,
+       -91,    430,  -4428,    -15,  -2857,    -62,    -27,   -170,
+        33,   -681,   -110,    -76,    153,     42,   -134,   -145,
+       222,   -177,    -39,    314,   2270,    526,    500,   2417,
+       339,   1808,    -17,    464,   -525,    -97,    124,    -32,
+       370,     48,  -1675,    -62,   -169,   2642,   2511,    -43,
+     -1037,   -184,     54,   -569,   -504,   -247,    -40,    327,
+         7,     82,   -197,   2774,    -34,  -2931,   -204,   -112,
+       194,   -362,    187,     65,   -166,    115,   -125,     14,
+       210,    144,    -75,     57,   -255,   -151,  -3566,   -153,
+       182,     89,  -2530,     98,   -265,   -173,   -133,    260,
+       -25,  -1292,     35,    131,    -98,    -85,   -237,     82,
+      1353,     47,   3842,    148,    171,    183,    234,     89,
+       -93,     47,    102,     -4,     90,   2980,    289,   -231,
+       353,    497,   -109,    190,  -2869,    697,    136,     90,
+      -244,    298,   -119,   -519,    -50,    207,    -43,  -1376,
+       356,   1934,    701,  -2323,    671,     71,    -56,   -167,
+     -3793,  -3749,   -103,    134,   -228,    -13,     27,    -45,
+      -105,    172,    -77,    -23,     53,    110,   -118,    -80,
+      -164,   -192,   -563,    393,    -58,   -428,   -360,   3696,
+       162,   -173,   1683,   -430,    452,    -92,    107,    -41,
+        28,    -85,    421,    -66,    354,    -88,    723,   2751,
+     -2955,   -481,   -134,   -231,   -145,      3,     65,    -88,
+       189,    187,    151,    174,    -36,    240,   -253,   -235,
+      -194,  -5410,    -47,    -98,    338,   -487,    -81,    -35,
+       -82,   -440,     31,    109,    217,    276,  -1805,    278,
+       273,   -369,    629,   -293,   -525,  -3832,     73,    -56,
+      -363,   1709,    177,  -2813,    796,   -162,   -341,   1176,
+       -75,    533,    854,    719,    242,   -194,     90,   -147,
+       203,   -136,   -138,   -764,      6,  -2787,    -13,   1104,
+      1497,   1097,     90,   -867,   -718,   -317,    119,    180,
+       160,    257,   2532,   -557,    -62,     14,    665,   1520,
+       456,    826,    394,   -605,    908,    222,   -140,    121,
+       121,    232,    124,     96,    -87,     48,    -51,     41,
+     -7821,    -37,    130,    -11,    -33,   -137,     16,     42,
+      1509,     -8,    119,    -83,    -18,     64,     41,   -178,
+       -28,    182,    532,    678,    -75,    277,   -230,    -70,
+       -71,     -8,   -150,    321,  -6298,    -20,   -131,    -65,
+       139,   -215,   -155,    -27,   -110,   -257,     32,    201,
+       215,    184,   8932,   -106,    -50,     66,     15,    -44,
+       203,    -38,     19,    -78,     65,    135,   -123,    166,
+       117,     76,      4,     34,    -90,   5984,     59,    -72,
+       356,    -64,      6,    -62,     43,    -86,   -175,   -106,
+        10,     25,   3812,   -135,  -3313,    142,    348,   -101,
+       -35,    378,   -250,   -106,   -299,    237,     40,    -32,
+       236,   -521,     63,   -143,    538,   -256,     43,    -45,
+      1642,    726,  -3225,    109,   -997,      3,   -256,    -27,
+      -182,    -78,  -4092,     -9,    231,     34,      9,     -6,
+       155,   2842,     53,   -130,   -390,   -146,    168,    -74,
+     -2023,   -955,    576,   -629,    -76,     70,    140,   -287,
+      -401,    966,    359,   1185,   -226,    713,    753,   -739,
+     -4238,   3364,     75,   -213,     27,   -172,    -34,    171,
+      -118,    -46,   -164,    -13,    -54,   -203,   -154,    -12,
+        65,  -3777,  -3452,    297,   -104,    -93,    -81,     69,
+      -179,   -321,     51,     47,    242,    -15,   -144,    -43,
+      2827,     67,   -305,     54,  -3044,     57,    -15,   -427,
+       311,   -205,    226,   -490,     37,    363,    -88,   -408,
+};
+
+static const int16_t cb0808m1[] = {
+      3329,     59,    195,    -91,    -70,   3262,   -132,    360,
+       157,   -410,    184,    -99,   -138,    337,    289,    317,
+       156,   -589,   -127,   -204,     37,   -175,  -5661,    -52,
+       942,    156,     -1,   -197,    353,     90,     57,   -287,
+      -218,    438,     -4,   -262,      9,    322,   -167,   2904,
+       -12,  -2647,   -248,   -203,   -267,   -116,   -135,    333,
+      -220,   -200,     40,    228,   2677,   -462,   -183,   -129,
+      2898,   -728,    793,    422,    541,   -350,     28,    222,
+      2790,   -231,   -195,   -191,   3002,    182,   -610,    145,
+      -226,   -102,    285,    344,   -357,    217,   -146,    -98,
+        18,   -255,     96,   -151,    266,    208,   -459,   -132,
+      -345,   4059,   -371,     79,     44,    -63,   -233,    334,
+        44,   3884,     49,  -3303,     88,    -23,   -287,   -461,
+        57,     94,    -53,   -129,    104,    167,    -25,    -79,
+      -125,   -630,  -2352,    150,   -419,     40,    -63,    603,
+        67,    209,    321,  -1765,   -200,     68,    473,    622,
+         5,  -2883,    112,    188,   -189,  -2765,    169,    397,
+      -330,   -642,   -798,    129,   -110,   -164,    -20,    176,
+      -213,  -5415,     39,     31,     13,    270,   -477,    166,
+       167,      4,    216,    -12,   -528,    -75,   -291,    396,
+      -499,  -2011,   -172,   -265,     96,     83,   -279,    114,
+      -166,    833,     30,   2493,     94,    130,   -183,   -659,
+         1,   -227,     75,    349,  -2757,     82,   -116,      9,
+       952,   -112,  -2444,   -333,   -206,   -406,    201,     15,
+      -768,     88,   1390,    -33,   -558,     97,   -201,     29,
+      3470,     50,    -40,   -271,   -171,    -26,     47,    485,
+      -250,   3318,    112,    639,  -2911,    123,   -264,      3,
+         8,    379,     73,     54,     88,    227,     73,     58,
+      -572,    782,   -183,    305,     49,    -23,  -2968,    -41,
+       291,    -25,    157,    295,  -2118,    125,      5,   -193,
+      -159,   -543,    -75,   1181,   -191,   -547,    -93,    117,
+     -1831,    265,   -607,    -30,    194,  -3929,    -70,    159,
+        79,  -1519,     38,    201,     14,    -24,    -76,   -366,
+        14,  -2748,      0,   -372,    405,     39,   -170,    320,
+      -257,   2153,    -12,    158,    322,  -4013,     22,   -101,
+       217,    637,    273,   -430,    228,   -428,    102,   -356,
+      -266,     82,    -31,     14,   -223,  -2595,   -360,   2094,
+      -379,    624,   -192,    245,    294,   1484,   -117,    156,
+       -53,   3668,  -3573,   -118,   -213,    257,   -211,     66,
+       -62,   -173,   -166,   -123,    163,    -81,    -39,    -74,
+       -21,    126,    722,   -136,   2050,   -206,     86,    275,
+        76,   -249,     55,  -2508,     95,    -60,    -34,   -360,
+        -9,    187,     34,    -87,    -30,    137,     48,   4761,
+       109,    511,   -496,    104,    399,   -361,    162,     78,
+       -29,    159,   -112,    182,    246,     52,    255,    338,
+       -35,     -1,    -68,      5,    182,   7675,   -119,    -14,
+     -1901,   -111,   -106,     22,    -16,     81,    159,  -2423,
+       -71,    -24,   -153,   -520,    126,    370,   -186,    230,
+       -51,   -401,    206,    -32,     52,    -71,    -79,    503,
+      -239,   -231,     55,   -133,   5226,    -45,   -165,     57,
+      2314,   -209,    302,     78,    154,  -3092,   -605,   -498,
+       410,    159,    336,   -147,   -120,    143,     36,    587,
+      -182,   -182,   1457,   1008,   2524,   -446,   2333,   -497,
+      -761,   -162,    125,    420,    225,   -117,   -324,    437,
+       -50,    190,    129,    259,     33,     -2,     -9,     32,
+       -24,     91,     97,    201,     19,    169,   3535,    485,
+      -144,    330,   -193,  -2715,    603,    303,   1124,    107,
+     -1386,  -1437,   -203,    180,    -81,    303,    209,    -21,
+       -65,     26,     91,     98,  -1349,    196,   2103,    917,
+      -732,    834,   1456,    -92,   -455,   -130,   -732,   -288,
+        39,    -85,   -557,    -39,   3213,    297,    392,   -378,
+      -520,    795,  -2407,      6,      7,    406,    203,    -73,
+      -247,    317,  -3336,   3166,    206,    -36,    159,   -279,
+       442,     54,   -324,    -18,    544,   -250,    142,   -440,
+       100,   -145,  -3772,   -199,    139,   -156,    -11,     34,
+      -178,   -233,   -370,    601,    -58,   1679,   -170,     76,
+       684,    -35,    -73,    -52,    -33,     -3,    -89,     -5,
+       -82,     73,    -11,     51,    -48,    -12,   -376,   4348,
+      -203,   -432,    189,    -35,    144,     31,    181,   -106,
+     -5112,    552,    480,      0,     63,     31,     33,    504,
+      1055,  -3007,   -214,    154,   -100,    246,    269,   -423,
+       579,     63,   1668,   -296,    390,    109,     21,     -6,
+        71,   3321,    246,    197,    355,   -198,    472,    135,
+       437,  -1734,   1299,    227,   -618,    -48,   -199,    217,
+      -230,     70,     99,   2632,   -203,   3105,    -87,    149,
+       303,    124,    362,   -322,    -44,     38,    104,    -28,
+        48,   -175,   -468,   -410,  -4451,   -152,   2157,     26,
+      -281,   -581,     36,   -205,    101,    230,    192,   -129,
+       319,     20,     65,   4879,    123,   -236,   -178,   -128,
+      -387,   -124,    528,    142,   -775,   -301,    -88,   -380,
+       120,    -42,    -17,     64,  -1074,  -3350,   1335,  -1078,
+       -14,   -462,   -113,    253,    450,     36,     -8,   -346,
+       -54,     -7,     52,   -100,     74,   8266,   -193,    -36,
+       -51,     12,     59,    -68,    190,    -36,     89,     38,
+       -59,     13,    269,    109,    -15,   -141,    -64,    -60,
+       238,      6,  -4338,    381,   1252,    354,    -41,     41,
+       191,   -236,    122,  -2712,    352,   -117,   -121,   -284,
+      1516,    473,   -332,   -277,  -1792,   -335,     84,     64,
+      9595,   -246,   -278,    446,    -95,    -32,     60,   -146,
+       104,    -84,     -3,    107,   -116,   -377,    101,   -149,
+       -45,    364,    104,   -193,   -254,   2929,   -164,    -93,
+       324,    749,   -928,    435,   2357,    350,    -40,   -153,
+       -48,   -626,    390,    -48,  -4248,   -458,   -930,   -218,
+      -486,   1769,    335,    152,    165,    111,    118,   -407,
+       -87,   -373,   -333,   -134,     86,    -32,   -144,    -18,
+       -16,  -7549,   -146,     49,   -184,    116,    -28,    -51,
+       190,    115,     80,     68,    129,    206,    294,    331,
+       179,   -270,    174,   2444,     55,  -3271,     70,   -124,
+       228,    330,    -21,   -419,     62,   -140,  -2388,      7,
+     -2683,   -129,  -1050,   -548,    811,    189,    359,   -385,
+       -82,   9031,     95,     77,    -69,    164,    261,     61,
+       -73,    230,   -163,    141,    -38,    -43,   -150,    164,
+        28,    164,     59,    -58,   -312,   -134,    102,    -67,
+       166,   -163,     63,  -6795,   -103,   -147,     81,    273,
+       133,    122,   -162,   -207,    127,    -60,   4628,     -1,
+      1315,    518,   -163,   -246,     54,    239,    154,   -154,
+       265,   2000,     25,    227,     42,    179,     88,  -3446,
+      -214,    182,    438,     90,    196,    -69,    134,    -56,
+      -451,    716,  -1120,   -287,    118,    230,    -37,    145,
+       284,   -250,    139,   -947,    203,  -3176,    -57,    151,
+      3201,    818,    -87,    347,   -486,   -201,   1176,   -325,
+      -966,   -263,   -184,    238,   -156,   -396,    152,    959,
+       -59,    -33,   -159,     -3,   9394,   -119,    -81,    -50,
+        67,      9,     27,    -62,   -121,   -210,     48,   -211,
+         5,    396,    633,     34,    -16,     67,   -247,    -77,
+       128,    441,   3896,    251,    970,    119,   -387,    -35,
+       124,    -64,   -664,  -6550,    101,    -52,     19,     44,
+      -132,     79,    731,   -155,   -262,   -140,    -31,   -191,
+      -110,    276,   -162,    -49,     81,   -117,     15,   -570,
+       420,  -1232,   -125,   3737,    -95,    544,   -149,    463,
+      -129,   -345,    350,    183,    173,    197,    464,    180,
+      -249,   -365,   -785,     -9,  -3411,   -235,   -124,    225,
+     -4516,    196,   -150,    -89,    -89,     54,   -110,    137,
+      -431,    272,    -12,     -7,    114,   -201,    166,   1570,
+       -74,    -88,   6019,    350,    -75,     68,    -29,    -81,
+       -50,     57,    -62,    103,     61,    276,     22,   -131,
+      -134,  -3347,    -60,  -3397,   -311,   -105,     90,   -159,
+      -222,    151,    224,   -210,    264,    192,     29,    -84,
+};
+
+static const int16_t cb1616l0[] = {
+       -15,  -7707,    115,     30,    -36,    -27,    -22,    -43,
+         2,      5,     31,     -1,     87,      2,     41,     21,
+       270,     16,   3747,   -773,   3027,    224,     92,   -168,
+        -7,    -62,    -79,    -44,     -9,     -4,    -58,    -78,
+      1063,    203,     -2,     76,    289,    -36,     92,    -29,
+       -78,   -148,  -5176,    137,    219,    299,     89,   -233,
+        62,   -129,     33,    123,    -30,    197,   4018,    -37,
+       -38,    139,     41,    153,     71,    -26,     27,     53,
+        72,   3358,    -68,   -122,    293,    -19,   -355,    104,
+        34,   3121,     16,     29,   -344,     37,    174,    -28,
+       -43,   -102,    -59,  -1661,     14,      5,    -62,     -1,
+        14,     15,    -42,      4,    -31,     -2,     13,     23,
+       957,   -419,     20,     31,    -14,     51,     24,    -46,
+         8,    -16,     27,    -75,    -27,    -33,    -28,     18,
+       -67,   -152,    -48,     47,     90,     48,    -74,   -103,
+       -18,   4863,      3,    132,    414,    -86,    -60,    285,
+        16,     32,    -44,      0,     22,   -163,     23,     -3,
+        23,    -61,  13224,     52,   -139,    -13,    171,    215,
+       -51,    -21,    -48,     33,    -10,    -17,    -21,  -7662,
+       -57,    -44,    -51,     35,     35,     34,    105,    178,
+       -77,     77,    147,     67,   -816,   2913,  -3087,    516,
+      -112,   -296,     21,    133,    211,    162,     87,    -25,
+      -535,   -830,    -12,     46,    -59,    -10,     -4,     42,
+         0,    -91,     -9,     47,    -90,    -29,     74,    322,
+      -106,     83,     44,   4693,   -788,    -73,    -85,   -105,
+       -76,  -1031,     34,      6,     78,    -34,    160,    -48,
+      -707,    -12,     -9,     39,     14,     23,     88,  -2286,
+        21,    -25,     42,    130,     39,    251,     16,    -50,
+       397,   -226,  -2570,     88,   -129,   -347,    159,     92,
+         0,    -44,    -49,    235,   -196,    -24,    -36,    113,
+     13387,     45,     22,     54,    -20,     29,     27,    -27,
+        54,     38,    -63,    -12,    -74,     45,     -8,   -115,
+       591,     46,      5,   -234,     57,    124,     86,  -3794,
+       -51,    292,   -160,   -152,     96,   -334,    348,     96,
+      -186,  -3870,  -3715,     54,      0,    -29,    -65,    -68,
+         6,    132,     47,   -155,     62,     26,     66,    -10,
+       -46,  -3093,     66,   3633,    183,   -171,   -132,    -24,
+       154,    157,    129,   -185,     12,    -26,     96,    -12,
+        88,    -34,     42,    -15,     37,  -6625,    -27,     13,
+        41,    -30,     62,    142,    -93,   -168,     84,    -22,
+       139,    -19,     18,  10590,   -111,     36,     13,    -44,
+         4,    -45,     -3,     -3,     28,    -25,     -4,    115,
+       119,    -49,     41,     33,     87,    -85,  12444,     73,
+        71,   -111,     61,    -15,    117,     23,    -24,     -5,
+       131,    -31,     -1,    -22,    -57,    -12,     50,     35,
+     -1555,    -20,     38,     82,    -52,     27,   -128, -14106,
+       808,    190,     89,    595,     63,   -291,    282,    -48,
+        32,   -706,   -433,   -673,   3285,   1311,    830,   3745,
+      -204,  -1185,   -584,    -51,    952,   1005,   -566,   1764,
+       186,   1211,   -495,   -112,   1213,    192,   2320,    -43,
+       -30,     24,  -1152,      2,      2,     32,    -55,    -25,
+        -2,    -17,    -14,     -6,     22,    -54,     32,     45,
+        10,    -85,    -26,    -16,    -66,    -60,   -210,   -104,
+       208,   -248,     62,    -28, -14552,    -11,    -44,   1601,
+        47,   -138,     46,    -35,   2647,    -81,     -3,    -38,
+       -66,    -59,    -33,    -19,     43,    -17,    -79,     53,
+      1821,  -1572,   2582,     85,     48,   -140,     78,   -155,
+      -173,     96,    -32,    121,    -58,    201,   -174,    -54,
+        74,  -2442,   -282,   -771,     37,  -2930,     15,   1762,
+       154,    263,    -15,    -19,    139,    246,   -243,    -31,
+        84,    145,      8,    152,     43,    128,    679,   1828,
+      3476,     17,     92,    102,    258,    -29,   -275,    -39,
+      -187,     88,     70,     28,      2,   2143,    274,    202,
+       -67,    -13,    -22,     68,    -35,    135,    114,    108,
+        27,      1, -11248,   -100,     14,     26,     59,     10,
+       -24,     30,      1,    -38,     -9,     21,     18,     -1,
+      2029,    -83,   -342,   3443,    -25,      7,      0,     54,
+        78,    198,     45,    233,     -6,      0,   -109,   -172,
+     -2250,     41,    -79,   2820,     44,    216,     39,     59,
+       -41,     52,     79,    -52,     12,     23,    -72,   -125,
+        83,     17,    -28,    -32,     13,      2,     28,      0,
+       -26,     75,    -81,     66,     25,    -81,   6516,      9,
+       -93,     49,  -4036,  -2484,    -42,    -71,    178,     99,
+      -133,     79,    -41,   -112,     57,     66,    -28,     13,
+        39,     64,   -123,   3174,   3061,    259,     55,    123,
+      -123,    246,   -138,    139,     75,     31,   -215,   -154,
+      -218,     26,     16,     21,    126,     26,    -33,    -10,
+       -15,     16,    -20,    -53,     21,  15526,    -35,    -59,
+       -50,    -11,    -58,     67,    -11,    107,    -24,    -37,
+      8155,     31,   -111,    -62,    138,    -60,    -10,     84,
+      -128,     37,     24,    -45,    -10,    129,    -68,    -37,
+        42,    -80,   -205,    -79,   5994,    -93,   -270,   -400,
+        20,    -89,    -39,   -200,    230,    197,    325,   -305,
+      -294,     94,   3207,    128,   3119,    226,     28,    -49,
+       264,    186,      8,    -29,    -13,     27,     22,    -63,
+        43,     84,    -19,     57,  -2605,    316,    259,    -43,
+        50,  -2241,    105,    -12,    -23,    -36,     89,     41,
+       -15,    145,     10,    -81,      7,    -50,     70,     60,
+       -23,     55,    -62,      0,     52,    -77,    180,     74,
+        79, -14297,      6,     24,    299,   -107,      4,    -29,
+     -3252,    -51,     40,   -143,   3550,    -28,    102,     24,
+       215,    147,   -169,    -60,    -43,   -486,      5,     -1,
+        62,   -116,  -2917,    430,     50,   2927,    139,    127,
+        63,    -53,    141,   -255,    -85,     95,   -101,   -176,
+       195,    104,  -3066,    -56,   3239,   -161,   -214,     57,
+        24,   -375,   -181,      0,   -259,    130,   -120,     -2,
+        -6,    175,   -147,   -185,     68,    219,    425,   2685,
+     -3120,    266,    246,   -270,    -70,    273,    168,    121,
+      -143,   2641,   -553,   -547,    638,    113,   2965,   -161,
+        29,   -374,    105,   -869,    108,     70,     15,    230,
+       -54,   -106,    -21,     -4,     86,     85,    155,   -120,
+       -17,    -21,  -2534,     57,    149,   -129,     21,   -169,
+     -2289,   -127,    -19,    -26,      3,     60,     35,      1,
+       -28,     -7,     36,   -180,    -13,     87,    -68,     56,
+        80,     64,     -8,    -73,   6691,    -32,     47,     48,
+        -6,     61,     36,     -8,    -41,     -1,     13,     68,
+       140,    -51,     25,     12,      3,     57,    -54,    -33,
+       -19,     12,     28,    -60,    -56,  -2399,    -14,    127,
+      1935,     84,    127,   -193,     -3,   3307,    -56,     15,
+        31,   -116,   -187,    236,   -289,    261,     69,    144,
+      1723,     79,    -68,    102,    727,     69,    654,    -60,
+        21,    124,   3497,    248,   -684,   1469,    368,   -254,
+      -211,  -2600,    771,   -138,    368,   3089,     52,   -206,
+       147,    200,    -15,   -136,    194,   -164,   -352,   -152,
+     -4870,      5,    191,     -3,    -97,     28,    -41,    107,
+         2,     11,     60,    -76,    -35,    -42,    129,    -77,
+     -2610,   -295,   -218,   -369,     10,    253,     15,   -125,
+        74,    -87,    -70,   3366,    115,    240,   -106,    -93,
+       121,     10,     36,      9,    -18,    -66,    -77,      7,
+        37,    -76,    -22,   2913,    242,     22,    172,    102,
+       186,   -231,     90,    -11,    -57,     45,    -10,    -44,
+       -84,     44,   -117,    -43,     49,   5585,     18,   -166,
+       -43,     64,     28,     -9,     26,   -160,     31,    -28,
+        29,     56,     29,    -57,    109,    -25,   3140,   -131,
+        57,    -20,     27,    -27,     -5,    -42,    -52,     18,
+        23,    -56,    -38,    -14,    213,    -33,    -86,  -4741,
+      -151,    -46,      1,    -17,     46,      7,    -13,      0,
+        50,     28,    -57,  -7291,    -20,     12,     66,    214,
+};
+
+static const int16_t cb1616l1[] = {
+       -81,      5,    -16,     34,     19,  10938,    141,    -21,
+        27,   -105,   -110,     32,    -67,    -75,     19,   -138,
+         3,    -14,   -408,   -302,     36,  -4612,     23,   -579,
+       -35,     19,   -312,     35,    120,     97,     82,   -109,
+        41,  -1745,   -158,    299,  -3069,     84,     18,   -447,
+       -33,     65,    -32,     45,     -7,    144,     86,    100,
+     -1738,    250,   -226,   -137,    159,    -45,    134,    438,
+       102,     37,    -15,   -161,    -23,   4221,    174,     47,
+      -264,   -182,   -182,    686,   -248,     89,    -41,     80,
+     -2687,   -194,   2552,    407,  -1106,   -970,   -181,   -228,
+      4395,    118,   1027,   -255,    136,    100,    -43,    246,
+        80,     15,     34,     82,    -54,   -367,    698,    232,
+      -177,     45,    -67,     49,    138,   -158,    168,    202,
+        43,    -70,   -101,     20,    -97,  -3465,   -342,   -255,
+       127,     25,    -52,     -5,      7,     76,     -3,     19,
+       -19,     42,     10,    -63,     16,    121,    732,  -3127,
+       -43,    116,     36,  -2519,     23,     18,    181,     41,
+       -32,    -11,     22,     51,     35,     16,    -34,    -62,
+      1744,     94,    173,  -1243,   -262,     11,   3218,    239,
+       149,   -219,     29,    118,   -382,   -289,    -42,    161,
+        17,     -1,   2551,    -83,     90,   -128,    138,   3238,
+        43,    -29,   -112,    110,   -268,    293,     23,   -117,
+       -64,   -137,     79,    -70, -10747,    -66,     73,     90,
+        35,     90,    -29,    -78,   -111,     75,     48,      8,
+      -169,   2944,     16,     89,    186,    -34,     82,    241,
+       -46,    257,   -243,     93,   2966,    178,   -256,    -18,
+       -33,    103,   -320,   -271,   3088,   2893,   -250,    102,
+       696,    124,   -211,     18,   -143,     97,    216,    -99,
+       195,     40,    -35,    144,     26,    135,   -152,   -215,
+       120,     25,   -254,  -1875,    657,    197,  -3527,   -332,
+       310,    -11,   1958,    102,    -12,    -45,      2,   -127,
+         4,      1,    -19,     47,    -20,    -52,     97,    -30,
+     -7738,     51,     26,      5,    -21,     18,     15,     15,
+        66,     30,     -8,     -7,    -31,     -1,    -33,     38,
+       164,     90,   6798,    -33,    -90,    -17,     -5,     14,
+       -42,     21,    -20,    -41,     48,     -6,    -36,      6,
+      -207,  -4363,   5075,     31,      6,    100,     65,     86,
+        19,   -158,     28,   -134,    -91,    -68,      9,    -26,
+       -37,   2588,    307,   3467,   -451,    101,   -441,    323,
+        62,    188,   -132,   -294,     98,    -22,    152,    -46,
+        65,    -39,    -37,    -82,     -9,     18,     43,     17,
+         8,     56,     97, -11564,     21,     15,     75,     85,
+       155,     15,     32,      0,     20,    -45,   7412,     48,
+         3,     38,     72,     30,     23,     42,    -20,   -110,
+      -454,   -233,    653,   -325,   -276,    504,   -481,    583,
+       270,   -649,    481,  -3166,   1619,    164,    -90,    150,
+        32,    -96,    -47,     49,    -13,    115,   -183,     75,
+        62,  -9026,     12,    -93,   -715,      6,    137,   -338,
+       810,    -39,   -277,   -108,    -20,    315,    572,     -3,
+     -4570,   1053,   -132,     13,    388,   -223,   -355,     31,
+       -47,     61,   -113,      5,    -38,     43,    -47,    -80,
+      2550,     27,    247,    277,    -86,    336,    139,    146,
+      -111,    -73,    187,   -312,     68,   -276,     72,    638,
+        73,    792,   -170,   1383,    421,   -703,  -3813,    112,
+       391,   -195,   -162,    -28,    -25,    317,    228,    -83,
+      4611,    654,    353,   -380,   -283,   -627,   -301,    161,
+      -156,    -81,      5,    -15,    -13,    -17,     53,    -50,
+        36,    -66,  -7921,     -2,    -54,    -41,    -26,     47,
+        -3,     22,     -6,     11,     63,      2,     42,     71,
+       -50,    -87,    -39,      2,    -56,     -2,  11165,     44,
+      -119,    -74,    131,    134,      5,    115,    -39,    144,
+       -23,      0,    186,   4648,    351,     36,    -70,    -71,
+      1706,   2131,   -228,     42,      6,      8,      4,    -43,
+       -12,    -40,    -44,     -7,    -14,     11,     83,    -93,
+      -144,    186,    -46,     -9,     13,    -87,   -120,     70,
+      -209,    115,  -3513,    139,    -46,    133,     96,     25,
+       215,    -35,   -437,    126,    403,   -115,    145,    203,
+       -69,   -334,     37,    934,   -481,   3163,  -2528,    -49,
+        57,    100,     76,     82,    251,    288,   -114,     46,
+      -201,   -161,   -161,   -716,  -4080,    378,   -830,   -254,
+        12,  -2110,   -300,     78,    288,     48,    -90,    -99,
+       -31,   -110,    201,     66,    327,    119,   -180,    148,
+       633,     71,  -4100,     33,     57,     -9,    -48,    151,
+       -20,     72,     71,    -11,     39,    -67,    176,     27,
+       143,    198,    383,    155,   3182,   -128,   -152,  -3209,
+      -172,   -262,    -13,    129,   -167,   -128,     55,     46,
+       -37,     70,    107,      7,    -23,  -2082,    241,    236,
+       -47,    -85,    105,    -47,   -202,    208,    201,     30,
+      -106,    -14,    -38,     14,    -45,     24,    -24,  12083,
+        22,    151,    -58,     -9,     59,    170,    113,    -82,
+       369,   -155,     53,     97,   -185,    -57,    203,    311,
+       236,   4789,    -24,   -591,  -1463,    118,     94,   -274,
+      3188,   -145,   -406,    183,      0,    -54,     17,    -22,
+        37,    -55,    -34,     63,   -340,    175,   -300,    106,
+      -190,    -38,     67,     -2,     19,    -46,    -42,     11,
+       -33,    -33,    -28,    -10,    -27,  -9235,     29,     62,
+      -927,   1285,     49,     72,     65,     89,     57,    -44,
+        -9,    -15,     85,     -1,     74,     81,   -123,    160,
+        69,  -2803,    -22,     47,   -467,    -74,    748,    168,
+        -9,    235,  -3155,   -154,     48,    483,   -341,     74,
+      2403,     97,     93,   -106,    219,    136,   -191,    -50,
+         7,     71,   -103,    261,   3283,   -124,   -624,  -2570,
+        73,    -31,     10,    -73,     30,    -15,  -2256,     -2,
+       -73,     55,     73,     14,    -74,    -81,     38,    352,
+       108,    -18,     25,     61,     54,      1,     -5,    109,
+        25,  -2676,    -25,    -52,   -316,      2,     36,    -36,
+      -355,     40,    -19,    120,     27,     -4,    -51,     -8,
+        42,    -10,    -28,    -90,   -143,     29,    -10,  -8442,
+       -22,   -566,     59,    -39,     -1,     27,     29,    -20,
+         6,     19,      0,    -36,     38,     68,    -43,     35,
+        22,    -47,   -146,   3567,     13,     12,   3230,    -18,
+       -32,     75,   -112,     -8,   -157,    -23,    101,    165,
+       198,     93,    383,   1236,   1077,  -3592,  -1401,   1135,
+       844,   -266,    -74,    -70,   -280,    -98,     67,   -109,
+        38,  -5109,    -66,    -57,     89,    -21,      6,     19,
+       -21,     70,     60,     76,     35,     18,     44,     51,
+        45,     40,     54,  -6685,    -67,      9,    113,    -29,
+       -10,    -96,     80,     98,    103,    -40,     -8,    -20,
+      -131,     15,    262,     47,   -253,   -116,    -12,  -4807,
+         2,    -81,     76,    -46,     37,    353,   -130,   -191,
+      -127,    -10,    -35,     91,   -122,    173,   -165,     -8,
+    -15179,     86,   -186,    123,   -295,    -25,     21,     63,
+       -93,    730,     20,   -120,  -4624,    340,   -253,   -473,
+        44,    -18,    -99,    -37,    -54,   -317,     65,    -52,
+      2167,     68,   -245,    224,    117,   -180,  -4695,   -276,
+       118,    142,   -101,    202,   -301,    -33,   -129,   -303,
+       -90,    -75,     50,     98,    -56,    -68,   -153,    -38,
+       168,   -278,    -22,    -64,   9757,    -91,    -23,   1284,
+        53,     56,    -11,    -46,  -1645,     11,     15,     12,
+         8,    -40,     -2,     84,    -56,     17,     -7,    -30,
+     -4010,  -3557,   -252,     56,    -79,    -87,     -7,      8,
+        79,     16,     21,     51,    -63,    -22,    118,    228,
+     -1525,    -78,    -22,     -2,     16,    -49,     17,    -37,
+        -3,    -14,     10,     31,     17,   -111,     32,   -144,
+     -3612,   3473,     79,     23,    -89,     74,     33,    -29,
+        11,    -42,    -42,   -129,    -41,    155,     52,     31,
+      -162,  12609,    147,     17,     68,      2,     15,    -12,
+       -39,     50,   -108,    -66,    121,     69,    -27,     94,
+};
+
+static const int16_t cb1616s0[] = {
+      1213,  -1302,  -1130,     90,    -69,     22,   -360,    360,
+       -55,    453,   -705,   4416,    227,    173,     -8,    149,
+       210,   -118,     51,  -3759,    949,   2418,   -238,    201,
+      -597,     94,   -253,     24,    225,   -497,    -59,    273,
+       576,    651,    608,   -483,    335,   -125,    256,  -2873,
+       318,   -146,   -650,   -306,  -2021,   1044,     41,   -455,
+     -1120,    832,    978,    212,   -463,   -209,     12,   -275,
+       -20,    118,     31,    639,   5933,   -180,   -121,   -285,
+        65,    212,    439,   -135,    538,    116,   -302,   -245,
+      2534,   -623,   1549,    -34,    727,  -1750,   1477,     79,
+      1669,   -828,    618,   -856,    773,   -286,    343,    -94,
+       107,   -320,  -3144,   -380,    694,    -80,    843,    103,
+      -700,   -269,    452,  -6847,    -12,   -527,     97,    -21,
+       -76,   -246,      2,   -104,    -68,     98,    312,    117,
+      -342,   1025,    207,    838,    -71,   2463,     60,  -1294,
+      1549,  -1310,   -202,  -1585,    682,    327,    608,    649,
+       664,   -801,    588,    137,   -468,    286,    234,  -6726,
+      -107,    177,   -147,    278,    118,    -81,   -242,     97,
+      -235,   1599,   -877,   1985,    448,   -319,   -745,   -504,
+      -433,  -1859,    -35,    286,   -665,  -1449,   -124,    -97,
+       930,   2622,    682,    698,   1898,   1120,   -323,   -142,
+      -679,    294,   -162,   -539,  -1649,    152,     23,   -414,
+      1493,    602,    913,   1428,  -3212,   -103,   -330,    557,
+       463,     92,    251,    339,     16,    936,   -116,    229,
+      -827,   -504,   2015,   1553,   -503,   -350,    214,    386,
+       295,   2697,    429,     72,   -705,   -120,    427,   -139,
+      -334,   -318,  -6613,   -468,     10,   -122,     59,   -322,
+      -165,   -144,     45,   -427,    -12,    -79,   -202,   -266,
+       981,   -273,    240,   -454,    -30,   -119,    340,     92,
+      -251,    247,    189,     71,    243,  -5648,   -601,   -434,
+      -674,    867,   -713,   -428,   -101,   -231,   1144,    -89,
+       -10,     57,    302,    154,    362,   -425,   2014,   2577,
+     -8659,    389,    -90,     76,     15,    147,     30,   -202,
+       -99,   -255,   -242,   -165,    257,     97,     41,    -72,
+       263,    613,    272,    400,   5020,   -199,   -196,   -177,
+      -276,    -25,     28,     97,   -155,    119,    763,     33,
+     -3540,  -1447,     16,   -169,    148,   -143,    707,  -2483,
+       178,     83,    -83,    154,    -75,    -15,    153,    283,
+      -323,   -139,  -1390,     69,    725,  -1744,    331,  -3665,
+       415,   -514,   -366,    124,    660,   -295,    180,     77,
+      -228,    192,    684,   -193,      4,   4409,    298,    427,
+       591,    290,   -159,   -166,   -372,   -514,  -1840,   -562,
+       795,  -1765,   -349,   1178,  -1619,   -391,    615,   -784,
+      1353,    746,   -871,   -994,    182,   -464,   -498,    -96,
+      -306,   -729,    743,    270,    223,   -731,     73,   2692,
+      1110,  -2354,   -328,    -21,   -172,   -339,   -528,     93,
+      -338,    548,   1498,    309,   -134,    160,   -247,   -619,
+      1127,    783,  -1557,    400,   1035,   -445,   -155,  -2443,
+       590,   -790,    137,    388,   1188,    844,   -395,   1005,
+        55,   1141,   -122,  -3174,    138,    155,   -506,    306,
+     -3255,   2432,   -116,  -1289,   -744,   -350,      3,    192,
+      -156,     95,   -552,    -57,    329,   -405,    737,    138,
+      -835,   4096,  -1037,    797,   -417,   -418,   -507,   -694,
+      -256,     78,    -94,    -63,    -93,    754,   -555,    -90,
+     -1518,   -878,    167,   -392,   -100,    -78,    -80,    -45,
+      4774,    114,   -284,   -560,    -21,    275,     15,   -195,
+     -1692,   -711,  -1057,    167,  -1555,   -690,   -263,   -267,
+       310,   -229,    -14,   -880,    426,  -2826,    320,    -49,
+     -1223,   -725,   3538,   -270,   -606,  -1812,    481,   -703,
+       176,   -284,   -173,    271,    847,    711,    239,    314,
+      1233,    -61,    477,    429,   -691,   -156,   6712,    850,
+       365,    229,   -197,   -355,    298,    250,    207,   -437,
+     -1647,   -261,    165,    114,    165,   1165,    -58,   -597,
+     -3290,   -517,   -478,   -842,   -187,   -448,   -302,   -204,
+       410,    544,    669,  -2012,    476,    434,    214,    698,
+       302,    100,     61,     63,   -386,    918,   4434,   -230,
+       157,  -1019,  -1487,   2239,   -774,   -234,   -378,    772,
+      -190,    270,    -61,    -19,    322,    488,    937,  -3582,
+      -415,   2091,   1862,     81,   -134,   1285,  -2732,    221,
+      -235,    388,   -216,    -63,    664,   -105,    -37,    165,
+       899,   -373,    284,   -375,    286,   -263,   -295,    276,
+      -246,    188,   5285,   -303,    290,    -60,     -1,     95,
+      -703,   -288,     74,   -717,   -127,    -53,   -422,   -452,
+       166,    -54,    -15,    268,    238,    -31,   -279,  -5872,
+       863,   -907,   -101,    885,    552,    442,  -2336,  -2142,
+      -804,   -147,   -791,   1000,     96,    250,   -306,    134,
+       743,  -1648,   -867,    673,   1594,   3725,    527,   -676,
+      -661,    238,    262,    560,    277,    -58,    444,    166,
+     -1039,   -702,    558,   -970,  -1763,  -1198,    580,    378,
+      -421,   -972,    630,   -279,  -2456,  -1222,   -232,   -749,
+     -3325,    174,    789,    729,   -487,    583,   -157,   1503,
+      -801,    -38,    -11,    556,     81,   1508,   -140,     74,
+      1373,    912,   1471,      4,  -1080,   -105,    -58,   -104,
+       -54,   -544,  -2392,   1550,    318,   -506,    -11,   -180,
+     -1891,   -230,   -259,  -1182,   -154,    524,   -568,   1972,
+       546,    469,   -720,   1089,  -1530,   -680,   1349,    429,
+        82,  -1524,   1894,    -90,    188,   -145,     15,  -1113,
+        15,     53,    282,   2212,   -736,   -941,  -1148,   -344,
+      1473,    344,    392,   -333,   -556,   -480,  -3833,     35,
+      -160,   -525,    151,   -534,   -782,     38,    520,   -416,
+      -384,   7582,   -158,    -29,     74,    -57,    -23,     73,
+      -393,   -245,    -12,   -260,   -154,   -319,    357,    247,
+      -306,    351,    273,    755,    227,     89,    283,   -152,
+        17,   5129,    191,   -213,   -531,    255,   -468,   -209,
+      1128,     72,   -807,    225,   -319,   1638,     42,     20,
+       935,    -52,   -326,    541,  -1174,    130,    284,   -112,
+       444,   3959,    262,   -631,   -262,    275,   1025,    190,
+      1125,   -265,    -95,    265,     35,    270,    -92,    -30,
+      -141,    325,   -435,     45,   -659,    149,   3648,    339,
+     -1701,  -1338,   -144,   -989,   -604,     84,   -394,    168,
+      -302,  -1294,   -433,   -921,   1271,     77,    374,   -604,
+      -230,     97,    206,   -138,   2909,    478,    707,      0,
+      1242,   -340,  -1659,    349,   2751,  -1175,   -146,   1038,
+        65,   -775,   -423,     14,     22,     41,   -905,    287,
+       280,   -933,    195,  -1817,    540,  -2374,   -661,  -1102,
+       879,   1232,     29,  -1683,    286,   -136,    658,   -395,
+     -1782,  -2823,   -624,   -223,   -299,   2859,   -103,    -45,
+       544,     82,    -21,   -263,   -666,   -362,   -732,    249,
+      1087,   -242,     30,    663,   -386,   -350,   1240,   -492,
+      -868,     69,    -41,     35,     30,  -1791,   3870,   -455,
+      1355,   1098,   2933,    347,    361,     79,   2855,    -26,
+       -66,   -598,    -43,     21,   -386,   -802,    -81,   -436,
+       846,   -673,    377,   -326,  -1217,   1465,   -480,   -205,
+     -2168,  -1689,    690,    355,   1192,    734,   -113,     39,
+      -486,   -644,    438,   1096,   -723,   -524,  -1634,   -621,
+      -394,    226,    167,   -625,   -709,    854,   3005,   -910,
+        13,   -793,  -1517,  -1254,     18,   -440,   -836,    651,
+       -31,    229,  -1081,   -126,   -191,  -3612,    487,    451,
+      -292,    943,  -2018,   -618,   -259,   -649,   -723,   -447,
+      -238,   1096,  -2228,    675,    563,   -316,  -1248,     32,
+       -28,    293,  -1817,    226,    267,   1291,    624,  -2279,
+       143,    650,      5,   -563,   -504,  -2124,    -94,  -1613,
+     -3050,    708,  -3458,    442,     30,     65,    -80,     89,
+       204,   -245,     94,     28,     -2,   -231,    623,   -189,
+      -405,  -2147,   1147,   3124,    806,   1048,   1145,    653,
+        47,     86,     -4,     46,    437,    229,   -190,    310,
+      1995,    -48,  -1015,  -1806,   -266,   -941,    361,    179,
+       172,    397,    182,    323,   -516,   3435,      7,     -5,
+};
+
+static const int16_t cb1616s1[] = {
+     -2521,   -518,   1830,    985,   -500,    109,   -807,   -197,
+       543,  -1036,    104,   1989,    428,    740,   1110,   -366,
+      1482,    899,  -1828,    159,  -3015,   -311,   -792,    -42,
+         3,   -412,   -157,    -13,    863,   -248,    261,   -187,
+      -409,    156,    772,    271,    318,   -262,     78,   -571,
+        28,    370,    119,    302,  -4794,    106,   -123,   -153,
+      1857,   -702,   1090,   -319,    415,   -327,   2124,   -170,
+      -411,    174,     62,     -7,    921,   -128,    735,   -127,
+       972,   1678,    166,  -1471,   -208,   -224,    871,   -900,
+      -223,   -817,    288,   -472,     10,     31,   -401,  -3201,
+     -1290,     -3,   -301,    183,    730,    473,    438,    -81,
+       882,    -64,   2898,   -242,    408,   -211,   -333,   -254,
+      -820,    612,  -1128,    -60,    -73,  -2516,     45,    637,
+      -130,    459,   -312,   -223,   -629,   1490,   1792,   -199,
+       -21,   -545,   1772,  -1084,   -173,    381,    380,   1289,
+      -117,    483,    138,  -1200,   -519,    598,  -3453,    349,
+     -3102,   1260,   -170,    238,   -684,     48,   -483,   -883,
+      -879,    139,    298,   -110,   -203,   -955,    195,     57,
+      -550,   1945,   -711,   -688,  -1470,   1527,     58,    317,
+       656,    310,     57,    162,   2006,   1387,    845,   -127,
+      -398,    318,   2520,   2002,   -906,   -323,   -194,    907,
+       588,   -228,   -357,   -316,    557,   -596,  -1559,     -3,
+      1614,   1317,  -1701,    936,    -89,  -2270,   1327,   1046,
+       400,   -233,     18,   -730,    -23,   -181,   -593,     74,
+      -570,   -969,    432,   -261,   -833,    -90,  -4675,    786,
+      -566,   -183,   -859,   -554,    346,   -493,   -201,   -220,
+       241,   -919,  -1896,    265,   -802,   1380,   -718,  -1103,
+      -574,    307,    138,  -1260,    175,   2540,    -82,     58,
+      1046,  -1381,   2486,    582,    455,    485,   -824,   -150,
+        57,    -45,   -155,   -490,  -1108,  -2191,    833,    423,
+     -2011,    267,    779,    140,    -28,     57,     94,      6,
+      -301,      5,   -833,  -1226,   -193,   1110,    -63,     79,
+      -492,  -1465,  -2733,    444,     56,  -1116,   -601,     20,
+      -618,  -1315,   -695,   1146,    -66,    336,   -166,    158,
+       530,    -53,   -371,   -594,   -685,    114,   -146,    373,
+       174,     -1,     47,    119,   -124,   -121,  -6697,    -94,
+     -3544,   1506,   1221,   -101,   2160,    558,   -254,   -728,
+       511,    378,   -383,     12,    626,    172,    183,    354,
+        49,   1669,   1188,   3810,    409,    152,    694,  -2520,
+       342,     61,    -85,    -38,   -170,      5,    305,    154,
+      -348,    699,    332,   2542,    673,  -1130,  -2601,    554,
+      1483,    466,    271,    490,   -644,    822,    -96,    477,
+       131,  -2051,   -111,     43,    -31,    -62,   -767,  -3257,
+       663,    488,   1823,    522,   -525,   -249,    481,     -7,
+     -1298,   -941,   -335,   -566,    305,    534,   -735,    207,
+       709,  -3170,     19,    -20,  -1888,    271,  -1697,    117,
+      1837,   2690,    305,   -483,   -463,    407,   -706,    467,
+       518,   1806,    244,    -80,   -453,   -505,    882,    843,
+      1328,   -280,    175,    319,   -842,    192,   -680,   -469,
+      5440,   -205,   -187,     53,    332,    204,   -184,     96,
+      1026,   -525,     20,    975,    125,  -1562,  -1873,   -757,
+      -137,    133,    -10,   -340,   -783,  -1484,  -2206,   1238,
+     -5212,   -466,    129,   -224,     17,    497,    -41,    846,
+        88,    -41,    285,    284,   -155,     21,   -225,    150,
+       223,   -807,   -444,  -1141,   -908,    292,   -326,    559,
+      -446,   -283,    -41,   -277,  -3479,   -667,    532,     83,
+       257,    383,  -2986,   1685,    697,    777,   1551,   -142,
+      1786,    579,   -531,    787,    712,   -984,    603,   -174,
+      -459,   1303,   -943,    741,   1103,    -73,    600,   -403,
+       -42,   -169,    -90,    220,    208,    105,  -4083,  -1069,
+       981,   -926,    124,    273,   -145,   -133,    307,   4720,
+       209,    324,    -79,     12,    -41,   -220,    211,   -184,
+       435,    307,  -1544,     83,   1565,   -445,   -217,   -648,
+      -379,  -1270,  -1590,  -2337,   -860,    348,    648,   -157,
+      -785,   3318,   -123,   -138,   -412,   -876,    358,   -173,
+      -280,    -81,   -149,   -167,   -160,  -2113,     20,    -40,
+      1022,    432,   -721,     55,   -651,     17,  -1135,   -380,
+      -542,  -1128,   2919,   -475,   -143,    -53,    176,   -152,
+         7,    -29,   -172,    174,    195,  -8005,    277,    105,
+        35,    115,   -314,    137,   -253,     75,   -278,     90,
+     -1508,     79,   -153,   -560,   1027,   -349,   -292,   -466,
+     -1101,   -324,    -84,   4251,    822,   -420,     55,     43,
+      1886,    281,    964,   2408,    425,   1187,    -27,    -84,
+     -1277,     63,   -978,   -143,    506,    727,   -155,   -384,
+      3434,    592,   -262,   -438,    -30,   2849,    -69,    -58,
+      -181,    -87,     20,    299,    412,   -263,    702,    131,
+      -271,    -10,    736,    121,  -6299,   -132,   -116,     26,
+      -253,   -586,     32,   -145,   -251,    -12,    471,    135,
+       585,    604,     29,    873,    363,     -2,  -1595,     41,
+     -1147,   -142,    665,  -2752,   1302,   -358,   -134,     29,
+      -691,    -12,   -702,   -459,    100,    278,      9,     54,
+        66,   -458,     53,    213,    193,     14,   -400,   4870,
+      -950,   -209,     50,    470,    449,      3,   -118,   2287,
+      -469,    -58,    126,   1011,   -826,    386,  -1019,  -2390,
+      -586,  -1401,    137,    760,    141,    -89,    117,   -252,
+      3106,   -936,   -198,    390,    463,   -245,   -509,   -123,
+      3057,   1200,   3451,    282,   -332,   -585,   -662,   -955,
+       165,   -276,     73,    373,    202,    506,    356,    125,
+       141,   -613,   -670,    446,   2031,   1521,   -446,   1339,
+       198,   -112,    214,     70,    265,  -1310,   2492,   -133,
+     -1880,   -347,   -961,    312,  -3714,   -475,    102,    391,
+        64,   1091,   -686,   -101,    144,    447,    173,     66,
+      -374,    342,     69,  -3379,  -1331,   1160,   -889,   -858,
+       982,  -1613,   -223,     57,    186,    428,    226,   -477,
+       449,  -1052,   -661,   -382,    459,    277,   -277,   -250,
+        12,   4077,   -260,   -161,   -163,     38,    159,    243,
+       131,    457,  -2253,   -301,  -1626,     37,    806,    104,
+       191,   1899,    346,    398,  -1108,   -623,   -391,   1092,
+      1252,   1126,     81,   -116,   1192,    674,  -1321,    -32,
+      1739,   -708,   -230,   -844,   -507,    415,    261,    211,
+      -619,   -191,   5460,      8,    139,    197,    392,   -556,
+      -215,     66,     64,   -808,      0,   -136,    151,    156,
+       260,     94,    418,  -1446,   1815,   -540,   -793,    451,
+      -477,   1788,   -124,    330,   1638,    342,   -503,   -384,
+     -1201,   -762,    929,  -2886,    888,    -63,    318,    598,
+        42,  -1226,   -400,   -462,   -136,    321,   1872,    376,
+      1260,    142,    -79,   4377,      9,    294,    -71,   -190,
+       -21,  -2612,   -240,     26,    -18,   -227,    864,     79,
+      2588,   -882,     87,  -2976,      9,    480,  -1573,   -170,
+      -429,    201,   -124,    171,    632,    -60,   -447,     64,
+       -37,  -1182,    -86,   -105,   2901,  -3557,   -134,    486,
+       141,   -259,    239,    465,    467,   1009,   -409,     34,
+       254,   2469,   1002,    834,    557,   -845,    149,   -747,
+      -504,    494,   1382,   1067,    353,    191,  -1105,   1705,
+      -586,   1472,   -444,  -1303,    198,    602,    471,    468,
+      4855,    127,   -141,    487,   -454,   -138,   -392,   -118,
+      -491,   -948,     58,   -290,     -7,   -662,    229,   -268,
+        -2,   -537,   -620,  -4770,   1152,   -173,    166,    -69,
+        32,  -2555,    433,   -583,  -2219,   1107,   1082,   -942,
+      -173,    399,   -601,    250,    423,    125,   -448,    352,
+      -571,   -406,      0,   4735,   -264,   -174,  -1020,   1105,
+     -1149,   -171,   -252,   -130,   -202,    -74,    601,    601,
+       570,  -2742,  -1403,   3129,   -349,    194,    309,    130,
+       261,     93,    154,   -117,   -418,   -657,    270,   -160,
+      1660,   -818,    613,  -1458,   -653,  -3763,   -232,     90,
+      -265,    -99,    -28,    -13,   -281,   -553,     11,   -142,
+     -1764,  -4548,    936,    -21,   -683,    -88,   -806,   -187,
+        28,     78,    -70,    -99,     -2,   -493,    -16,     48,
+};
+
+static const int16_t cb1616m0[] = {
+     -3821,  -3397,    203,    -25,    -22,     68,    189,    -13,
+      -286,     94,     18,    288,     29,     -5,      3,   -414,
+      1483,   -172,  -1275,   -180,  -3792,    360,    145,   -143,
+       444,   -139,   -198,     70,    -17,   -353,   -121,     -6,
+        76,    -50,   2987,    173,  -3070,   -229,    -16,    192,
+       134,    -55,    -86,   -200,    128,  -2052,    -59,    -11,
+        -4,    309,    179,    494,   -138,   -363,   -336,    119,
+      -127,   2497,   -169,   -316,    -87,   -538,     42,   -534,
+       315,   2364,     61,    269,    -87,    -94,     82,  -2069,
+        18,   1238,     -7,     79,     -9,     41,     70,     50,
+       209,   -158,   -136,     28,   -275,     62,    296,     77,
+      6269,   -184,     73,    -19,    -25,    -57,    134,    -52,
+      8569,   -176,     -8,     17,     15,     79,     36,   -137,
+        12,     44,   -270,   2335,    111,    517,    -83,    207,
+      -276,   2577,   -198,     83,    376,    -75,   -273,     62,
+       109,      4,    -48,    122,    -41,     99,    -87,     14,
+     -7696,   -118,    -66,    171,     96,    -31,    123,   -217,
+      -676,   -439,    407,     97,   -281,   1873,    626,   -148,
+      -548,   1634,    704,     97,  -2076,   -336,    632,   -371,
+       113,    544,    -88,    184,  -2200,   -420,   -592,   -168,
+       759,    291,   2215,    704,   -140,   -145,  -4088,    295,
+       186,   -270,    283,    294,    -42,     76,     69,     41,
+      -140,   1635,   -200,   -682,    302,   -192,    902,   -540,
+      -843,   -494,   -529,    102,   -759,   -165,   3160,   -180,
+     -1450,   -424,    -16,      6,   -548,    296,  -3056,    219,
+     -1883,   -109,   -566,   -431,     95,   -422,   -532,    -26,
+       120,    -46,     23,    174,    175,   -369,    110,     -2,
+        25,    132,     -1,  -3338,    -67,   2140,    -25,    566,
+      -129,     35,   1187,    337,   1999,   2712,    -71,     45,
+      -177,     94,   -321,   -197,   -573,     98,    225,     46,
+        53,     78,    -40,     82,     23,   2718,   2534,     89,
+       -65,     77,    206,    343,    527,    102,   -191,     94,
+       463,    111,  -4529,     97,    876,   -205,   -944,    181,
+      -132,    467,    366,     85,   -302,   -100,    -33,    -76,
+     -3087,  -2546,    215,    277,    -52,    352,    137,    -45,
+       162,    590,    406,    382,     85,  -2824,    141,    219,
+     -3790,     40,    126,     32,     30,    100,    121,   -210,
+       196,   -268,    178,    102,   1229,    -80,   -750,    -11,
+       -57,     84,    238,   3571,    274,   -254,     55,  -1616,
+      -176,   -755,     46,  -1306,   -201,   -228,    101,    197,
+       -93,   -156,    319,     82,   -385,    -17,  -4660,    180,
+      1278,   -113,   -215,    103,    832,   -233,    412,    249,
+      -900,   -132,  -3427,     52,    416,    267,    317,   -384,
+       130,     78,     91,   -360,     75,    386,   2219,   -360,
+     -2975,     17,    286,   -294,   -213,    231,    131,    821,
+      -358,    222,   -230,    -44,    -93,  -1151,    294,   -316,
+        -8,    129,    231,   -993,    -58,   3319,     48,  -2546,
+      -213,    -14,   3208,    162,   -240,   -176,    307,   -165,
+       -20,    348,   -113,    -78,    -91,     -8,   -261,   8033,
+      -179,     64,     -7,   -113,    -59,    -32,   -170,     52,
+        55,    -80,    140,     64,    -39,    915,     28,    416,
+        38,  -2328,    206,    115,    366,    -92,    652,    110,
+     -2838,    -59,    613,     23,    109,   -151,   -198,    185,
+      3033,   -122,   2863,   -273,     86,     41,    114,    -99,
+       315,    372,     14,   2191,   -171,    531,    -18,    -34,
+      -352,    130,   -360,    117,  -2896,      2,   -564,     51,
+       223,     57,   -257,   3161,   3130,   -384,    126,    -40,
+      -160,   -232,   -138,     81,    -34,    -96,     82,      9,
+        62,   -161,    344,    100,    790,   -243,   -344,   -393,
+      -531,    401,     90,    171,    144,   -329,      7,  -4639,
+      -135,     -6,    351,    -21,   -195,    224,    -25,   6027,
+       224,    -14,    344,    170,   -169,    -97,    252,   -488,
+      -379,    -73,    629,     -9,    266,    152,    -64,    330,
+        -8,   2080,    -91,  -3315,    229,     25,     45,   -528,
+      -123,   2951,     40,    -85,     -4,  -2695,    -38,   -112,
+        84,    -30,     79,    762,    151,  -4089,    -95,   -151,
+         9,    138,   -206,     -3,  -2114,     99,   -100,    116,
+      -403,    -56,     -8,    -36,    115,    -18,   -195,    -38,
+      -240,      8,    -32,    122,    125,  -7406,     45,   -210,
+       111,   -152,   -152,    -35,    -72,     28,   -154,    303,
+     -3147,    459,  -2881,    -14,    -13,    -56,   -126,    -69,
+      -213,    -97,    202,    -88,   -277,   -557,    451,   -376,
+       -91,    319,    141,   2728,     23,   2506,   -101,    632,
+        62,   -314,    159,     44,   1231,    -65,    -37,    192,
+      3118,   -186,   -396,   -108,     71,   2111,    586,     95,
+        15,    -28,    176,     20,    -67,      3,   -265,    101,
+      -182,    -21,   -455,    -15,  -6225,    -45,   -353,   -384,
+       -22,    113,    -40,    -47,     57,    -73,   -503,    134,
+       736,    -70,   -125,     -5,   -250,     62,    165,    182,
+       185,   -132,    426,   -276,    100,   -497,    -23,     81,
+      -112,  -3528,  -1997,   -234,   -154,    -91,   -125,    -26,
+       179,   -611,    655,    767,  -1064,    130,   -264,    107,
+      2811,  -1391,    298,    -20,     37,    -74,    -12,   -157,
+      -270,   -106,   2559,    -89,  -3107,     55,    187,   -265,
+       195,    140,      1,   -484,    713,    171,  -1123,   -226,
+      3666,   -367,   -516,   -249,     38,    195,    236,   -378,
+      -383,   -205,    -72,     -7,     15,  -9329,     -6,    -26,
+        56,    141,     48,      6,   -141,    -95,    -69,    -40,
+       -99,    -80,     73,   -253,    456,   -174,     51,   -250,
+       -48,  -2115,    -63,  -2555,    -25,  -2058,    -58,     66,
+       176,     14, -10053,    -23,    -39,    -37,    -15,     38,
+        82,     11,     97,    169,      5,    -67,     57,     61,
+     -2248,    108,    -19,    256,   -169,   -122,   -336,   -431,
+       -77,   -250,   -156,   -745,    184,    684,  10559,   -199,
+       -34,    -37,     96,    -82,    -17,     60,     65,     21,
+       -67,   -337,     62,     35,     74,   -214,     38,     47,
+      -129,   6139,   -139,    -57,   -154,    261,      7,   -127,
+       109,     40,    179,    -99,    198,    -51,     48,    -36,
+     -2377,   -194,   -334,  -2826,    103,   -220,    -57,     41,
+       979,   -895,     68,   -217,  -1712,   -430,    -98,     91,
+      -107,  -1755,   2615,     84,   -500,    231,    480,    -31,
+       146,   -157,   -120,    152,   2342,    -36,  -1969,     57,
+      -109,    476,   -243,    261,    -58,   1998,      4,   1388,
+       -98,     45,   -140,    400,    -76,   -321,    -22,     -9,
+       210,    517,      5,  -4708,     66,   -330,   -405,    -19,
+      2158,    -65,  -2163,    244,    -16,   -192,    494,   -381,
+      -194,    413,     89,    220,    455,    -54,      4,    206,
+       221,  -4998,     63,   -365,    354,    364,    677,    207,
+       -66,    -27,   -477,   -182,    841,     85,    -40,    166,
+      -185,    321,   -293,   -181,   -429,   -231,   1401,   -122,
+       938,     67,   -185,     51,   3188,   -802,    421,  -3230,
+      1432,   -432,   -658,   -587,   -843,    421,    177,    446,
+       510,   -140,    -90,   -127,    -78,      2,   1089,   -185,
+       301,   -393,   4100,   -152,    265,    224,     25,     95,
+       534,    280,   -254,    -45,     -5,   -207,     49,   -126,
+      8922,     43,      9,     21,     28,     21,    -42,    -84,
+        38,     90,  -2014,     61,   -149,    188,  -3350,   -120,
+       -43,     10,     14,    155,   -225,   -351,   -114,     28,
+       -23,  -4400,    367,    -51,     76,    -89,   -113,    122,
+      2007,     25,   -348,   -227,   -370,    -61,    135,    -79,
+};
+
+static const int16_t cb1616m1[] = {
+      -321,     -7,  -6725,    -36,     77,    -20,   -101,   -529,
+      -166,     97,    -76,   -232,    -70,     16,     13,     93,
+       -50,    222,   -258,  -4424,   -125,    125,     83,    313,
+      -246,   -325,    108,   -331,    484,   -188,    192,   -964,
+      2603,    -38,  -2236,     58,    337,   -254,    -17,    -90,
+       -88,     40,   -141,  -1293,    -56,   -811,    247,    -78,
+       -34,    144,    112,     43,    142,   -137,   -147,     56,
+      -406,     12,    210,    132,   3707,    109,   -896,   -268,
+     -2295,   -509,     32,   -219,    113,   -104,    141,    273,
+        18,   -358,     16,  -3354,   3474,   -167,    220,     10,
+       104,   -175,     -8,    -71,    -77,    -48,    277,     82,
+        86,     35,   -712,    -32,     36,    -65,    213,    121,
+       -76,   -742,    291,  -4587,   -169,   -122,    -77,   -285,
+        54,   -120,     89,     71,     12,   -133,     54,   -215,
+     -1906,   -115,   3220,   -194,   -391,     87,    415,   -212,
+      -210,   -138,    182,    590,    713,    944,    320,    142,
+     -1970,    197,    -79,   -548,    458,   2836,     33,    -62,
+      -183,   -149,   -640,    147,   -427,   -113,   -178,  -1631,
+      -108,   2666,    -58,   2210,   -251,    288,     16,    382,
+      2123,    636,     -4,   1118,    232,    335,    -33,   -114,
+        24,    -68,   1309,    -38,   2080,    534,    288,   -162,
+      -630,   -360,   -643,     10,     62,  -2229,    263,     19,
+       310,    -44,    419,   2846,  -2579,   -159,   -246,    685,
+       -67,    394,    314,   -356,   -158,     19,     90,    116,
+     -2261,    163,    664,    163,   -191,    -49,    -18,   -308,
+       -15,   2508,   -370,    693,    -62,    818,   -307,   -658,
+       133,   1858,  -4900,     53,  -2485,    -48,     -9,    126,
+       159,      6,    -71,    291,    102,   -367,    -62,     27,
+        88,     -6,    204,    -65,   -725,     31,   -159,     -1,
+        -5,     45,   -133,   -146,    261,  -4481,    -19,    694,
+      -261,   -478,   -177,     88,    214,   -836,    -14,   -762,
+      -111,    501,      0,    254,   1971,  -1024,   2678,   -141,
+     -6064,     76,    430,    160,   -195,   -582,    280,    580,
+       183,   -315,    -13,    665,    -53,    315,   -199,    438,
+       220,   3267,    194,      2,   2808,    -88,     42,    150,
+      -179,    237,   -155,    143,     46,     99,     27,     30,
+     -6137,    -51,    -89,    201,    145,   -179,     13,   -358,
+        55,     71,     -3,     28,     -9,    -16,    125,    160,
+       159,    -21,  -5407,   -485,     -4,    -88,    -89,     44,
+         3,    166,     22,   -413,    993,     80,    485,   -107,
+       446,   -943,   1025,    261,     -3,   2991,    547,   -268,
+      -109,    536,    -10,    187,     17,    388,   -120,    -71,
+      -343,   -416,    162,     69,     -9,     46,   -477,     83,
+      6134,    146,   -236,   -125,    -94,    -55,   -274,   -231,
+      1120,    171,   -139,  -2714,     80,   -111,     20,   2475,
+      -135,  -1710,    317,   -762,    155,   1222,     68,   1192,
+       -15,   1825,    -36,    -45,   -120,   -484,   -131,   -162,
+      -128,    163,   -407,     72,   -222,    -46,   -222,  -5319,
+       278,   -373,   -436,    284,    138,   -243,   -104,     28,
+       -77,   3022,     93,    -15,   -581,   -498,    292,   -165,
+     -1740,    121,    195,  -1368,   -134,    -68,    -20,    -75,
+       -10,    113,    128,   -381,   -507,   -237,   -709,     13,
+       -22,    155,  -5065,    -95,    246,   -226,    193,    687,
+      1839,    246,   -232,   -359,    475,    106,    297,    205,
+     -2702,   -378,   -219,    -20,    140,  -3198,    192,  -3077,
+      -135,    -38,    -23,    213,    -72,    255,    -90,   -130,
+      -150,     62,   -484,    -94,  -2625,    -89,    344,   -129,
+      2655,    369,    -35,     17,   -697,    251,   -343,     68,
+        53,    176,   3104,    237,    -75,  -3020,    178,     45,
+       -86,     45,   -115,    183,     49,     26,    140,     77,
+        40,  -2315,    249,   1791,     48,   -755,    -12,    201,
+      -455,   -250,    -62,   1729,   -113,   -959,    238,   -114,
+       289,   -135,  -2208,   2748,     65,    306,    -83,      3,
+      -513,   -481,    -49,   -163,   -568,    -88,    668,    -51,
+     -2586,    106,    -22,    584,   -453,   -350,    333,   -177,
+      -236,   -657,    536,   -349,    394,    -56,     14,    133,
+       -55,    -84,    210,    -19,  -8647,    154,     80,     27,
+        -7,    -76,   -117,    100,   -201,      1,    296,   -101,
+        -6,   5642,    137,    -59,    -93,     95,   -110,   -280,
+       -61,   -300,     25,    887,     43,    -30,   2493,     76,
+       -22,   -343,    489,    266,    308,    163,    132,   -349,
+      2021,     18,  15536,     61,     11,    -41,    -42,     41,
+        -4,   -183,    -40,    -24,     26,    241,   -102,   -115,
+      -164,   2044,    -35,   -217,   -226,    734,   -228,  -2546,
+       218,      0,    122,   -150,   -528,   -188,  -1273,    155,
+       107,    -33,    -37,   -293,      6,    112,   -155,   -228,
+       192,  -2378,    153,  -1045,    213,   2975,     39,   -159,
+       -10,    -41,     34,   -125,      4,    -30,   3907,    -41,
+       848,   -346,    191,   -195,   -292,   -126,   3421,    -24,
+      -244,     92,    693,     64,   -193,    192,    121,    -33,
+      -141,    523,   -162,   2754,     71,     59,     40,    -63,
+      -142,   -100,   -338,    379,   -136,    -64,   -196,     11,
+      3198,    162,   2097,   -132,  -2359,   -193,   -398,   -318,
+       842,   -635,   -168,    425,   2001,   -136,    290,    206,
+       562,    -96,     -8,   -214,    -45,    -11,      4,     52,
+       177,   -148,    229,     33,    -48,    -46,   6538,   -106,
+       -27,    -22,   6527,     20,   -405,    157,     87,    208,
+      -117,     -4,     30,     87,     28,   -356,    -76,   -108,
+       -33,   -568,   -270,    177,     49,   -457,  -3210,    119,
+       103,    256,   -180,    211,  -1209,   -369,   -256,     37,
+       -47,   4976,     84,    207,    225,    224,   -425,    396,
+       921,     58,   -150,    104,   1509,     15,    -58,   1724,
+        47,    -24,     21,    376,    353,    482,   -236,    634,
+       306,   3179,     73,    -33,    -54,   -169,   -214,    146,
+      4322,   -216,   -644,    305,    305,   -453,     53,    143,
+        -9,  -1472,   -141,   1314,     57,     40,    -55,    -80,
+        67,   9264,     57,     86,     22,   -147,      1,     -6,
+         0,     39,      7,    114,    -51,   -137,    155,    -15,
+      -122,      5,    137,    125,    213,     -6,   7158,     36,
+       -52,    -54,    149,    901,    859,    703,    366,    673,
+       -13,   1186,    588,   -202,   -451,     18,   -585,   -250,
+     -2632,   -134,     61,  -3038,   1022,     78,   -672,   -276,
+        96,    838,    533,   -254,   -525,   -106,   -378,   1627,
+        12,     31,    317,   -118,     81,    313,   -186,    197,
+       452,  -2971,     83,   1326,    419,  -2366,   -328,    -87,
+      -103,   -243,   -280,     25,   -240,    590,   -232,    105,
+     -2966,  -2391,   -326,    338,     80,   -392,   -243,    271,
+        -7,   1127,      1,   1901,  -2279,   -207,     32,    -99,
+       560,   -193,    371,    494,    506,    255,    332,  10737,
+        48,      8,    -33,    -33,     32,    -33,     45,   -104,
+      -259,    -99,    -37,   -134,     72,    -50,    138,    428,
+     -2258,     77,    744,      5,     96,   3020,   -269,     49,
+       112,   -223,    186,     48,    224,   2571,    340,   -129,
+       -39,  -1900,    -45,   1978,   -261,    223,    294,     22,
+      -108,    -58,    109,    -31,  -3252,   -138,  -2969,    -19,
+      -133,    190,    -36,    132,   -136,     63,   -175,    351,
+       -76,    232,  -2708,    -17,    -24,   -130,   -474,     74,
+     -2978,     45,   -139,    -23,    227,    -42,   -141,    278,
+        81,      8,  -2491,   -446,    315,    -64,   -167,   -643,
+      -275,    100,      0,   2484,   -482,   -128,   -144,   -206,
+};
+
+static const int16_t cb4432l0[] = {
+     -3764,   -227,    184,   -258,  -1713,    122,    410,    -32,
+      -244,  -1337,   -328,    -20,   -236,   -359,    -13,    -52,
+       -75,   -260,    426,    -96,    -37,    -38,    117,   -938,
+       487,     60,    286,    571,    368,   -551,    198,   -102,
+        15,    -11,   4535,   -127,   -241,    114,    -77,   -316,
+       302,    195,   -149,    -73,    357,   -128,    -23,     34,
+       319,    -97,    189,   5918,    -20,   -134,    -47,   -249,
+         7,      3,    116,      7,     48,     47,     92,     19,
+        14,     31,   -388,   -329,  -1878,   -944,    958,    632,
+      1973,    182,   -130,   -193,   2309,   -868,     63,    260,
+       -12,    -89,    -88,   -208,    127,   -168,    237,     74,
+      1153,    925,   2292,   2992,    -35,    204,    766,   -930,
+       -87,    341,   -101,    501,     35,   -182,    112,     91,
+       -28,     79,    193,    -73,    -71,     52,     82,   -427,
+      -147,    -69,   4722,    468,   -187,     98,   -295,    292,
+      -991,     43,     98,    225,   -555,   -595,    -66,   -181,
+        91,   -152,     -3,     89,   -219,    356,   -375,   -114,
+     -1546,   -620,    648,   1946,     39,   -608,   -942,    103,
+       179,    170,  -2350,    157,   1132,   -944,   -283,     64,
+      -393,     15,    -90,    761,   -185,    644,   -360,      5,
+     -5212,    106,   -136,    -40,   -159,    -40,   -120,    -43,
+        -8,   -195,    208,   -179,   -295,    -63,     19,     32,
+      -104,    -23,    132,    660,   -460,    237,    523,   -676,
+      -378,    -81,   -184,   2718,     64,    531,   2119,  -1564,
+       614,    933,      6,     65,    -50,     55,    243,   -539,
+      1168,    953,   -283,     45,    476,   -346,   2285,   1892,
+       615,   -521,     23,  -2079,     57,    -11,    208,   1029,
+       371,     28,    170,    -63,   -167,    184,   -217,     76,
+      -320,  -2747,    542,  -2098,   -407,    -10,   -876,  -1477,
+      -306,    565,     57,    -49,   -111,    185,   -250,    120,
+      -186,    214,   -520,    463,    792,  -2420,   2760,   -383,
+      -783,  -1097,   -441,   -535,   1070,     78,     96,    122,
+      -193,    516,    114,    100,   -413,    100,    -23,   -153,
+      1267,  -4210,   -742,    228,    659,    399,   -169,    412,
+       -81,   1056,      4,   -254,    173,    109,   -218,    196,
+        64,     26,   -113,    -60,     -8,     15,   5497,    -76,
+       169,   -294,   -394,    596,    379,     12,    -64,   -203,
+      -138,     41,   -249,    -53,    -44,    -19,     55,    -34,
+        99,     36,    -70,      8,     46,   2787,    842,   1917,
+      -693,   -424,    151,    464,  -1162,   1027,    148,  -1027,
+      -173,    328,     23,    792,   -184,    395,   -684,    229,
+      -139,     -7,   2788,    404,     43,  -1508,   -590,      6,
+      -184,    904,    475,    -37,    276,   -361,   1924,   -188,
+      -113,  -1334,   -176,     11,    -34,    -70,    -68,     95,
+      -433,    225,    437,   -451,    471,   -272,   -385,   2793,
+     -2685,    544,    881,    409,   -789,    700,     -5,   -144,
+        66,    -17,    504,   -397,    264,     74,    -81,  -1803,
+       444,   -573,    633,   -391,  -3339,    192,    484,   1126,
+      -306,    153,    303,     61,   -253,   -255,    -57,   -277,
+       -88,   -100,     32,     79,  -1320,   -857,   3080,   1178,
+       323,    353,   -149,   1316,   -399,    236,   -129,    231,
+       323,    696,     59,   1217,   -567,   -268,    642,    384,
+      -327,    -47,    466,   1530,   1092,  -1176,    612,    257,
+      -143,   -270,    487,    -62,    332,   1089,    961,   -706,
+       938,     78,     97,  -2805,  -1088,   -871,   -273,     87,
+      -345,    148,    113,    167,     97,     31,     68,    -47,
+       -53,     53,     29,  -5723,    -53,    -12,    241,     92,
+       131,    139,     48,    102,    -26,    -47,    664,   -580,
+        -7,   1287,   2531,   1061,   -710,     24,   1389,  -1742,
+       254,  -1147,    539,   -150,    -24,    495,   -204,   -171,
+       955,    202,   -111,    147,  -1458,  -3973,    421,   -416,
+      -544,    392,   1419,   -178,   -168,    -53,     50,   -537,
+        -7,   -346,   -289,    -52,    -38,   -259,   -115,   -136,
+      -138,    -89,   -205,   -661,  -4429,   -110,    380,   -721,
+      -180,    127,  -1371,    -78,    276,    319,    229,   -934,
+       267,   -353,     44,     65,    449,    -32,    159,    -11,
+       -22,   -571,    100,   -676,   2892,  -2740,    907,    511,
+       248,    441,    -62,   -517,   -347,   -235,    319,     -8,
+      -140,    309,    258,   -106,    215,      1,  -3252,    426,
+       455,  -2213,   1031,    430,    746,    367,    602,    187,
+      -147,   -200,     97,    555,   -107,   -249,    -71,    101,
+        59,    -94,    -64,    -33,    221,    184,   -791,    671,
+      -191,    284,  -1311,    402,    -29,    250,   -190,   -503,
+        38,    106,    586,   4767,    526,    147,   -182,    249,
+       146,     17,    293,  -1095,   1079,   -161,    141,     -2,
+       681,   -275,   -171,  -4504,     61,   -105,   -306,    -66,
+       229,     20,   -102,    -93,    334,   -189,      5,     -6,
+       417,   2551,    -63,   -852,   1608,   1820,    670,   1592,
+       102,    203,    147,   -767,   -147,    310,   -718,    175,
+       551,    -98,   -202,    309,     70,     81,    -55,   1518,
+       222,    338,   -356,    349,     97,     86,    495,   -233,
+      -121,   2936,    200,    935,   -381,   2474,     53,    494,
+       248,   -139,    -45,    100,  -1287,   -181,   -370,    311,
+       287,   3016,    -96,   -128,   2146,    567,   -383,   -551,
+       -96,    144,    495,    428,    -32,    137,     27,   -272,
+      -149,      9,    -61,    177,  -5236,     91,   -837,    611,
+      -279,    -74,    652,     14,   -178,    -82,    -89,    347,
+      -245,    647,    -62,     49,   -215,     29,    -55,    -27,
+       178,     79,    -19,    -59,    177,   -152,      0,    189,
+       -10,    128,   -115,     33,     61,   -106,     56,    -13,
+       135,    116,  -5772,    157,     43,     26,    -11,    102,
+        -4,    -52,    208,   -186,    198,     99,     81,    -29,
+      -103,    193,    -35,    -84,     -4,   -111,  -5251,     84,
+        71,    -85,    -77,     55,    234,     38,      0,    -35,
+        60,   5875,     98,     36,   -219,    -17,   -419,   -136,
+        47,     34,     55,    -21,    -17,     -1,     72,     94,
+        52,     -3,   -703,  -1437,   -518,    557,    121,    356,
+      -345,   -717,   -438,   -279,     13,     70,    -95,     -2,
+     -4170,     40,    136,     17,   -153,      8,   -149,    -27,
+      -559,    268,   -237,    -82,   -220,   -921,   -588,   -150,
+      3481,  -1906,    647,    675,   -455,    598,   -386,    -52,
+        -7,    222,   -201,     90,     54,     75,   -283,    118,
+      -375,   5768,     20,   -126,   -141,    -99,     64,    116,
+        16,    -58,      0,    -31,    -15,    250,   -104,    -30,
+      -144,    115,     12,    117,   -482,  -1709,   -436,    122,
+      -246,     -7,    271,   1961,    154,    149,    -86,    147,
+       258,    531,   1760,    914,  -1196,  -1800,    812,   -621,
+       125,   -161,   1361,     50,   -651,  -1307,    360,   -785,
+       205,   -156,    294,     21,  -3484,    -18,    -79,   -266,
+       770,    307,     29,   -765,   -250,    183,     55,    131,
+      1452,    260,    224,    221,   -347,    360,   -352,  -2188,
+      -664,   -503,    313,    406,   -251,   3268,    210,    -46,
+       129,   -276,    343,   -143,    104,    -55,    461,     17,
+      -576,   -287,   -289,     33,  -2500,    -85,   -428,  -1137,
+       918,   -245,   -490,   -260,   -270,   -133,   -591,    199,
+      -294,   2784,    102,     19,   -109,   -745,     91,   -524,
+       -44,     28,    252,   -511,    -80,   -146,    271,    519,
+      -216,  -2280,   -411,   3699,   -368,   -538,    427,   -158,
+       114,    -50,   -589,   -340,   -180,    703,   -186,    487,
+      -649,    668,   -916,   -436,  -3684,  -1016,    877,    -65,
+      -153,    -62,   -148,    -17,   -106,    142,    -73,     -1,
+       -68,    567,   -658,    815,   2270,   -563,   -519,   -226,
+      -223,   -282,    584,    240,  -1522,  -1935,   1169,    880,
+       127,  -1276,   -127,    399,     63,     25,  -1297,   2131,
+       592,   1652,   2609,     69,   -581,   -179,    947,    597,
+       150,     35,      0,   -255,   -232,   -728,    239,     91,
+       130,   -234,    231,     56,  -2181,   1774,  -2196,   1633,
+     -1065,   -662,    777,   -175,   -128,    267,     -7,     51,
+        27,   -133,     95,   -500,    188,   -167,     94,   -176,
+       -29,    -65,   -161,   -141,   -694,   -968,    594,   -269,
+      -422,   -472,   -731,   1210,   -816,   2142,  -1321,  -1746,
+      -149,   -983,   1310,   -839,    762,    284,     99,    -31,
+     -1169,    -84,  -1119,    -55,   -720,   -944,  -1115,   -271,
+     -1032,   1064,    187,  -1013,   2987,     26,   -209,    516,
+        -8,    107,    -24,    188,    278,    -53,    624,    460,
+      -275,  -1881,  -2001,    851,  -1740,   -407,   1643,   -352,
+       -17,   -528,   -538,   -175,    179,    416,   -297,     54,
+       132,   -491,    -76,     34,   -440,    175,   2065,  -2006,
+      -164,     38,   -403,    902,   -129,    215,   1545,   -414,
+     -1183,   -532,    578,    248,   -308,    189,   -563,   -345,
+      -949,   -279,   1693,   -959,    101,    783,      9,   1641,
+      1494,    167,   -294,   -538,    951,    115,    590,    105,
+      -847,  -1003,    464,   -368,  -1268,    641,    254,    243,
+       488,   2636,  -1209,   -272,    437,    445,    781,   -463,
+      -415,    538,   -811,    588,   1083,    206,   -547,    171,
+      -585,   -744,    343,   -604,    395,    -76,    910,   -523,
+      -108,   -449,    625,   -325,  -1079,    273,  -1473,  -1096,
+      -137,   -565,   2077,   -623,    214,   -342,   -273,    769,
+      1137,   -879,   -731,     56,  -1098,    211,    822,    579,
+      -839,    164,   -600,    -80,     61,    316,    644,   1445,
+       891,  -1796,  -1798,   -162,  -1631,   -492,   -626,    593,
+       544,     66,     63,   -857,  -1273,    406,   1665,    899,
+      -467,     87,   -117,   -469,    126,     30,   -931,   1446,
+      -190,    388,  -1608,   -316,  -2199,   -127,    484,    -51,
+        56,   -524,   1524,   -103,   1231,   -740,    717,   -861,
+       823,   -665,  -1790,    411,   -690,    303,  -1615,     63,
+      -232,     19,   1090,    -96,    137,     80,  -1027,    581,
+       -61,    672,    133,    444,   -767,    766,    -42,  -3174,
+      -270,    -23,   -126,  -1111,     67,  -1367,      4,    315,
+       -53,    -90,   -165,     48,  -1657,   -117,    392,    356,
+       792,   -610,   -618,   -219,    446,    102,    374,    207,
+      1026,   2480,   -461,   -782,   1161,  -1351,   1032,    486,
+      -308,    290,   -272,    899,   1912,     36,   -624,    286,
+      -428,   -623,   -665,     12,   -621,  -1985,    -34,    468,
+       318,   -467,    127,   -972,    -39,   -663,   2307,    -26,
+       406,   -468,   -657,  -1404,   -342,   2356,   -395,  -1422,
+     -1243,    465,     90,   -665,   -280,   -290,    -21,  -1752,
+       280,    271,    395,    240,   -402,     55,   1077,    148,
+      -309,   1818,    483,  -1293,     43,    261,    566,   -131,
+       947,   -815,   -872,  -1021,  -1001,   -395,    263,   -555,
+        78,  -2193,   -360,    -76,  -1029,   -493,   -464,   1339,
+       -53,    750,   -671,  -1349,    133,    -70,    114,    501,
+       766,   -816,    703,   -992,   -122,   -520,  -1323,  -2539,
+      -365,    -35,   -555,   -888,   1515,   -191,   1322,   1633,
+      -674,    451,  -1246,    270,   -868,    703,   -394,    106,
+      -779,    754,    650,   1066,   -417,  -1305,    149,   -165,
+};
+
+static const int16_t cb4432l1[] = {
+     -3867,   -448,   2202,    129,   -100,    393,     37,   -267,
+      -156,     23,   -274,    222,     33,   -191,    104,   -140,
+       -50,    -28,   -148,   -181,    -22,      6,    489,    993,
+     -2764,   1191,   -773,    781,   -460,    843,    -77,  -1417,
+       390,    124,   -203,    205,    662,    -16,    569,   -963,
+       609,   -155,     64,   -293,   2649,  -2533,     70,   -472,
+      -482,  -1732,    235,     -5,   -485,    116,   -177,   -104,
+       314,   -355,    118,     25,    921,    285,    130,    -94,
+        77,    121,   1068,   -435,   1407,    447,   -427,  -1096,
+      -757,    258,     19,   3236,    702,    362,   -928,   -348,
+      -150,   -784,   -687,   -388,   -176,    -38,     16,    -14,
+      1017,    879,    935,   1280,   1014,    -85,   -256,   -103,
+     -3384,   -928,   -200,   -406,   -175,    304,    -54,    195,
+       -78,    676,   -356,   -167,   -165,    -56,  -3133,    156,
+      -171,   -684,   -698,   -135,    230,    -30,     32,    542,
+      1959,   -124,    -76,    162,    182,   -174,   1011,    -97,
+       678,     10,    188,     30,   1086,   -262,   -157,    250,
+       241,    233,   -584,   3276,   2126,    -50,   -207,    637,
+      -440,    331,   -434,    251,   -267,    269,   -392,     68,
+      -244,      8,    928,    827,  -1096,   -309,   -356,   -375,
+     -3204,    422,    695,      2,    240,    595,    641,    582,
+       342,     42,      7,    539,    -64,   -116,     82,     16,
+        26,   -136,   -122,   -114,  -5814,     22,   -272,     10,
+       113,    186,   -422,    -95,    309,    308,   -118,   -208,
+        52,   -175,     12,   -106,     -6,     20,     58,   6053,
+      -101,    -20,     10,     70,    189,     57,    -11,    210,
+        83,    239,     -6,    -79,   -233,    -59,     31,    -30,
+       -62,     64,    -38,     25,    -78,   -202,   -215,   -115,
+      1477,    255,    101,  -2575,    186,   3140,    -46,    -45,
+        53,   -183,    -89,   -412,    183,   -222,     50,   -237,
+        96,     35,   1684,   -521,   -169,   -436,   -295,   1390,
+       261,     27,    163,    352,     68,  -3677,     12,    310,
+      -599,    331,    138,   -333,   -269,   -130,    -44,    -14,
+       265,   -626,    258,    -59,     31,    -17,    222,    -10,
+      -364,    280,   -183,   -235,   -217,     73,    -67,    114,
+       196,  -5132,    269,    159,     -6,    -36,   -248,    274,
+      -328,   2712,   -393,   2763,    507,   -110,   -166,    -84,
+       -72,  -1111,    -19,    370,     25,      5,    156,    -32,
+       237,    -57,   -106,    -22,    370,   -229,   1099,   4297,
+       152,     72,    -56,    347,     64,   -501,    -57,    178,
+       175,    -14,    -84,   -626,    555,    155,     20,    -75,
+        20,    -33,   -254,   -125,     -9,    150,     91,     -7,
+       -45,    239,   -109,     72,    -66,   -172,   -211,   6063,
+      -205,    171,    -75,     50,    -75,     22,    109,     21,
+       -58,     58,   -105,   -432,    310,   3782,    -18,  -1071,
+        19,     20,   1455,    337,   -257,   -288,    -52,    519,
+        43,     80,   -175,   -218,      9,    176,    -28,   -418,
+       200,   -514,    351,    119,  -5920,    -96,    -33,   -289,
+        74,     26,    120,    -37,    113,     47,   -145,    -17,
+       334,     46,     47,     19,    274,    172,    159,   -404,
+      3151,   -408,   -559,    987,   -178,    253,    -90,   -498,
+      1454,   1183,    392,    762,    220,  -1207,   -220,    -69,
+       -85,     22,   1644,   1858,    725,   1084,      0,   -257,
+       290,   1712,   -151,   -188,   -390,    638,   -327,  -2185,
+      -322,  -1116,   -150,    120,   -140,    198,    162,    -83,
+      1321,    232,    242,    -52,   -456,    778,   -288,     65,
+      2431,     37,     85,   -489,    862,   2776,    260,    -72,
+       792,    100,     17,   -210,    588,     49,    600,    246,
+      -258,    128,    -51,   -492,   -395,   -489,     50,  -5308,
+       -67,    314,    124,     46,   -188,    -64,   -101,     51,
+      -535,    108,     56,     -4,   -191,   -923,    485,    578,
+      1320,    228,   -535,    310,    227,    395,  -1441,   2660,
+       226,   -392,    221,   -686,   1749,   -175,   -904,   -571,
+      -129,    154,   2622,    609,   -247,   -240,   -893,     98,
+       291,  -2277,    411,    260,   -160,   2061,   -203,   -437,
+       359,     21,   -101,     19,     49,     15,    -98,     82,
+         3,   -555,    164,   -152,    -58,     38,    175,   -439,
+       -37,     68,    -21,   -181,  -5556,    -27,      8,     48,
+        21,   -151,    381,      3,   -152,    -74,    202,    -29,
+      1863,   1713,   -922,  -1976,    551,  -1522,    525,   -116,
+       146,  -1730,   -238,    -72,   -183,    126,    234,   -240,
+        82,    138,    -60,   -131,  -2226,    226,   -702,    183,
+       -81,    462,  -2851,  -1419,  -1005,    124,    -81,   -252,
+       -65,    147,    -58,   -179,    306,    154,    122,    -69,
+        69,     11,    115,    296,   3340,   -501,  -2580,   -804,
+         9,    591,    -86,     88,    127,    588,    183,     48,
+        79,    -38,   -199,     63,   -140,     29,     88,    -28,
+       259,     69,   1743,   -531,    110,    -18,    776,    -18,
+      -177,    112,     36,   -243,   -208,    528,    -47,   4709,
+       107,   -125,    140,     -1,     22,     15,    416,   -194,
+      -267,    -49,     43,     -3,   -308,    214,   -128,    140,
+      5372,   -123,     70,    275,    210,    182,   -147,   -131,
+       -84,     69,    116,     29,   -401,   -162,   -236,   -173,
+       378,     45,    -12,    -77,  -6209,   -103,    126,     54,
+       -19,    -20,     43,     64,     92,     -8,    -12,    118,
+      -123,     58,  -3628,   -414,  -2147,     76,     95,    -99,
+       357,    -10,    278,      4,   -608,    504,    105,    -72,
+      -109,    -92,    -55,    367,   -167,     40,    -34,     76,
+       220,   3434,   -366,    191,    248,     29,    187,   -177,
+       155,   -348,   -341,  -2466,    272,   -136,    510,    139,
+        81,    184,     33,   -299,     92,    -44,   -402,   -583,
+      -725,   -400,   -159,    751,   -225,    377,   -160,   1556,
+     -2652,    685,  -1077,   1276,    332,   -257,  -1449,   -282,
+      -231,   -145,     58,    173,    421,    271,    401,   -186,
+        79,   -258,    127,    252,    214,     96,    157,    195,
+       205,    118,  -4771,    -95,   -164,    217,    477,    -51,
+        -4,      8,   1450,    -51,    -52,    952,    675,    929,
+      -273,    475,      9,    282,   -249,    236,    746,  -1407,
+      -272,   1845,    692,   -105,   2690,    168,      1,     -1,
+       157,   -599,    305,    255,  -2252,     45,   -199,    119,
+     -3489,   -161,      6,   -263,   -259,    338,   -251,     61,
+       153,   -124,    432,     -7,    131,      5,    305,   -322,
+     -3283,    -32,   -336,   -273,   2243,    863,     -1,    681,
+      -365,   -246,   -152,    375,   -133,    -15,   -208,   -104,
+        89,    128,   -135,     44,   -255,    549,  -2751,    -48,
+       270,  -2584,   -549,   -631,    445,    182,   -198,    743,
+      -215,    -60,   -400,   1383,    167,    -65,    250,    146,
+       185,     22,   -484,   -161,     86,   1758,    964,    404,
+     -2574,   1026,      6,   -516,   -724,    315,  -1891,    311,
+         2,    339,    -39,    324,    299,   -497,    -12,    179,
+     -1242,    364,   -185,   -197,  -1474,    232,   -490,   4042,
+      -105,    887,     31,    539,    235,     75,   -112,   -200,
+       -31,     74,    -76,    -16,    -20,     38,   -159,   -143,
+       114,    -77,   -110,     28,    -18,    -84,    -27,    -53,
+       -82,   -224,     75,      0,    -46,    -64,     44,   -112,
+        84,    -85,  -6030,    -24,    661,   -474,   -178,      8,
+     -1023,   -396,    199,    -19,    -50,    -93,    385,    209,
+     -1227,   2492,   2163,    986,  -1359,    399,    848,    681,
+      -829,    211,    696,   -599,  -1398,   1951,   -113,    374,
+       -17,  -1113,  -1708,   1294,    666,   1774,    623,    259,
+       105,    961,    -87,     43,   -463,     65,    155,    -26,
+       -31,  -1477,   -508,   1091,  -1463,   -524,  -1853,   1354,
+       434,     86,    893,   -871,    151,  -1887,    205,    423,
+       857,    -55,    -11,    -39,    341,     61,   1158,   2650,
+       899,  -2491,   -593,   -843,  -1399,    -15,   -713,   -171,
+      -195,   -523,    -46,    243,    117,    241,     -8,    140,
+      -149,   -191,     70,    134,  -1158,   1933,   1135,  -2284,
+     -1049,   1717,    378,   -155,    -37,    171,   -692,   -280,
+       918,   -786,   -123,    558,    571,     39,   -315,     62,
+        27,     59,    708,   -134,   -200,   -168,   -134,    148,
+      -142,     25,    164,   -282,    284,    -95,    -35,    376,
+       165,    367,   -335,    271,    249,  -4520,    176,    -36,
+      -216,  -1303,    375,     92,    602,   -889,   -390,    284,
+        78,  -1318,   1259,   1865,   1498,   2063,   -234,   -840,
+      -391,     88,    168,   -235,    -74,     31,   -239,   1221,
+        71,  -1637,   1513,     68,   2201,   1513,  -1099,   -622,
+       426,    343,   -330,   -648,    381,   -156,     27,    -31,
+       -92,    133,    210,    103,   -155,   2061,   -366,  -1173,
+       -31,   -274,   -713,   -471,    509,   1044,    208,    403,
+       486,    -66,   -521,  -1883,   -180,   -537,   1283,    -98,
+     -1464,   -456,    508,   -619,   -546,    685,    944,    -85,
+       311,   1172,   -194,   1406,    -99,   -827,   1506,    396,
+       196,  -1534,  -1181,   1588,   1250,     47,   1034,   -171,
+     -1247,    -98,   -120,   1181,  -2195,   -384,    945,    627,
+        26,   -248,   1372,   -671,    214,   -649,    -17,    -44,
+      -500,   -559,    577,   -601,     32,    421,    531,    344,
+     -1233,    145,    348,    614,   -560,   -244,   -357,   -202,
+       814,   -494,  -2320,    308,  -2277,   -481,   -518,   -431,
+      -851,     43,   -204,    -26,   -742,   1083,   -130,   2002,
+      1642,  -1156,   1746,   -529,    937,   -544,    416,   -741,
+       763,   -232,    509,    243,   -458,     78,   -130,    143,
+      -123,     71,   -666,   -105,     31,  -1061,    441,    -48,
+       411,  -1547,    155,   -730,    439,   1624,    873,   -611,
+      -470,   2348,   -157,   1184,    678,   -174,    542,    -95,
+       -12,   -405,    237,    322,  -1194,   1903,   1496,    357,
+       -34,   -661,  -1024,   2236,    860,   -256,    617,    756,
+      -485,   -273,   -589,    536,    214,   -286,    782,    418,
+       346,   -462,    443,   1056,   -914,   -304,   -564,   -332,
+      1823,   2079,     93,   -975,   -891,  -1089,   -720,  -1127,
+       702,    300,    787,    374,    -78,   1070,    691,   1339,
+      -797,     57,    482,    432,    748,   1538,    673,   1885,
+      -504,   1913,   -190,   -135,    881,   -139,     84,    379,
+      -176,   -129,   -331,    -34,   -690,    282,   -563,     51,
+        71,   -714,   -103,   1074,   -651,   -582,   1388,   -320,
+     -1115,   1547,  -1088,    -65,  -2634,   -201,   -653,    116,
+      -238,   -218,    476,   1417,   1671,   1135,  -1025,    614,
+      -662,    127,    863,   -117,    726,   -971,   1382,   -286,
+       465,   1195,   -715,    862,  -1256,    105,     37,  -1190,
+      -442,  -1777,     50,    162,   1577,    580,    762,    253,
+        92,   -308,  -1238,   -161,    295,   -150,   1733,   1831,
+      -527,   -527,    -28,     70,   -359,  -1590,    860,   -221,
+        47,  -1201,   -254,     39,    780,   -326,   1097,  -1019,
+       834,    362,    357,     41,    693,  -1099,  -2687,    614,
+       270,   -128,   -322,  -1149,    631,    -46,   -343,   1495,
+      -896,   -864,   1545,    200,   -922,  -1133,   -637,  -1231,
+       484,   -796,   -743,   -371,    999,   1300,    173,    -19,
+};
+
+static const int16_t cb4432s0[] = {
+     -2558,   2751,   -440,   1200,   1067,   -725,   -492,    588,
+       234,   -209,   -108,   -230,    223,   -231,   -235,   -132,
+       -51,     88,   -290,   -214,    -99,    -60,    175,   2546,
+      -991,    907,    446,    635,    284,    707,    238,    220,
+      -308,    259,      8,   -435,  -2207,  -1487,  -1579,     46,
+       285,   -249,    154,   -370,     37,     42,   1524,  -1853,
+      1393,   1204,    126,   1751,     82,    136,    363,  -2411,
+      -782,   -128,   -818,   -232,    765,   -173,   -127,    732,
+       260,   -101,    868,   -249,    290,     32,    645,     55,
+     -1742,  -1077,    392,   -568,    629,   -920,   -243,    791,
+      -604,   -363,    117,  -1360,    -15,   -245,  -3655,     54,
+      -297,     10,    124,     11,  -1114,   -567,   3882,  -2042,
+     -1120,    -42,   -114,   -914,    419,    307,     44,    277,
+      -101,    429,    170,    187,   -528,   -705,    348,    -19,
+       180,    -76,     91,  -1861,   -181,   -171,    804,   -730,
+       222,   -184,    349,    191,   -125,     14,   4270,   -467,
+      -272,     29,   -216,    212,    426,   -222,     11,    -16,
+      -852,    101,    576,    178,    351,    647,     90,    179,
+      -681,   -187,     77,   4115,   -976,   -726,    711,    763,
+       572,  -1166,    -46,   -445,   -103,    135,    294,    300,
+        10,    737,    386,   -399,   -349,    -52,   5393,   -107,
+       -32,   -229,   -154,   -181,     82,    -68,    -13,    -77,
+        48,     75,    117,    -50,    254,    233,     98,     75,
+     -2218,  -2214,   1491,    832,    225,  -1057,    267,    539,
+      1963,   -245,   -353,    454,   -430,    -54,   -747,    -58,
+      -438,    -90,    -64,    277,    214,   -105,    -47,  -1301,
+      -404,  -1179,    682,  -4093,    764,   -270,   -342,   -367,
+     -1378,      6,    -83,    429,    398,     61,   -149,    180,
+        31,    169,   -218,    152,    -71,    -38,   2605,    679,
+      -175,   -533,   1787,    611,    484,   -322,    158,   -561,
+       125,    -35,    -42,   -190,    529,    449,    157,  -3105,
+       106,    168,     -8,    -66,    -80,   1463,   1136,   4793,
+       -98,   -432,    538,   -145,    241,   -158,    105,   -372,
+        39,   -160,     92,   -223,     81,    245,   -142,   -162,
+      -167,   -297,    -49,    -98,    582,  -5178,   1130,   -271,
+       567,   -251,     55,    487,   -303,     31,    -25,     87,
+       -70,    154,    -23,   -221,     70,    208,     48,   -137,
+        46,     59,     -9,  -1397,   -970,    224,    714,    161,
+        24,   -307,   1295,   1467,   -155,   -505,   -521,   -244,
+       503,    -25,   -989,   3664,   -148,     12,   -135,    218,
+      -159,   -156,   -769,   -421,    553,    715,    697,   -181,
+      1426,    425,    -39,   -103,  -4558,    171,    347,    161,
+       170,    128,   -210,    -35,     31,    125,   -264,   -135,
+      -100,   2685,   -230,   2062,   1618,    -99,   -874,    926,
+       757,    380,    404,    -73,     30,     29,    462,    725,
+      -389,   -246,     20,    150,   -234,    -58,   -183,     10,
+       156,    482,   -232,    124,    115,    180,   -615,   -395,
+       330,    -85,   -435,   3279,   1493,    686,   1157,    245,
+     -1067,  -1953,     23,    796,   -540,    175,     56,  -1931,
+        89,    705,   -342,    551,  -1999,   1951,  -2305,   -497,
+      -266,    275,  -1503,    351,   -355,   -353,    236,   -358,
+      -271,    -40,    136,    217,    -13,    -45,  -2091,   1141,
+       730,  -1888,   1131,    660,   1271,    439,   2597,     92,
+       319,    -91,     62,    316,    287,   -260,    121,    -33,
+      -117,    -22,    -79,   -170,   -164,   1486,    134,    -62,
+       -36,  -3367,   -235,   1221,   1239,     78,    -54,   -489,
+       268,   -560,   -774,    851,   -973,    -62,   -174,   -138,
+      -459,    390,    -22,    -42,     83,   1339,   1307,    462,
+     -3768,    511,    300,   -525,   -787,    -89,    675,  -2074,
+        37,    -48,    252,    598,   -332,     67,   -187,      2,
+      -106,    -35,   -148,   -186,   -542,    799,   2363,   -155,
+      -665,  -2867,   -209,   -200,    -80,   1682,   1082,      2,
+       516,   -481,    276,     -1,   -220,     54,    -12,    259,
+       161,   -148,    566,  -1489,   -731,   1262,    499,   -816,
+       115,   4057,    -71,    701,     39,   -132,   -223,    -16,
+       229,     -2,    -40,    -61,    234,    405,    108,    304,
+       -62,   -396,   1369,  -1438,  -2045,   1954,    759,    969,
+      -166,   -235,   -115,    -68,   1923,   1815,   -776,   -855,
+        34,    -63,     17,     87,    223,   -145,   -130,    -16,
+      -313,  -1704,   -458,   -332,    420,   1332,    676,    878,
+     -3847,   -360,    427,    537,    651,   -167,   -451,   -197,
+       277,    136,   -201,    517,     10,   -156,     35,   -927,
+      1250,   -173,   1004,   -169,    322,   -140,   -559,  -4656,
+      -343,   -264,    -61,    -12,    195,    -10,   -123,    -23,
+       -20,     -6,   -367,   -102,   -215,     41,    838,   1513,
+       552,  -1609,   -753,   -763,   -656,   -633,     14,     35,
+       141,    117,   -121,    857,  -1494,    578,   2546,   1034,
+      -676,    571,    817,   -218,   -111,   1424,    -51,    878,
+     -2860,   -257,    104,   -526,    782,    708,   2350,   -500,
+      -342,    219,   -406,    836,   -117,    288,   -415,    798,
+        14,   -311,   -455,      3,   -410,   -144,    -30,   -977,
+      -145,  -2466,   -957,   1370,  -3201,   -327,    -85,    149,
+      -580,    198,    350,    140,   -104,    327,   -128,   -178,
+        58,    294,     50,   1814,    581,   -909,    287,   -267,
+     -3992,     61,   -860,    258,   -271,   -223,    237,   -291,
+        -3,     66,    110,   -620,    319,    -62,    177,    364,
+       110,   -163,   -921,   -863,    251,   4922,    280,    121,
+       128,    209,   -126,    578,    -56,     41,    124,    350,
+       245,   -465,    -67,      5,    651,    147,    200,      0,
+        21,   -609,   -332,     -3,    247,   -412,    128,     42,
+     -1405,   -301,   -341,   -484,   -491,    -55,    361,   -100,
+       -30,   -405,    643,   4249,    -31,    -91,    -10,      6,
+       425,   -350,  -1501,    817,  -1348,   -201,   -345,  -3643,
+       235,    691,    332,    219,    199,   -398,    130,    -50,
+      -190,     89,    -23,    100,   1327,   -200,    146,    482,
+      -624,   -479,   -391,    188,    129,    614,   -335,   -564,
+      1021,   -107,   -199,    145,    201,    571,   1276,   4253,
+        58,    121,    295,     38,     26,     47,  -1333,   1138,
+      3125,    357,    -72,    347,    276,   -272,    120,    -77,
+       535,    247,    -71,  -2054,  -1860,    -73,    -62,    266,
+       -30,    183,     17,    -46,     -7,   -140,    997,    526,
+       -47,    -59,   1540,    373,    162,   -150,   -107,    -74,
+      -278,    -37,   4268,    -21,   -269,    359,    111,   -115,
+        -5,   -206,    -87,    -44,   -517,     54,  -2859,    189,
+      -297,   -863,   -918,   -929,   -543,     25,  -2866,    -79,
+     -1101,   -275,   -410,   -458,    -75,   -211,   -420,     96,
+       467,    -66,    -15,   -580,   -420,   -586,     -7,    109,
+       236,    227,   -488,    106,    258,     76,     78,     -8,
+      -199,  -4888,   -134,   -205,    -33,   -243,    -19,    -10,
+       157,    129,    120,   -928,    604,   -345,    -47,   -430,
+      -257,    273,     81,   1949,    490,    272,   -205,   2460,
+       -54,    103,  -2924,   -529,   -211,    -60,    279,    220,
+       -57,    342,    209,    984,  -1410,  -3363,  -1028,  -1301,
+     -1293,    227,   1142,  -1068,   -512,    758,    364,     46,
+      -358,     16,    257,   -158,   -253,   -182,     -2,    181,
+      1475,   1574,    215,   -968,    246,    369,   -273,   -717,
+       546,     74,  -3872,    293,     98,    130,   -244,     41,
+       143,    699,    -56,   -126,     67,     54,     -2,   -878,
+      2334,    883,    215,  -1979,    246,   -759,    499,    248,
+       751,   -202,    580,  -3018,    359,   -139,    210,    -47,
+      -168,     89,   -659,    259,    -54,    -40,   -490,   -169,
+      -769,    569,   -171,     64,   -845,    519,   1251,    -71,
+      -459,  -4436,    257,   -334,   -826,   -183,    115,   -408,
+       -77,    544,    173,   -258,     48,    331,   1735,   1035,
+      2793,   1154,  -1901,    275,   -109,  -1185,   -403,   1332,
+      -282,     36,   -367,     21,     27,    362,   -425,    217,
+       150,   -304,    192,     53,  -1100,     27,    628,    698,
+      -634,    -25,     84,      8,   -103,    533,   -301,    218,
+      4350,    119,   -109,    309,     24,   -352,   -147,   -274,
+       156,     85,      9,   1706,   -854,   2012,  -1573,    112,
+      -673,  -1538,    -91,    415,  -1525,    866,   1493,   -621,
+      -396,    277,   -604,   -363,    114,   -360,   -252,    -18,
+       -31,    -77,   -591,   2483,    535,  -1520,  -1057,  -2189,
+       -51,    798,    276,  -1426,     72,   -303,    402,    111,
+       327,    272,     -8,   -216,    189,   1282,    152,    -45,
+       -33,   1524,   2301,   -341,   1992,    939,   1678,   1011,
+       114,    167,    586,   -500,     40,   -473,   -274,    596,
+      1237,   -126,    205,    254,   -284,   -367,   -119,     64,
+      1915,    437,   -585,      1,    402,   -271,   -984,    530,
+       267,   3634,    495,   -219,   -728,    -67,  -1340,    983,
+       122,      6,    110,   -166,    111,    102,   -139,  -2499,
+       753,   1011,   1755,  -1252,    872,   -510,  -1844,   1388,
+      -782,    287,    461,     36,     77,    437,   -361,   -216,
+      -415,    158,    -77,   -123,     57,    -93,   3408,    504,
+      -942,    434,   -648,   -251,   -420,   -387,   1373,   -229,
+       236,   -191,      3,    204,    612,    393,   -285,    560,
+      -164,   -199,    303,    146,     93,   1248,   2425,   1001,
+      1261,   -239,   1085,  -1878,   -375,   -544,   -995,   -192,
+      -319,    542,    280,   -716,  -1323,    -67,    -34,    252,
+       -36,    206,   -126,    -28,     26,  -1135,   2799,    527,
+       -47,  -2008,    509,   -232,   -953,    332,   -386,   -108,
+       290,    507,    578,   -809,    375,    850,  -1413,    831,
+      -137,    259,     25,  -1075,    407,   1784,  -1539,   1658,
+      1450,   -969,    467,      4,    785,   -595,    912,     34,
+        91,    286,   1035,   -524,    276,   -322,     11,    651,
+       733,    243,     45,   -145,    357,    524,   -697,   -259,
+      -757,  -1057,    181,   1324,    148,   -502,    -64,   -379,
+      -746,   1385,    395,    184,   -749,   -197,  -3375,   -546,
+        -4,    532,   -270,    687,    501,    285,    401,    431,
+     -1888,   -639,    655,   -325,   1896,  -1883,     53,  -1018,
+     -1475,    802,   -486,    -68,    232,   1337,    428,    232,
+      1754,  -1687,   -518,   -372,    508,  -1269,    327,   -900,
+      -468,   1127,   1397,   1597,    837,    659,   -617,     99,
+       264,   -460,    296,     44,   -295,   -209,   -174,   1105,
+       896,   1065,   -174,      5,    845,   1311,   1370,  -2548,
+       351,   -660,    -24,  -1089,   -787,  -1312,    -22,   -585,
+      -197,    749,    293,   -112,   -169,    -23,      3,   1151,
+       529,   1173,    224,  -1517,    930,    -52,    268,  -1282,
+      -559,    466,   -528,   1506,   -231,   -337,    993,  -1314,
+      -250,  -3042,     57,     19,     15,   1812,    697,   -389,
+      -201,    647,   -723,  -1098,   -177,   -225,  -2694,   -495,
+      -431,   -238,    388,  -1731,    997,    227,   -765,   -222,
+        94,   -611,     35,    187,   -935,  -1470,   1013,   1051,
+      -378,    311,   -710,   -566,   -532,   -369,  -1599,    553,
+       167,    450,  -1068,   2834,   -125,    601,   -113,   -503,
+        40,     14,    -36,   -220,  -1543,    867,   -612,  -1834,
+       888,  -1791,   1296,   -229,   -593,   -760,   -197,    428,
+     -1290,    892,    -62,   1113,  -1228,   -965,    -90,   -300,
+       288,   -133,    779,  -1211,   -627,    268,    180,    913,
+      2230,   -413,   -146,   -217,    170,  -1157,  -1551,    877,
+        75,   1784,   -174,   -230,   -757,   1243,    625,    -49,
+       114,   -218,   -409,    195,  -1165,   1492,    213,   1100,
+      -101,   -957,   1016,    663,   -704,    817,     94,   -279,
+      -256,    469,    -75,   -123,  -2954,    948,   -407,    275,
+};
+
+static const int16_t cb4432s1[] = {
+      5416,   -223,   -123,    156,    -33,    185,   -144,   -108,
+      -199,    -68,    -36,     11,     37,    124,   -301,     58,
+       -21,    155,     99,    -10,    -78,    -26,    -70,  -3160,
+     -1037,     98,    155,   -373,    834,    652,   -277,   -429,
+      -529,   -103,   -358,    187,   1161,   -157,    147,   -400,
+       461,    156,    237,    481,    -67,     99,    939,   1179,
+      -659,   1337,    578,   -489,   -481,   -427,   -622,    131,
+      1826,   -734,   -995,     -5,   -461,    514,    -83,   -271,
+     -2928,    -86,   -382,   -205,   -133,   -386,   -195,    -67,
+       508,    586,    607,   -910,   -181,  -2046,   1212,   -179,
+        23,    408,  -1929,   2044,   2160,   -879,     74,    179,
+        72,   -164,     47,    162,   1497,    826,   2978,   -912,
+       454,   -618,  -1907,   -501,   -494,   -299,     96,   -138,
+      -114,    -51,   -171,    445,   1144,   -187,    217,    224,
+       402,     13,     42,    -58,  -1692,   4162,   1272,    970,
+      -278,    327,     88,    -31,   -182,    279,   -610,     78,
+      -432,   -147,   -142,   -725,    -17,    -95,    388,    133,
+       -61,     28,  -1365,   1441,    606,    411,    923,   -332,
+      1843,   1934,  -1451,   -514,   -283,    768,    940,   -428,
+        31,   1105,    248,    -78,  -1477,   -367,    404,     68,
+      -178,     17,    691,   -265,   -105,   1681,   -476,  -1307,
+     -3434,  -1700,   -524,   -871,    472,   -171,    237,    104,
+      -142,   -231,   -292,   -285,    266,   -259,   -166,    -97,
+      -432,   4003,   1220,   -356,   2110,   -220,   -465,    -48,
+       117,   -178,    290,    -21,    205,    -19,    321,   -343,
+      -328,    -57,    215,   -345,    304,      2,     10,  -2071,
+       185,    433,    212,  -1165,    112,    242,   -294,   -162,
+      1107,   1176,   -396,   1400,  -2600,   -434,   -640,    457,
+       100,   -268,    809,    128,   -236,    -66,    -94,   -842,
+        82,    163,    227,  -2641,   -485,    291,   -326,     42,
+       234,   -648,   1355,   3016,  -1403,    -71,    188,    792,
+        15,    -16,   -522,    -75,    106,   -824,   1133,    947,
+       477,   -642,   -531,   -808,   4100,    -34,   -407,    133,
+        33,     15,     63,     72,   -223,    -15,   -491,     38,
+        47,    258,   -236,    192,   1628,    173,  -2116,    687,
+       295,    -74,   -183,     95,    529,    149,   -372,    182,
+      1317,     21,  -1424,  -3156,   -111,    -96,    580,    284,
+      -274,     41,    145,   1314,     79,   1830,    262,   -325,
+       -16,    169,   -245,  -2038,   1959,    892,    946,    303,
+      -171,   -432,    883,     34,   -238,   2463,   -294,     25,
+        24,   -106,    -45,    509,   -154,    496,    109,    115,
+       169,    702,    396,    -97,    657,   -251,   -112,   -114,
+      -144,   -230,    517,   -190,   4885,    -45,   -152,     -9,
+      -170,  -2021,    541,   -905,  -2015,   2588,   -936,    -20,
+      -300,    384,    433,   -123,    119,   -505,   -126,    295,
+       526,  -1352,    450,    142,   -126,   -115,      1,   -140,
+      -734,    672,   -147,   -660,   -747,    652,    161,   -163,
+        51,   -616,  -1974,   1413,  -3145,    922,  -1289,    215,
+       182,   -838,   -171,    107,   -333,     34,    216,   -307,
+      -359,    496,   -343,   -325,  -2552,  -1573,    588,   -441,
+      1296,  -3075,    119,   -131,     54,    206,    278,    106,
+      -100,    112,    220,    -49,    -80,   -229,   1051,   3271,
+     -1300,    324,    -31,  -1025,   1659,   1526,   -161,    669,
+       -56,    430,    201,   -535,   -126,     -9,   -380,    222,
+       212,   -345,   -282,    195,    -41,  -1235,   -593,   -593,
+      1557,     71,   1023,   -831,    545,   -875,    161,   -772,
+        99,   -190,   1616,    338,   -251,   -201,  -3104,   -774,
+         4,   -121,    178,    -80,    652,  -1018,   -441,   -343,
+      -236,   -240,   -244,    -26,   2192,     75,  -1348,   3771,
+       -22,   -850,   -251,    316,    132,    -21,     63,    104,
+       152,    185,    -40,    275,  -1356,    482,   3081,    571,
+      -481,  -1387,    815,   1285,   -352,    -98,    -41,    573,
+      -307,  -1879,    427,    196,    169,    -26,   -232,    -98,
+      -411,   -231,  -2034,   -969,    271,   1421,  -1485,   -407,
+      1404,   -343,    861,    888,    -11,    202,   -245,   -397,
+       104,    229,    309,  -2757,    315,    416,    393,    194,
+      -176,   -663,   -166,   -229,    244,   -152,    183,     24,
+      -205,     97,   -255,   -299,    123,    -12,     53,    102,
+      -362,    371,    223,     46,    132,  -5177,    157,    -92,
+     -1114,    -28,    135,   -831,    627,   -428,  -1116,    421,
+       761,    458,   3256,   -167,    355,   2045,    113,    234,
+      -154,     20,    -39,     61,    -81,     63,     98,   -171,
+      1727,  -1193,   2103,    416,   -421,   -575,   -636,   -114,
+       700,   -260,   1610,   -336,    521,   2591,   -738,     43,
+       103,    -63,   -335,    168,    110,     41,   1995,   3554,
+      1443,    -53,   -206,    992,    767,   -372,    141,    -24,
+       173,     60,   -237,     69,   -173,    -73,    137,    167,
+      -164,   -159,    312,   -151,    -78,    619,   -192,    689,
+       -69,  -2805,   -259,   -288,   -231,     28,  -1682,   2316,
+      2298,   -336,   -131,     59,    542,   -218,   -281,   -214,
+       -41,    116,    138,      8,   -297,    -45,   -215,   -167,
+      1587,  -1061,  -1976,   -445,    401,  -2392,    -42,    581,
+      -519,   -230,   1461,    542,    113,   -634,   1776,    332,
+       191,      5,    174,   1939,    -26,   -242,    120,    230,
+      -986,   3501,  -1125,    -89,      3,   -580,   -219,   -255,
+        37,   -119,     94,    -17,   -297,   -176,   -434,   -234,
+        55,    -63,  -1167,   -492,  -1753,  -3397,    185,   -794,
+       689,    819,    -32,   -836,    335,   -133,    724,   -299,
+      -318,    424,    558,   -654,    119,   -447,    140,   -100,
+        72,   -872,  -1432,   -203,    -40,    -14,    -59,    550,
+        85,    -53,   5007,    258,    401,   -184,   -313,   -170,
+        66,   -185,    -82,    -61,    210,     48,   -204,    -96,
+       130,   -562,  -1700,  -1037,  -3926,   -884,   1115,     -6,
+      -100,    842,   -450,    877,     76,    568,   -623,     27,
+        73,   -195,    328,     41,    -24,    124,    -77,   1499,
+       540,  -1064,   4517,    -22,    -35,    839,    -48,    253,
+      -259,     96,    409,     90,     26,   -177,    365,    -48,
+      -324,    -26,    -23,    -83,    -77,    -80,   1599,   1486,
+       266,    659,    236,    231,    -16,    359,   -163,    455,
+      -999,  -1169,   2453,   -599,   -945,      4,  -2110,   -174,
+      -736,    344,    232,    142,     32,    -99,    763,    133,
+      -325,    -56,   1635,   -439,    843,      2,  -1704,    -13,
+       771,   3680,    -89,    182,      4,     42,    394,    404,
+        82,    312,     91,    141,  -1577,   1765,   3141,    625,
+      -271,  -2122,    423,    353,    489,    606,   -290,   -190,
+       486,   -131,    118,    236,    248,   -209,     -2,   -162,
+       -95,     95,    170,    278,  -2233,    549,     34,   -846,
+      3595,    445,   -400,    -65,    131,    -14,    -16,    611,
+      -116,   1293,     98,   -680,    189,    217,    -15,   -549,
+       131,      8,   -768,  -1082,    841,   -346,    129,    -33,
+      -778,    322,  -2508,  -2128,  -1895,  -2021,    -27,    -42,
+       -51,   -536,    239,     -1,     78,    105,     48,     79,
+       207,    422,   -181,     18,    -94,   -152,   -181,  -5012,
+      -187,     -3,   -118,   -397,    -84,    -49,    129,   -276,
+       188,     45,   -146,   -235,   -109,     83,     32,    -79,
+      2039,   -616,    257,  -1575,  -1756,  -2364,    222,    195,
+     -1138,   -290,     58,   -641,   -252,    -11,    402,    -31,
+     -1040,   -592,    676,   -118,   -231,     94,   -123,   1642,
+      1404,   -334,   -728,  -3425,    382,    111,   -194,    677,
+       177,   -182,    434,    860,  -1022,     84,   1214,   -733,
+       300,     -2,   -259,    140,     35,     96,   1164,  -1476,
+      -757,    -74,    239,   -203,   1796,   1207,   1732,  -3029,
+      -610,    658,    490,   -465,    136,     56,   -614,   -612,
+      -123,     93,   -151,    162,     56,    502,   1634,  -1825,
+        45,   1033,   1554,  -2380,   1615,   1317,    786,    387,
+      -255,   -423,    -44,   -246,   -213,   -149,    107,    -74,
+       -94,     45,   -204,     13,  -1959,    936,   2023,   1000,
+      1031,    112,    574,    323,    163,    947,   -657,    492,
+     -2624,    -44,    739,   -305,    -31,    247,    270,    213,
+       -46,    -90,     43,  -1504,    931,    -61,   4045,   -863,
+       389,   -386,   -130,   -374,   -583,   -800,   -900,    158,
+      -455,    169,    134,   -164,     54,   -117,   -185,    -90,
+      -203,    -41,   -811,  -2082,    169,    287,   -378,    -15,
+       231,     83,     89,   -187,    198,     18,    178,    -18,
+       527,    -40,     94,     54,     79,  -4356,    248,    162,
+       -94,  -1431,    -31,  -2048,    651,   1231,   -508,  -1089,
+     -1255,    766,   1673,    357,     13,   -813,  -2403,    179,
+      -470,     65,   -339,    154,      9,     56,    246,     66,
+     -2308,   1443,   -947,   -744,  -2473,  -1248,   -113,   1017,
+      -608,    149,   -182,     41,   -524,     16,    285,   -268,
+      -781,    -57,   -346,    194,    256,    -51,    107,   -484,
+      -190,   -125,   -645,    487,    314,     74,   -555,  -1012,
+       325,     76,    233,   -205,   -189,    -48,  -4593,   -122,
+        10,    121,    -91,    108,    -49,    254,  -1662,   2500,
+        87,  -1540,   -200,    287,   -329,    -50,   -401,    182,
+     -1300,    689,    915,   -224,   -768,    471,   -339,    133,
+       407,   -344,     99,     96,    111,   1224,  -1431,   2069,
+      -282,    127,    397,   -119,   1332,  -1299,    744,   -535,
+       800,    327,    874,    700,   -424,  -1596,   1365,   -651,
+      -151,    113,    102,    -24,    464,    125,    911,  -1583,
+      -372,    747,      2,    429,    -47,    -64,     34,   1700,
+      -741,    343,    728,   -226,   1889,     78,   -515,   2827,
+        77,    -66,    108,    515,     90,   2227,   -678,   1301,
+      -974,    122,   -983,   2357,     64,  -1479,    186,   1436,
+      -245,    204,    460,    191,   -677,   -335,   -200,   -135,
+      -106,   -101,   1112,  -2733,   -641,     73,   1265,  -1281,
+     -1332,   -743,    675,    129,  -1144,  -1169,    331,   -143,
+       -87,    809,   -891,   -848,    246,    243,     97,   -170,
+        36,  -1109,    102,   1055,  -1395,   1384,   1155,    439,
+     -1549,   -300,  -2069,   1014,    187,   -782,    980,   -971,
+      -345,   -583,    -66,   -138,   -317,   -124,     48,   -152,
+       -98,     92,   2446,    128,  -1232,   2148,   -337,   -615,
+       467,   1573,   -613,    857,    303,    422,  -1340,   -420,
+       305,   -626,     94,   -496,   -386,   -129,    243,     27,
+      -200,  -1373,   1468,  -2040,    151,   -675,     65,   1464,
+      -432,    545,    269,   -510,    584,  -1935,    970,   -319,
+      1465,    490,    263,    555,   -256,    -49,    315,   -242,
+      -394,   -312,    -88,    201,   -121,   -302,    172,     49,
+       234,     59,    327,    155,    199,   -187,    -41,    -74,
+        52,    -31,    -59,  -5574,   -121,    282,    343,   -125,
+      -200,   -575,   1328,    155,  -1928,    250,    702,     21,
+     -2718,   -153,   -102,   2131,    612,    432,  -1072,   -457,
+       222,    427,    144,    149,   -433,  -1573,   1337,   -650,
+       176,     13,  -1273,    280,   -751,   -236,    453,    204,
+     -1595,  -2896,   -272,    233,    485,     82,   -139,   -528,
+      -140,   -399,    -56,   -274,   -335,    176,   -756,    243,
+      2250,   -305,    721,   1711,      7,  -1230,  -1590,  -1872,
+      -137,   -714,    263,  -1643,    362,   -266,   -176,     64,
+       -36,    -63,    687,   -483,  -1488,    709,    929,   1349,
+     -1245,    645,  -1619,    735,   -651,   1850,   1031,    159,
+      -625,    838,    242,   -396,   -397,    -41,   1237,    304,
+        81,    -94,   -736,    578,   1279,   1064,     81,   1900,
+      -179,    224,    266,   -429,    734,    500,    995,   -882,
+      1563,   1813,   -519,    758,    532,    -27,     27,    453,
+};
+
+static const int16_t cb4432m0[] = {
+     -6132,   -262,   -273,  -1250,   -577,    984,   -430,   -410,
+      -464,    577,   -578,   -178,    -32,    369,   -624,    267,
+       -68,    474,   -480,   -225,    166,   -409,    437,   4633,
+        98,  -1560,   -464,   -869,    103,    193,    461,     72,
+       292,   -245,   1102,    417,   -325,    461,     74,     43,
+      -120,   -213,    333,    160,   -468,   -212,     31,    -81,
+      6516,    182,    201,   -212,    -66,    -49,   -266,    148,
+      -108,     98,    -46,    -11,    -59,    -20,    -20,   2332,
+      -294,   -560,    198,   -647,    -47,   -638,  -3877,     11,
+       834,    547,     47,   2541,   -126,     -5,   -366,    339,
+         3,      2,    -66,     60,   -526,    914,    321,   -658,
+      3605,     59,  -2392,   -655,    384,    775,    366,    327,
+       356,    386,    751,   -375,     38,   -205,    -15,   -442,
+      -212,  -1241,   1913,   -421,   -755,     45,  -1637,    -36,
+     -2435,   1504,  -1248,   -763,   -664,    133,   -123,    814,
+       241,   -243,   -446,     66,   -131,   -213,   2036,   1294,
+     -2138,    677,  -1042,   -771,    294,    371,    474,     85,
+      1403,  -2618,   -478,   -537,    275,   -826,    349,     84,
+       264,   -272,    -61,   -705,    175,   -972,    868,     25,
+      4183,    881,   -639,   -833,   -757,  -1063,   -991,   -257,
+      -137,   -619,   -285,   -454,     77,   -169,    316,    -45,
+      4362,   -203,  -2132,   -424,   -820,   -503,    340,    340,
+      -612,    648,      2,   -342,     81,    630,  -1518,    235,
+       216,    210,    665,    231,    130,   -879,     38,    675,
+      -136,    -48,    540,   -234,   -152,   -169,  -5745,   -294,
+       -24,      8,   -129,     -8,    308,    -14,    -16,    147,
+        62,     70,    248,  -2014,     76,   -190,   -328,  -1899,
+      -353,   -140,    836,   -365,   -112,  -3945,   -736,    467,
+      -258,    601,    617,     74,     62,    394,    180,   1151,
+      -810,     36,    457,    406,     75,     -8,  -5004,   2335,
+      -108,   -123,    299,   -335,    112,   -499,   -268,   -185,
+       461,    208,    -38,   -164,    764,   -504,    272,   4853,
+       396,    265,  -1133,   -433,    769,   -458,   1005,    645,
+        81,   -172,    385,    -56,   -130,   -393,    128,    -73,
+        31,   2038,    127,   -436,    123,  -2525,    282,   -448,
+      -489,   -295,    -14,     85,   -462,    -49,    262,    -93,
+       238,   -148,  -3953,   -414,   -259,     33,   -892,    459,
+     -2186,     60,    444,   -610,    844,   -486,   -299,    219,
+      -433,     19,  -1183,    276,    -29,    388,   3327,    102,
+      -914,   -221,    486,   -892,   -550,    190,    151,   -141,
+      -336,    194,   -242,   -224,    405,    879,   1600,    349,
+     -2082,    -38,   -514,     18,  -3574,    161,   -142,    -38,
+     -1815,    540,    228,     33,    164,   1074,      4,   -278,
+       -58,   4085,   -295,   -795,     31,    494,    555,   -250,
+        22,   -202,   -312,     92,    109,   -238,   -448,   -622,
+     -1511,  -4346,   -417,   -706,     37,   1157,    -96,   -199,
+       -59,    285,    -43,   -217,    -22,    -95,    103,   2242,
+       244,     45,    -74,     -7,    366,    -79,   -359,   -286,
+       188,    -14,     34,     49,    245,   -108,    -84,     88,
+      -333,   -216,    -79,     15,  -5710,    -36,   -102,   -552,
+      -213,     -8,   -356,    515,    212,   -265,     80,    316,
+     -1163,   -561,   -517,   -714,   -375,  -4176,     73,   -666,
+      -363,    -28,   1248,    -68,    478,   2648,    642,   -710,
+      -555,   -744,   -166,   -744,   -596,    138,    499,     59,
+       453,   -583,   -290,    -11,    -48,   4174,   -252,    -74,
+       -78,    -62,    449,   -265,   -818,   -357,    171,   -513,
+        72,    106,    -45,    649,    145,   5558,    -60,   -136,
+        69,   -172,   -134,    -66,    -68,    100,    683,   -427,
+       795,   -407,    345,   4930,   -838,    361,    279,   -190,
+       173,   -341,     -9,    722,    383,   -140,    123,   -269,
+       154,     31,    335,   -465,    311,     46,   4535,   -131,
+        90,    151,    287,    -11,   -526,   -614,  -2253,   -321,
+       -93,   -550,   -128,     25,    303,   -139,     19,      0,
+     -3255,   -161,    276,    103,   -245,   -515,    816,  -1042,
+     -1449,   1693,   -627,   1287,   -837,   -727,    -80,   -478,
+      -337,    116,      1,   -270,   -567,   -311,   -407,  -1656,
+      -216,    196,   3004,   -285,   -521,   1510,   1818,   1392,
+        42,    -44,   -244,   -349,    959,   -183,     25,     58,
+        43,   -345,   -310,  -8192,    -84,    311,    -60,   -348,
+       125,     33,    -79,   -138,     88,    138,   -121,    -37,
+      -211,   -118,   -142,    -37,   -132,    181,    162,  -1423,
+      1781,  -3453,   1261,    134,    670,   1218,    761,    292,
+      -146,   -825,    672,    737,    293,    433,    245,   -392,
+        46,    598,    257,   -234,  -1201,    718,  -4549,   -573,
+      -696,   -224,    -85,     75,   -268,    244,   1817,    341,
+      -166,    436,   -386,  -1247,     22,   -112,    -55,   -451,
+       106,    388,    -32,   -254,  -2400,   -373,    892,    334,
+     -4114,   -307,   -107,   -316,     41,   -214,   -403,    -56,
+      -469,   -246,    120,   -237,    266,     43,   3257,  -3925,
+       291,    239,    752,   -411,    162,    437,    159,    256,
+        37,     71,    -79,   -136,   -475,    124,   -208,   -216,
+      -245,     16,     40,   -459,  -4320,    340,  -1462,    914,
+        10,    490,    436,    162,    271,   -238,    -38,   2219,
+        25,   -141,    405,    107,    235,    282,    -55,     -7,
+     -3429,    565,  -1095,   -678,   1979,    233,   -874,    592,
+      -474,    680,    402,   -738,     21,    274,   -321,    655,
+      -348,   -546,    510,     62,     23,   4722,    572,    423,
+      -256,    473,   1240,   -997,   -899,    -53,    -73,    332,
+      -902,   -771,   -335,      0,    769,   -587,    592,   -703,
+      -600,    -77,    -94,   -207,    792,   -133,   -758,    500,
+       -14,    330,     22,   -281,  -5460,    152,    607,    337,
+       -39,   -118,    -80,    -51,    228,     65,     -6,    540,
+     -3515,  -1712,   -449,   -157,   -164,   -195,  -1655,  -1285,
+        90,   -517,   -116,     11,   1402,   -162,    -64,   -103,
+        46,    302,     37,     71,   2903,   2952,    780,   -487,
+      -297,   -426,   -369,    150,   -129,   -233,    813,   1639,
+       190,    310,   -311,    320,     94,   -247,   1484,    -32,
+        70,   -220,    560,    372,     54,    205,     96,  -3567,
+      -680,   1683,  -2377,     17,    548,   -266,    257,    656,
+       331,    205,   -121,   -814,    139,    326,   -370,    625,
+      2035,    818,    775,  -1165,    -41,  -4258,     41,   1109,
+       984,   -885,    -43,   -314,    204,    204,     95,    407,
+      -351,    101,    133,   -929,    899,     -6,    384,   -177,
+      -330,    240,     90,     78,   -318,   -455,     -5,   -365,
+       -61,    -80,    -72,  -4850,   -338,   -384,     30,    181,
+     -2721,   -767,   3217,    453,   -226,   -582,    283,    135,
+      -103,    265,    494,  -1444,   -120,     70,   -976,    -67,
+       -90,    660,    366,   -609,     32,    205,     73,     51,
+       346,     -6,   -120,    -10,    300,     32,    270,    139,
+       -55,    453,   5712,    353,   -145,    176,   -168,    216,
+       205,    -30,   -304,   1085,    221,    464,   -426,   1662,
+     -1397,  -1114,    301,  -1058,   3553,   -388,    743,    696,
+      -893,   -296,    -57,   -254,   -251,   -178,    417,     82,
+      -988,  -3566,   2171,  -1312,   -954,    -23,  -1349,    480,
+       566,     24,   -643,   -292,    -68,    303,     73,    -81,
+       296,      7,    371,     94,   1718,    498,   -774,    857,
+      1014,    358,    436,    210,  -3481,   -202,   -416,     59,
+      1987,    137,   -476,     32,   -627,    193,    368,     -3,
+      -290,  -3035,   -352,   -455,   -609,   -175,     -5,   -600,
+      -181,   -249,  -2551,    226,    105,   -249,   1851,    -86,
+     -1203,    214,    -57,   -505,   -522,   -247,   -154,    -40,
+       -17,   -523,    333,  -1777,   -354,  -1568,  -3492,   1032,
+      1577,     90,    153,    534,   -106,   -538,    102,      3,
+      -198,    -99,    -23,    835,   3495,  -1099,     44,    732,
+      -350,    926,   -472,    533,   1529,     54,   -844,   1295,
+       573,    414,    -23,    -71,    279,   -891,    287,    126,
+      1456,    973,    456,   1608,   -646,  -1244,    452,    651,
+       694,    855,   -235,   -503,    745,   -544,  -3512,   -138,
+       678,    473,    220,   -273,     -9,    265,  -1874,    397,
+      1196,    284,   -963,    298,    318,  -2309,   -162,    322,
+     -1250,    -16,  -1004,     -5,   2800,    -64,     72,   -482,
+      -162,   -412,  -2922,    774,   -335,    238,  -1144,   -134,
+      1428,    558,   1969,   -659,    902,  -1698,    793,   -858,
+      -613,    998,    253,   -336,   -348,    -80,   -117,   -264,
+       355,    808,    784,   -559,   2030,   1952,   -244,  -1130,
+      -986,   1883,   1171,   -493,   -326,   -880,   2588,   -243,
+      -204,    194,   -172,    -65,   2026,    424,    587,   -317,
+      2550,   -601,    203,   -669,    475,   -676,  -1492,     27,
+        41,  -1078,   -299,   -630,    177,   -164,   -429,   -246,
+      -357,   1191,   -867,  -1363,   1621,   -110,    916,    217,
+     -1269,    622,   -434,  -1113,    888,    -41,   1020,  -1774,
+        46,     80,   -483,   -892,    -61,   -472,    193,   -192,
+      2000,   -103,    740,   -223,   2493,    422,   2508,   -331,
+       470,  -1233,     47,    595,    795,   -465,   -320,   -163,
+       128,      6,   -209,    603,    536,   -416,  -1455,    -87,
+     -1191,    -98,   -281,   1003,   1421,    388,   1163,  -1146,
+       -81,   -299,   2518,  -1072,    207,   -443,    506,   -220,
+      -346,     98,   2119,   -416,  -2268,   -498,    109,  -1342,
+      -335,   1125,   -712,    156,  -1088,  -2092,   1164,   -500,
+       113,    -17,    551,   -199,    262,    -27,   -692,   -629,
+       204,  -1448,  -1606,  -1554,    289,    382,   -691,   1229,
+       414,  -1746,  -1198,   1113,   -386,    310,   1354,    -12,
+      -284,   -569,     46,   -558,   1495,    172,   -899,    617,
+       827,   -365,    100,   1008,    136,   2111,     10,   2320,
+      -291,    364,   -401,   -408,   -528,   -612,    127,   1218,
+      -384,    129,  -1603,    438,   1029,   2536,   -150,  -1432,
+      -856,   1068,    773,   -762,   -808,    676,   -693,    404,
+       145,      4,     27,   -148,   -318,  -1019,   -277,   1404,
+       880,  -1135,    861,    903,    739,    303,    139,   1918,
+      -952,    801,   -306,  -2439,     -3,    442,   -590,  -1034,
+       178,    430,    153,   1853,   1997,    742,   1745,   -608,
+      -237,    160,    523,    950,     82,  -1468,  -1592,    807,
+       719,    618,    319,     57,    235,    287,   1344,    -50,
+       324,   -182,   -365,   -381,   -377,   1989,    147,   -573,
+      1246,   1769,   -473,   -178,    961,  -1297,   -750,  -1428,
+     -1246,    789,    158,    612,     17,   -292,   -227,   -142,
+        64,     51,    -16,   -301,   -287,    -60,   -404,   -267,
+       109,   -108,    189,   -438,     48,     95,  -5059,    -42,
+};
+
+static const int16_t cb4432m1[] = {
+      7567,    273,    268,    -74,    201,    274,   -149,   -146,
+      -262,    243,   -273,     63,   -127,    135,   -160,    231,
+       120,    209,    -91,   -218,    -38,  -1206,   -468,   -159,
+       278,    536,   -995,    -60,     22,   1041,   -550,   -121,
+      -241,   -664,    427,   -416,  -1395,   -732,    152,   3247,
+       -67,   -154,  -2430,    421,   -405,   -558,    -73,  -2887,
+      -272,    -60,    365,    745,    287,   -622,  -1103,    412,
+       266,     82,     61,  -2172,   -379,    529,   -125,  -1482,
+       319,    643,    222,   -508,   2451,   -970,     71,    237,
+      -280,    202,    983,   -223,   -307,   -130,    217,   3209,
+        49,    -30,    275,    -12,   -260,  -3959,   1219,   -104,
+     -2700,   -201,     54,    851,   -590,    691,   -254,    408,
+       296,    -48,   -364,    216,     16,    220,   -415,    218,
+        83,     43,  -4032,  -1359,     25,     15,   -279,  -2092,
+       794,   -433,   -195,   -162,    606,    166,     87,   -316,
+       508,    242,   -359,    687,   -178,     14,  -2969,   -500,
+     -1041,   3234,    679,    170,   -791,   -127,   -630,    -16,
+       -19,    181,     -2,   -185,   -172,    -88,   -118,   -167,
+       128,    121,    239,    321,   -125,    217,  -7260,   -157,
+      -161,   -347,   -257,    102,  -1181,     71,   -379,   -205,
+      -268,    144,   -174,   -106,    305,     23,    -47,    202,
+      -110,    660,     54,  -2963,   -119,  -1371,  -2823,   1171,
+      -726,    690,    534,    161,   -435,    753,     58,    227,
+       241,    138,    -76,    473,    193,  -1926,  -2183,  -2526,
+     -1428,    284,  -1270,    336,  -1458,    208,     41,   -356,
+       345,    153,   -273,   -166,    500,     42,    120,    -35,
+       -81,     56,   1747,  -3050,  -2029,   -764,   -947,    888,
+       422,    374,    143,   -318,   -225,    604,    343,    -91,
+      1626,     75,   -211,    160,   -667,   -195,     38,   -446,
+     -1269,   -108,   -959,   -616,   -530,    554,   2865,   -156,
+      -358,   -429,   -261,     23,    511,    340,   -548,   2347,
+       105,     12,    -32,    164,    170,   -168,    268,   2587,
+      3511,    612,    329,    159,    456,    273,   -452,    168,
+      -394,    799,    -58,    160,   -480,   -257,    242,    167,
+        46,  -1433,  -1631,     50,    852,    509,    864,   -381,
+      -306,   -698,    261,   -702,    -19,   4113,    -38,   -153,
+       -11,    405,   -441,   -120,    139,   -265,    225,    342,
+       199,   2085,    237,    278,    252,   1537,    119,    182,
+      -174,   -193,   2486,     87,   2903,   -311,   -304,    273,
+      -217,   -256,   -264,   -675,   -819,   -188,   -615,  -1183,
+       495,   -154,   -687,   2423,    197,    -63,   -146,   1151,
+       896,  -1129,    -58,   1114,  -1644,   1219,   -648,    -71,
+      -130,  -2643,    533,   -218,   3942,    -83,    208,   -724,
+       198,   -643,    590,   -944,    -56,   -420,    115,     23,
+      -414,   -144,    295,    219,    -36,    393,   -174,     91,
+       290,  -7066,    158,   -275,    -70,   -119,     -1,    302,
+      -262,    -73,    -61,    110,   -196,    -25,     87,   -446,
+      -159,     -6,   -107,    115,  -7562,      5,    -33,    284,
+      -106,     34,   -140,    160,   -304,   -272,   -169,     25,
+        93,   -205,     28,    169,   -165,    -34,    -50,    343,
+      2204,   1440,    817,  -1921,   -590,   -527,     81,   -364,
+      -354,    163,  -1058,   1977,    244,    -75,   1201,   -207,
+       293,   -289,   -105,   -121,   3588,    925,     -2,   -201,
+      -860,    917,    100,    265,   -200,    -44,   -529,    351,
+      -579,   -103,    186,  -3622,     52,    181,   -259,   -411,
+        -4,   -328,    380,    517,    306,     57,    340,    -65,
+      -263,   -311,    494,    326,  -6136,    747,   -141,    296,
+       217,     -2,   -125,      8,    -88,    254,  -2934,   -259,
+       946,   -905,    653,    436,   3393,   -147,   -157,     27,
+       166,    299,      8,    -16,    643,    114,    217,     57,
+       -21,   -298,     19,    129,   1721,   -134,   2337,    781,
+      -483,   -748,    118,   -330,   -226,  -3762,    222,   -417,
+      -154,    -24,    -13,   1138,    210,    357,   -122,    257,
+      -369,    863,     13,   -320,   -439,   -433,   3469,   -869,
+       116,  -2772,    202,   1065,   -130,   -287,    142,   -288,
+        54,    318,    131,    -16,     84,    238,   -361,    934,
+      1341,     37,    130,   -412,    146,   -724,     -3,   -823,
+      2555,  -1263,     11,   -147,   3164,    -83,    -39,   -127,
+       258,     26,  -1181,   3339,   -676,    -30,    -56,    691,
+       867,    715,   -903,    293,   -205,   -392,    -22,    529,
+       -76,   2201,    433,    134,   1338,    -18,     85,   3128,
+        33,    924,    257,   1662,   -769,    321,   -449,   -374,
+       -58,   -597,  -1670,     97,    222,   -998,    404,   -155,
+       133,    358,   -250,   -125,    163,   6027,   -228,   -116,
+       -61,   -878,   -693,    710,   -516,   -191,    -27,    443,
+        83,   -174,   -695,   -117,   -107,    -53,   -142,     92,
+      -145,   -114,    -62,   -710,  -3192,   -872,   3284,   -521,
+       -36,   -948,    252,   -253,   -143,    260,    109,    -24,
+       262,   -169,   -196,    195,    105,     27,   -135,   1722,
+      1862,   -513,   -270,   -144,   -414,    -59,     91,   -288,
+       -96,    -56,   -204,    273,    170,   -171,    -62,  -4993,
+      -125,    -67,    -50,    226,   -275,    600,    105,   -217,
+      -450,    -87,    -20,   -353,     24,    -74,    167,   1881,
+     -4260,   -144,     48,     92,    187,    319,    341,     22,
+        -4,    405,    147,    237,   -120,    122,   -237,     56,
+      -515,   -153,    333,    834,    401,    210,  -5516,      7,
+       127,    147,   -140,   -479,    -26,  -1669,    -21,   -147,
+        60,    387,    565,   -140,  -5827,   -269,  -1119,   -324,
+       118,   -199,    -11,    105,    -49,    150,   -148,    178,
+       182,    162,    150,     68,   -227,      3,    221,   -330,
+       -23,     65,   6262,     71,     48,    -41,    -10,     -1,
+       -44,   -255,    -50,   -138,   -109,    -54,    -31,    492,
+      -214,    239,   -194,     35,  -6348,   -148,      9,     25,
+      -123,     84,   -448,    241,    148,    -35,     52,     35,
+         7,     99,    -16,     57,    -43,   -256,   3336,    373,
+       211,   -513,   2328,     86,   -274,    386,     74,   -174,
+       624,  -1037,  -1154,     36,   -209,  -1028,   -101,   -412,
+      -103,   -267,   -107,   -126,    163,   -394,  -1097,   -100,
+     -1575,   -542,   3326,  -2149,    547,    626,   -278,   -414,
+      -781,    486,   -186,   -159,    138,   -187,   -821,    419,
+       393,  -4266,    828,    431,     86,    745,   1313,   1484,
+       260,     52,    163,   -455,  -1071,    186,    522,    288,
+       421,     18,     97,   1267,    200,   2637,   -189,    729,
+       746,    203,   -639,   -843,   2164,    671,     84,  -2384,
+       430,   -161,    404,    166,    -33,    -17,    591,   -227,
+     -3849,   1579,    175,   -718,     99,   -410,   -844,   -239,
+        32,    212,    163,    480,    843,   -379,   -621,   -317,
+      -424,    113,   -262,     44,    -93,    529,    144,   -218,
+       140,   3257,   -575,  -2697,    144,    -83,   -186,    -44,
+       977,    153,   -230,  -1530,    234,    212,    212,    331,
+       412,   -125,     -3,    422,   -329,  -2181,   1406,    363,
+       -90,    -86,    329,   -267,  -4462,   -189,    -87,    154,
+        66,   -200,     37,     80,   -109,   -199,    125,   1983,
+       260,   -438,  -2417,   3259,   -974,    453,     41,    -77,
+      -538,   1123,    119,    120,    254,   -239,   -134,     33,
+      -384,   -407,     27,    465,   1810,   -910,    980,    -15,
+     -1307,   -919,   1880,   -327,   -303,   -198,    149,    413,
+      2176,   2269,   -707,    343,    360,    169,    148,    182,
+       104,    163,    857,    291,   -153,    303,   -679,   -386,
+      -868,   2283,   -320,    167,   3257,   1741,    338,    467,
+       209,    207,    834,   -226,   -479,   -120,   1674,    -61,
+       696,    -93,  -1327,   2176,    716,    402,   1688,   2219,
+      -339,    779,    366,    358,    241,   -695,   -272,   -136,
+       -48,     36,   -269,    862,   -616,   -118,  -2028,   1678,
+      1971,    115,    290,     71,   -765,     31,  -2874,    122,
+        13,   -424,   -281,   -320,    233,  -1032,     40,   -186,
+      1208,    274,  -2310,  -1594,    289,    230,   1264,    962,
+      -310,     23,   -548,     12,    -38,  -2734,    664,     37,
+       346,   -620,    266,    -98,     82,   2369,    963,  -1391,
+      -451,    833,     82,    175,    448,   1874,    345,   -440,
+       155,    130,     94,    326,   3223,    234,   -163,   -384,
+      -354,   -539,    827,     -9,    530,   -226,    -21,    332,
+     -2298,   3221,   1470,   -282,   -800,    231,    314,   -998,
+     -1051,   -648,   -434,    743,    -72,    119,     91,    414,
+       379,   1370,   -637,   -998,    851,  -2904,   -266,  -1652,
+     -1356,  -1339,  -1679,   -181,    245,    731,   -231,     -2,
+       221,   -182,   -325,   -411,    346,    246,  -2629,   1736,
+      -361,     24,    229,   1168,    747,    309,    425,   -128,
+      -320,   -496,    109,   1496,    -70,   -797,     37,   -271,
+       -39,    906,    -62,   -194,   1753,    311,    689,   1354,
+     -1035,   -973,   -438,   1166,   2197,    -99,   -380,   -274,
+     -1565,    447,    100,    349,    485,    653,    744,     50,
+      -582,   -123,  -1396,    156,    -27,    349,  -1067,  -1382,
+      1388,  -1061,   -554,    894,    -80,   -783,  -1500,   -736,
+       897,   1158,  -1386,    -40,   -280,   -819,   -672,   -895,
+       994,   -308,   -466,   -578,    455,  -1536,    879,   -448,
+       542,   1508,    850,  -2465,    816,    641,   -427,    310,
+      -168,    -41,   -908,   -302,   1513,    -29,  -1144,    588,
+     -1703,   1144,   2623,     90,    284,    866,    335,   -351,
+       419,   -745,    879,   -183,   -824,  -1713,    -34,    -15,
+      -913,     37,   -460,    778,   2130,   -145,   -153,   1761,
+      1420,   -243,    -32,   -877,    140,   -700,    612,  -2053,
+       321,    -78,   -165,    200,    526,  -1002,   2176,  -1022,
+      1436,    298,    -21,  -1378,    515,    304,    974,   1722,
+      2054,    661,    425,    282,    471,    438,     70,    169,
+      1587,  -2076,    -40,   -702,    264,   -146,  -1499,   -863,
+     -1775,  -1059,   -490,     92,    631,  -1194,  -1031,    335,
+       257,  -1299,    241,   -270,   -325,   -322,    -37,      0,
+      -685,    897,    984,   -909,   1556,   1281,   1367,  -1269,
+     -1591,    415,  -1156,   -374,   -110,   1552,   -695,     74,
+      -167,   -473,   1421,   -611,    175,   1521,   1322,    436,
+      1969,   -787,   1041,   -730,   -598,    188,   -794,   -531,
+     -2198,   -317,    -11,     -8,   -407,    198,  -1180,  -1675,
+       174,    981,    467,   -149,   -890,    263,   1030,   -121,
+      2147,   -135,   1975,   -634,    431,   -238,   -695,   1338,
+      -172,    110,    147,   -334,   -726,     65,   -873,    667,
+       997,  -1118,   -339,    144,   -700,   1303,   -207,   -609,
+     -1617,   -765,    839,    505,    -36,    -58,  -2894,    226,
+};
+
+static const int16_t cb4448sl0[] = {
+     -3850,  -1289,   -449,    -36,  -1178,  -1175,    705,    -97,
+        37,   -650,    426,   -477,   -145,    124,      6,    207,
+       -96,  -3145,   2917,   -260,    349,    668,    -72,      6,
+       157,    -62,   -128,     20,    -82,  -1357,   -707,   -619,
+      -313,   -229,   3010,   -169,    -27,    738,    971,  -1450,
+       246,    154,   -163,    -15,    -93,      5,    -35,    -42,
+        24,     31,    -25,   6803,     33,    -32,    -68,    -68,
+       -44,    317,     43,   -106,    608,   -999,   -699,    582,
+        46,   1631,    830,  -1570,  -2645,    992,   2126,    132,
+      2377,   1551,    247,   -247,   1508,    -34,    162,   -275,
+       -81,   -654,   -625,    125,    -33,   -210,    309,    900,
+       571,    726,   2691,   2821,   -698,     60,     46,   -483,
+        14,   -210,   -295,    102,    214,    226,   2622,    -82,
+      -390,   1436,    107,    554,    381,   1307,   2283,   -190,
+        27,    -35,   5557,    283,    103,    180,    104,    -89,
+      -186,   -319,   -225,   -141,     92,      1,  -1942,   1025,
+       906,     32,     -3,  -1089,    182,   -799,    483,   -368,
+     -1734,   -103,   1680,    474,   -133,  -1067,   -545,   -219,
+      -118,   -635,  -2559,   1002,   2554,   -640,   -505,    179,
+      -344,    -81,    107,    -61,     79,    -12,    -29,    -37,
+     -7574,    -92,     64,     92,   -164,    -20,    -61,    -35,
+      -312,   -159,    333,  -3401,  -2596,   -344,     88,    604,
+       535,    -87,    365,    -13,    -77,    131,    127,    588,
+       302,    -94,   -506,   2427,     99,    304,   2653,  -1104,
+      1380,    976,   -530,   -120,   -105,    293,      9,   -826,
+       388,    -66,    421,   -202,    605,    675,   4060,    978,
+       143,    -94,     21,  -2444,    -30,    554,    695,   2878,
+       657,   -104,   -435,   -326,    307,     20,     20,    159,
+       106,  -3473,    326,  -1029,   -304,    670,  -2109,   -431,
+       573,    704,    293,    -45,   -169,   -119,   -191,    599,
+      -910,   1976,   -165,    581,   1209,  -1689,   2365,   -370,
+      -601,   -696,    374,    202,   -114,    -61,      3,    -63,
+        30,    369,   -158,   -128,    198,     52,    -98,    -44,
+      -323,  -5118,  -1100,   -669,   2256,     32,    -66,    206,
+        65,   2801,    783,   -470,   -973,    471,   -211,    -27,
+      1879,    302,   -388,   -249,    301,    537,   2761,    321,
+       571,     20,    337,   1336,    522,    231,    368,   -363,
+     -2065,    -57,  -2565,   -584,   -611,     56,    814,   -382,
+      1671,    408,    492,     12,   1201,   1513,    247,   2165,
+      -592,  -1246,   -493,  -1012,  -1330,   1251,     75,   -100,
+       182,     52,    -47,    710,  -1137,   2420,   -559,    266,
+      -801,   2523,   1229,    736,   -409,    -49,    269,   -174,
+      -179,    -24,    348,   -661,    251,  -1039,   2647,    283,
+       728,  -1850,  -2088,    196,     39,    -72,    -35,    -94,
+      -540,    266,    340,   -450,    763,     -5,    113,   2618,
+     -2737,   1047,   -246,   -522,   -182,    376,   1068,    203,
+      1238,   -938,    211,   -308,   -395,   -629,    596,  -2634,
+      1452,  -1155,     83,    -89,  -3121,    419,     40,   2691,
+      -306,   -343,      4,   -347,   -725,   -117,   -315,    115,
+      -215,     26,    429,   1074,  -1831,  -1850,   2609,     72,
+       467,    191,    432,    857,   -186,      0,   -443,    -24,
+       500,    541,     30,   2324,  -1160,  -1153,   1783,   1282,
+     -1992,    101,   -108,   -108,    556,  -2012,    506,    691,
+       -65,   -610,    402,    610,   1941,   -121,    942,    589,
+      1879,     58,    312,  -2218,  -2056,  -2284,   -350,   -453,
+       306,     38,   -579,   -185,   -101,   -196,   -150,    156,
+       126,    -44,   -143,  -7923,    126,   -120,   -138,   -233,
+        97,    -20,   -121,   -175,     -8,    -13,   -123,   -365,
+       251,    730,   2883,    667,   -418,   -208,   2170,  -1442,
+       196,   -389,   -516,    252,    -98,    525,  -1819,   -647,
+      1575,    768,   1124,   -428,  -1010,  -2027,    411,   -473,
+       863,    210,    908,     40,    145,     37,    192,    189,
+        52,   -217,   -168,     63,     -7,    -53,   -121,     13,
+      -145,      0,    -37,     61,  -7979,   -142,     32,    118,
+       190,     -7,    -13,    113,     36,     31,   1461,  -2088,
+      2391,   -939,    -66,    822,    280,    246,   -157,   -183,
+      -433,   -356,     88,   -101,   3969,  -3388,    -84,     84,
+       130,     35,     74,     37,    181,   -195,    219,    -29,
+       -23,    -32,     69,    625,   2328,   -192,  -2617,    287,
+       543,  -1604,    823,   -547,   -277,    764,    276,    156,
+       198,     17,     84,    346,    -27,   -129,    143,    217,
+       212,   -249,     20,   6449,      7,     51,   -889,    -88,
+       265,    282,  -1956,   1327,  -1025,   1338,  -1709,  -1008,
+       372,     57,   1404,    234,   2621,    -18,    663,    301,
+         0,    167,   -372,  -2534,   1945,   -191,    198,    359,
+       -43,     92,     24,  -5498,    -63,    189,     36,   -369,
+       352,    381,   -205,   -144,   -119,   -267,    -60,    -10,
+       387,   2388,   -155,   -450,    465,   1529,   -216,   2673,
+      -146,    118,     50,    290,    147,     11,  -2912,    863,
+      2184,   -689,    -44,     59,   -663,    663,    675,    295,
+      1331,   -115,    -10,    -54,     -1,     31,   1699,    127,
+       215,   2966,    163,    416,  -1053,   1216,    356,   1428,
+      -166,   -172,     -2,   -355,   -169,   -331,    -94,    -78,
+      -123,   4875,    311,     67,   1145,    397,   -288,    212,
+      -344,   -290,    126,     16,    176,    485,    551,   -526,
+        11,    120,   -274,     83,  -5399,   -154,  -1611,    887,
+       321,   -446,   1166,   -333,    652,    310,   -895,     62,
+      -219,   2840,   -753,    -34,  -3203,  -3600,    464,   -249,
+       336,    297,    -85,    316,    144,    306,   -249,    149,
+       112,     73,    192,    -89,     18,    197,    116,     51,
+        37,    212,  -7248,    163,     31,    -52,    -31,   -101,
+     -1366,   -353,   -325,  -1335,   -440,   1193,    670,  -2635,
+       872,   1400,    733,    395,    122,    130,  -4146,      0,
+      -382,   1486,    308,   1179,   -412,    288,    701,    161,
+       147,    959,     60,     77,   -123,     17,    193,    204,
+      -226,    388,    272,   -588,   -157,   2823,    735,   -745,
+      2368,    359,  -1088,  -2004,  -1293,   2018,    483,    320,
+     -1014,   -806,   -479,    -68,    -51,    168,    873,     27,
+     -7906,     57,     19,    -23,     27,     43,    -13,    -50,
+        93,     16,     29,     31,    -26,     32,    -22,    453,
+      2922,  -2560,    138,    923,  -1245,   -405,     10,    228,
+      -270,    145,   -192,     83,     48,    101,     77,   -226,
+        36,   7792,    126,   -275,    -37,    -36,      9,     45,
+       -89,     13,    148,    125,     24,   -442,    111,    -12,
+       540,   1794,   3008,   1620,   -185,  -1394,   -161,    -25,
+      -313,   -317,    591,   2507,    134,   -369,     77,    527,
+      -619,   -236,   2681,     87,  -1060,    -34,   1894,  -1123,
+       373,   -628,   1934,  -1279,  -1689,   -609,   -472,   -598,
+       405,    229,    414,     12,  -2923,    -33,   -435,    -49,
+      2380,    -34,   -344,  -2171,   -284,    274,    226,   -287,
+       -84,    -57,     -1,   -169,    -50,    479,    707,  -2774,
+      -532,   -640,   -244,     44,    458,   2519,   -590,   -472,
+};
+
+static const int16_t cb4448sl1[] = {
+     -2878,   -714,   3098,    -76,    -51,    232,    118,   -780,
+      -691,   -267,   -309,    105,   -179,     -5,    -84,    -11,
+      -120,   -379,    458,  -3161,     65,   2994,     64,    374,
+      -440,     62,   -183,     28,   -561,     73,     59,  -2565,
+       445,   -451,  -1026,    437,     10,   -173,   1243,  -2278,
+      -481,   -395,   -154,  -2402,    945,  -2789,    117,  -1184,
+        75,   -704,    527,    478,   -589,     17,    131,   -110,
+       574,  -1055,   -628,   -277,   2798,   1483,   -657,  -1996,
+      -248,    194,   -284,    822,    225,   -170,    -10,   -302,
+      -427,  -1700,    -90,   2756,   2124,    -49,   -964,    372,
+      -637,    443,     13,    -69,    -71,    196,  -1971,    110,
+      1147,    698,   1333,   1369,    527,    165,    903,    577,
+     -2134,     56,    -33,     34,    183,    247,   -342,    974,
+      1079,   2478,    -26,     80,  -2377,    430,  -1422,    428,
+     -2187,   -469,  -1280,   -326,    -40,    188,    911,    405,
+      2772,    279,   -493,    265,    768,     45,   5778,     44,
+       121,   -257,   -135,    124,    263,     15,    197,   -114,
+         5,    -14,     -8,    -82,   3989,   -511,    197,   2446,
+      -292,   -205,   -919,    162,   -121,    145,    -40,     71,
+      -105,     72,   2035,    960,   -145,   -467,   -518,    167,
+     -2988,    421,    860,    320,     40,   -446,    319,    160,
+       140,    511,    -55,    213,   -148,   -527,   -666,    687,
+         9,     23,    344,   -156,  -4646,   -125,   -220,      9,
+       134,    -25,     16,  -1319,    763,     58,  -1586,   -438,
+       301,   -411,   -337,  -3398,    358,    -68,   -111,   5483,
+       -36,   -456,    -94,   -116,    204,     95,     84,    -73,
+      -163,     69,   -190,     64,  -3716,   -326,   1815,   -843,
+       312,   -498,    684,   -641,   -766,   -104,    606,     70,
+      2630,     51,   -170,  -3584,    167,    461,   -162,    132,
+       496,     91,    171,    255,     48,      2,   -120,  -1196,
+       534,   -431,   2669,   -403,      8,    287,   -391,   2557,
+       849,    167,   -275,   -184,    605,  -3570,    113,     22,
+     -2586,    668,    294,   -910,     67,   -141,      0,    418,
+       271,     75,     90,   -124,    446,   -142,   -635,    631,
+      -956,   1566,     25,  -1982,    790,   2770,     33,   -520,
+        23,  -7488,     67,    -73,     60,     64,    -46,    -36,
+        76,      3,     22,    149,     61,     34,    255,   -380,
+      -284,  -2531,  -1423,   1507,   -926,  -1074,   -929,  -1430,
+      -141,    165,    -80,   -268,     21,   -767,   1542,   3197,
+      -191,   2014,   -304,    595,    536,   -906,   -126,   -354,
+       -76,   -162,   -125,  -3139,   3197,    934,    366,   -923,
+      -330,    277,   -284,   -163,    -12,    402,     15,   -146,
+        20,     83,    111,    196,     23,     71,     77,   7287,
+      -175,    -13,   -227,    -59,    -56,    -28,      1,    163,
+       -50,     59,    635,    150,     95,   2750,    775,  -2057,
+       423,  -1078,   1749,     -3,   -655,   -365,   -357,    145,
+       -76,      5,    -93,    224,    150,    108,    -34,    173,
+       148,   -371,     34,     48,  -8037,     65,     50,    103,
+       -42,    -10,    -96,    -90,     -3,     60,     92,    -79,
+       -76,    386,    114,  -1947,    833,  -1279,   -484,    217,
+      3156,    226,    485,   1191,    425,     88,    -59,   -243,
+      2292,   1681,    671,     62,    899,  -2453,   -100,   1039,
+       713,   -104,    554,    219,    356,    963,    741,   -102,
+       455,   2067,   -324,    172,     28,    772,    752,  -2351,
+     -1438,   -865,  -1668,    105,   1034,   1195,     14,   -350,
+      -425,   -648,   2086,   -532,    634,   1537,    -33,   -598,
+      2888,    -85,    184,    158,   -164,   3339,    237,   -284,
+       -54,   -246,     46,   -254,    365,     55,   1928,   -346,
+      -357,    331,    139,     16,    674,   -384,    -67,  -3399,
+       165,     76,    215,    137,  -3187,   -146,   -264,   -165,
+     -3039,    235,   -541,   -630,    -32,    -33,   -211,    160,
+      -121,   -111,  -1296,    -47,   -128,    292,  -1523,   1540,
+       771,   -166,   -509,    212,   2758,   -327,   -418,   -305,
+        -9,    465,   2513,    195,    -70,   -209,    -66,    127,
+      -147,  -3161,   -192,   -541,   -555,    131,   -858,  -1609,
+       973,   -156,  -1877,     60,   1011,     66,   -348,    912,
+     -1731,  -1296,    305,   -369,   -560,    470,     46,   -863,
+      -124,    -37,     40,   -395,  -4886,    -20,    221,    228,
+       177,    182,     98,   -151,   -195,    854,   -194,   -374,
+       301,    586,     58,   -908,    -19,  -4198,   -171,    330,
+        48,  -3312,   -164,   1913,   1183,    -42,   1287,   -353,
+       757,    620,   -547,    251,   -520,     59,     43,   -179,
+      -191,   -131,  -2951,   -944,  -2479,    344,   -813,    104,
+      -697,    -44,   -270,    198,    245,   2866,    208,    178,
+      -248,     38,     19,    577,   2812,   -765,   -855,   -439,
+       -60,    -30,   -352,   1521,  -1069,    457,    415,    572,
+      -749,   -144,    100,    515,   -794,  -1554,   2507,   -270,
+        10,     62,   2507,  -1550,    -75,     70,   2530,    562,
+       132,   -141,    251,    156,    835,    102,    717,   3226,
+      3327,    172,     84,   -205,    -11,    208,   -310,    164,
+       -27,     11,    281,     37,   -518,     20,    -76,     82,
+      5436,   -543,   -301,    112,    359,   -140,    -94,     78,
+       -18,     38,   -196,    -92,     13,   -111,    -23,     30,
+       -15,    -94,    101,    142,  -6455,    321,    322,     50,
+      -216,   -321,    -10,   -465,    101,     45,   -585,   -969,
+      1248,   -456,  -2523,   -852,  -2129,   -889,     33,  -1424,
+      1462,    583,    749,    527,  -1737,   1262,   -594,    414,
+      -215,  -1184,    412,   1758,  -1836,   1248,    440,   -178,
+       784,   3591,   -227,     43,   -493,   -766,   -270,    150,
+       151,    -56,   -110,  -2832,    -73,   -166,    470,   -179,
+      -681,     71,   -114,  -2743,   -806,   -560,     63,   -244,
+       -90,    182,   -143,    995,    404,    -13,  -1343,   1524,
+     -2472,   1718,   -957,   1229,    458,   -395,  -2817,   -579,
+       -99,    340,   1538,    684,   -492,   1156,    -45,    -65,
+      -305,  -1408,   -325,   -270,   -358,   -127,     92,    -97,
+       415,     85,  -4749,    173,   -296,   -203,    331,    315,
+       184,    -46,   1315,   -146,    -55,    427,     37,    255,
+      -209,    272,    735,    506,    105,    103,    902,  -3449,
+       116,   2304,    616,  -1564,   1508,    478,    320,  -2418,
+       244,   -176,    -32,    238,     92,    290,   -168,    -78,
+     -3464,    270,  -1902,      2,    696,     92,  -1610,   -206,
+       -49,    178,    121,     27,    119,     72,   -253,   -398,
+     -2720,    -81,   -162,   -550,   2595,   1445,    249,   -104,
+       218,   -310,    -95,     18,   -473,   1908,    432,   -227,
+      -168,  -2725,   -240,  -1830,    199,    437,  -1392,    304,
+      1461,  -2394,   -603,   -540,    769,    340,   -104,   1569,
+       -21,    338,   -874,   1533,    281,    -59,    487,   2120,
+       179,   -140,   -328,    -57,     63,   -110,  -1330,   -485,
+     -2427,   1159,    355,    -26,  -2055,    154,   -563,   -132,
+        49,   -329,   -187,    -24,    -71,  -3970,    276,    158,
+        92,   -202,      7,   -422,   -578,    186,   -407,   4960,
+      -595,   1027,    417,    691,     69,    133,    123,   -147,
+};
+
+static const int16_t cb4448ss0[] = {
+     -2680,   2499,   -328,   2212,   1288,    -57,   -727,     76,
+      -210,   -218,     41,   -343,    -26,    -38,     43,    606,
+      -619,   -531,  -2082,     87,  -1127,   1282,    -23,   2272,
+     -1816,    104,    -31,     85,    -22,     60,   1293,    138,
+       382,    432,    489,   -372,  -1649,  -2809,  -2556,    -98,
+      -232,   -233,    169,    186,     79,   1157,   2113,   -942,
+       636,    877,   -601,   2277,   1411,   1165,   1029,   -613,
+      -348,    -38,    -19,     45,   1318,  -1980,     12,   2762,
+      1519,    184,   1980,    -49,   -270,    361,   -172,   -601,
+      -196,    186,    -67,   -124,   1503,  -1011,    263,    223,
+      -384,    153,    -21,  -1063,   -239,   1171,  -3501,    512,
+      -162,   -180,    139,   -680,    609,  -1919,   2969,  -2321,
+      -183,    194,   -558,     26,     91,    340,    -25,    -31,
+       127,    662,    182,    191,  -2201,  -2603,   2252,   -523,
+       277,     50,    355,    295,    -65,    355,    207,     82,
+      -489,   -143,   -218,     89,    666,   -359,   2716,  -2310,
+     -1912,    417,    400,     43,    110,    -93,   -142,     61,
+     -3000,    454,   -153,      0,   -413,    469,    339,    318,
+      -197,     75,    -80,   2894,   -129,     82,   1431,   1183,
+       429,  -1556,  -1339,  -1573,    -92,   -911,   -230,    -12,
+        -4,   -145,   -388,   -419,     -5,   -241,   7120,    165,
+      -125,   -122,    126,   -150,    109,   -146,    -61,    -49,
+        47,     70,    -43,     40,   1867,   1473,  -1278,   1229,
+     -2256,    -90,     10,   -744,   1196,   -109,    402,    258,
+       690,    -74,     26,   1294,  -1079,    142,  -2384,   -324,
+     -1696,  -2741,    321,     66,     83,   -127,   -131,    156,
+       166,    135,   1812,  -3445,     10,    535,   -547,    481,
+     -2243,    287,   -335,    218,    195,     -1,    -25,    -94,
+       195,   1433,  -1428,  -1444,    520,    219,   3363,   -388,
+      -807,   -454,    -29,    316,    125,    159,   -144,   -156,
+      -317,    752,    256,    216,    340,    488,    147,  -5662,
+        55,   -110,    387,   -102,   -211,    -66,    -26,   3688,
+      -172,  -2366,   -244,     -5,    353,     11,    503,     88,
+       227,     69,   -240,   -187,    -58,   -389,  -1783,  -1427,
+        20,   -618,    544,  -1337,    628,  -3180,    708,   -538,
+      -423,    115,     49,   -161,    184,   -682,   -223,    689,
+      1299,   -891,  -1073,  -1228,   -305,     47,  -2221,  -1559,
+       598,   -380,    166,    143,   -366,    287,   2122,    509,
+       629,    235,   1523,   2900,   -640,   -425,   -462,   -231,
+       -53,    -27,   -263,   2090,  -1892,  -1147,    -42,    866,
+     -2301,    461,  -1082,   -625,    -85,    148,    229,    -25,
+        85,     53,    259,    -81,  -4072,   2577,    -12,     -7,
+       335,   -151,   -691,   -137,     98,    372,    -37,   -192,
+       -17,   3318,   -558,   2064,    396,    258,  -1067,    229,
+      1122,    298,    -25,     40,     27,   -134,   -166,   -247,
+     -2010,   -440,   1066,  -1400,  -3454,   -289,    428,    629,
+      -158,    126,    129,    183,    -12,   -171,   -120,    421,
+      -445,     66,   -900,   3680,   1583,   1985,     25,    229,
+      -535,     -1,     45,    207,    -54,    -30,   1581,   -938,
+      -703,    405,    878,   -398,  -1069,   1748,  -2587,  -1419,
+      -375,   -441,   -487,    109,     21,  -1399,    648,   -271,
+      -701,    635,    115,   -138,   -458,   -600,  -1891,    585,
+       420,  -1916,   1135,      7,   1584,    910,   4267,   1328,
+       279,    395,    -35,    -99,   -168,    503,    216,   -126,
+       211,    212,    193,  -2205,    491,    696,     41,    283,
+       649,  -3425,   -999,    200,    625,   -261,   -378,    -47,
+       -15,    -30,  -1262,   1700,  -2191,    196,  -1773,   -251,
+        84,    498,   -261,    150,    451,     41,    336,     27,
+       -56,    562,    -86,     -1,  -1073,   1461,   2148,  -2961,
+      -326,   -257,    440,    -42,    -48,   -320,    122,     94,
+     -1267,   -830,   2810,    -94,   -201,    990,   2415,   -740,
+      -166,   -267,   -157,     68,    301,    290,     65,    931,
+      1969,   -170,      6,    149,   -272,   -105,    542,    -11,
+     -3888,    105,    305,    333,    -14,    -39,   1944,  -1164,
+        88,   3829,  -1190,   -535,   -644,   -330,    509,    -93,
+      -314,   -228,   -294,   -342,    -26,   1143,  -2371,   -400,
+        74,    101,    -68,   -583,  -1091,   3367,   1146,   -638,
+      -436,    136,     41,    -92,   1518,   2818,  -2214,  -2044,
+       636,     -2,     79,   -508,    676,   -439,   -358,   -198,
+       -69,    271,     59,   1638,    468,     97,    264,     -8,
+     -5152,   -152,    152,    252,    401,   -375,    -17,   -132,
+        51,     63,    633,   -180,    367,    111,    -18,     15,
+       -52,    128,    -54,     11,     96,   -122,    -26,  -7257,
+       -42,  -1221,   -688,    197,   -107,   -217,    141,   -289,
+       141,    269,    439,   -747,  -3743,   2098,    226,    137,
+        26,  -1645,  -1735,    -80,     43,   -216,    245,    544,
+       157,     40,    238,    237,   -989,    379,     88,    639,
+     -1335,   1542,   1147,   -510,   1008,   -134,   -626,    696,
+     -3034,    334,   -689,    115,   -168,     39,   1750,   -649,
+      -233,    -99,   -231,    515,    112,    -11,   -162,   -133,
+      -138,   -486,  -4137,    204,   -102,    867,  -1030,    219,
+      -254,  -2787,   -128,    961,  -2837,   -482,   -195,    691,
+      -170,   -178,    164,    -54,  -2008,   -116,     74,    398,
+       -96,   -472,    407,     27,    287,    628,     97,  -1425,
+     -3923,      6,    117,  -1081,    930,    396,    452,     87,
+      -441,   -155,   -738,   1089,   2128,  -3133,    -21,   -622,
+       -48,   -127,    506,    985,   -200,   3361,    184,   -522,
+        41,    503,    209,     14,    -96,    791,   1263,    289,
+      -101,  -1728,  -1073,   -517,   4156,   -685,    214,   -721,
+      -608,   -102,   -295,   -114,    126,   -340,    109,     88,
+     -1588,     82,   -549,   -376,     76,     84,   -210,     59,
+      -130,    321,    678,   4704,    564,     -1,    100,    325,
+      -296,    256,   -936,   -886,  -1088,   -191,    476,  -3684,
+      1359,     12,   -397,    -70,    -17,     58,    569,    353,
+       821,    -77,    253,    153,   5697,   -171,    181,      3,
+       -90,   -413,   -265,    142,     62,    959,    151,   -103,
+       845,   -340,   -280,   -733,   -592,   -244,   2534,   3089,
+       935,   -393,   -105,    145,   -666,  -2865,  -1532,    717,
+      2867,    206,   -800,   -125,    -34,   -189,   -138,     42,
+       189,   -141,    107,  -3030,  -3795,   -494,    108,   -149,
+       382,    760,   -142,    337,   -844,    228,    124,    232,
+       -23,     -1,   2298,    750,    636,   -353,    157,    676,
+      -191,    812,   3434,    759,    543,    -17,   -213,    -95,
+       316,   -693,   -604,  -1059,     32,   -496,  -3334,   -272,
+      -104,   -495,   -130,    627,   -376,     74,   -599,     55,
+     -2185,   -968,    517,   -343,     21,   -249,   -963,    268,
+      3339,    239,    771,   -134,     42,    231,     75,   1633,
+       331,   -125,   -414,    457,   -316,    111,   -475,    363,
+      -687,  -4105,    469,    443,    113,     72,   1498,    406,
+       915,   -229,    564,   -377,     89,    137,     39,      2,
+       -29,   -416,   -149,   3598,   -253,     12,  -1015,   3016,
+       916,   -726,  -2286,    -99,  -1085,   -238,    690,    -44,
+       -51,   -115,     25,     56,   -905,  -3050,  -1121,    -24,
+     -2160,  -1424,   1009,   -180,   -424,    188,   -417,    -66,
+       -86,     74,    -28,   -225,   -937,    -90,    251,  -1850,
+      1939,   1843,    833,  -1879,   -192,   -318,    103,   -363,
+       -22,    -57,  -2833,   -118,   -277,    -98,    -85,   -495,
+      -874,   3027,   -141,  -1490,   -172,   -266,    -32,    190,
+       -12,   -364,   -380,  -2107,    249,   -217,    662,   -584,
+        89,   -563,   1153,  -3091,   -656,    463,    144,    -26,
+};
+
+static const int16_t cb4448ss1[] = {
+      6475,    -60,    162,     42,    -71,     50,    -85,   -278,
+       -14,    -60,    -53,    132,     28,    -65,    -71,    -62,
+         6,    119,    195,   -140,     28,     37,   -603,  -4956,
+      -290,    700,   -241,     11,   -301,    297,  -1009,    468,
+       885,    192,     40,    495,    846,    -28,    201,   -255,
+       927,   -644,   2424,   2882,    -82,  -1764,   1077,    315,
+       946,    843,    399,    176,    567,    546,    377,    283,
+      2469,  -1815,    -65,     12,    422,   -368,   -639,   -493,
+     -5606,     84,    122,    241,    267,     -8,   -257,    -23,
+      -220,   -118,    139,  -1582,   -218,  -2436,   2539,   -270,
+       146,   -262,   -489,   1551,    604,   -225,    363,    234,
+      -110,   -166,   1058,   2342,   1950,     43,   2362,  -1189,
+       492,    172,   -296,    159,   -430,   -311,   -135,   -182,
+        77,   -444,  -1995,   -855,   2080,   -457,    389,    872,
+      2549,    935,   -128,    519,   -374,    310,     96,    119,
+      -263,   1981,  -1019,   -628,    212,   -173,  -2292,   1066,
+     -1985,   -426,    115,   -746,    147,      3,     94,    195,
+     -1762,   1713,   -337,   1884,   -123,   -480,     95,    777,
+      1073,   2117,   -969,     16,     11,    123,    374,   -394,
+     -1419,    829,   1657,   1294,  -2770,    286,    813,   -290,
+      -115,    111,    312,     53,     44,    896,     34,  -2288,
+     -3443,  -2053,     98,    293,    429,   -168,     74,    -58,
+       221,   -383,    100,     63,   1925,  -1207,    199,     94,
+       -94,   3060,   1825,    611,    292,   -141,    382,    141,
+       105,   -151,      0,   1448,   -267,    206,    932,   -682,
+       251,   -183,   1080,    161,   4334,   -397,    525,    -91,
+       127,   -104,    921,  -2282,   -274,  -1070,    387,   -312,
+      1380,   2769,   -554,   1501,   -921,    102,   -183,   -104,
+       -66,  -1656,   2049,    122,  -2271,     84,   -276,   -204,
+       353,    380,   -414,  -1757,  -1035,   -318,   -130,    -10,
+       163,   -471,   2425,   2864,  -1892,    294,    817,    754,
+       277,    -29,   -214,    -39,   -312,    -57,    -54,    986,
+      2286,   -574,     34,   -641,   3783,    214,   -399,   -155,
+        38,   -148,    -42,    -89,     97,    -17,  -2192,    729,
+       272,   1168,  -3593,    150,     96,   -473,    211,    -60,
+       136,    -26,    142,   -285,     93,    666,   -465,   -181,
+      2016,   -338,  -2186,  -2608,   -449,    107,    -18,     45,
+        24,    245,   -119,    244,    442,   1509,    158,    242,
+       169,    -16,   -221,    104,    115,     16,   -217,     23,
+       -25,    130,   4076,    662,   -315,   3068,    -35,     36,
+      2785,   -223,   -528,   -157,     43,    186,   -514,   -240,
+        15,   -245,    520,   -110,   -781,   -641,    294,    -20,
+        64,    -44,    400,   -109,   4756,   1334,   -421,   -195,
+       130,  -2182,     64,   -897,  -1423,   3081,   -523,    378,
+      -164,    968,    593,   -192,     71,    114,   -143,    -10,
+      1961,  -3141,   3173,    -39,   -110,    -57,    144,    -68,
+      -429,     30,    -10,    467,    159,     40,     67,    260,
+       814,   -168,   -836,   1073,  -3562,   1786,  -1205,   -148,
+      -105,     94,      5,    143,    138,     18,  -1384,     20,
+       635,   -126,    -71,    -87,   -320,   -407,    559,   -151,
+      1312,  -4395,   -755,   -263,    -77,   1657,    699,    426,
+       469,   -469,    253,    -80,    317,    -71,    268,   3592,
+     -2051,    304,    157,     43,   1872,   3794,  -1537,   1226,
+      -159,   -335,    340,   -385,   -253,   -195,     21,    106,
+       -31,   -187,    -63,  -2771,    446,   -708,    202,   -186,
+       548,    832,   1757,  -1274,   1234,   -756,   -160,     76,
+       -82,     64,   2169,     13,   -849,    244,  -2486,  -2138,
+       844,   -178,    270,    297,    150,    202,    -41,   -188,
+       121,  -1272,    371,   -319,   2848,   -469,  -2059,   1290,
+      -457,   -380,    690,    148,    -51,   -340,    113,     57,
+     -1259,   -396,  -1404,    336,   -511,    576,   4441,    124,
+       143,   -483,     85,    138,    196,     38,   -188,   1177,
+      -764,  -2067,    820,   -264,    218,   -300,   -501,   -230,
+     -2529,   1349,  -1606,   -199,     92,    -55,  -1324,   -702,
+      2078,  -1269,    414,    -50,     29,     12,     87,   -593,
+       217,    -82,     94,  -2392,    308,   2315,   2188,    768,
+     -1103,    -77,    579,   1706,   -826,   -224,   -297,    145,
+      -640,    570,    146,   -199,   1187,   -872,    327,   -310,
+      -122,    -23,    -13,    808,   -139,  -4425,   -670,    412,
+        -4,    -70,   -162,  -1056,    685,   -312,   -957,    339,
+       893,   -252,   4040,   -105,     76,    993,    281,    -79,
+      -139,    168,   -298,    795,  -1107,    395,    386,   -524,
+      1052,  -2341,   2537,    474,    726,  -1028,   -357,    -52,
+       115,     -9,   1349,  -2240,    785,   2751,     77,    922,
+       385,   -539,   -148,    410,    251,    -70,    199,     51,
+      1728,   -206,   1181,   1182,   1388,   -791,    121,     -3,
+         8,   -147,    -95,    101,    886,  -2412,     19,   2401,
+      -116,    718,   -592,   -221,    724,    -33,    690,   -180,
+       868,  -3330,    377,   -336,    128,    267,  -2075,   2848,
+      2994,   -300,      3,   -153,     41,   -456,     38,    -31,
+       309,   -106,    -92,    -14,     96,    672,    634,    207,
+      1556,    438,  -2147,    282,   2443,  -1662,    511,    457,
+      -259,   -505,    173,   -204,   -858,   -117,   2751,    852,
+       220,   -512,  -2576,   1542,    357,    -77,     -4,    165,
+       -63,    189,    302,   -699,   -764,  -1559,     25,   -233,
+       405,    173,    698,    -73,   -300,  -1442,  -2923,  -1326,
+       -25,     98,   -196,  -2915,  -1169,  -3392,    691,    353,
+      -196,     96,     41,    180,    198,    280,    207,   -158,
+       -19,   1556,    991,   -523,   -280,  -1599,   1368,  -3247,
+      -996,    159,   -136,   -469,    -48,      0,     30,     95,
+      -765,     33,   6580,   -180,    316,   -176,    105,    -21,
+        -9,    166,    148,    -52,    -49,     42,      2,    318,
+       -55,    -91,  -1461,  -1474,  -3086,   -756,   1479,    -29,
+      -668,   -255,    -51,    241,    249,   -212,    132,   -129,
+      -410,    113,     17,    301,    185,     96,     10,    188,
+        38,   -772,   5152,    -13,    -10,   1527,    806,    -23,
+       -79,   1102,    -77,    329,    -99,   -404,   2276,   -873,
+     -2681,   -765,     71,     20,  -2448,   -803,   1827,   1115,
+      -160,    -15,    288,    -46,    573,    100,   -726,   -694,
+      -406,    288,     61,  -2216,   -904,     77,  -2983,   -962,
+     -1438,    809,    -38,    -79,     95,     52,   -231,    518,
+       115,     41,    908,    780,    805,   -207,  -2161,    554,
+       968,   3111,    133,   -158,    -13,    -34,   -182,    -60,
+       105,    718,  -1245,    227,   -818,   1184,    903,    603,
+      -988,  -2647,   1847,    141,    817,   -337,    131,    393,
+      1653,    839,   -261,    466,    465,   -297,   1440,   -431,
+      2058,  -1857,  -1416,    310,   -722,    -54,    203,   -266,
+      3770,    172,   -593,    -73,   -508,    -61,   1110,   1261,
+       275,   1681,    447,   -147,    -95,     33,   1281,  -3119,
+        24,   -308,    366,   -468,    232,    358,    667,   -942,
+       696,   -924,  -2059,    -62,    151,  -2102,    332,    258,
+      -186,   -636,    685,    214,  -3174,  -1243,    573,   -276,
+         9,   -262,    -20,    158,   -174,    -21,    593,  -6198,
+      -266,   -270,    -63,   -203,     63,   -396,   -100,    191,
+       212,     85,    120,   -791,     37,    -47,   2108,    652,
+       519,    346,    106,  -1840,  -2566,   -563,     14,    266,
+        10,    214,    504,  -1269,     50,    164,    120,   -105,
+      -546,   -212,    -79,     41,   -171,    675,   -252,   4373,
+       -16,  -1697,  -1491,  -3588,   -587,    623,     67,    269,
+       484,    -25,   1067,    580,   -598,    195,     47,    -17,
+};
+
+static const int16_t cb4448sm0[] = {
+     -5114,    166,   -785,    635,   -528,   -102,    269,    492,
+      -185,   -614,    122,   -124,     85,    145,    270,   -154,
+        39,   2524,     58,    -57,    119,      5,    343,   2873,
+      -278,   -787,    137,     62,   -169,   2049,   1476,   -325,
+       130,   -702,   2882,    -19,    310,   -258,   -135,     88,
+      -268,     69,     69,    695,  -1935,    815,    678,     44,
+      3085,    278,   -587,  -1326,    360,    145,    -17,     66,
+     -2475,   -594,    132,    358,    406,   -369,   -237,   3363,
+       329,   -424,     52,     49,    291,   -236,  -2332,   -261,
+        49,    -27,    170,   3656,   -214,   -603,    264,     60,
+       -87,    145,    116,    179,    190,    679,    339,   -340,
+      3272,    641,  -2631,    484,    159,    305,    290,    208,
+       226,     68,    102,   -145,   -356,    153,    647,  -2046,
+       937,  -1666,   1093,    -29,  -1161,    749,  -2360,    171,
+     -2185,    841,  -1406,  -1057,  -1764,   -300,   -205,    452,
+      2168,   -214,   -153,    291,   -106,     79,   1717,    -20,
+     -1771,    286,   -466,    686,    167,    137,      5,     43,
+      1075,  -2601,    261,    -86,   -333,   -724,    162,    186,
+         4,   -334,   -412,   -309,    888,   -114,    531,    297,
+      4284,    297,  -1695,   -212,     75,   -263,  -2313,    102,
+      -434,    352,  -1813,   -472,    114,   -185,      6,     66,
+      8061,    414,   -577,    672,   -152,    152,      1,     38,
+       -66,     48,    -35,     62,    -98,    -19,  -3762,     98,
+       242,    114,    359,   -162,    115,  -3038,    340,    253,
+      -526,   -144,     14,   -147,     28,   -352,  -5858,     46,
+      -597,   -392,    226,    -54,    -70,    -47,    -45,     16,
+        53,    137,    172,  -3017,    -22,   -163,   -267,  -3289,
+       -31,   -174,    110,    794,    425,     67,     58,    -72,
+      -156,   3937,   -585,   2116,     99,  -1115,   -257,    801,
+       270,   -329,   -257,    -18,    122,   -369,  -2196,   1746,
+      -305,    599,    800,    749,   1466,   -299,  -1519,   -255,
+      -233,    217,   -117,   -256,    301,   -249,   -327,   5530,
+        86,    135,   -784,   -137,    610,     -7,     55,     93,
+      -106,    -50,    267,   -229,    -26,  -1070,     13,    -75,
+      1733,   2929,   -130,   -713,     15,  -2144,    104,   -318,
+       282,     -8,   -285,   -468,   -124,     59,    520,    -78,
+      -332,   -654,  -5048,    212,   -388,     97,  -1523,    227,
+     -2545,   2159,   -127,   1020,     79,   -664,    403,    -31,
+      -356,     -1,   -436,    -86,     75,    610,   3048,    235,
+     -3133,  -1189,    -44,    -23,   -324,    260,    469,   -113,
+        22,     53,    525,    427,    469,   1016,    420,    493,
+     -1229,   -238,  -2671,    361,  -2745,    193,   -253,    -59,
+        15,     53,    -57,     36,   -144,    127,     25,     11,
+       -34,   6560,    -12,    -80,    -72,     70,    654,  -1135,
+       158,    279,    298,    746,   -190,  -1382,    138,    527,
+     -1504,  -2753,   -106,    -55,    225,     54,    136,     53,
+       506,    174,    268,   -533,    -43,   -416,   -196,   6266,
+       -81,     22,   -158,    350,   1177,   -728,    594,     34,
+      -368,   -226,   -584,    247,    804,  -1141,     78,   3923,
+       -53,    309,     58,    -45,  -7634,    -73,     39,   -152,
+        55,    -77,    -45,    -62,    -25,   -247,   -161,     28,
+     -2629,   -401,   -295,   -687,    298,  -3240,      0,   -251,
+         7,    -49,    494,   -198,    202,   2201,   -301,     83,
+        45,   -964,    256,  -1499,  -2394,     24,   -267,   -599,
+        46,    161,   -370,     81,    636,   3146,  -2077,   -964,
+       322,    400,   -635,   -688,   -630,    -92,   -235,    104,
+       -77,   -541,    511,   2722,    441,   2757,    952,    739,
+      -257,   -254,   -438,   -122,   -151,     12,    578,    -92,
+      -440,    -63,     93,   4971,   -499,    419,   1374,   -165,
+      -417,     64,    -13,   -235,   1080,    -77,    536,     68,
+      -842,   -772,   1627,   -471,  -1350,   -144,   2849,    219,
+       114,     68,    -55,    350,    -11,  -1334,  -3042,   1166,
+      -147,   -891,   -483,   1461,    339,    808,    362,   -101,
+     -2807,    -24,   -377,    518,   -438,    194,   -110,    194,
+      -826,   3380,    -81,    -30,    -43,    103,    -99,   1539,
+      -614,    -13,  -1154,    196,  -3122,   -521,   1454,   -319,
+       159,   -428,    722,   -208,    162,   1871,   2534,   2287,
+       946,    261,   -483,   -645,     26,   -170,    -31,     17,
+       164,    104,    -44,  -8192,    -20,     94,   -235,     56,
+        68,    -58,    380,    -25,   -170,     17,     16,   -154,
+        63,    477,   1280,    614,   -529,  -2347,   -360,    159,
+      1967,  -2085,    485,    335,    378,    178,   1633,   -437,
+       -46,     23,    640,   1465,    -91,   1279,  -1025,  -1007,
+      -236,   2632,   -257,    262,    177,   3029,  -3149,  -1001,
+       231,   -262,     87,   -243,    -68,   -597,    109,     62,
+      -264,     37,   -463,  -3105,   -633,    881,   1026,    -86,
+       417,    705,  -1144,    -68,  -2084,     46,    124,    -36,
+     -2461,    -73,   -126,   -303,   1079,   -358,  -2764,   -761,
+     -1454,   -245,    203,      0,   -179,   -117,   2571,  -4751,
+       -20,    194,    298,    258,    390,    270,    -36,    182,
+       152,    -56,    -97,    -47,    138,   -233,   -111,  -1490,
+      -490,   -329,    662,   -320,  -4697,    443,     66,    352,
+       203,   -114,   -119,    186,    649,   -106,     -5,   2280,
+      1132,   -376,   1168,    919,   1858,    271,  -1741,   -130,
+     -3388,    264,    618,  -2375,    260,   1279,    110,    732,
+       128,   -373,     54,   -182,     99,   -131,      9,     30,
+       -83,     27,    204,    109,   -306,   6903,    130,     -7,
+      -115,     92,   -241,    119,   -640,   -871,    -40,    372,
+       -68,   -147,  -1503,    -58,    920,   -466,    311,    144,
+     -3648,   -121,   -357,      5,   1968,   -737,  -1491,    596,
+       818,    122,    688,   -137,  -2415,   -368,    236,     71,
+      -597,   -193,   -395,    795,    855,    657,    -49,    844,
+     -3320,  -1921,    846,     17,   -293,    -17,  -1676,  -1826,
+      -138,    897,   -207,     -3,   1838,   -901,     86,    275,
+       964,    230,    510,    -10,   2879,   3949,    332,    289,
+       109,   -229,     18,    238,    244,    287,     44,    103,
+       367,     21,  -1134,   -378,   1338,   -828,   3500,      5,
+      1027,    475,    208,    654,    589,    -92,    236,    -85,
+      -115,   1095,  -2504,    827,   -885,   -806,   -155,   2112,
+      -346,   1120,   -350,   -911,   -234,    231,     55,     87,
+      1957,    601,    755,  -1248,    753,  -2726,   -481,   2038,
+        96,   -363,    309,    150,    299,   -561,   -698,  -1030,
+       118,   1224,   3240,  -1523,   1476,    342,   -688,    -76,
+       192,     -8,   -319,    350,    149,   -331,    155,   -436,
+       286,   -994,    160,  -2696,   -423,  -2798,   -135,   -108,
+     -2846,   -254,   3590,    350,    130,   -810,    463,   -123,
+        59,   -256,    251,   -750,    -76,     -8,  -1633,    150,
+      -931,   1958,   1523,  -2527,    239,   -287,    172,    332,
+       -13,    486,    247,    -26,    149,     59,    130,    265,
+        19,    209,   7220,    -23,    -99,    -69,    -66,    -70,
+       -54,    -75,     60,   -264,   -102,   1079,   -535,   1587,
+      -557,  -1499,    241,  -2596,   1157,   -140,    270,     33,
+};
+
+static const int16_t cb4448sm1[] = {
+      7894,   -331,    383,   -556,     63,   -371,    -23,     73,
+        46,   -145,    105,     43,   -199,    -52,    -85,    -85,
+        13,    -21,   -230,   7379,    268,   -243,   -460,    251,
+        73,     12,    115,    -18,   -247,    433,    -90,   -518,
+       962,      0,   -960,    184,   -305,  -2003,    276,   1696,
+      2418,    270,  -2140,   -215,   -534,   -389,   -403,  -3500,
+       416,    567,   -393,   -183,    253,   -100,   -285,   -107,
+       100,    281,   -527,  -2944,    -86,   2652,    311,   -785,
+      -811,   -283,    425,    -77,    393,    136,    170,   1290,
+      -765,    108,    676,   -213,  -1226,   -470,    427,   3499,
+       616,  -1211,   -226,    -37,     88,  -2792,    351,     78,
+     -2975,     99,    192,   1390,   -338,     47,     -8,     58,
+      -255,     50,    221,    -49,   -788,   -207,  -2122,   -167,
+      -692,    379,  -3239,   -965,   -698,   -463,    -45,     34,
+      1785,   1026,  -1107,    113,    124,   -258,   -277,   -714,
+      2764,   -178,   -200,    907,    -45,   -213,  -2575,   -530,
+      -112,   3616,   -128,     76,   -366,   -135,    -22,    -51,
+       125,   -100,    -79,    142,     54,    107,     87,    493,
+       -34,   -221,   -448,   -243,    994,    845,  -4656,   -105,
+      -487,     41,   -112,    349,  -4328,    -72,    513,   -112,
+      -685,   -470,   -138,   -541,    340,  -1505,    -24,     37,
+       169,   -405,   -434,  -2994,    -42,   -416,  -1927,   1551,
+     -1488,    420,    179,    -66,     14,     92,    147,    141,
+       497,    404,   -412,   2301,    336,  -2877,  -1845,   -948,
+      -784,    262,   -211,      6,  -1678,   -434,  -1433,   -727,
+      1254,    542,  -1430,   -302,   1558,    107,    617,   -833,
+      -369,   -178,   1682,  -2569,  -1232,  -1556,    -87,   -178,
+       400,   -178,   -427,   -124,    -63,    142,   -221,     33,
+      2880,   -227,   -356,   -466,  -3362,   -398,   -167,    164,
+       126,     59,     -1,      5,    212,     25,   2062,   -462,
+       -33,    -46,     45,   -201,    823,   -268,   -302,   3623,
+       389,    382,    136,    -30,    -64,      2,   -600,   3114,
+      2720,    273,   -588,   -235,   -313,   -141,     37,    -28,
+       355,    184,   -433,   -110,   -576,    -56,    134,   -623,
+      -271,  -2529,  -2753,    947,   1319,     -2,    620,     36,
+      -412,  -1986,    221,   -404,    514,   3223,   -106,   1497,
+      -368,   -167,   -142,   -366,   -125,     16,    142,   -435,
+      -160,   2845,   -153,    470,    387,   3117,    -75,   -375,
+       658,    259,    755,     -3,   3744,   -517,  -1446,   -667,
+      1372,  -1692,    117,    -96,    195,   -201,   -134,    -76,
+       179,     97,     71,   1887,    161,    365,    228,   1177,
+       235,   -834,    -48,   1667,  -1123,   2217,   -209,    100,
+      -219,  -2778,     81,   -579,   3421,   -326,   -492,   -233,
+        78,     32,    117,    -74,    -80,     85,   -282,    453,
+       500,    721,    800,     83,   -624,   1000,    165,    -20,
+      -516,  -4193,   -334,    107,   1221,  -1507,    -10,    523,
+        85,    -44,     21,     34,    199,   -106,  -2233,    525,
+      2138,     40,    -55,    -63,  -8179,    326,    333,   -152,
+       -27,    137,    212,    130,    -10,     76,    -61,   -113,
+      -544,   -179,   -187,      0,  -5308,    322,   -326,    513,
+       415,    375,    -92,   -354,     69,     77,     65,     93,
+      -352,   -165,  -1837,   1790,    914,   -276,   2215,  -1418,
+       343,    281,      4,    283,   4398,   1695,   -248,    153,
+      -166,    751,    822,   -406,   -456,   -251,    185,   -251,
+      -222,   -169,   -266,  -6323,    249,    -40,    -45,   -203,
+        47,    -83,   -621,   -174,    327,     30,    114,    -29,
+      -505,   -224,   1804,   1582,  -2292,   2102,   -746,   -421,
+       170,    438,   -171,    153,     84,   -157,  -2937,   -123,
+       -81,   -227,    -98,    263,   3531,     36,    105,   -479,
+       -94,   -357,    -22,   -124,    279,   -116,    543,    201,
+      -393,   -226,  -2255,   -133,   1613,   -123,   2687,     70,
+       191,    240,   -996,   -676,    606,  -1245,   -306,    413,
+      -272,   -539,    485,   3583,   -224,    432,    389,     31,
+      -888,    318,   -149,   -228,    764,   -426,   1608,  -2656,
+       254,  -2193,    252,    484,    -90,   -117,   -257,  -2210,
+      -156,    553,    559,    680,    298,    -16,   -519,   1172,
+      2172,   1288,   -113,    186,   -199,  -1415,    -83,  -1984,
+       667,  -1013,    344,   -399,   2889,  -1175,   -908,    186,
+       185,    -22,   -328,   3132,  -1166,    209,   -213,    386,
+      2140,    552,   1023,    719,    529,   -169,    421,    196,
+        76,   1995,    532,    -75,   2060,   -526,    396,   2974,
+      -264,   -348,    149,    586,     22,     97,   -337,   -252,
+       357,    103,  -2308,  -2578,  -1836,   -277,    346,   -314,
+      -989,    185,   -314,    102,     56,   3779,   -265,  -1029,
+       -12,   -126,   -431,    356,  -2493,    -86,    172,    116,
+        61,   -146,  -2220,    211,   -165,    233,   -327,     73,
+        -7,   -104,   -546,    253,  -2406,    361,   2252,    486,
+       675,   -177,   2643,    603,    300,   1123,   -642,    361,
+       684,  -2151,    569,  -1014,    120,    -50,    321,   3174,
+      3080,   -733,   -427,    299,    169,   -123,   -140,    -13,
+      -315,     21,   -120,    -24,    174,   -191,   -350,  -7842,
+      -145,   -169,   -419,    -15,    150,   -130,    -73,    162,
+        -9,     38,   -287,    109,    390,    147,    151,   1907,
+     -4243,      7,   -207,   -147,   -230,   -343,   -117,   -111,
+       107,    132,   1457,    -88,     -8,   -445,   -176,   -172,
+     -1799,   -813,    486,   1150,  -3026,   -168,  -2620,   -584,
+       178,   -543,  -1868,   -359,   -113,  -1783,    214,   -663,
+       473,    866,   -136,    169,  -3324,   -129,  -3404,   -249,
+       234,    422,    251,    340,   -343,    231,    134,    -42,
+        32,     64,   -209,     12,    236,   -267,   -419,      1,
+       260,   -109,   6508,    105,      7,   -273,   -123,   -107,
+      -152,   -274,   -157,     75,     74,   -201,     46,     37,
+       338,    -21,   -180,    208,  -6417,    794,    250,    -81,
+      -585,      4,   -119,   -314,    529,    219,    159,   -132,
+      -277,     76,   -613,   4933,     15,    213,   2461,    286,
+       542,    177,   2767,    389,    136,    750,    559,   -994,
+       684,    -12,  -2081,   -546,    -89,  -3733,    548,   -620,
+       675,    118,   -121,    190,    -52,     19,    -19,     25,
+     -1224,    344,   3094,  -2067,      7,    273,  -1268,   -375,
+      -297,   -201,    271,   -191,    123,      6,   -260,   2284,
+      -308,  -3062,    242,    668,   -221,   1146,   1218,    473,
+      -133,     82,     57,    112,  -1677,     78,   -229,    354,
+      -463,    763,   1628,   2243,   1386,   1630,   -145,    255,
+       -60,    228,    195,   -864,   2539,   -466,    985,  -3075,
+         2,    118,    221,   -395,   -450,   -256,   -158,    -32,
+     -3829,   2012,    -50,   -465,    146,  -1091,   -318,    271,
+       -12,    596,    160,    120,     92,   -209,   -335,    104,
+       -28,    689,    305,   -548,   -849,   1617,    605,    185,
+      -414,   3899,   -273,     51,    182,   -192,    121,    616,
+      1219,    414,   -959,  -4219,   1319,     60,    246,   -468,
+       -32,    225,    338,    -39,   1235,  -2079,   2250,    626,
+       121,    296,   -137,   -339,  -1870,    -47,   -397,    124,
+};
+
+static const int16_t fcb8l[] = {
+     -1239,  -1310,  -1240,  -1146,  -1337,   1303,   -482,   2215,
+      2026,   2222,  -1144,  -1188,  -1209,   2535,  -1111,   -844,
+      1485,    625,   1254,   1204,   5932,  -1116,  -1235,  -1208,
+      -801,  -1020,   -558,   1387,   1513,  -1079,   3220,   -896,
+     -1083,  -1166,   2246,  -1210,   -838,   -950,   -960,    764,
+     13941,  -1307,   -817,  -1253,   1850,  -1320,  -1361,  -1218,
+      -671,    780,   -839,  -1068,   -776,   2977,   -714,   -944,
+      -823,   -580,    357,    591,    302,  -1078,   -895,  -1020,
+      3116,  -1144,   1438,   -891,    -71,   1528,   -238,  -1297,
+     -1020,   4616,  -1185,   -514,  -1154,  -1157,   1901,   2372,
+     -1131,  -1289,  -1273,  -1289,  -1311,  -1331,  -1340,    439,
+       455,   2395,   -537,  -1180,   2409,  -1084,   -580,   1937,
+       846,    -51,    615,   1099,   3854,  -1177,   -912,  -1095,
+       656,   -995,   -647,   3298,   -976,   -436,  12323,  -1291,
+     -1187,  -1341,   4779,  -1368,  -1357,  -1317,   -985,   1407,
+      -513,  -1387,  -1224,  -1069,  -1218,  -1117,   -181,  -1209,
+      5376,   4256,    -22,  -1232,  -1173,   -834,  -1054,   -947,
+      -611,   -822,   -206,   5572,   -988,   1067,   -837,    738,
+      -332,    -38,    -59,    143,    248,    386,   -447,  -1233,
+     -1258,  -1169,   3653,  -1045,   -657,   -926,   2004,   2201,
+     -1164,   7042,  -1302,  -1313,   -812,    150,   -129,    305,
+       442,    742,  -1185,  -1293,  -1220,   -872,  -1304,  -1260,
+      -853,  -1293,   2962,   3011,   -178,  -1187,  -1087,   -896,
+      -895,  -1053,   3788,     59,   -169,   1632,  -1201,  -1289,
+      5263,   -896,    331,   -852,    218,    825,   1129,   1024,
+       -39,  -1186,  -1054,   1862,  -1198,   2010,  -1075,  -1005,
+       702,   1550,   4491,  -1055,   -890,   -645,   -987,   2465,
+       529,    194,    -72,    370,   1547,   -968,   -849,  -1153,
+      6459,  -1164,  -1061,  -1020,   -838,    125,   3698,  -1168,
+     -1066,   1882,  -1159,   -439,  -1017,   -759,    744,   1302,
+      -812,   -985,  -1002,  -1029,   -871,   3690,   -170,    604,
+       623,   1272,   6135,  -1012,  -1231,  -1066,   -927,  -1082,
+      2393,   -843,   1537,   1240,   -866,  -1161,   -866,   6639,
+      -994,   -860,   -264,   -298,    469,   1184,   -868,  -1262,
+      2167,  -1177,   2132,   -987,   -563,    969,   1145,   1508,
+      -735,  -1232,  -1090,  -1204,   1507,  -1101,   -393,    755,
+       975,   1246,   1944,  -1068,  -1169,  -1040,   -987,  -1301,
+      5488,  -1057,   3150,   1890,  -1133,   2725,  -1123,   -963,
+      1901,    260,   -484,    449,    564,   1144,    679,  -1118,
+      -989,   -702,   -556,    162,    689,    712,    673,    443,
+      -695,  -1247,  -1019,  -1065,   -406,  -1143,   1750,   -743,
+      2644,   2402,  -1171,  -1157,  -1059,   -823,   -688,   1314,
+      1458,    629,    857,    856,   -875,  -1316,   3470,  -1061,
+      -846,   -761,   -712,   -955,    978,   1967,   -980,   3517,
+      -994,   -953,   -903,     56,    228,    -30,    359,    560,
+      9926,  -1178,  -1056,   -627,   -952,   -481,  -1168,   -268,
+      -701,   -555,   -887,  -1212,   1768,  -1156,   -396,   -755,
+      -119,   1594,    949,   1201,   -844,   1734,   1312,   -331,
+      -500,   -280,   -125,   -219,   -139,    496,  -1121,  -1227,
+     -1145,   -215,  -1123,   -765,   -173,   4055,   1086,   1465,
+      -714,   -904,   -901,   -713,  -1073,   1233,   -797,    645,
+        58,    897,   -518,   -624,   -441,   -554,   1139,    549,
+       147,     72,    127,    428,  -1104,   -979,   2433,   1867,
+      -237,   -745,   -280,    110,    794,    631,  -1049,   1141,
+      -974,   -920,   -849,   -392,    634,    414,    614,    797,
+     -1162,  -1344,  -1192,  -1259,  -1079,   -912,   2717,   2548,
+      1847,   1920,  -1004,  -1091,  -1006,   -692,    -85,    -24,
+      1014,   1427,    751,   -584,   6057,  -1206,  -1072,   -795,
+      -921,  -1103,  -1157,   -623,   -818,   2641,   3121,  -1084,
+     -1095,   -939,   -664,   -694,    884,    555,    144,    593,
+      -874,  -1074,    417,  -1027,     -6,   -790,   1687,     80,
+      1018,    738,   -527,   -958,   -701,   -377,     -4,    155,
+       304,   -348,   -947,   -342,   2269,  -1040,   1124,   -494,
+       -76,     76,      2,    114,   -194,    348,    904,    466,
+      -577,   -717,    107,    -39,    -29,    158,    101,    149,
+      -968,   -921,    558,   -264,   -445,    138,   -121,    -33,
+       105,    243,   -478,  -1047,   -937,   -751,   -609,   -822,
+      -709,   -976,  -1006,   2800,  -1108,  -1292,  -1055,  -1272,
+     -1295,  -1152,    305,  -1144,    635,   2067,   -584,  -1135,
+      -663,  -1130,   -754,  -1009,   -937,   -515,   1473,    841,
+     -1235,  -1338,  -1305,  -1141,  -1109,  -1217,   -238,   1915,
+      3550,   2306,   -963,   -985,   -874,    763,   -826,   -694,
+        19,    391,    379,    776,   -582,  -1216,  -1285,  -1164,
+     -1276,  -1305,  -1273,   2631,   -579,   2487,   1058,   -655,
+      -808,   -878,   -910,  -1006,  -1122,   -590,   -663,    428,
+      2185,  -1125,  -1032,  -1076,   -873,  -1139,  -1029,   -477,
+      1720,   1238,  -1111,  -1311,  -1343,   1074,  -1328,  -1181,
+      -970,   -386,   2359,   1777,  -1045,  -1189,  -1117,  -1053,
+      -942,   -329,    501,   1237,    808,   1022,   -866,  -1048,
+      -678,   1597,   1528,   -262,   -256,    231,    418,    728,
+};
+
+static const int16_t fcb8s[] = {
+     -1022,   -858,   -773,    304,   -881,   -771,   -341,    937,
+       270,    420,   -684,  -1000,   -795,   -903,   -671,   -575,
+        14,   3327,    528,    893,    965,   -541,   -947,  -1027,
+      4008,  -1081,   -743,   -991,   -808,    933,  -1406,  -1173,
+      7513,   -824,   -213,   -797,   -648,    -40,    176,    217,
+     -1298,   6743,   -755,   -232,   -440,   -680,   -269,    -60,
+       -80,    -85,   -893,  -1044,   -726,   -733,   -834,   -641,
+       231,   -779,   -501,   1832,  -1296,   2548,   2754,     19,
+      -210,   -708,   -205,    -74,     18,     55,  -1225,  -1123,
+     -1239,   6991,   -689,    272,   -290,     56,    356,    675,
+      1623,  -1134,   -607,   1426,   -872,    511,  -1060,    408,
+       253,    423,   1960,  -1337,  -1152,   -985,   -924,   2020,
+      -398,    348,   4188,   1044,   -650,   -831,   2909,   2083,
+      -457,     -5,  -1037,   -964,   -128,    -40,   6019,   -858,
+      -937,   -559,   -624,   -601,   -411,    120,   -289,    412,
+     -1271,  -1351,   3858,  -1214,   2224,   -325,   -165,    535,
+       559,    386,   1868,    649,    269,    245,   -708,   -778,
+      -179,    -12,    101,    -12,  -1235,   -892,   -829,   2570,
+      -574,   -431,    170,    167,    492,    531,   -930,  -1093,
+     -1037,  -1177,  -1151,   -912,   -466,    303,   1601,   4089,
+     -1234,   3160,   -631,  -1090,   -741,   -274,    103,     13,
+       356,    289,   2709,  -1115,  -1011,   -965,   -948,   -563,
+      1939,    870,   1187,    550,  -1028,  -1217,   -726,   -954,
+      -694,   -753,   3729,    141,    518,    854,  -1102,   1138,
+      -947,   -620,   -379,   -436,     72,    449,    432,    428,
+     -1112,   1276,    544,   -334,   -445,    179,    -32,    -37,
+         9,     28,  -1252,   2983,   -963,   1256,    419,    -10,
+        17,    211,    218,    191,    126,   -942,   -691,   -529,
+      -533,   -193,   1216,    150,    389,    152,  -1191,   -987,
+      -942,   -860,   -463,   -705,   -159,    184,   1893,   1080,
+      1753,   -694,   -609,   -699,     61,    269,   -126,     93,
+       236,    380,   -527,   -966,   -334,    163,   -662,   3295,
+      -477,    591,    259,    638,    397,    181,   -598,   -129,
+        35,    -51,   -122,     64,    -32,    -98,  -1351,  -1140,
+      3372,   -753,   -776,    718,    513,    134,    420,    354,
+     -1128,   -546,   -743,    297,   1819,    -77,    179,     17,
+       181,    206,  -1028,  -1027,   -757,   -755,   -389,   1035,
+       227,    249,    315,    395,   -931,   -881,   1207,   -777,
+      -165,   -531,   -375,     73,    346,    332,  -1159,   -788,
+      1196,    959,   -432,   -337,    243,    176,    321,     -7,
+};
+
+static const int16_t fcb8m[] = {
+     -1379,  -1331,  -1277,  -1266,   -927,      0,   2552,   2575,
+       425,     48,   2568,    -26,   -841,   -762,   -679,   -562,
+      -420,    186,     68,     69,   -743,   -193,    266,     92,
+      1714,   -241,   -357,    -93,   -252,   -222,   -884,   -385,
+      2436,   -446,   -150,   -533,   -192,    -33,    226,      8,
+      -756,  -1180,  -1238,  -1258,  -1250,  -1147,   -764,    141,
+      3075,   4136,  -1255,  -1288,  -1202,  -1188,  -1222,  -1257,
+      -500,   1989,   4062,   1328,   -300,   -186,   -399,   -329,
+      -330,   -533,   -313,   2030,    193,   -128,   -933,  -1016,
+        66,   1648,   -228,   -321,    236,    114,    356,    212,
+      -677,   -826,   -784,   -670,   -484,   -423,   -188,    215,
+      2476,    652,   3424,   1991,    940,   -576,   -942,  -1038,
+     -1097,  -1161,  -1120,   -956,   -763,   -416,   2824,   1429,
+      -693,   -755,   -455,   -670,   -535,   -225,   4814,    116,
+      -940,   -953,  -1008,   -856,   -797,   -582,   -531,   -213,
+      -412,   2479,   -156,   -218,   -319,   -168,   -236,   -248,
+      -305,   -515,   -224,   -382,   -501,   -759,    139,   1789,
+      -258,   -343,   -167,    721,  -1014,  -1092,   -975,  -1070,
+     -1126,   -778,   -178,     36,    522,   5371,   -402,  -1351,
+     -1577,  -1662,  -1642,  -1560,  -1249,   -870,    602,   8968,
+     -1126,  -1102,  -1118,  -1072,   -946,   -511,    482,   1635,
+      1108,   2471,   -935,   -748,   -302,   -445,   -810,   -359,
+      1433,    -83,    336,   1834,   -712,   -773,   -752,   -609,
+      -391,    625,   2550,    403,   -447,    -18,   -261,     91,
+      5096,   -199,   -887,  -1018,   -728,   -930,   -921,   -684,
+       -22,   2422,   2118,   -417,   -757,   -789,   -732,   -794,
+      -785,   -664,   -627,    885,    471,    798,   -429,   -684,
+      -454,   -185,    185,    -26,   -990,   -369,   1048,    -25,
+       -98,    720,     41,    -60,     -3,    -92,   -790,   -147,
+       846,   4007,   -346,   -907,   -849,   -730,   -639,   -842,
+      9096,    617,  -1164,  -1275,  -1380,  -1396,  -1391,  -1364,
+     -1342,  -1080,    655,   5687,    505,   -818,  -1134,  -1125,
+     -1136,  -1123,  -1088,   -996,      3,     36,    -48,    -28,
+       121,    -55,    172,    -43,     21,    -74,   1537,    -69,
+       378,    -38,   -113,    159,   -149,   -609,   -693,   -796,
+      -715,    588,    376,   -744,   -659,   -316,    145,    448,
+       659,    320,    787,   -315,   -956,   -682,   -595,   -327,
+       146,    348,    837,    577,  -1011,  -1014,   -647,   -159,
+       679,    158,    294,    670,    507,    540,    418,    558,
+        12,   -674,   -901,   -897,   -827,   -682,    323,   2580,
+};
+
+static const int16_t fcb16l[] = {
+       -13,   -798,   -772,    235,    515,   -181,   -120,   -509,
+      -392,  -1159,   -844,  -1041,   -881,  -1193,   1103,  -1080,
+       214,   1615,   1819,   1510,   -914,  -1190,   -273,  -1099,
+      -522,   -996,   -206,   3946,    996,   1678,  -1220,  -1201,
+      2850,  -1022,   1101,   -814,   -188,    879,   1549,   1279,
+     -1129,   1928,   1550,     38,   -356,   -574,   -157,    286,
+       481,    475,  -1079,  -1176,   -861,   -548,   -657,   -381,
+       538,    948,   -838,    779,  -1149,   -962,   1788,   -779,
+      -742,   -311,    205,    299,    472,    715,    702,   -843,
+      -931,   -790,   -624,   -332,    324,    778,    785,    670,
+     -1137,  -1205,   -103,  -1182,  -1071,   -950,    101,    527,
+      1596,   1004,    682,   -564,  -1053,   -844,  -1184,   1732,
+      -862,   1994,   -988,   1131,  -1069,  -1276,  -1053,   6414,
+     -1259,   -186,   -930,    118,    375,   1092,   6215,   -900,
+      -920,   -935,   -981,   -970,   -766,   -902,   -334,   1629,
+     -1094,  -1142,  -1155,   -779,  -1092,   1011,   -490,   1063,
+      1569,   1340,   2242,  -1313,   6027,  -1319,  -1337,   -789,
+     -1296,   -457,    819,   2276,  -1071,  -1065,   -715,    802,
+      -996,    397,   2396,    -27,   1225,    935,   1400,   -862,
+      -802,   1846,   -513,   -249,   -704,    515,    872,    662,
+     -1141,   5876,   -691,   -404,   -603,   -148,    -57,    187,
+       649,    788,  -1116,   -915,   -551,   3843,   -737,   -133,
+       498,    155,    227,    718,   1798,   1397,   -868,   -716,
+      -586,   -580,    -71,    -67,    311,    536,   2465,   -524,
+      1837,   -231,   -210,    263,    231,    -10,   -164,   -324,
+      -951,  -1130,   5206,   -525,   -603,   -401,    223,    438,
+      1011,   1077,   -726,  -1102,  -1013,   -386,   -786,   4281,
+      -329,    262,    550,   1292,   -629,   -943,   -976,    773,
+      -867,    908,   -680,   -154,    362,   1056,  -1051,   -703,
+     -1333,  -1424,  -1026,   -793,   -859,   -882,   -148,   9958,
+     -1193,  -1156,  -1077,   1241,  -1013,   -726,   -139,    551,
+      1150,   1019,   -733,   -997,   -651,   -625,    -54,    722,
+        73,    -14,    361,    435,   4013,  -1260,  -1195,   1452,
+     -1105,   1273,   -670,   1546,   1038,   1680,   -812,  -1060,
+      -853,  -1058,   2094,   -801,   -457,   -320,    683,    960,
+     -1019,  -1158,  -1118,  -1034,   -617,    404,   1376,    847,
+      1014,    951,    -12,  -1004,  -1221,  -1131,    649,  -1052,
+       442,   -167,   -859,   3868,  -1216,  -1298,  -1311,   2866,
+     -1310,   -639,  -1079,   1576,   1760,   1837,    118,  -1080,
+      -862,   -845,  -1065,  -1069,   2199,   -766,    495,   1309,
+      -996,  -1040,   -741,   1357,   1726,    382,    264,     92,
+       659,    665,   -781,  -1356,   2055,  -1198,     15,   2143,
+       631,    569,    918,   1120,   -948,  -1253,  -1234,   2442,
+     -1062,   2206,     48,    660,   1822,   1480,   -639,    627,
+      -432,   -477,    845,    216,    228,    152,    157,    295,
+      2444,   -908,   -465,   -768,    109,    251,     72,    -59,
+       169,    405,   4395,   -837,   -931,   -839,   -215,   -564,
+       655,    359,    503,    296,   3514,  -1082,  -1185,   -827,
+      2879,  -1224,   -811,   -970,    804,    911,   3028,  -1284,
+      -688,  -1226,  -1251,   -551,  -1247,   -275,   3441,   2322,
+      -630,  -1213,   -108,  -1191,   1129,   -854,   2848,   1609,
+      1048,   1535,   2784,  -1245,    772,  -1230,  -1298,   -686,
+     -1293,   -639,    278,   2455,   9975,  -1077,  -1233,  -1055,
+      -139,   -853,    -48,     24,   -720,    533,  -1191,   2809,
+     -1015,   -899,    -28,   -765,   -147,    146,    592,    814,
+     12493,  -1274,  -1072,  -1297,    877,  -1068,  -1179,  -1032,
+      1023,  -1178,   -840,    930,   -660,   1216,   -366,   -406,
+       -97,     77,    179,    340,   -973,   -993,   2280,   1775,
+      -631,    -17,   -186,    507,    459,    645,   2095,  -1019,
+     -1067,   -949,   -857,  -1202,   -904,    -48,   1156,   1273,
+     -1230,  -1245,  -1203,  -1036,  -1150,   -955,   1193,   1943,
+      1437,   1329,   -618,  -1055,   -730,  -1014,   4953,  -1125,
+      1089,   1085,   1047,   1045,    813,  -1036,   1270,   -715,
+      -684,    -96,   -131,    289,    782,    628,   -979,   1060,
+      -975,   -964,   -811,    -14,    223,    422,    563,    696,
+      -901,   -633,    496,   -136,     22,    -83,    -52,    264,
+        24,    147,   -446,  -1197,  -1258,   -687,  -1239,   -795,
+     -1066,  -1196,    147,   2653,  -1231,  -1275,  -1240,  -1041,
+     -1260,  -1159,   1961,    -34,   2937,   2128,  -1318,  -1355,
+     -1326,  -1300,  -1345,  -1326,   -870,   -298,   2014,   3890,
+      -933,  -1014,   -859,  -1074,   -506,  -1163,   -954,   -819,
+       440,    732,   -582,  -1268,  -1206,  -1037,  -1081,  -1255,
+     -1150,   -835,   2360,   1469,  -1232,  -1384,  -1388,    542,
+     -1359,   -606,  -1335,   1852,   2142,   3722,  -1218,  -1321,
+     -1268,  -1207,  -1203,  -1316,   -954,   -696,   4730,   2920,
+     -1225,  -1306,  -1131,  -1273,  -1276,  -1238,  -1040,   2079,
+      2652,   1931,  -1167,  -1302,    659,   -532,   -650,   -560,
+     -1028,    186,   1224,   2811,   -896,   -449,   -999,   -823,
+       -81,   -876,    502,   -293,    680,    733,   -836,  -1111,
+     -1132,   -865,  -1141,   -938,   -980,   1287,    581,   1438,
+};
+
+static const int16_t fcb16s[] = {
+      1260,  -1427,  -1400,   -996,   -958,  -1195,   6261,     31,
+       967,    752,   3776,   -975,   -840,   -707,   -696,   -555,
+        45,   1159,      4,    358,   4718,  -1471,  -1464,  -1291,
+     -1364,   -934,   -878,   5198,   -273,   1555,  -1438,  -1729,
+     -1579,  -1470,  -1820,  -1436,  -1255,   -631,   4287,   4025,
+      1233,   -684,   -748,   -742,   -547,   -229,    321,    126,
+       794,    670,   6689,  -1041,  -1160,   -861,  -1002,   -976,
+       147,   -668,    521,    940,  -1186,   2097,   -570,   1759,
+      -251,   -442,    -92,     46,     99,     12,  -1336,  -1061,
+      4427,   -945,   -861,   -460,   -306,    494,    481,    536,
+     -1101,  -1105,   2695,    316,   -801,   -159,   1042,   -577,
+       -78,    340,   2347,   1448,    135,   -381,   -688,   -493,
+      -254,   -234,    -74,    -80,  -1047,  -1246,   -729,   -985,
+      5399,  -1018,    643,    822,    889,    432,   -328,  -1386,
+     -1420,   -702,  -1450,   6927,  -1107,    465,   1625,   1116,
+     -1258,   2847,   -893,   -895,   -521,   -263,    112,    157,
+       556,    500,    182,   -652,   -226,    258,   -638,   -566,
+      -419,   -669,   -224,   -221,  -1197,   -227,   -582,     92,
+      1914,   -184,    -11,    -18,    270,    166,  -1294,    -62,
+      1536,   2470,   -413,   -619,   -399,     24,    106,     54,
+     -1223,   2672,   2400,    -54,   -577,   -692,   -301,     -3,
+       206,     89,  -1424,  -1491,   8425,  -1072,   -242,   -420,
+      -194,     -1,    489,    331,   -938,  -1319,   2493,  -1355,
+       551,   2297,    197,     -9,    717,    434,  -1237,   -773,
+     -1021,   3945,   -566,    116,    246,    150,    510,    370,
+     11804,   -457,  -1006,  -1231,  -1175,  -1086,  -1221,    589,
+      -679,   -757,  -1183,   6502,   -584,   -454,   -629,   -570,
+      -413,   -352,   -279,    -32,  -1236,   -946,   -760,   1535,
+      -865,   -712,   -224,    343,    647,    613,  -1348,   -938,
+      -961,   8273,  -1130,   -591,   -225,    210,    420,    140,
+     -1247,  -1166,   -966,   -986,  -1120,   -907,   -181,    470,
+      1888,   1161,  -1076,  -1298,   3479,  -1151,   2410,   -396,
+         1,    -44,    357,    594,   -896,    745,    -33,   -422,
+      -332,   -259,      0,     48,    143,    190,  -1009,   -837,
+      -876,   -371,   -370,   1520,   -150,    251,    240,    448,
+     -1024,  -1008,   -568,   -450,   -611,   -536,   1763,    -34,
+       355,    454,   -769,   -599,   -639,   -737,   -912,   -725,
+      -504,   -230,    532,   3294,  -1077,   -289,   -875,   -542,
+      -574,   -604,   -339,   2511,    479,    742,  -1218,   -946,
+      1321,   -522,   -544,   -950,   -765,    632,    639,    497,
+};
+
+static const int16_t fcb16m[] = {
+      -940,  -1197,  -1190,  -1200,  -1192,   -960,   -718,    610,
+      3300,   3253,  -1515,  -1689,  -1798,  -1798,  -1793,  -1764,
+     -1616,     33,   2377,   7778,   -668,   1745,   1501,    785,
+      -336,   -823,   -708,   -446,   -455,   -812,   8862,    159,
+     -1141,  -1261,  -1323,  -1299,  -1261,  -1227,  -1214,  -1090,
+      3584,   2092,    688,   -531,   -848,  -1000,  -1047,  -1192,
+     -1104,   -887,   5163,   -347,  -1129,  -1285,  -1336,  -1291,
+     -1249,  -1109,   -498,   2511,   -611,   -703,   -516,   -240,
+       -68,    399,   1570,    252,     -5,     43,  -1163,  -1168,
+     -1008,   -921,   -995,   -569,    925,   1511,   1001,   2023,
+     12926,    135,  -1598,  -1778,  -1847,  -1850,  -1836,  -1734,
+     -1695,  -1690,    621,   4647,    588,   -752,   -973,   -996,
+      -953,  -1081,  -1060,   -672,   -868,    259,   4940,   -117,
+      -718,   -907,   -828,   -776,   -606,   -981,  -1002,   -526,
+      -385,    527,   1501,   -239,     38,     25,    112,    -77,
+      1122,   -250,   -352,  -1113,  -1101,   -942,   -681,   5156,
+      -800,   -636,   5814,   -160,   -777,   -825,   -844,   -747,
+      -697,   -645,   -668,   -492,   -936,    491,   -280,   2573,
+      -269,   -736,   -375,   -265,    -98,   -243,   -920,   -236,
+       446,   1095,   -666,   -600,   -246,    783,    282,      0,
+     -1064,   -116,   2271,   -118,   -482,   -240,   -187,   -271,
+        36,     91,   -695,   -254,   -383,   -948,    745,   2722,
+      -129,   -799,    238,   -379,   2872,   -516,   -868,   -623,
+      -551,   -275,     22,    379,   -185,   -230,   1524,   -672,
+     -1062,  -1164,  -1177,  -1137,  -1058,   -790,      6,   4928,
+      -551,   -389,   -460,   -394,   -674,   -586,   -327,   -178,
+       615,   2868,  -1467,  -1203,  -1316,  -1120,   -996,    747,
+      -219,   2023,   1875,    254,   -871,   -992,  -1062,  -1110,
+     -1149,   -992,   -492,     40,    528,   5374,     83,   -559,
+      -862,   -760,   -541,     28,    207,    629,    502,   1260,
+      -473,  -1110,  -1336,  -1390,  -1412,  -1379,  -1329,  -1081,
+      -238,   9844,  -1332,  -1306,  -1275,   -881,  -1267,  -1249,
+      -237,   2882,   3535,    584,    -13,     52,    -50,     -4,
+         7,      5,     20,    -55,      5,     45,   1587,    350,
+       191,    617,    153,   -236,   -336,   -649,   -798,  -1063,
+      1451,    707,    253,   -733,   -923,   -859,   -621,   -738,
+      -555,   1623,   1727,   -411,   -724,   -772,   -746,   -675,
+      -688,   -209,    915,    622,  -1038,   -474,   -343,    -91,
+      -173,   -104,    255,     96,   1547,    773,   -625,   2272,
+       -90,   -509,   -527,   -247,   -147,   -234,    -45,    166,
+};
+
+static const int16_t fcb44sl[] = {
+      2433,   -925,  -1015,  -1009,   -875,   -276,    378,    464,
+       694,    795,  -1044,   -601,   -658,    257,   -898,   -509,
+      -346,   2160,    694,    952,  -1302,   -619,    502,   -378,
+      -624,   -178,    349,   -100,    204,    546,  -1450,  -1127,
+     -1302,  -1297,  -1051,   -840,   3426,   1346,   1577,   1723,
+     -1267,   -710,   -872,    448,  -1023,   -728,   -521,   -134,
+       874,    936,  -1134,   -549,    203,   -932,  -1051,    755,
+      -608,   -199,    858,   1008,   1819,   -842,   -773,   -739,
+       818,   -371,    289,    293,    656,    704,    308,  -1009,
+      -959,  -1089,    466,   -468,    279,    897,    764,    797,
+     -1433,  -1276,  -1253,  -1326,  -1182,   -992,    -85,   4339,
+      2135,   2136,   1131,   -917,   -966,   -859,   -889,   1178,
+        62,    659,    771,    882,   1844,   -607,   1184,   -766,
+      -805,   -385,    -61,    502,    648,    732,  -1245,   1315,
+      -818,   -827,    621,   -588,    193,    480,    649,    776,
+     -1178,  -1202,  -1152,  -1088,   -857,   -191,    -49,    129,
+      1950,   1237,  -1461,  -1290,  -1342,  -1401,  -1338,  -1213,
+      -623,    224,   4086,   2517,  -1150,   -814,   -747,    916,
+       807,   -288,    319,    436,    560,    718,    392,   -973,
+      -988,    411,   -954,   -502,    214,    621,    856,    831,
+     -1268,   4012,   -852,  -1002,  -1014,   -577,     32,    552,
+       987,   1138,  -1205,  -1319,  -1145,   -928,     80,    371,
+       277,    779,    859,    902,  -1141,   -991,   -957,    707,
+      -892,   1098,    126,    381,    668,    870,  -1254,   -995,
+     -1163,   -926,  -1149,   2572,    -17,    747,   1456,   1509,
+     -1004,   -867,   1205,   -797,    938,   -657,    346,    520,
+       782,    872,  -1328,  -1080,  -1111,  -1067,   2227,   -892,
+       665,   1604,   1425,   1477,   1869,   -668,   -712,   1044,
+      -800,   -139,      0,    355,    609,    717,  -1192,   -632,
+      3546,   -780,   -870,   -501,    141,    504,    921,   1027,
+     -1125,  -1087,   1154,   -660,   -987,    937,     82,   1390,
+      1360,   1243,   1259,   -550,   -769,   -787,   -743,   -362,
+       -12,    177,    321,    505,  -1147,   -899,   -947,   -849,
+      1371,   -462,   -127,     16,    752,    954,  -1405,    448,
+     -1181,  -1259,  -1204,   -868,   -468,    110,   1293,   1263,
+     -1267,  -1180,  -1238,   -930,   -940,    916,   1793,    653,
+      1070,   1137,   -216,   -997,   -845,   -659,   -699,   -174,
+       758,    961,    417,    630,  -1123,   1691,   1229,   -732,
+      -937,   -491,    -78,    265,    744,    864,   4771,   -856,
+     -1005,  -1007,   -934,   -484,    -17,    579,    861,    959,
+     -1264,     70,   -961,   -864,   -860,   -302,    314,    788,
+       487,    686,  -1133,   -790,   -466,    561,   -812,   -256,
+      2078,    -58,    757,    953,  -1133,   -286,   -655,   -476,
+       -23,   -629,      7,    182,    426,    504,  -1110,    314,
+       497,   -822,   -662,   -754,   1179,   1726,    696,    955,
+      1793,  -1143,  -1268,  -1279,  -1207,   -873,   -183,   1546,
+      1440,   1305,  -1278,   1396,   -779,    558,   -840,    -32,
+       -18,    257,    616,    757,    265,   -906,    499,   -897,
+      -846,   -435,    362,    434,    752,    732,    453,    150,
+     -1029,  -1182,  -1195,   -940,   -297,    876,   1084,   1051,
+     -1377,   1354,  -1148,  -1313,  -1211,   -937,   -366,   1942,
+      1323,   1410,    311,   -270,    -81,   -159,     42,     42,
+         7,    357,    255,    285,   1973,   1386,   -752,   -873,
+      -916,   -466,    -39,    493,    638,    759,  -1338,   1107,
+     -1081,  -1165,  -1038,   -484,   1722,    534,   1038,   1102,
+     -1446,  -1212,  -1337,  -1452,  -1422,  -1291,   -690,   1634,
+      1348,   1640,  -1044,   -184,   -757,   -683,   -100,   1044,
+       369,    349,    432,    584,  -1137,   -528,   1425,   1294,
+      -842,   -257,    -32,    289,    639,    796,  -1418,  -1229,
+     -1282,  -1391,  -1421,  -1234,   -852,   -765,    737,   2076,
+     -1104,   -928,   -936,  -1088,    378,   -765,   1603,    581,
+       753,    925,  -1191,   -841,   -919,   2886,   -907,   -232,
+       180,    543,    956,   1070,  -1314,   -843,    804,  -1094,
+     -1209,  -1031,   -626,    698,   1049,   1152,    256,    831,
+      -841,   -814,   -841,    -54,    134,    347,    535,    658,
+       104,   -801,   -959,   -519,   -406,    156,     12,     13,
+       380,    494,  -1144,  -1112,   -973,   -965,   -916,   -474,
+      -225,    460,    402,    734,  -1448,  -1316,  -1278,    231,
+     -1086,   -578,    584,   1115,   1275,   1260,  -1321,   -963,
+     -1127,  -1288,     41,  -1102,    -31,   1331,   1003,   1145,
+       112,  -1270,  -1343,  -1376,  -1114,   -778,    392,   1918,
+      1165,   1246,  -1247,   -870,  -1232,  -1147,  -1075,    570,
+       181,   1983,    971,   1216,  -1309,  -1199,    260,  -1136,
+      -950,   -742,   1067,    703,   1150,   1144,  -1405,  -1533,
+     -1564,  -1549,  -1264,   -737,   1085,   1706,   1806,   1785,
+       282,  -1173,  -1128,  -1188,   -971,   -885,   -291,    254,
+       841,    987,   -142,  -1068,  -1264,  -1232,  -1058,    138,
+       546,    521,   1096,    987,    890,   -936,  -1020,  -1051,
+      -871,   -521,   1686,    625,    930,    936,  -1343,   -924,
+     -1231,  -1247,  -1052,   -951,   1110,    125,    826,   1116,
+};
+
+static const int16_t fcb44ss[] = {
+      6575,   -881,  -1291,  -1258,  -1090,   -517,   -268,    -56,
+       106,    295,   -303,  -1134,  -1113,   -650,   -508,   1843,
+      -235,   -141,    454,    832,  -1212,    856,   -404,   -620,
+      -682,   -487,    -69,    865,    341,     95,   3626,  -1037,
+     -1366,  -1349,  -1126,   -558,    187,    343,    657,    765,
+      -410,   -735,  -1046,  -1023,   -897,   -673,   -366,   3174,
+      1264,    720,   -730,   -922,   -523,   -821,   4042,   -463,
+        45,    329,    213,    -93,    301,  -1011,    277,   -840,
+      -820,   -451,    417,    470,    739,    953,  -1219,  -1286,
+     -1545,  -1426,  -1209,   -803,   1156,   1311,   1329,   1329,
+      -643,  -1136,  -1200,   -912,   1221,   -695,    342,    910,
+       905,    812,   -996,   -365,   4868,   -738,   -591,   -621,
+        17,    -42,      0,    100,   2085,  -1214,  -1434,  -1432,
+     -1243,   -577,   -626,    140,   1357,   1821,  -1064,  -1261,
+     -1629,  -1525,  -1488,  -1101,   -631,    551,   3556,   3974,
+      -635,   -846,  -1005,   -646,   -803,    123,   -151,    357,
+      2137,    953,  -1168,  -1055,  -1115,  -1061,   -823,   -651,
+      3842,    606,    491,    491,  -1297,  -1063,   -990,  -1051,
+     -1202,   -983,   -468,    -47,    163,    336,  -1131,   -446,
+      -683,    644,   -660,   -675,   1251,    373,    195,   -123,
+     -1109,   -430,   1820,   1883,   -862,   -743,   -265,    119,
+        66,    -41,  -1281,   -768,   1941,   -955,  -1054,   -856,
+       528,    363,    488,    545,   -936,   -682,   -814,   5534,
+      -826,   -347,     58,    -38,    168,     14,   1224,   -719,
+      -300,   -766,   -407,    630,    269,     39,   -230,   -701,
+      1601,   -958,   -945,   -955,   -734,   -487,    -20,   1392,
+       544,    282,   -118,  -1133,  -1161,  -1065,   -939,   -213,
+      -129,   -271,    451,   2570,   -895,   -805,   -536,   1455,
+      1496,   -647,   -199,    114,     95,    -42,   2230,   -855,
+      -715,   -819,   1762,   -699,    -50,   -109,    163,    207,
+      -334,   -759,   3297,   -645,   2561,     77,   -239,   -259,
+      -275,   -445,  -1304,   3536,   1610,   -526,   -926,   -582,
+       -12,     44,   -180,    -69,   -804,   1107,   1451,   -868,
+      -851,   -589,   -354,    -85,     88,    336,   -537,   -444,
+        40,    231,   -715,   -523,   -351,   -379,   -123,    171,
+      1223,   -328,   -567,   2182,   -291,   -352,     20,   -157,
+      -338,   -635,   2194,   -476,   1624,   -802,   -762,   -585,
+      -245,     48,     63,    -45,    -32,   -646,    847,   -556,
+      -727,   -259,   1309,    239,   -128,   -755,  -1018,   -640,
+       876,   -642,   -906,   1394,    -26,    338,    204,    148,
+      -988,   -521,    135,   -807,   1065,   -525,    -80,   -248,
+       383,    836,    521,     13,   -553,   -865,   -928,   -631,
+      -137,    -83,    446,    221,   1924,     48,   -621,   -845,
+      -782,   -544,   -531,   -418,    -79,    915,   -711,   1247,
+      -938,   -766,   -995,   1459,     31,    199,    261,    190,
+      -670,  -1207,  -1013,    108,   -670,    204,    407,    266,
+       473,    998,   -606,   -923,   1845,  -1061,    910,   -774,
+       268,    493,    178,     61,   1938,  -1237,  -1010,  -1097,
+      -780,   -368,   1125,    354,    398,    550,   1032,  -1128,
+     -1196,   -908,   -767,    529,   2326,    728,    227,    -13,
+     -1113,   -367,    382,   -939,  -1094,   -896,   -463,    446,
+       896,   1128,   -591,   -823,   -894,   3052,   -968,   2157,
+      -153,    -71,    111,    118,  -1106,   -930,   -911,   1663,
+      -905,   -691,   -226,    503,    665,    702,   2067,  -1149,
+      -828,    990,   -850,   -426,   -159,    148,    379,    512,
+     -1268,  -1390,  -1492,  -1343,  -1419,   2246,   -224,   2124,
+      1523,   1338,    522,   1613,   -344,   -694,   -487,   -325,
+       293,     96,   -374,   -679,   -364,    124,  -1201,  -1274,
+     -1078,   -513,     15,   1045,    529,    680,    131,  -1067,
+     -1030,   -888,   -806,   -122,   1002,   1302,    757,   -473,
+      -530,   -538,   -821,   -373,     72,    797,    864,    265,
+      -542,  -1090,   -241,  -1095,  -1205,   -991,  -1172,   5025,
+      -420,    728,    461,    103,   2325,   -915,  -1012,   -854,
+     -1117,   2018,   -377,    -35,    266,    443,   -949,  -1163,
+     -1064,  -1057,   -802,    721,   1278,    470,    308,    263,
+       474,   -773,  -1033,   -892,    227,    -30,     39,    101,
+       456,    476,  -1263,   7275,   -946,  -1157,  -1304,   -922,
+       248,    143,    -98,    312,   3419,   -402,   -649,   -629,
+      -554,    -48,    487,     72,   -171,   -687,  -1167,   1869,
+      -524,   1490,   -869,   -236,    111,     68,     77,    -85,
+      1481,    906,  -1189,  -1321,  -1124,   -554,    429,    321,
+       814,    699,  -1048,    486,   -858,  -1096,  -1072,   -744,
+      1676,    -73,    593,    632,    779,  -1265,  -1470,  -1379,
+     -1050,   -548,    781,    524,   1022,   1079,  -1149,   3719,
+     -1064,  -1180,  -1159,   -775,   -211,    241,    492,    555,
+      3025,   2828,   -849,  -1133,  -1063,   -567,    -70,   -142,
+      -176,    -62,   -614,   1745,   -684,   -610,   1478,   -619,
+      -235,   -361,    -84,    -44,  -1155,   1494,  -1183,  -1210,
+     -1294,  -1017,   -330,    210,    931,   1368,  -1306,   2714,
+     -1052,  -1128,  -1220,   -908,   2409,    441,    310,    318,
+};
+
+static const int16_t fcb44sm[] = {
+      5619,   -163,  -1005,   -856,   -831,   -644,   -612,   -759,
+      -770,   -456,    199,   -551,  -1348,    -80,    131,   -481,
+       334,    202,    366,   1246,  -1245,    499,  -1454,   -396,
+      -675,   -257,    525,   1001,    878,   1075,  -1004,  -1010,
+     -1127,   -947,   -976,    332,   3533,   1315,    265,   -683,
+     -1114,   1056,  -1009,   1154,   -728,   -212,    620,    169,
+       102,   -110,   -658,   -902,  -1238,  -1213,  -1238,   -926,
+      -735,   -455,   1130,   5139,  -1184,    190,   1590,   -604,
+      -800,   -373,   -366,    251,    720,    571,     -6,    304,
+     -1228,   -369,   -659,   -506,    -25,   -234,    313,   2366,
+       623,   1473,   -315,    780,   1048,   -416,   -586,   -737,
+     -1029,  -1094,    483,   -725,   -771,   -379,   -268,    -15,
+       697,   1774,     -1,   -999,   -987,   -867,  -1339,  -1255,
+     -1018,   -652,   -125,    643,   3006,   2417,   -543,   1629,
+      1557,   -684,   -568,   -474,   -132,   -291,   -338,   -321,
+     -1250,    641,   -158,   -935,   -575,   -575,    154,    415,
+       798,   1421,   3147,   1903,   -335,   -767,   -729,   -627,
+      -611,   -752,   -836,   -735,    678,    502,   -946,    556,
+      -821,    -51,   -256,     94,    151,     70,   -808,   -324,
+      -359,   3637,    286,    -90,   -365,   -613,   -782,   -871,
+        75,   1051,   -780,   -487,     47,    273,   1768,   -102,
+      -828,  -1267,  -1093,   1420,   -624,    225,   1307,     85,
+       239,   -152,   -649,   -853,  -1072,   -796,   -644,   1383,
+      1143,   -199,     94,    -25,     70,     52,  -1064,   2487,
+      -844,   -607,   -587,    148,    726,    224,   -238,   -484,
+      -957,   -729,   1517,   1334,   -475,   -317,   -253,   -186,
+         1,     17,   -832,   1450,    423,   1408,   -576,   -825,
+      -630,   -579,   -312,    314,    788,    382,  -1000,  -1060,
+      -763,    968,   -135,     56,    143,    477,   -736,     30,
+      4023,     68,   -266,   -420,   -538,   -751,   -893,   -879,
+      -935,     59,    465,    887,   -351,   1396,    176,   -250,
+      -684,  -1019,   -515,   -815,   -957,   -439,    188,   3794,
+        86,    -98,   -245,   -829,   1894,   -386,   -865,   1513,
+        24,   -506,   -281,   -615,   -476,   -364,  -1283,   -963,
+      -339,   -133,   -161,   -480,     25,    230,   1364,   1815,
+      1766,   -844,  -1423,  -1185,   -972,   -458,   -275,    138,
+      1317,   1778,  -1295,   -874,  -1211,   -792,   -601,   -500,
+      2301,    901,   1336,    842,   1355,   -426,  -1160,   -959,
+      -801,   -433,   1852,    144,    284,    169,  -1122,   -851,
+      -957,    272,   -393,    817,    862,    262,    333,    802,
+       320,   -576,   1615,   -615,   -886,   -311,    108,     13,
+         1,    320,  -1205,    962,   -483,   -791,   -749,   1158,
+       677,    -57,    166,    279,   -860,   1237,   -971,  -1057,
+      -598,   -285,    884,   1174,    657,   -303,   2254,   -706,
+     -1113,   -655,    719,    234,   -124,   -199,   -135,   -360,
+      -758,   -623,   -385,    -18,   3243,    470,   -139,   -286,
+      -520,   -953,  -1193,  -1140,  -1297,  -1137,   -764,     25,
+       235,   2217,   1501,   1369,   2024,    781,  -1353,   -835,
+      -824,   -601,   -259,   -140,    387,    671,      3,   -974,
+      -760,   -884,   -485,    709,   1505,    -95,    321,    739,
+      1610,   -156,   1515,    -76,   -420,   -369,   -189,   -506,
+      -705,   -907,  -1052,   -516,  -1048,   -996,   -471,   1195,
+       212,    184,    800,   1665,    747,  -1029,  -1013,    789,
+      -703,    559,   -139,    -98,    380,    523,   -355,   2047,
+      -766,   -991,   -809,   -566,   -257,   -242,    485,   1322,
+      1989,   -330,   -945,   -559,   -448,   1241,    811,     10,
+      -767,  -1218,   1600,   -755,    428,   -729,   -355,   -665,
+      -416,   -120,    381,    548,   -717,    -14,   1587,   -886,
+        -9,    353,    839,    201,   -454,  -1112,  -1334,   -309,
+       660,   -375,   -661,   -511,   1437,    540,    492,      0,
+        95,   3911,   -237,   -301,   -562,   -483,   -569,   -799,
+      -883,   -580,   -670,   -980,  -1056,   -896,   -797,   1551,
+       267,   1000,   1617,     75,  -1132,   -403,   -988,   -830,
+      -627,   1164,   1315,   1594,    310,   -564,  -1091,   -563,
+      1195,   -442,   1086,   -344,   -176,   -258,    175,    476,
+       923,    -37,   -629,   -919,   1278,   -610,    113,   -314,
+       -81,    192,    731,   -944,  -1297,  -1108,   -934,   -259,
+       640,   1164,   1326,    558,   -767,   -519,   -875,   -930,
+      -817,   -533,    496,   2605,   1359,   -131,  -1010,    912,
+     -1055,   -309,    768,   -198,   -166,    -76,    429,    640,
+      3283,   -895,  -1229,   -853,   -853,   -399,    147,     44,
+       237,    495,   -833,   -909,  -1004,   -811,   1039,   1627,
+      -194,    295,    738,    290,   -771,    237,   -912,   -479,
+      -648,   -518,   -226,    573,   2346,    419,   1013,   1510,
+      -865,   -873,   -982,   -557,    598,     50,     81,    -81,
+     -1150,   -640,  -1011,   1991,   -561,   -140,     42,    175,
+       521,    799,   3231,    -46,  -1004,   -994,  -1140,  -1094,
+      -957,   -860,      8,   2346,    212,   -499,    -55,   -997,
+      -623,   -588,     38,    -58,    975,   1529,   -986,   -891,
+     -1121,   -619,   1967,   -463,     -7,    632,    768,    953,
+};
+
+static const float lsp8[] = {
+     0.2702,  0.5096,  0.6437,  0.7672,  0.9639,  1.0696,  1.2625,  1.5789,
+     1.9285,  2.2383,  2.5129,  2.8470,  0.1740,  0.3677,  0.6082,  0.8387,
+     1.1084,  1.3721,  1.6362,  1.8733,  2.0640,  2.3442,  2.6087,  2.8548,
+     0.1536,  0.3279,  0.5143,  0.6859,  0.9763,  1.2744,  1.5605,  1.8566,
+     2.1007,  2.3450,  2.6075,  2.8850,  0.2075,  0.4533,  0.7709,  1.0377,
+     1.2953,  1.5132,  1.7826,  2.0351,  2.2590,  2.4996,  2.6795,  2.8748,
+     0.1393,  0.2453,  0.3754,  0.5453,  0.8148,  1.1289,  1.4389,  1.7592,
+     2.0353,  2.3215,  2.5934,  2.8588,  0.1250,  0.3627,  0.7613,  1.1380,
+     1.4163,  1.5565,  1.6920,  1.8130,  1.8678,  2.0427,  2.4318,  2.8544,
+     0.2256,  0.4223,  0.6452,  0.8599,  1.0673,  1.3118,  1.5486,  1.8366,
+     2.0759,  2.3026,  2.5284,  2.8030,  0.2304,  0.4404,  0.6891,  0.8964,
+     1.1510,  1.4202,  1.6483,  1.8580,  2.1181,  2.3686,  2.6078,  2.9128,
+     0.2230,  0.3816,  0.5520,  0.6062,  0.7909,  1.0988,  1.4330,  1.7846,
+     2.0713,  2.3457,  2.6048,  2.8708,  0.2447,  0.5800,  0.8249,  0.9905,
+     1.1721,  1.3990,  1.6694,  1.9064,  2.1307,  2.4255,  2.6815,  2.9117,
+     0.1974,  0.3812,  0.5802,  0.7759,  0.9280,  1.1547,  1.4170,  1.6369,
+     1.8890,  2.2587,  2.5626,  2.8239,  0.1209,  0.2510,  0.4841,  0.8048,
+     1.1197,  1.3563,  1.6073,  1.8926,  2.1350,  2.3669,  2.6291,  2.8985,
+     0.2352,  0.4347,  0.6582,  0.8178,  0.9548,  1.1654,  1.4942,  1.8812,
+     2.1703,  2.3779,  2.6412,  2.8871,  0.2091,  0.4084,  0.6730,  0.9151,
+     1.1259,  1.3262,  1.5937,  1.8129,  2.0237,  2.3317,  2.5778,  2.8620,
+     0.1167,  0.2406,  0.4520,  0.7298,  0.9848,  1.2448,  1.5137,  1.7874,
+     2.0280,  2.3020,  2.5914,  2.8794,  0.3003,  0.4966,  0.6520,  0.8505,
+     1.1600,  1.3981,  1.5805,  1.8346,  2.0757,  2.3102,  2.5760,  2.8499,
+     0.2451,  0.4163,  0.5960,  0.7805,  0.9507,  1.2438,  1.5587,  1.8581,
+     2.0735,  2.3198,  2.5704,  2.8220,  0.3112,  0.5517,  0.7032,  0.8528,
+     1.1489,  1.4257,  1.6848,  1.9388,  2.1577,  2.4265,  2.6678,  2.9051,
+     0.2249,  0.3897,  0.5559,  0.7473,  1.0158,  1.3581,  1.6914,  1.9930,
+     2.1843,  2.3534,  2.5512,  2.8065,  0.2600,  0.4574,  0.7349,  0.9691,
+     1.1696,  1.3848,  1.6335,  1.9021,  2.1174,  2.3481,  2.5902,  2.8390,
+     0.2246,  0.3372,  0.4560,  0.5249,  0.7056,  1.0273,  1.3810,  1.7132,
+     1.9819,  2.2574,  2.5410,  2.8491,  0.1419,  0.4834,  0.8835,  1.1453,
+     1.2839,  1.4224,  1.5593,  1.7877,  2.1285,  2.4070,  2.6043,  2.8511,
+     0.1886,  0.3677,  0.5617,  0.8099,  1.1277,  1.3841,  1.5804,  1.8136,
+     2.0307,  2.2805,  2.5399,  2.8322,  0.2351,  0.4151,  0.6675,  0.8713,
+     1.0464,  1.3292,  1.6586,  1.9281,  2.1355,  2.3495,  2.6222,  2.8782,
+     0.2700,  0.4489,  0.6206,  0.7121,  0.7737,  0.9848,  1.3658,  1.7433,
+     2.0139,  2.2243,  2.4806,  2.8175,  0.2479,  0.4425,  0.6490,  0.8745,
+     1.1161,  1.3849,  1.6773,  1.9566,  2.1491,  2.3624,  2.5685,  2.8114,
+     0.2035,  0.3701,  0.5567,  0.7953,  1.0082,  1.2758,  1.5373,  1.7822,
+     2.0175,  2.2601,  2.4759,  2.7771,  0.1856,  0.3461,  0.5998,  0.9041,
+     1.2383,  1.4612,  1.6667,  1.9305,  2.1617,  2.4107,  2.6477,  2.8656,
+     0.2107,  0.3715,  0.5289,  0.6651,  0.8420,  1.1168,  1.4401,  1.7230,
+     1.9901,  2.2687,  2.5452,  2.8655,  0.1218,  0.2999,  0.6348,  0.9482,
+     1.2745,  1.5876,  1.9129,  2.2348,  2.4020,  2.4922,  2.6351,  2.8357,
+     0.1617,  0.3483,  0.5869,  0.8163,  1.0366,  1.2344,  1.4609,  1.7029,
+     1.9476,  2.2337,  2.5258,  2.8442,  0.2505,  0.4894,  0.7510,  0.9152,
+     1.0845,  1.3657,  1.6528,  1.8346,  2.0160,  2.2811,  2.5338,  2.8136,
+     0.0947,  0.1158,  0.0578, -0.0337, -0.0066,  0.0104, -0.0447, -0.0505,
+    -0.0778, -0.0293,  0.0251, -0.0143,  0.0349, -0.0227, -0.0909,  0.0523,
+     0.0325, -0.0410, -0.1045, -0.0899, -0.0009,  0.0075, -0.0575, -0.0855,
+    -0.0129,  0.0575,  0.0597,  0.0391,  0.0371, -0.0184, -0.0083,  0.0287,
+     0.0143,  0.0167,  0.0120, -0.0168,  0.0452,  0.0223, -0.0352,  0.0119,
+    -0.0496, -0.0965, -0.0661, -0.0072,  0.1099,  0.0843, -0.0087, -0.0478,
+    -0.0128, -0.0120, -0.0004,  0.0731,  0.1047,  0.0630,  0.0196, -0.0103,
+    -0.0399, -0.0986, -0.0912, -0.0390, -0.0247, -0.0694, -0.0749, -0.0066,
+     0.0223,  0.0634,  0.0343, -0.0134,  0.0727,  0.0241,  0.0066,  0.0437,
+     0.0610,  0.0364,  0.0248, -0.0358, -0.0686, -0.0104,  0.0426,  0.0088,
+    -0.0137, -0.0165,  0.0671,  0.0815, -0.0863, -0.0644, -0.0088,  0.0023,
+     0.0482,  0.1174,  0.1270,  0.0594,  0.0165,  0.0949,  0.1098,  0.0137,
+     0.4951,  0.4999,  0.4958,  0.4907,  0.4984,  0.4965,  0.4958,  0.4996,
+     0.4987,  0.4958,  0.4986,  0.4977,  0.2841,  0.2186,  0.1474,  0.1687,
+     0.2217,  0.2632,  0.2706,  0.2624,  0.2162,  0.2453,  0.2460,  0.2531
+};
+
+static const float lsp16[] = {
+     0.1813,  0.3911,  0.6301,  0.8012,  1.0057,  1.2041,  1.4271,  1.6943,
+     1.9402,  2.1733,  2.3521,  2.4989,  2.5839,  2.6846,  2.7634,  2.8950,
+     0.1311,  0.3183,  0.4659,  0.5601,  0.6658,  0.7828,  1.0065,  1.2717,
+     1.5185,  1.7339,  1.9530,  2.2189,  2.3739,  2.4991,  2.6984,  2.9256,
+     0.1627,  0.4519,  0.6323,  0.7012,  0.7848,  0.9801,  1.1810,  1.3222,
+     1.5413,  1.8129,  1.9338,  2.0809,  2.3180,  2.5189,  2.7066,  2.9514,
+     0.1475,  0.2447,  0.4240,  0.5669,  0.7872,  0.9838,  1.1823,  1.3814,
+     1.5358,  1.6820,  1.8794,  2.1419,  2.4132,  2.6112,  2.7911,  2.9511,
+     0.1224,  0.2876,  0.5013,  0.6985,  0.8902,  1.0901,  1.2835,  1.4768,
+     1.6596,  1.8538,  2.0467,  2.2304,  2.4124,  2.5942,  2.7729,  2.9531,
+     0.1741,  0.3034,  0.4677,  0.5879,  0.7258,  0.9648,  1.1417,  1.3220,
+     1.5081,  1.7151,  1.9212,  2.1286,  2.3208,  2.4938,  2.6765,  2.8891,
+     0.1657,  0.3174,  0.4907,  0.6559,  0.8295,  1.0254,  1.2071,  1.3880,
+     1.5737,  1.7845,  1.9027,  2.1139,  2.3323,  2.5157,  2.7323,  2.9015,
+     0.1592,  0.2758,  0.4417,  0.6315,  0.8257,  0.9873,  1.1277,  1.2830,
+     1.4337,  1.6315,  1.8899,  2.1356,  2.3572,  2.5632,  2.7468,  2.9420,
+     0.1524,  0.4325,  0.5931,  0.7036,  0.7696,  0.8923,  1.1739,  1.4773,
+     1.6609,  1.7911,  1.9666,  2.1972,  2.3754,  2.5045,  2.6613,  2.8882,
+     0.2130,  0.3013,  0.3721,  0.4257,  0.5079,  0.7015,  0.9815,  1.2554,
+     1.4648,  1.6966,  1.9138,  2.1075,  2.3318,  2.5292,  2.7453,  2.9347,
+     0.1142,  0.3748,  0.6205,  0.7642,  0.8121,  0.9022,  0.9843,  1.1558,
+     1.4467,  1.7422,  1.9574,  2.1302,  2.3812,  2.5898,  2.7720,  2.9583,
+     0.1255,  0.2339,  0.3570,  0.5323,  0.7458,  1.0003,  1.1729,  1.3567,
+     1.5217,  1.6977,  1.8924,  2.0942,  2.3145,  2.5408,  2.7553,  2.9337,
+     0.1316,  0.2289,  0.4327,  0.6663,  0.8509,  0.9994,  1.1697,  1.3804,
+     1.5609,  1.6903,  1.8572,  2.1019,  2.3687,  2.5789,  2.7715,  2.9472,
+     0.1502,  0.2546,  0.3883,  0.5333,  0.6976,  0.9163,  1.1071,  1.3364,
+     1.5420,  1.7525,  1.8948,  2.0839,  2.2819,  2.4651,  2.6875,  2.8987,
+     0.1593,  0.3014,  0.4573,  0.6354,  0.8157,  0.9805,  1.1783,  1.3747,
+     1.5678,  1.7326,  1.9286,  2.1340,  2.3253,  2.5280,  2.7180,  2.9298,
+     0.1811,  0.3167,  0.4655,  0.6507,  0.8198,  1.0075,  1.1892,  1.3743,
+     1.5227,  1.7090,  1.8849,  2.0743,  2.2750,  2.4830,  2.6896,  2.8953,
+     0.1846,  0.3577,  0.5315,  0.7290,  0.9176,  1.1016,  1.2654,  1.4525,
+     1.6315,  1.8268,  2.0238,  2.1934,  2.3868,  2.5753,  2.7682,  2.9469,
+     0.0876,  0.1439,  0.2048,  0.3654,  0.6281,  0.8853,  1.0907,  1.2992,
+     1.5227,  1.7373,  1.9395,  2.1419,  2.3488,  2.5486,  2.7466,  2.9348,
+     0.1391,  0.4170,  0.6561,  0.7953,  0.8734,  0.9986,  1.1870,  1.4520,
+     1.6042,  1.7910,  2.0135,  2.1870,  2.3358,  2.5066,  2.7409,  2.9955,
+     0.0804,  0.1355,  0.2599,  0.4998,  0.7408,  0.9474,  1.1276,  1.3428,
+     1.5556,  1.7712,  1.9699,  2.1535,  2.3605,  2.5548,  2.7489,  2.9325,
+     0.1304,  0.3087,  0.4979,  0.6584,  0.8414,  1.0329,  1.2244,  1.4189,
+     1.6118,  1.8200,  1.9985,  2.1893,  2.3915,  2.5794,  2.7647,  2.9344,
+     0.1895,  0.2849,  0.3705,  0.4126,  0.6265,  0.9207,  1.1774,  1.3762,
+     1.5757,  1.7728,  1.9568,  2.1662,  2.3615,  2.5575,  2.7561,  2.9416,
+     0.1800,  0.3078,  0.4805,  0.6796,  0.8503,  1.0046,  1.1703,  1.3269,
+     1.4862,  1.6502,  1.8454,  2.0873,  2.3175,  2.5356,  2.7516,  2.9469,
+     0.1950,  0.3233,  0.4568,  0.5940,  0.7589,  0.9978,  1.1701,  1.3383,
+     1.5017,  1.6565,  1.8243,  2.0605,  2.2938,  2.5147,  2.7419,  2.9396,
+     0.2531,  0.4391,  0.5790,  0.7170,  0.8998,  1.1430,  1.3577,  1.5326,
+     1.6328,  1.7627,  1.9726,  2.1762,  2.3563,  2.5478,  2.7385,  2.9067,
+     0.1805,  0.2788,  0.3591,  0.3881,  0.5441,  0.8055,  1.0766,  1.3165,
+     1.5316,  1.7508,  1.9477,  2.1374,  2.3438,  2.5484,  2.7501,  2.9410,
+     0.2044,  0.3671,  0.5396,  0.7042,  0.8582,  0.9831,  1.1261,  1.3194,
+     1.4769,  1.6979,  1.8717,  2.0463,  2.2620,  2.4739,  2.7054,  2.9208,
+     0.1048,  0.2175,  0.4206,  0.5923,  0.7483,  0.9400,  1.1356,  1.3799,
+     1.5958,  1.7320,  1.8984,  2.1296,  2.3594,  2.5492,  2.7387,  2.9305,
+     0.0842,  0.1729,  0.3951,  0.6447,  0.8688,  1.0605,  1.2472,  1.4330,
+     1.6232,  1.8144,  2.0216,  2.1915,  2.3878,  2.5763,  2.7685,  2.9464,
+     0.1461,  0.2593,  0.4105,  0.5677,  0.7328,  0.8919,  1.0484,  1.2302,
+     1.4386,  1.6635,  1.8873,  2.1024,  2.3116,  2.5268,  2.7273,  2.9269,
+     0.1503,  0.3108,  0.4756,  0.6731,  0.8600,  1.0233,  1.2115,  1.3971,
+     1.5915,  1.7892,  1.9517,  2.1603,  2.3487,  2.5460,  2.7308,  2.8998,
+     0.2163,  0.3669,  0.5125,  0.6709,  0.8143,  0.9930,  1.2095,  1.4205,
+     1.6176,  1.7112,  1.8398,  2.0896,  2.3513,  2.5290,  2.6667,  2.8960,
+     0.2133,  0.4382,  0.6287,  0.8702,  1.1088,  1.3749,  1.6062,  1.7446,
+     1.8333,  1.9122,  1.9614,  2.0669,  2.1789,  2.3449,  2.6038,  2.8849,
+     0.1598,  0.2719,  0.3877,  0.4815,  0.5926,  0.7795,  1.0449,  1.3045,
+     1.5210,  1.7391,  1.9462,  2.1397,  2.3553,  2.5458,  2.7540,  2.9392,
+     0.2918,  0.5607,  0.6801,  0.7404,  0.8285,  0.9431,  1.1579,  1.4080,
+     1.6332,  1.8472,  1.9738,  2.0771,  2.2890,  2.5178,  2.7445,  2.9830,
+     0.1664,  0.2842,  0.3965,  0.5463,  0.8162,  1.0346,  1.1849,  1.3446,
+     1.5122,  1.7563,  1.9960,  2.2002,  2.3796,  2.5689,  2.7712,  2.9550,
+     0.0911,  0.2397,  0.5052,  0.7868,  1.0299,  1.1311,  1.2244,  1.3333,
+     1.4395,  1.6790,  1.9369,  2.1717,  2.3689,  2.5538,  2.7340,  2.9326,
+     0.1647,  0.2931,  0.3836,  0.4978,  0.6255,  0.9243,  1.1339,  1.3001,
+     1.5269,  1.8010,  1.9715,  2.1419,  2.3784,  2.5503,  2.6719,  2.8745,
+     0.2440,  0.3802,  0.4756,  0.6613,  0.8627,  1.0292,  1.2291,  1.4060,
+     1.5198,  1.7354,  1.9044,  2.1010,  2.3147,  2.4996,  2.7171,  2.9041,
+     0.1590,  0.2876,  0.4572,  0.5996,  0.7713,  0.9490,  1.1205,  1.2815,
+     1.4516,  1.6385,  1.8179,  2.0457,  2.2759,  2.4785,  2.6861,  2.9080,
+     0.2297,  0.4309,  0.5712,  0.6717,  0.8138,  1.0463,  1.2492,  1.4560,
+     1.6796,  1.8458,  1.9642,  2.1452,  2.3636,  2.5395,  2.7456,  2.9495,
+     0.2975,  0.4678,  0.4996,  0.5809,  0.6279,  0.6884,  0.8606,  1.1386,
+     1.4412,  1.6876,  1.8760,  2.0932,  2.3178,  2.5166,  2.7345,  2.9280,
+     0.1278,  0.3737,  0.6004,  0.7069,  0.8147,  1.0180,  1.2581,  1.3812,
+     1.4855,  1.7268,  1.9970,  2.1258,  2.2936,  2.5702,  2.7563,  2.8983,
+     0.1314,  0.2508,  0.3999,  0.5680,  0.7424,  0.9367,  1.1286,  1.3175,
+     1.5336,  1.7404,  1.9317,  2.1404,  2.3514,  2.5562,  2.7510,  2.9402,
+     0.1043,  0.2367,  0.4293,  0.6376,  0.8160,  0.9836,  1.1779,  1.3850,
+     1.5835,  1.7875,  1.9765,  2.1593,  2.3654,  2.5577,  2.7465,  2.9398,
+     0.1529,  0.2515,  0.3454,  0.4374,  0.7011,  0.9015,  1.0744,  1.3532,
+     1.5699,  1.7545,  2.0021,  2.1259,  2.2278,  2.4546,  2.7264,  2.9425,
+     0.1429,  0.2808,  0.4395,  0.6334,  0.8069,  0.9705,  1.1520,  1.3250,
+     1.5109,  1.7285,  1.9356,  2.1469,  2.3479,  2.5554,  2.7512,  2.9348,
+     0.1625,  0.3022,  0.4756,  0.6315,  0.8032,  0.9924,  1.1596,  1.3204,
+     1.4994,  1.6929,  1.8955,  2.1090,  2.3025,  2.5018,  2.6908,  2.8980,
+     0.1692,  0.3427,  0.5228,  0.7756,  0.9688,  1.0950,  1.3056,  1.4360,
+     1.5675,  1.8049,  1.9376,  2.1151,  2.3407,  2.5012,  2.7192,  2.9258,
+     0.0474,  0.1251,  0.1939,  0.3841,  0.6501,  0.9231,  1.1153,  1.3240,
+     1.5478,  1.7599,  1.9651,  2.1510,  2.3645,  2.5552,  2.7542,  2.9393,
+     0.2196,  0.4656,  0.7492,  0.9922,  1.1678,  1.2489,  1.3112,  1.3657,
+     1.4223,  1.5302,  1.7212,  1.9996,  2.2523,  2.4844,  2.7036,  2.9145,
+     0.1128,  0.2368,  0.3704,  0.5476,  0.7723,  0.9968,  1.1930,  1.3992,
+     1.6013,  1.7957,  1.9888,  2.1857,  2.3825,  2.5705,  2.7616,  2.9434,
+     0.1341,  0.2768,  0.4510,  0.6359,  0.8332,  1.0335,  1.2004,  1.3952,
+     1.5762,  1.7681,  1.9815,  2.1735,  2.3657,  2.5552,  2.7514,  2.9498,
+     0.1247,  0.2559,  0.3516,  0.4726,  0.6861,  0.9483,  1.1852,  1.3858,
+     1.5851,  1.7815,  1.9778,  2.1737,  2.3729,  2.5664,  2.7620,  2.9429,
+     0.1988,  0.3320,  0.4777,  0.6737,  0.8425,  1.0265,  1.1694,  1.3655,
+     1.5463,  1.7135,  1.9385,  2.1650,  2.3529,  2.5367,  2.7545,  2.9585,
+     0.1376,  0.2620,  0.4273,  0.6169,  0.7755,  0.9441,  1.1169,  1.3157,
+     1.5179,  1.7020,  1.8931,  2.1059,  2.3112,  2.5136,  2.7169,  2.9198,
+     0.2112,  0.4385,  0.6091,  0.7618,  0.9553,  1.1543,  1.3445,  1.5396,
+     1.7153,  1.9192,  2.1263,  2.3593,  2.5958,  2.8171,  2.9394,  3.0409,
+     0.1347,  0.2099,  0.2646,  0.3453,  0.5266,  0.7869,  1.0513,  1.2795,
+     1.4880,  1.7181,  1.9294,  2.1332,  2.3362,  2.5442,  2.7433,  2.9362,
+     0.3141,  0.5935,  0.7517,  0.8313,  0.8568,  0.9570,  1.0250,  1.1275,
+     1.3422,  1.6303,  1.8577,  2.0705,  2.2957,  2.5095,  2.7244,  2.9262,
+     0.0962,  0.2116,  0.3961,  0.5641,  0.7122,  0.8883,  1.1023,  1.3481,
+     1.5623,  1.7554,  1.9618,  2.1675,  2.3706,  2.5556,  2.7430,  2.9337,
+     0.0898,  0.1510,  0.3060,  0.5820,  0.8221,  1.0388,  1.2261,  1.4289,
+     1.6054,  1.8103,  1.9941,  2.1844,  2.3742,  2.5711,  2.7632,  2.9474,
+     0.1326,  0.2316,  0.3761,  0.5177,  0.6782,  0.8761,  1.0952,  1.3175,
+     1.5078,  1.7034,  1.9051,  2.1245,  2.3424,  2.5484,  2.7444,  2.9389,
+     0.1740,  0.3293,  0.5174,  0.6824,  0.8394,  1.0372,  1.2046,  1.3723,
+     1.5656,  1.7444,  1.9442,  2.1386,  2.3139,  2.4960,  2.7071,  2.9297,
+     0.2304,  0.3775,  0.4865,  0.6182,  0.7842,  0.9208,  1.1151,  1.2843,
+     1.4641,  1.6988,  1.9209,  2.1260,  2.3099,  2.5229,  2.7414,  2.9276,
+     0.0094,  0.0261, -0.0037,  0.0041, -0.0092, -0.0044, -0.0232, -0.0073,
+    -0.0047, -0.0021,  0.0250, -0.0580, -0.0140, -0.0342, -0.0586,  0.0020,
+     0.0449,  0.0155, -0.0523, -0.0279,  0.0299, -0.0183, -0.0736, -0.0639,
+    -0.0017,  0.0336,  0.0209,  0.0046,  0.0077, -0.0148, -0.0114, -0.0120,
+     0.0115, -0.0050,  0.0445,  0.0048,  0.0188, -0.0137, -0.0080,  0.0239,
+    -0.0184, -0.0524, -0.0195, -0.0126,  0.0284,  0.0632,  0.0141, -0.0093,
+    -0.0096,  0.0196,  0.0230,  0.0379,  0.0308,  0.0237, -0.0224, -0.0600,
+    -0.0755, -0.1074, -0.0988, -0.0606, -0.1038, -0.1552, -0.1480, -0.0672,
+     0.0504,  0.0676,  0.0336, -0.0042,  0.0729,  0.1013,  0.0868,  0.0846,
+     0.0954,  0.0515, -0.0066, -0.0851, -0.0485,  0.0294,  0.0395,  0.0087,
+     0.0078,  0.0446,  0.0881,  0.0672, -0.0384, -0.0025,  0.0415,  0.0353,
+     0.0080,  0.0052,  0.0190,  0.0182,  0.0069,  0.0168,  0.0374,  0.0037,
+    -0.0292, -0.0429,  0.0302,  0.0681, -0.0233, -0.0238, -0.0003, -0.0043,
+     0.0054, -0.0029, -0.0149,  0.0642,  0.0622,  0.0341, -0.0232, -0.0461,
+    -0.0082, -0.0469, -0.0618, -0.0326, -0.0452, -0.0649, -0.0597, -0.0398,
+    -0.0318, -0.0116,  0.0011,  0.0009, -0.0384, -0.0384, -0.0156, -0.0260,
+    -0.0007,  0.0473,  0.0111, -0.0358, -0.0484, -0.0204, -0.0029, -0.0090,
+    -0.0285, -0.0495, -0.0376,  0.0917,  0.1192,  0.1026,  0.0745,  0.0397,
+     0.0463,  0.0253,  0.0025,  0.0465,  0.0100,  0.0488,  0.0416,  0.0223,
+     0.0263,  0.0072, -0.0053,  0.0595,  0.0060, -0.0518, -0.0316, -0.0043,
+    -0.0133, -0.0233, -0.0075, -0.0251,  0.0277, -0.0067, -0.0136, -0.0004,
+     0.0235,  0.0112, -0.0182, -0.0324, -0.0210, -0.0035, -0.0395, -0.0384,
+     0.0005, -0.0150, -0.0356,  0.0127, -0.0033, -0.0034,  0.0205,  0.0747,
+     0.1138,  0.1015,  0.0995, -0.0161, -0.0045,  0.0129,  0.0472,  0.0575,
+     0.0222,  0.0091,  0.0037, -0.0471,  0.0371,  0.0132,  0.0208,  0.0247,
+     0.0117,  0.0164,  0.0225,  0.0124, -0.0023,  0.0088, -0.0046,  0.0047,
+    -0.0393,  0.0018,  0.0148,  0.0020,  0.0044,  0.0165,  0.0229, -0.0208,
+    -0.0477, -0.0310, -0.0164, -0.0390, -0.0764, -0.0525, -0.0094,  0.0075,
+    -0.0102, -0.0045, -0.0504, -0.0709,  0.0822,  0.0710,  0.0426,  0.0014,
+    -0.0371, -0.0400, -0.0157, -0.0155, -0.0173, -0.0138, -0.0015,  0.0134,
+    -0.0418, -0.0682, -0.0256,  0.0050,  0.0360,  0.0354,  0.0074, -0.0396,
+    -0.0235,  0.0284,  0.0494,  0.0153,  0.0448,  0.0025, -0.0061,  0.0252,
+     0.1000,  0.2260,  0.2158,  0.2116,  0.2198,  0.2055,  0.2110,  0.1873,
+     0.1907,  0.2071,  0.2164,  0.2009,  0.2059,  0.2124,  0.2141,  0.2093,
+     0.0875,  0.0981,  0.1177,  0.1071,  0.1033,  0.1248,  0.1048,  0.1238,
+     0.1166,  0.1008,  0.1062,  0.0992,  0.0994,  0.1067,  0.0999,  0.1187,
+     0.0750,  0.0794,  0.0828,  0.0854,  0.0859,  0.0801,  0.0891,  0.0933,
+     0.0969,  0.0920,  0.0915,  0.0862,  0.0868,  0.0891,  0.0842,  0.0824,
+     0.0625,  0.0930,  0.0815,  0.0853,  0.0898,  0.0828,  0.0822,  0.0910,
+     0.0873,  0.0906,  0.0856,  0.0840,  0.0774,  0.0785,  0.0684,  0.0711,
+     0.3319,  0.4219,  0.4588,  0.4090,  0.4092,  0.4014,  0.3548,  0.3353,
+     0.3708,  0.3352,  0.3720,  0.3538,  0.4084,  0.4289,  0.4060,  0.4210,
+     0.0588,  0.0209, -0.0082, -0.0115, -0.0343, -0.0621, -0.0541, -0.0346,
+    -0.0346, -0.0366, -0.0220, -0.0265, -0.0102,  0.0374,  0.0306,  0.0404,
+     0.0306,  0.0090, -0.0054,  0.0333,  0.0047,  0.0238,  0.0141,  0.0165,
+     0.0306,  0.0420,  0.0159,  0.0124,  0.0414,  0.0158, -0.0237,  0.0141,
+     0.0765,  0.0057, -0.0260, -0.0426, -0.0395, -0.0126, -0.0579, -0.0417,
+    -0.0429, -0.0615, -0.0893, -0.0618, -0.0384, -0.0134, -0.0232, -0.0238
+};
+
+static const float lsp44s[] = {
+     0.0927,  0.2291,  0.4059,  0.5779,  0.7288,  0.8821,  1.0377,  1.1915,
+     1.3433,  1.4931,  1.6475,  1.7989,  1.9381,  2.0858,  2.2321,  2.3765,
+     2.5187,  2.6530,  2.7895,  2.9354,  0.0944,  0.1974,  0.3046,  0.4714,
+     0.6116,  0.7829,  0.9027,  1.0375,  1.1869,  1.3488,  1.5036,  1.6781,
+     1.8276,  1.9983,  2.1449,  2.3089,  2.4534,  2.6113,  2.7553,  2.9062,
+     0.1168,  0.2843,  0.4907,  0.6706,  0.8100,  0.9417,  1.0753,  1.2014,
+     1.3151,  1.4496,  1.5832,  1.7379,  1.8642,  2.0230,  2.1681,  2.3250,
+     2.4676,  2.6242,  2.7602,  2.9066,  0.1353,  0.2335,  0.3370,  0.4380,
+     0.5819,  0.7353,  0.8671,  1.0160,  1.1435,  1.2977,  1.4860,  1.6739,
+     1.8412,  2.0028,  2.1537,  2.3124,  2.4741,  2.6272,  2.7862,  2.9536,
+     0.1003,  0.2226,  0.3584,  0.4971,  0.6291,  0.7710,  0.9157,  1.0669,
+     1.2143,  1.3624,  1.5104,  1.6681,  1.8164,  1.9823,  2.1394,  2.3082,
+     2.4677,  2.6306,  2.7909,  2.9382,  0.1056,  0.2027,  0.2956,  0.4005,
+     0.5215,  0.6708,  0.8545,  1.0557,  1.2344,  1.4023,  1.5676,  1.7278,
+     1.8808,  2.0381,  2.1846,  2.3376,  2.4887,  2.6377,  2.7878,  2.9504,
+     0.1015,  0.2462,  0.4122,  0.5783,  0.7233,  0.8833,  1.0377,  1.1903,
+     1.3341,  1.4727,  1.6138,  1.7582,  1.8912,  2.0370,  2.1701,  2.3125,
+     2.4500,  2.6006,  2.7507,  2.9166,  0.1787,  0.2418,  0.3265,  0.5379,
+     0.6584,  0.7681,  0.9545,  1.1050,  1.2125,  1.3528,  1.4763,  1.6705,
+     1.8136,  1.9594,  2.0936,  2.2724,  2.4394,  2.5919,  2.7037,  2.8747,
+     0.0859,  0.1600,  0.2980,  0.4933,  0.6696,  0.8285,  0.9958,  1.1545,
+     1.3107,  1.4591,  1.6127,  1.7652,  1.9143,  2.0680,  2.2171,  2.3643,
+     2.5141,  2.6611,  2.8143,  2.9691,  0.0910,  0.2110,  0.3364,  0.4718,
+     0.5856,  0.7298,  0.8910,  1.0514,  1.1988,  1.3572,  1.5178,  1.6861,
+     1.8399,  2.0099,  2.1639,  2.3225,  2.4774,  2.6321,  2.7863,  2.9412,
+     0.1904,  0.2874,  0.3681,  0.4981,  0.6248,  0.7880,  0.9121,  1.0750,
+     1.2185,  1.3809,  1.5296,  1.7007,  1.8592,  2.0470,  2.1913,  2.3250,
+     2.4519,  2.5984,  2.7408,  2.9023,  0.0917,  0.2067,  0.3246,  0.4961,
+     0.6310,  0.8024,  0.9438,  1.1008,  1.2362,  1.3892,  1.5407,  1.7033,
+     1.8427,  2.0061,  2.1498,  2.3117,  2.4550,  2.6053,  2.7462,  2.9029,
+     0.0989,  0.2193,  0.3756,  0.5410,  0.6929,  0.8368,  0.9801,  1.1250,
+     1.2677,  1.4184,  1.5677,  1.7292,  1.8770,  2.0311,  2.1803,  2.3306,
+     2.4836,  2.6339,  2.7943,  2.9549,  0.0861,  0.1943,  0.3057,  0.4867,
+     0.6194,  0.7592,  0.9184,  1.1052,  1.2486,  1.4064,  1.5609,  1.7273,
+     1.8703,  2.0291,  2.1686,  2.3225,  2.4628,  2.6115,  2.7471,  2.9005,
+     0.0932,  0.2110,  0.3737,  0.5479,  0.7120,  0.8570,  0.9975,  1.1364,
+     1.2772,  1.4220,  1.5612,  1.7089,  1.8410,  1.9827,  2.1263,  2.2859,
+     2.4459,  2.6172,  2.7788,  2.9395,  0.1193,  0.2341,  0.3523,  0.5029,
+     0.6437,  0.7803,  0.9367,  1.1007,  1.2392,  1.3869,  1.5425,  1.7168,
+     1.8709,  2.0248,  2.1584,  2.2949,  2.4308,  2.5823,  2.7235,  2.9034,
+     0.0834,  0.1988,  0.3557,  0.5261,  0.6767,  0.8427,  1.0029,  1.1683,
+     1.3138,  1.4527,  1.6046,  1.7583,  1.9011,  2.0517,  2.1928,  2.3397,
+     2.4839,  2.6291,  2.7771,  2.9329,  0.0938,  0.1967,  0.3213,  0.4675,
+     0.6068,  0.7664,  0.9418,  1.1120,  1.2535,  1.3932,  1.5243,  1.6801,
+     1.8346,  1.9931,  2.1376,  2.3035,  2.4636,  2.6244,  2.7829,  2.9371,
+     0.1017,  0.2552,  0.4327,  0.6017,  0.7467,  0.8797,  1.0097,  1.1442,
+     1.2628,  1.4049,  1.5541,  1.7090,  1.8461,  1.9982,  2.1486,  2.3029,
+     2.4513,  2.6075,  2.7594,  2.9209,  0.1031,  0.2295,  0.3747,  0.5122,
+     0.6596,  0.7935,  0.9345,  1.1050,  1.2384,  1.3543,  1.4739,  1.6136,
+     1.7447,  1.8914,  2.0434,  2.1916,  2.3557,  2.5396,  2.7419,  2.9401,
+     0.1007,  0.2374,  0.3715,  0.5173,  0.6465,  0.8069,  0.9553,  1.1145,
+     1.2594,  1.4143,  1.5617,  1.7166,  1.8457,  2.0012,  2.1462,  2.2864,
+     2.4258,  2.5910,  2.7372,  2.9018,  0.0808,  0.1726,  0.2849,  0.4592,
+     0.6118,  0.7853,  0.9588,  1.1256,  1.2751,  1.4392,  1.5898,  1.7514,
+     1.8977,  2.0554,  2.1937,  2.3430,  2.4831,  2.6249,  2.7601,  2.9155,
+     0.1669,  0.2574,  0.3694,  0.5569,  0.6773,  0.8061,  1.0160,  1.1667,
+     1.2791,  1.4041,  1.5452,  1.7207,  1.8524,  2.0038,  2.1414,  2.3338,
+     2.4747,  2.6157,  2.7303,  2.8848,  0.1598,  0.2521,  0.3416,  0.5149,
+     0.6703,  0.7941,  0.9408,  1.1164,  1.2017,  1.3293,  1.4908,  1.6783,
+     1.8438,  1.9927,  2.1149,  2.2698,  2.4420,  2.6193,  2.7583,  2.9103,
+     0.0902,  0.1978,  0.3265,  0.4578,  0.5878,  0.7439,  0.9110,  1.0906,
+     1.2556,  1.4125,  1.5688,  1.7295,  1.8829,  2.0472,  2.2058,  2.3537,
+     2.5075,  2.6548,  2.8058,  2.9538,  0.0818,  0.1695,  0.2794,  0.4470,
+     0.6069,  0.7641,  0.9313,  1.0946,  1.2411,  1.4072,  1.5640,  1.7186,
+     1.8651,  2.0254,  2.1726,  2.3286,  2.4784,  2.6287,  2.7750,  2.9339,
+     0.1980,  0.3134,  0.4099,  0.4975,  0.6491,  0.8376,  0.9441,  1.0298,
+     1.1795,  1.3866,  1.5784,  1.7209,  1.8137,  1.9271,  2.0863,  2.2930,
+     2.4696,  2.6184,  2.7587,  2.9251,  0.1338,  0.2341,  0.3566,  0.4797,
+     0.6129,  0.7580,  0.9093,  1.0491,  1.1911,  1.3313,  1.4841,  1.6503,
+     1.8035,  1.9685,  2.1128,  2.2694,  2.4093,  2.5728,  2.7206,  2.8994,
+     0.0937,  0.2034,  0.3447,  0.5032,  0.6370,  0.7993,  0.9674,  1.1323,
+     1.2830,  1.4199,  1.5492,  1.7010,  1.8513,  2.0087,  2.1550,  2.3115,
+     2.4643,  2.6237,  2.7812,  2.9392,  0.1085,  0.2152,  0.3126,  0.4569,
+     0.5718,  0.7213,  0.8837,  1.0604,  1.2053,  1.3755,  1.5397,  1.7001,
+     1.8409,  2.0039,  2.1498,  2.3080,  2.4535,  2.6063,  2.7505,  2.9110,
+     0.0562,  0.2066,  0.4034,  0.5490,  0.6682,  0.7924,  0.9495,  1.0800,
+     1.1869,  1.3156,  1.4834,  1.6619,  1.8404,  2.0199,  2.1509,  2.2755,
+     2.4072,  2.5580,  2.6993,  2.8913,  0.0939,  0.2303,  0.3742,  0.5260,
+     0.6662,  0.8294,  0.9769,  1.1315,  1.2792,  1.4153,  1.5436,  1.6701,
+     1.8215,  1.9920,  2.1310,  2.3005,  2.4534,  2.5786,  2.7204,  2.9068,
+     0.1005,  0.2442,  0.3898,  0.5398,  0.6958,  0.8474,  1.0008,  1.1556,
+     1.3020,  1.4456,  1.5954,  1.7470,  1.8922,  2.0500,  2.2019,  2.3492,
+     2.4963,  2.6412,  2.7890,  2.9423,  0.1022,  0.2031,  0.3213,  0.4402,
+     0.5637,  0.7117,  0.8673,  1.0242,  1.1727,  1.3206,  1.4846,  1.6465,
+     1.8015,  1.9655,  2.1233,  2.2873,  2.4464,  2.6074,  2.7685,  2.9409,
+     0.1985,  0.3497,  0.4622,  0.5982,  0.7489,  0.8752,  0.9925,  1.1679,
+     1.3288,  1.4606,  1.5820,  1.7492,  1.8922,  2.0511,  2.1780,  2.3373,
+     2.4760,  2.6233,  2.7466,  2.8978,  0.1284,  0.2433,  0.3630,  0.4852,
+     0.6117,  0.7460,  0.8904,  1.0360,  1.1738,  1.3142,  1.4696,  1.6185,
+     1.7719,  1.9318,  2.0961,  2.2697,  2.4408,  2.6046,  2.7681,  2.9451,
+     0.1042,  0.2286,  0.3598,  0.5064,  0.6438,  0.7899,  0.9350,  1.0891,
+     1.2323,  1.3807,  1.5225,  1.6747,  1.8153,  1.9669,  2.1145,  2.2832,
+     2.4430,  2.6085,  2.7748,  2.9346,  0.0780,  0.1724,  0.2440,  0.3489,
+     0.5280,  0.7426,  0.9272,  1.0914,  1.2562,  1.4188,  1.5804,  1.7376,
+     1.8909,  2.0473,  2.1946,  2.3457,  2.4950,  2.6424,  2.7926,  2.9549,
+     0.1103,  0.2608,  0.4087,  0.5538,  0.6923,  0.8418,  0.9940,  1.1507,
+     1.2919,  1.4406,  1.5802,  1.7262,  1.8638,  2.0085,  2.1572,  2.2975,
+     2.4329,  2.5866,  2.7380,  2.9107,  0.1297,  0.2532,  0.4003,  0.5329,
+     0.6733,  0.7950,  0.9557,  1.0859,  1.2235,  1.3538,  1.5037,  1.6389,
+     1.7964,  1.9285,  2.0898,  2.2541,  2.4231,  2.5711,  2.6875,  2.8947,
+     0.0871,  0.1968,  0.3425,  0.4949,  0.6424,  0.7959,  0.9534,  1.1132,
+     1.2656,  1.4229,  1.5785,  1.7271,  1.8729,  2.0355,  2.1998,  2.3562,
+     2.5151,  2.6663,  2.8145,  2.9534,  0.1038,  0.2204,  0.3248,  0.4566,
+     0.5947,  0.7443,  0.8811,  1.0379,  1.2031,  1.3772,  1.5430,  1.7092,
+     1.8625,  2.0322,  2.1904,  2.3417,  2.4960,  2.6458,  2.7979,  2.9485,
+     0.1329,  0.2763,  0.3943,  0.5147,  0.6512,  0.8071,  0.9410,  1.0879,
+     1.2298,  1.3850,  1.5282,  1.6674,  1.8137,  1.9993,  2.1344,  2.2749,
+     2.4257,  2.5863,  2.7410,  2.9184,  0.1052,  0.2142,  0.3584,  0.5033,
+     0.6387,  0.7804,  0.9320,  1.0780,  1.2172,  1.3764,  1.5421,  1.6887,
+     1.8246,  1.9833,  2.1245,  2.2797,  2.4237,  2.5779,  2.7257,  2.9097,
+     0.1092,  0.2676,  0.4071,  0.5355,  0.6661,  0.8142,  0.9621,  1.1173,
+     1.2628,  1.4185,  1.5696,  1.7220,  1.8595,  2.0178,  2.1720,  2.3221,
+     2.4718,  2.6259,  2.7775,  2.9334,  0.0929,  0.2017,  0.3073,  0.4570,
+     0.5775,  0.7635,  0.9299,  1.0832,  1.2334,  1.3935,  1.5420,  1.7112,
+     1.8601,  2.0309,  2.1735,  2.3230,  2.4543,  2.6034,  2.7418,  2.8988,
+     0.0775,  0.2005,  0.3490,  0.5200,  0.6747,  0.8383,  0.9885,  1.1738,
+     1.3141,  1.4236,  1.5892,  1.7402,  1.8474,  2.0210,  2.1593,  2.2730,
+     2.4235,  2.5604,  2.7128,  2.9005,  0.1104,  0.2292,  0.3353,  0.4732,
+     0.6152,  0.7675,  0.9164,  1.0907,  1.2594,  1.4064,  1.5218,  1.6426,
+     1.8018,  1.9937,  2.1362,  2.2961,  2.4523,  2.6083,  2.7613,  2.9202,
+     0.0826,  0.2000,  0.3384,  0.5144,  0.6694,  0.8377,  0.9870,  1.1461,
+     1.2950,  1.4495,  1.5872,  1.7387,  1.8793,  2.0329,  2.1723,  2.3114,
+     2.4415,  2.5908,  2.7354,  2.9028,  0.1063,  0.2268,  0.3442,  0.4735,
+     0.6116,  0.7507,  0.9028,  1.0768,  1.2426,  1.4052,  1.5566,  1.7015,
+     1.8243,  1.9742,  2.1276,  2.2824,  2.4262,  2.5953,  2.7627,  2.9290,
+     0.1150,  0.2814,  0.4543,  0.6095,  0.7373,  0.8592,  0.9908,  1.1108,
+     1.2339,  1.3590,  1.4864,  1.6168,  1.7392,  1.8752,  2.0212,  2.1688,
+     2.3128,  2.4869,  2.7019,  2.9239,  0.0948,  0.2074,  0.3433,  0.4943,
+     0.6346,  0.7645,  0.8809,  1.0610,  1.2307,  1.3487,  1.4655,  1.6186,
+     1.7534,  1.8859,  2.0486,  2.2200,  2.3835,  2.5581,  2.7565,  2.9502,
+     0.1062,  0.2239,  0.3683,  0.5197,  0.6704,  0.8184,  0.9642,  1.1127,
+     1.2556,  1.3976,  1.5405,  1.6940,  1.8375,  1.9888,  2.1377,  2.2980,
+     2.4555,  2.6184,  2.7849,  2.9452,  0.0888,  0.2005,  0.2847,  0.4322,
+     0.5763,  0.7577,  0.9262,  1.1095,  1.2719,  1.4331,  1.5843,  1.7452,
+     1.8845,  2.0385,  2.1805,  2.3345,  2.4750,  2.6217,  2.7555,  2.9013,
+     0.1713,  0.2617,  0.3868,  0.5859,  0.7073,  0.8535,  1.0593,  1.1778,
+     1.3109,  1.4508,  1.5910,  1.7463,  1.8911,  2.0651,  2.2035,  2.3355,
+     2.4947,  2.6440,  2.7424,  2.8943,  0.1346,  0.2549,  0.4089,  0.5488,
+     0.6949,  0.8394,  0.9810,  1.1145,  1.2528,  1.4044,  1.5423,  1.6872,
+     1.8274,  1.9726,  2.1403,  2.2809,  2.4128,  2.5564,  2.6887,  2.8895,
+     0.0776,  0.1621,  0.2553,  0.4191,  0.5988,  0.7921,  0.9651,  1.1350,
+     1.2930,  1.4475,  1.6011,  1.7585,  1.9068,  2.0638,  2.2102,  2.3594,
+     2.5096,  2.6581,  2.8099,  2.9654,  0.0864,  0.1778,  0.2854,  0.4235,
+     0.5568,  0.7220,  0.8963,  1.0609,  1.2217,  1.3830,  1.5422,  1.7018,
+     1.8551,  2.0206,  2.1783,  2.3328,  2.4869,  2.6366,  2.7923,  2.9539,
+     0.1144,  0.2576,  0.4186,  0.5594,  0.6875,  0.8221,  0.9598,  1.0944,
+     1.2273,  1.3713,  1.5152,  1.6628,  1.8070,  1.9525,  2.0965,  2.2535,
+     2.4132,  2.5725,  2.7250,  2.9150,  0.1079,  0.2221,  0.3334,  0.4845,
+     0.6083,  0.7516,  0.9018,  1.0594,  1.2060,  1.3673,  1.5212,  1.6880,
+     1.8208,  1.9831,  2.1269,  2.2909,  2.4366,  2.6027,  2.7339,  2.8924,
+     0.0994,  0.2233,  0.3634,  0.5145,  0.6568,  0.8131,  0.9746,  1.1296,
+     1.2666,  1.4116,  1.5748,  1.7264,  1.8649,  2.0217,  2.1716,  2.3293,
+     2.4900,  2.6455,  2.7818,  2.9362,  0.1120,  0.2079,  0.3128,  0.4124,
+     0.5291,  0.6816,  0.8478,  1.0150,  1.1772,  1.3456,  1.5208,  1.6882,
+     1.8458,  2.0078,  2.1627,  2.3198,  2.4733,  2.6251,  2.7796,  2.9489,
+     0.0853,  0.2030,  0.3669,  0.5326,  0.6678,  0.8086,  0.9526,  1.1142,
+     1.2551,  1.4158,  1.5694,  1.7073,  1.8431,  1.9686,  2.1153,  2.2376,
+     2.3686,  2.5591,  2.7320,  2.9104,  0.0905,  0.2166,  0.3539,  0.5201,
+     0.6700,  0.8346,  0.9883,  1.1457,  1.2714,  1.3845,  1.5172,  1.6688,
+     1.8008,  1.9535,  2.1019,  2.2708,  2.4135,  2.5974,  2.7486,  2.9033,
+     0.0084,  0.0374,  0.0164, -0.0153,  0.0288,  0.0107, -0.0255, -0.0242,
+     0.0000, -0.0055, -0.0081, -0.0075, -0.0022, -0.0052, -0.0069, -0.0017,
+     0.0003,  0.0091,  0.0028, -0.0027,  0.0085,  0.0043, -0.0235, -0.0411,
+     0.0202,  0.0359,  0.0376,  0.0321,  0.0306, -0.0358, -0.0276, -0.0090,
+     0.0032,  0.0048,  0.0309,  0.0332,  0.0284,  0.0237,  0.0051, -0.0101,
+    -0.0233, -0.0428, -0.0585, -0.0387,  0.0039,  0.0081,  0.0029, -0.0017,
+    -0.0006, -0.0068,  0.0044,  0.0182,  0.0376,  0.0387, -0.0334, -0.0269,
+    -0.0182, -0.0069, -0.0026,  0.0035, -0.0049, -0.0212, -0.0408, -0.0245,
+     0.0186,  0.0189,  0.0153,  0.0120,  0.0157,  0.0055, -0.0046,  0.0179,
+     0.0284, -0.0032, -0.0261, -0.0205, -0.0039,  0.0174,  0.0299,  0.0207,
+     0.0012, -0.0056,  0.0010,  0.0141, -0.0119,  0.0190,  0.0315,  0.0033,
+    -0.0128,  0.0300,  0.0328,  0.0308,  0.0353,  0.0266,  0.0066, -0.0328,
+    -0.0273,  0.0054,  0.0145,  0.0175,  0.0015, -0.0171,  0.0062, -0.0164,
+     0.0045, -0.0071,  0.0025,  0.0278,  0.0283,  0.0117, -0.0026, -0.0285,
+    -0.0408, -0.0366, -0.0059, -0.0208, -0.0354, -0.0334, -0.0263, -0.0064,
+     0.0072, -0.0006, -0.0235, -0.0037, -0.0307, -0.0294, -0.0163, -0.0197,
+    -0.0235,  0.0192,  0.0013, -0.0219, -0.0123, -0.0004, -0.0081, -0.0096,
+    -0.0123, -0.0101,  0.0021,  0.0151,  0.0106,  0.0151,  0.0292,  0.0033,
+     0.0283,  0.0124,  0.0058, -0.0017, -0.0038,  0.0152,  0.0141,  0.0132,
+     0.0178,  0.0157,  0.0073,  0.0176,  0.0141,  0.0097, -0.0092, -0.0163,
+    -0.0230, -0.0134, -0.0099, -0.0147,  0.0040, -0.0183, -0.0175, -0.0080,
+    -0.0083, -0.0290, -0.0417, -0.0398, -0.0269, -0.0199, -0.0143, -0.0053,
+    -0.0099, -0.0054, -0.0199, -0.0219, -0.0170,  0.0107,  0.0194,  0.0035,
+     0.0437,  0.0406,  0.0215,  0.0120,  0.0053, -0.0028,  0.0238,  0.0337,
+     0.0217,  0.0011,  0.0227,  0.0244,  0.0327,  0.0378,  0.0437,  0.0356,
+    -0.0033,  0.0113,  0.0407,  0.0334, -0.0125, -0.0003, -0.0141, -0.0273,
+    -0.0137, -0.0079, -0.0145, -0.0071,  0.0114,  0.0181,  0.0150,  0.0085,
+    -0.0077, -0.0038, -0.0219, -0.0263, -0.0187, -0.0233,  0.0133,  0.0265,
+    -0.0156, -0.0091, -0.0110, -0.0016,  0.0143,  0.0177,  0.0240,  0.0082,
+    -0.0143, -0.0257, -0.0014,  0.0002,  0.0082,  0.0180,  0.0325,  0.0340,
+    -0.0153, -0.0389, -0.0240,  0.0082,  0.0140,  0.0046, -0.0138, -0.0378,
+    -0.0366,  0.0297,  0.0252,  0.0078,  0.0063,  0.0006,  0.0044,  0.0074,
+     0.0094,  0.0113,  0.0105,  0.0137,  0.0438,  0.0262, -0.0078, -0.0185,
+    -0.0215, -0.0407, -0.0435, -0.0208, -0.0004, -0.0144, -0.0205, -0.0248,
+    -0.0159, -0.0069, -0.0153,  0.0132,  0.0355,  0.0298,  0.0120,  0.0072,
+     0.0236,  0.0526,  0.0479,  0.0233, -0.0133, -0.0283, -0.0468, -0.0549,
+    -0.0370,  0.0032,  0.0056,  0.0023,  0.0050,  0.0024,  0.0279,  0.0116,
+    -0.0045, -0.0012,  0.0107,  0.0190,  0.0253,  0.0191,  0.0043,  0.0193,
+    -0.0348, -0.0246,  0.0123,  0.0210,  0.0135, -0.0096, -0.0109, -0.0076,
+    -0.0156, -0.0290,  0.0160,  0.0194,  0.0219,  0.0259,  0.0250,  0.0195,
+     0.4948,  0.4961,  0.4940,  0.4878,  0.4849,  0.4727,  0.4571,  0.4551,
+     0.4534,  0.4468,  0.4412,  0.4354,  0.4298,  0.4272,  0.4498,  0.4506,
+     0.4560,  0.4592,  0.4758,  0.4941,  0.2476,  0.1771,  0.1974,  0.1881,
+     0.1667,  0.1826,  0.2067,  0.2031,  0.1734,  0.1534,  0.1415,  0.1761,
+     0.1897,  0.1772,  0.1651,  0.1247,  0.1041,  0.1231,  0.1809,  0.2234
+};
+
+static const int16_t shape8[] = {
+      2765,   1262,   6624,    867,    688,   1884,   3245,   1248,
+     -2160,    593,    182,  -1004,  -1067,    687,   1021,   -920,
+      1396,   -242,  -2817,  -1838,  -3351,   1000,   5995,   2459,
+      -283,   1909,   1452,  -4569,    556,  -2004,    -42,  -3393,
+       -50,   -385,    597,    983,    420,   6311,  -1572,  -1665,
+      6128,  -1688,  -5191,   -337,  -4199,    371,   1032,    -84,
+      2169,    931,   -392,   -250,    137,    831,   8194,   -489,
+       -92,    209,    115,   1453,    246,   -647,    936,   1097,
+      -400,    597,    392,     93,  -7709,   -711,   -724,   2051,
+       497,   1919,   -876,   -769,   -172,   2972,    952,    555,
+       151,   -617,    773,   4840,  -3671,    841,    244,   -661,
+     -3424,    958,     81,    532,   -315,    796,   5491,   -516,
+        -1,  -1371,   -531,  -5538,    313,  -1749,   2413,   -835,
+     -3143,   -244,  -3470,   -850,  -4241,   -859,    -74,   2141,
+     -1005,   4643,   -339,   4089,   -861,  -6612,    483,  -2888,
+      -580,    -45,   3662,    918,   -317,   3596,   -741,    897,
+     -2578,   -654,  -1628,  -1865,    629,   3219,    214,  -1898,
+      1173,  -4509,   1682,  -2161,    697,   -147,   9839,    751,
+     -1094,   -341,   -669,  -1322,    649,   -832,   -382,  -5467,
+       -44,   3510,   1312,   3104,   -202,   1870,   -155,    601,
+       719,    -22,   -350,    394,     81,    397,  -9185,   -174,
+       351,  -4717,  -4450,   3672,   1163,   2351,   1720,   1048,
+     -1221,   -280,    -18,    -15,    678,  -3931,   4707,    -99,
+      1823,   -535,  -1836,    138,   1166,  -3031,   5515,   1362,
+      1235,    455,    595,  -3671,   1102,   -163,     62,   1104,
+       813,    870,   -295,  -1088,   -299,  -3976,    805,  -7468,
+      -412,  -2109,    236,     46,  -5764,    615,  -1475,    853,
+       790,  -6197,    312,    637,  -3923,   -422,  -1086,  -5647,
+       878,  -1410,   2085,    -51,  -2941,   -769,    -63,    838,
+       823,    741,   2785,    450,  -7003,   -121,   -915,     60,
+       -41,      0,    -39,   8774,    647,   -521,    379,   -342,
+      -344,    818,   1316,   1056,    182,   2765,   -467,   7886,
+        45,    791,   -415,   3864,  -2428,   2255,   -661,    -64,
+      1693,    144,   1784,  -1194,    -46,  -1856,   1208,   4131,
+       914,   8028,    -17,   1939,  -1415,    533,    291,   -466,
+       186,   -705,    668,   -614,   -253,  -2190,    287,   3929,
+      1472,  -1561,      5,    889,  -2020,    158,    -14,  -1419,
+      1338,   -353,    622,    -54,     87,  -1104,  -2911,    513,
+      -632,   1533,   -267,     22,   6567,    295,    325,   6883,
+       963,   -373,   -349,    183,    896,   1845,  -1157,    351,
+      -367,   1171,   4362,    508,   5632,    704,  -1420,  -1886,
+       686,   5230,     -9,   2422,    230,    264,   3738,   -270,
+      -344,   -528,   -936,   2286,   -540,   4274,    337,   -665,
+       737,   1639,  -1307,   5827,    592,  -1372,   -412,   1419,
+      4579,    335,    223,  -1067,   -112,   -446,    149,   1375,
+      -155,   -392,  -1980,    561,    -67,    341,   6957,    475,
+     11449,     39,     81,    766,  -1880,    558,   -134,  -7940,
+      -489,    249,   -886,   -358,   6850,   2794,  -2217,   1111,
+     -1222,  -1130,   -818,   1076,  -1823,    865,  -2220,   1179,
+      4492,    224,  -2073,   -338,  -5351,   -390,    133,    496,
+       -42,    -16,     46,    437,    322,   -275,    -72,     48,
+      -325,    313,   1108,  -1044,   -851,  -5030,   1035,   4316,
+     -1281,   -913,  -1419,   -941,   1914,    960,   1242,    202,
+      5109,    475,   1254,   1725,  -1504,     -4,   -269,   -421,
+      -150,  -4409,   -610,  -1548,  -1684,   -817,   -210,     72,
+      -679,   -106,  -3809,  -1137,      4,   7220,    -95,    810,
+      2432,   -331,    492,    -81,    138,    -62,   -613,   -636,
+       106,  10908,    912,    144,    192,   1251,  -3970,   -954,
+      1145,   1175,  -1721,   5326,  -1721,   -569,  -3661,  -1166,
+      6605,   -744,  -1494,    853,    134,   3259,   -504,  -1740,
+       180,   -207,   -659,    196,    179,   -106,    118,    789,
+      -834,  10339,   -420,  -3002,   -456,    113,   6435,    949,
+       721,  -2709,  -1599,   -684,  -8068,    174,  -1416,    -58,
+       974,    308,   -726,   1237,  -1594,    519,   -131,   -198,
+     -1395,   1180,   -173,    338,  -5584,   -279,   -236,   6817,
+        89,   -220,   3967,   -107,     65,   2479,    -22,    642,
+      7179,   1179,   -229,   -202,   4948,  -5465,   1632,  -1285,
+      2188,  -2037,   1763,    636,   4247,    995,   1176,      2,
+     -2398,   1236,   -661,    382,  -1075,    130,    103,   -187,
+       604,   -306,  -2635,  -2185,    157,    775,   6373,   -924,
+      1758,  -3043,   1707,   2852,  -2148,   6779,    376,  -1018,
+     -2374,   -989,    249,  -5393,    -32,    538,   -416,  -5108,
+      -658,   1839,    419,   1153,  -3956,   -617,  -1925,   5434,
+       626,   1488,  -3824,    140,    370,  -2230,  -7031,   1989,
+      -581,    639,  -4249,   -216,   1225,   -776,   -973,   -542,
+     -2922,  -1783,  -2430,  -3251,    958,   3313,    636,  -6277,
+       119,   -866,   -406,   -156,  -4839,    966,   -469,   5559,
+       193,    376,  -4810,   -870,    163,   4130,   2596,   2203,
+      -114,   2423,   -622,   -424,   2935,    749,   2500,   4230,
+      -162,  -1489,   2169,  -5156,    751,   2748,   2240,  -1549,
+      4821,    175,   2274,    854,   2993,    838,    322,  -2663,
+      -794,   -283,    -98,   1393,   -709,    362,    285,  -1085,
+      1075,    374,   1062,   6512,  -3375,  -3138,   3939,   3628,
+      3926,  -2442,   1989,   -583,  -1282,  -1882,  -3920,  -4593,
+       540,   2667,   -155,    156,  -2428,   1229,   -436,   1754,
+      2815,  -1634,  -2299,   1155,    990,   3689,  -1242,   3145,
+      3951,     45,    186,  -1110,    257,   -335,   8929,    533,
+      -173,    813,     21,   1584,    541,    -44,   1349,    108,
+     -5163,   -684,   5522,   -868,  -5795,    769,    583,   2827,
+      -818,  -5551,   1485,     37,   -631,   -262,  -4352,   -532,
+        61,    434,   1775,   8974,   -112,   -852,  -1227,  -1645,
+       260,    298,   -430,    863,  -3860,    -97,   6467,   -328,
+     -2418,    -61,  -1253,   1575,     30,  -5683,   2113,    973,
+      -371,    -51,   5355,    471,   -584,   -492,  -2187,   2799,
+      -506,   4435,   1950,  -3415,   -363,   -404,    941,   2628,
+      -146,    434,   2853,    889,    634,   5749,    -54,    126,
+       189,  -1384,   -379,  -3205,   -540,   1720,    942,  -6300,
+      -286,    -58,  -1083,   3782,    251,   -334,   4172,    631,
+        17,     83,    707,   1322,   3273,   -573,   1024,  -6112,
+      -540,   4916,    155,  -1209,    308,   -738,  -2150,    786,
+      -168,     68,   -201,    -64,   -752,  -1595,  -9188,    320,
+      -426,    111,  -2183,    886,   -737,    193,   -837,   3219,
+      5936,   4022,    764,    -82,   3344,   -855,   3705,  -2652,
+      1533,   -206,  -3673,   1235,   1163,  -1217,   3183,   1313,
+      -745,   6554,   7019,   1302,   2129,    268,    -70,    110,
+       412,   -155,  -1703,  -4945,    105,  -1705,    412,  -6588,
+      2905,   1279,     73,  -2446,  -5635,   1168,   2974,    404,
+      -650,    265,  -1773,  -1857,   -108,   -651,    657,   -824,
+      3352,    177,    155,   1275,   2012,     31,     -7,  -1065,
+      2062,    411,  -2325,   -208,  -6306,    683,   1037,  -1060,
+       191,   -187,   -585,   6103,   -459,    571,   1640,   -693,
+       922,  -2291,    537,   1934,    263,   3847,   -202,   7060,
+       136,   4368,   2963,  -1032,     18,   1836,   -144,  -3853,
+       474,   2005,   1298,   2396,    825,  -2274,     12,   3759,
+      -394,    907,    490,   2997,   2180,  -1570,  -1000,   5982,
+      -129,   -820,  -3001,   2684,  -1132,  -2908,   1101,   5044,
+       393,  -1637,    393,   1343,  -1231,    404,   1817,   1463,
+      -443,   1053,   -584,  -7756,     45,    499,  -4109,    214,
+       535,  -3348,     54,  -1594,   6913,      0,    -94,   8772,
+       500,     13,    734,      5,    798,  -1521,    853,    -82,
+      -263,   -619,   1558,    456,   5911,  -1376,   1054,   -971,
+     -1275,   -147,   -111,   4964,    321,     67,   7024,   -525,
+       620,    883,  -1058,  -1132,  -3313,    630,    226,  -6201,
+     -1011,   1111,   -820,   -295,    580,    636,   2452,   -638,
+      6840,   -285,    655,   1502,  -1049,   -567,    329,    -33,
+      -249,    570,    186,    167,    780,   1104,     42,    197,
+     10034,  -1295,   -208,     32,  -1473,    716,    159,  -6672,
+       -45,    519,  -4300,   -246,   3692,   5062,   4305,   -748,
+      -548,    181,   -382,   -881,  -1968,    580,    964,   -420,
+      -327,  -3397,  -1584,   2770,  -3501,   1659,  -1252,   2352,
+         6,     30,      0,   -273,     27,   -204,   -485,   -432,
+        -6,    176,   -428,   1562,    104,  -6511,  -1084,   2205,
+       -11,  -5254,   -132,   -508,    -69,    373,  -1503,    208,
+       -58,   5311,     92,   -966,  -6563,   -480,    -24,   1424,
+     -1498,   -165,   4594,   -903,  -1787,   -353,  -7284,    142,
+      1008,    875,  -6109,    -16,    162,   4895,     30,   -188,
+      2099,   1581,    300,   -259,   -921,   -386,   -488,    140,
+      -482,   7135,    -77,    494,   -196,   3207,   -250,   -102,
+       318,    978,    161,   7292,     55,  -1347,  -2605,    898,
+      1833,    602,  -1988,    630,   -145,   -102,   -414,   -133,
+       417,   -603,    156,  -1151,   -395,    625,  -1676,     86,
+       680,  13321,    322,  -5816,   -292,   -223,   4205,   -361,
+       903,   -224,   1745,     95,  -6598,     79,   2323,    -24,
+       263,    778,    146,   -939,   1814,   1945,    720,    367,
+     -2987,    899,  -4409,    136,  -3185,   -342,  -3304,   1016,
+       284,   -345,   2313,   -403,    389,  -1403,   1835,    151,
+      -132,  -1702,   -339,  -5679,   2026,  -2990,     47,   -564,
+       399,  -2167,   1392,   1384,   5094,  -2954,   4467,    -22,
+       -23,    408,   1620,   1381,   2380,    805,    380,    -36,
+      -803,    765,   -778,    905,   -200,   -669,   3942,    289,
+       176,  -4767,   2015,  -3554,   1206,   6071,    180,   2057,
+       -48,    365,    -48,  -2423,    585,   -109,  -1298,   2519,
+      -525,   -589,    374,    976,   3667,   2091,  -2890,   1371,
+      -726,   -216,  -1027,   -116,   2122,   -619,  -3826,   4649,
+      1167,      0,   1237,   1538,   2505,   -548,  -3093,   1344,
+      -558,  -1927,    199,   2462,   1327,   4597,    833,  -3660,
+      -341,  -1010,    428,    148,  -1682,    130,   1569,   8785,
+      -752,  -1032,  -2407,    353,   -379,   3311,    892,    893,
+     -2596,   -217,   -835,  -2291,   1137,  -4339,    -58,   2759,
+       991,   3527,   -281,  -6050,  -1251,   1802,      8,  -3916,
+};
+
+static const int16_t shape16[] = {
+      -855,   1549,  -4841,    629,    932,  -5896,    840,  -2041,
+      -305,  -2574,    343,    -31,   -780,   -773,   -353,    403,
+     -1907,  -2371,   -555,   -324,   -479,   6961,   -286,  -4290,
+       626,   -953,    -14,  -1681,   -443,   1504,   -366,    513,
+     -1206,    870,   9239,    112,   -213,    425,    381,   1802,
+       750,    594,     61,   -152,  -2060,  -8997,   -752,    197,
+      -493,   -176,   -389,   -591,   2988,    654,   2404,   -204,
+       304,   -279,    202,     66,   -185,    415,    159,  -1514,
+     -6775,    -37,  -2617,  -1246,  -4012,   1208,   -554,   3240,
+      -655,   -394,  -1464,  -4448,    388,   1058,   -364,  -1760,
+      1081,   -558,   -116,   -108,     99,   -925,    763,  -1301,
+      -251,    258,    -33,    311,    555,    227,   -279,   -601,
+      -135,   -675, -10615,   -937,    158,    503,  -2044,   1075,
+      -114,   4278,  -9040,     67,  -1076,   -705,   -122,   -533,
+      3299,  -1826,  -1316,    708,  -3840,   -740,   -370,  -1074,
+        87,   -462,   2177,  -1177,     57,  -6311,   -170,   -777,
+      -256,    435,    291,  10371,    -82,   -425,  -1757,   -196,
+      3824,  -6289,     62,   4506,   -519,   -783,   1155,    878,
+       295,  -2044,    305,    186,    263,  -1716,   -482,  -5678,
+       415,   2709,    213,   7531,   1376,    813,   1803,    190,
+       398,   6483,   1425,    235,   2713,    520,  -2892,  -1191,
+      6074,    654,  -6535,    320,   -736,   -478,   2563,   -309,
+     -3477,   -155,    275,   1024,    390,   -386,   -331,  14043,
+       251,   -410,   1496,     24,   1272,   -816,    549,   -238,
+     -2489,    158,    194,      1,   -306,  -3088,   -264,    200,
+       -30,   -520,   -472,    -30,   -464,   -764,    440,   -659,
+        88,    778,    -31,  -1794,  -3817,   -344,    887,   -551,
+       115,   -763,  -5338,   2906,     50,    736,   5536,  -1101,
+       330,   -405,    416,   1022,    -93,     71,  10034,   -200,
+     -1258,  -3405,    480,    141,    399,    500,    311,   -503,
+       301,   4398,    454,   -922,    975,   -101,   -775,    -81,
+     -1723,   1077,    857,  -1682,    813,    847,    342,   -276,
+      3582,   2991,   5571,    713,   1280,    596,  -1325,  -1087,
+      -681,   1411,    391,  -1728,    492,    544,   1512,   -724,
+     -7445,   -426,      6,   -534,  -3643,  -1598,   2650,   -834,
+      2096,   -333,     67,   1746,  -1584,  -1003,   1272,   1710,
+      1666,    176, -11716,    329,  -1829,    385,    802,   -382,
+      2244,     -8,   -222,  -2351,    369,  -1067,  -9354,    293,
+       -51,  -1849,   -500,  -2350,  -1824,   -826,   -450,  -2155,
+       456,    245,   1796,    320,    -73,   -306,   -122,    290,
+       118,   -298,   -675,   -180,   -828,     86,    -44,    165,
+       435,  -8249,    769,    630,  -1670,   -762,    453,   5893,
+       259,    -92,  -1003,   -358,    -32,  -1350,   -535,   -289,
+       409,   -558,   -344,   -752,   6037,   -680,   2471,    581,
+      -351,   1251,  -5827,    194,   -104,    815,   1257,   -619,
+       243,    410,   4455,   -969,     50,   1286,  -1013,   -293,
+     -7740,     73,    615,    523,   -149,   -824,   2235,   1571,
+       970,    944,   4778,   -132,  -5082,     83,    129,   -820,
+      -803,    694,   1615,   1163,    517,   -402,    -80,    762,
+      -107,   -419,    142,   -294,  11298,    301,    484,   -513,
+       105,    547,   1130,  -4253,   -742,    376,  -1545,   1076,
+      4372,   2338,  -2847,    495,   -190,  -2444,    931,   6487,
+       117,  -1273,   1488,    -75,   -322,   -487,  -2614,   -251,
+      1233,   4111,   -321,   -219,  -7961,    -11,    107,   -808,
+       450,    111,   4395,     89,    772,  -1878,  -1894,   1075,
+      -544,  -9467,   -459,    637,    842,   -956,   -738,   4452,
+       777,    -75,   -209,   -302,   -796,    785,  -7413,    321,
+       649,    -55,    114,     43,  -1026,   -223,   -611,    209,
+     -5543,   8206,    907,  -3358,   1452,   -543,  -3173,    525,
+       -95,     35,   -475,   -525,   -705,   -569,    350,    206,
+      -108,  -1523,   -680,   -283,  -2583,  -4992,    -59,   -968,
+     -1719,  -2750,   5884,    455,     29,    436,    784,   -101,
+      -216,    110,    612,   -511,    -12,     98,    -67,    177,
+     -1210,    222,   -345,    243, -12670,   -472,    282,  -2149,
+       687,  -2631,   4434,     77,   -521,   -404,   -934,    212,
+      -695,   -369,   1138,   1348,   -905,    501,    299, -10467,
+      1018,    818,   1941,     31,    257,   1219,    944,   -157,
+      1968,  -1649,   -126,   -440,   -599,     -1,   6190,   2574,
+      -332,    753,    195,   -131,   5972,   -297,    672,    -86,
+      -143,   -303,      5,   -121,   -154,   -613,   5541,  -1516,
+      -304,    962,     69,  -1857,   4142,   -134,    706,    896,
+     -1226,   -135,   -310,  -9261,   1135,  -3437,    620,    802,
+       -33,   -582,   1909,   1407,    242,   2599,  -1533,   -279,
+       836,   8070,  -1207,   5745,    200,    -77,    162,    781,
+      -466,  -1555,   3297,   -957,    225,   1290,      7,    677,
+        41,   -549,  -2778,   1400,    379,  -3367,    369,    615,
+     -6402,    527,     58,   5679,   -114,   -180,   2842,     88,
+     -2611,    -50,    371,    161,   -444,   2062,    -38,    272,
+     -8562,    769,     18,  -2593,   -226,   -503,   -959,  -1295,
+       189,   -371,   -675,  -1528,    -98,    514,  -1236,    116,
+       202,  13662,   1596,   -328,     61,   3567,   -486,  -3316,
+     -8473,   -317,   2868,   -419,    -17,    535,   -965,   -503,
+     -3848,   2222,    620,  -1740,      2,   6505,    473,   -297,
+       -70,   3043,    -51,  -1520,    993,   1046,   1965,   3240,
+      1971,    -60,   -650,    -53,   -248,  -4428,   -365,  -3723,
+      1122,  -1681,   1629,   1358,    -17,   1136,   -256,   2344,
+      -282,    156,    127,   -155,    318,  -1281,  -1066,     57,
+      -889,   -253,  -1396,   -579,   -920,  -1006,  -9202,   -703,
+       195,   5186,    241,   1742,    996,    118,   1431,   4415,
+     -2452,   6837,  -1272,   -569,   3485,    328,    441,    832,
+       553,     94,    648,     92,   -378,  11167,    775,    457,
+      1712,    -24,    941,   5433,  -1645,   2166,    249,    -55,
+     -1816,    383,    735,   -876,    443,   -568,    293,  -1266,
+      6963,   -178,   -174,  -1186,   1119,   -208,    821,   1499,
+     -1496,  -2171,   1434,    874,    133,  -7466,   -545,   2193,
+      -775,  -1405,  -1205,   -575,  -1996,   -645,   -552,   -263,
+      8861,   -517,     76,   -992,    278,   2417,  -1369,     35,
+     -1461,  -1399,    517,    185,  -2895,    347,  -3871,   3644,
+       284,   3284,    -12,   -169,  -1981,   1196,    -67,   2868,
+       910,    134,   -530,    150,  -1328,   1902,   -746,    351,
+      -222,    522,  -5702,    797,  -1900,    241,   2270,    764,
+      -335,   1348,   -349,    784,  -1586,   -537,    148,   3211,
+     -1692,     56,   1678,   -321,   -290,   7902,     69,     52,
+       310,    337,    250,    596,   9998,    336,   1037,    163,
+        64,   -441,   2894,  -1033,    730,   -718,  -1252,    459,
+      -131,   7840,   -922,   -555,   5671,    299,    689,   1115,
+      -646,   -505,   -263,    608,   -494,      0,    442,  -1802,
+      -598,   -701,  -4184,     70,  -1319,    -90,   9155,   -339,
+         0,    121,    462,    735,   -639,    481,    125,   6924,
+      3379,    683,   3053,  -1219,   -499,   1067,   -148,  -2705,
+       -11,    795,   1675,    898,    226,   1232,     49,   -572,
+     -9309,   2223,    949,    767,   -821,    -91,   1075,   -352,
+     -7829,    554,   -593,   1284,   -245,   1239,   1166,  -1157,
+     -5274,    808,    871,  -1446,   7575,   -397,   -755,    752,
+      4193,    179,   -205,    -37,   -750,  -2675,   -407,   -700,
+       220,    -77,   1604,     63,    461,  -9994,   -645,  -1629,
+       103,    576,    132,  10005,    -49,  -1005,     97,  -1608,
+       515,    -10,   -146,  -1878,    880,    429,  -1271,    996,
+      -365,     76,   -409,   2461,     29,   1159,    217,  -6240,
+      -200,   -746,    118,  -1884,    457,   -816,   -608,   3215,
+       244,    749,   2268,   -236,  -1276,   -278,   1392,  -1767,
+      1255,  -1474,  -8136,   1388,   -770,    225,   -443,     10,
+      -392,    659,  -1118,  -1651,   -514,   -935,   -111,   1112,
+       973,   -247,   -235, -13010,   -737,     40,   -141,   5167,
+      -910,    279,   -467,  -3762,    847,  -3935,   1018,   1922,
+       830,    190,    253,  -1130,   -415,    371,    718,   3833,
+      1036,  -5358,   -928,    866,   -514,   2724,   2354,    449,
+       210,   1462,    680,  -1880,    -62,  10988,    809,   -602,
+       145,   -536,    114,   -147,   -568,   3193,   -322,    892,
+      -637,  -1381,    -65,    761,   1615,   5025,   -327,   4941,
+      -631,  -5225,   1204,   3042,    998,  -1047,   -959,   -106,
+      1610,   -151,    120,  -1152,    191,     30,  11963,    101,
+        18,   -410,  -1288,    370,   -771,   1337,   -544,   -613,
+       289,   -117,   1625,  -4506,   2582,  -1690,   -105,  -5324,
+       -93,    285,  -1167,  -3564,   -729,  -4790,    595,    275,
+      -216,   -217,  -6000,    682,   -171,   -875,    224,   -164,
+      2919,    796,    -81,   1434,    186,   -375,  -4113,   -179,
+       277,   1363,   -453,   2505,    388,  -1840,   -165,  -4800,
+       -42,  -6632,     54,   -735,   -553,  -1679,    917,     -2,
+      -632,    417,   -478,   -494,   -265,     73,   -372,   -360,
+       179,   -448,    265,    299,   -152,   -211,  12730,    -77,
+      1954,   -534,    773,    524,    438,   1901,  -4413,   -358,
+      1552,   -248,  -1588,   -122,   -127,   5405,    226,   -849,
+     -7495,   -357,    -89,    185,    746,    851,    669,    305,
+      -247,   3457,   -193,   -161,    638,    600,    610,    855,
+     -1292,    398,   1528,   2250,   1651,  -8414,    763,   1529,
+      -346,   3769,   -111,  -6494,    347,   -742,   1941,   1967,
+       582,  -5499,   -765,   -818,   1850,  -1604,   -243,   -943,
+       -11,    884,  -2996,  -2375,   1010,   -374,   6605,   -287,
+     -5073,    211,   -758,    703,  -2607,    747,   -130,   -429,
+     -2481,   4894,   -457,   3225,    958,   8533,    542,   6177,
+     -1069,  -1210,   -963,  -5943,    -86,   1424,   -567,    827,
+      -510,  -6577,   -258,     -4,  -4430,    115,   5401,   1390,
+       354,   1755,   -998,    852,    993,   -481,    218,   -987,
+       779,   -417,    591,   6011,    528,    289,   -336,   -558,
+        60,   9124,   -174,    235,   -239,   -144,   -260,  -3472,
+       746,   4781,    652,  -4831,   -739,    -21,    864,  -2310,
+       652,   7147,    116,   -318,    -50,  -3485,   -325,   -345,
+     -5784,   1144,   2399,  -1443,    991,  -2318,   -785,   -281,
+      -207,  -1448,    309,   1001,    952,   1472,  -5901,   -780,
+     -2459,   1518,   9878,  -1229,    670,   -523,   1217,   -164,
+       -55,    -95,    243,   7909,     86,  -4380,   -859,   -599,
+      -183,  -2339,    774,  -1210,   -502,   -899,     53,   1039,
+        34,  -7753,   -296,  -1951,  -4559,   1182,   -150,   2878,
+     -4910,   2761,  -1481,   2048,   2600,   1808,  -2953,  -2257,
+        62,    162,   1115,    214,  -4510,    926,  -6669,   1443,
+      -124,    193,   -314,    302,    699,    -18,    745,    341,
+       895,   -615,   -295,   -181,    143,   -427,   6528,   1074,
+     -1126,    374,   -298,  -1274,     22,    887,   -511,  -1057,
+      3228,    722,    607,    624,    -95,  11085,   1006,   -788,
+      -285,    -92,   1342,   -325,   -828,     42,  -3588,   -631,
+      -576,   4559,   -668,  -1294,   1739,   1697,   -647,   2336,
+       376,   -120,   1350,    646,   -325,     95,   5974,    775,
+       199,  -8557,    931,   -336,   -651,   -561,   -433,  -2266,
+      -129,   -657,  -1184,     67,    577,    617,   1880,    552,
+        90,   -617,   -273,  -1571,  -7481,    261,    -26,    -20,
+      -459,  -1028,     57,  -8516,    -43,   2774,      1,  -4238,
+       680,  -3310,    -56,   -152,    548,  -1983,    920,    899,
+      2180,   -307,  -2230,  -1685,   -998,   2091,   -112,     21,
+     -1551,   1182,   6649,   -326,    792,   1818,  -7596,    563,
+      1076,   7422,   -908,   1524,   -223,   5798,   1318,  -3376,
+       517,   4162,    756,  -4142,   1776,    390,    334,    -44,
+       218,   5290,    792,     39,   1692,    542,    -62,   -595,
+       590,     27,   8922,    989,    182,    725,    112,    458,
+     -9170,  -1000,   1176,  -1290,  -1403,   -726,   5990,   -297,
+      1234,  -1724,   -601,    528,   1072,    184,   -146,     61,
+       685,   1208,    -88,   -211,    356,   9569,   -363,   -135,
+      -159,  -1061,   -105,   -410,    -58,    335,  -9986,   -300,
+      -211,    607,    443,   -410,  -1730,   -328,    275,    579,
+       805,    899,   -464,    -18,    296,   -446,   2396,    -13,
+       414,  -9662,   -385,   -808,  -1867,    154,   -572,   3351,
+     -1839,    -80,   1157,   -326,    481,   8815,  -1039,   1065,
+      2110,   1223,   -960,    -33,   -464,  -5660,    490,   -314,
+       346,    730,   -387,  -1102,   6656,   -719,  -1173,    -57,
+     -1186,   2394,  -1300,   -665,   -586,    -39,    -71,    155,
+      1184,      4,  -3269,   -333,   -747,    580,    279,   -583,
+      7164,   -185,    110,   2465,    428,    507,   4462,  -4461,
+       199,    337,  -3597,   -249,    -70,   -680,  -5549,   1533,
+       917,   -303,  -9230,   -431,   -124,  -1019,    369,    139,
+      1367,    151,  -1047,   6820,   -151,    222,  -2934,   -817,
+       971,  -7325,    556,   1035,  -1240,   3115,  -1326,   4012,
+      2812,   1057,   2580,   -261,   3989,   1999,   1624,   2402,
+      -310,    779,   -354,   -377,   -149,   1035,  -2363,    358,
+      3666,   -246,  -1896,    375,   3919,  -1392,    683,    624,
+     -5872,    644,    391,    288,   -198,   -237,     68,   -284,
+        88,  -1016,    250,     32,   1188,   -243,   -608,   -320,
+      -219, -11087,    543,    156,   1034,   -169,   -183,   -549,
+       -66,    716,    996,   -928,   -309,   5577,    229,    125,
+     -1328,   9027,   -698,   -485,  -1694,    839,    343,    449,
+      1655,   1005,   1053,   -408,   9106,    186,    670,    774,
+       314,    573,   3888,   -882,     26,   2518,   -533,   -195,
+       555,    337,   -246, -10779,   -231,     31,   -314,   -941,
+      1129,    333,  -7503,    168,   -551,    237,   -159,   4399,
+       421,    693,    198,   -196,   -561,   1035,   -548,   1058,
+       527,   3617,   -361,   1317,  -1975,  -2638,  -1966,   -120,
+      -324,   5678,  -2252,   -663,    181,   -273,  -3073,   -282,
+      -622,    363,     71,    184,   -776,    284,  -1516,   -430,
+         3,    937,   8587,    258,  -1060,  -1555,   -830,   -338,
+       318,  -9130,   -110,    459,   -572,     70,     93,    120,
+      -534,   1296,   -168,     29,   -914,   -332,   -997,   -818,
+       270,   -243,    523,     56, -11847,   -448,     11,   -154,
+       164,   2115,    -13,   -635,    708,   -663,     43,   -248,
+     -3244,    254,     19,  -1125,    508,    154,   8697,    191,
+       595,   4393,  -2806,   -168,  -1916,    393,   3976,    897,
+     -1716,    -35,   -180,    605,  -1057,  -1194,    100,   -384,
+       -37,   -107,   2739,   -207,   6899,    176,     81,   -901,
+      1280,  -1670,   -101,    281,   1147,     48,     21,   -151,
+     -1236,    210,     98,   -114,   -573,   7940,   -153,   -302,
+     -1331,    337,   -322,   6598,    477,    147,   -999,  -3166,
+      -232,  -5104,   -799,  -1866,    -58,  -4213,   1376,    181,
+       675,    562,    126,    235,   2260,  -5152,   -243,   -699,
+     -1476,   4135,    569,    567,    737,  -4163,    613,  -1057,
+      1778,    546,   -450,    -24,    325,    366,   2406,  -1319,
+        60,  -5126,     49,    657,  -5937,   -194,    882,   3267,
+       178,   -298,   1873,  12422,    459,    272,    195,  -1827,
+       212,   -802,    730,    471,   1556,    422,    640,    236,
+        71,    597,   5783,   5378,   -649,   1524,    829,    437,
+      -351,   -122,  -1400,   2119,   -128,     75,  -1677,   -633,
+      -322,  -6382,   -573,   -974,   1672,   -378,   -242,   3708,
+        79,  -1325,    397,   -150,   1977,    442,    747,   -127,
+};
+
+static const int16_t shape44s[] = {
+       -20,   -140,    683,   -586,  -1742,    177,   -538,   1900,
+      2193,    -17,  -2096,    261,    645,    339,     77,   1136,
+      -521,    537,   -924,   -156,   -261,    195,   1049,    -39,
+       236,   -137,      0,   3199,    225,     46,     86,   -215,
+       557,  -5394,     17,    911,  -1690,    -48,    -48,   -175,
+       -11,   -631,   -153,   4474,   -347,    -39,   1759,    154,
+       170,   -180,   -273,    603,   -590,  -5195,    -74,   1789,
+       240,   -212,    431,   2447,    368,    -76,   -313,     11,
+     -2926,     19,    -71,    208,    -51,   -728,  -6412,    -61,
+       141,   -112,   5280,    -76,   4435,   -402,    -25,     46,
+       210,   -104,    172,  -3830,   -366,    -23,    239,   -112,
+       137,   6692,  -6288,   -720,   -132,   -136,    552,  -1688,
+      -345,   -289,   -485,    149,    174,    180,    361,   -236,
+        92,    407,      6,   2373,    380,   -167,    845,    444,
+      -834,  -9358,    413,  -1302,    460,     77,     34,     56,
+     -1516,   -143,    207,    -43,    -31,   -106,    -52,    403,
+      -309,    298,    -88,   1552,   -240,   -776,    624,  -4181,
+      -342,  -4804,     57,    -23,    160,    -44,    469,    -17,
+     -3997,  -5079,   -263,     72,    181,   1085,    538,   -611,
+      -368,     59,   -204,   -195,    -40,   -201,   -803,  -5093,
+     -3216,    480,     46,   -729,    244,   3320,    185,    503,
+      2979,   -416,    110,     25,    140,   -502,   2236,  -4420,
+       -36,   -238,   -278,     60,    -82,   -597,    218,     69,
+       -95,  -2102,  -2138,  -2308,  -3796,     20,   -211,   -229,
+       297,   3665,     81,    148,   1315,  -4537,    -38,    186,
+     -3106,   -526,     90,    -35,   -193,   -302,  -5860,    276,
+      -308,    206,    645,      1,   -242,    580,   3025,  -2583,
+       -90,    511,   -315,   -137,  -2033,  -4313,    693,    485,
+      -211,   1486,   1180,    181,   -136,    204,     23,    383,
+      1479,   -213,     42,     32,    -64,   -136,    -91,   -146,
+       434,    231,     36,    -58,  -3254,  -2647,    -18,    345,
+       171,    -60,     84,    209,    246,   -587,   9447,    -67,
+      -187,   -108,   -226,   -458,   -519, -11089,   -422,   -502,
+       132,     79,    298,   -475,   -412,    196,   -164,  -7347,
+       185,   -131,    369,     18,   -500,    644,   -334,     93,
+       -77,     71,    341,   3566,   -281,  -4191,   -145,     87,
+        37,    306,  -3482,  -5739,    161,   -245,    293,    208,
+       380,   2888,     31,    -23,  -2061,   -597,    -56,    350,
+      -105,   1167,     64,    342,   3638,    -79,   -106,    148,
+      5422,   -719,   -232,      8,   -395,   3249,  -5093,   -222,
+      -707,    241,    318,    735,    376,     78,   -166,  -1614,
+        -9,  -3373,    330,  -1540,   2028,   3400,     -9,    317,
+         9,   4903,    262,     62,    222,    -95,   -208, -13376,
+      -101,    121,    298,      5,    172,    406,   -164,     79,
+       172,   1993,    235,    229,   1193,   -274,   5944,   -918,
+       -15,   1304,    307,   1150,   -385,   -794,  -3467,    660,
+      2143,    147,   -279,   -751,   -305,   1052,    205,   -108,
+       572,   -212,     29,    -50,      6,   3749,    238,  -2016,
+     -1118,  -1329,   -971,   2633,    519,    194,   3545,    -11,
+        77,    -92,   1215,   -439,    152,   -863,   1604,    180,
+      -514,    252,    308,   -131,   -938,    133,    378,     11,
+     12153,     51,    486,     71,   -476,   -599,     57,   -127,
+      2685,   -173,   -182,    468,  -3469,   -594,   -380,    265,
+      -879,   -352,   -278,   -309,    575,    124,  10814,   -765,
+       -64,    710,   -105,    296,   2562,     98,   -358,    556,
+      2921,   -133,     -5,   -406,     42,    496,  -1053,  -1957,
+       701,    266,    260,   -441,     43,   -192,     -1,  -2174,
+      9894,    -90,   -181,     29,     50,   -858,     59,   -190,
+        49,   -282,   1632,   1525,    100,  -3659,     13,    173,
+      -240,   5304,   -383,    263,   -311,   1747,    169,  -2203,
+       -29,   -106,    342,   -301,     66,     49,     23,    857,
+      -607,    698,  -1198,   -191,   -450,  -1875,   -329,  -2156,
+       156,     95,    145,    129,   -321,     88,   1049,   3980,
+       -14,    321,  -1484,    895,    -30,  -2174,    289,    933,
+      -933,     15,   2631,     68,   3054,    221,    -87,    175,
+       200,    937,    -87,  -2032,    348,    146,   -372,     60,
+     -2566,   3497,    -98,    313,    536,   -299,    -58,  -8949,
+       323,   -524,   -331,    713,    -47,    360,    155,    168,
+       687,  -1391,   1973,    670,    788,   -202,   -129,  -5113,
+        54,   1178,   1218,    172,    630,   -154,  -1047,    840,
+        71,   -337,     91,    214,   -474,    624,   -773,     16,
+      -126,    340,   -631,   -482,   -155,    419,     50, -10976,
+      -742,   -781,    169,    149,     33,   -169,     44,    354,
+        26,    129,   -179,   1401,    776,   -155,  -3996,   -813,
+       594,    238,    -61,    168,   -383,  -9261,    294,    470,
+      -322,   -190,   -956,   -290,     27,   -438,   -254,  12571,
+       344,   -393,   -568,     56,     81,    171,   -115,  -4370,
+        49,   -322,   -237,   -692,    -55,    -49,   4317,     -6,
+     -4837,   -156,    179,    247,   -338,    -48,    952,  -1061,
+       -33,   -934,    250,   -256,  -1622,   1039,   -738,   2719,
+       -20,   -190,    249,   -119,   -235,   6080,    123,   -502,
+     -1443,     86,  -1684,   -177,   -128,    -58,   -237,   -641,
+      -177,     64,  -2416,     15,   -116,  -6465,   -412,    161,
+       419,    768,     36,    113,   -944,   -241,  -1424,    -95,
+       635,   1798,  -2257,    -18,   3046,    173,    -33,   -207,
+       -52,   -831,  -5730,    -54,   -199,    194,   -255,    467,
+      -211,   -853,   -512,  11619,    148,   3681,  -4603,   -282,
+       129,   -205,   -606,    167,    306,    464,    485,   -959,
+      -203,    254,    151,  -6880,   -262,   5180,    658,  -1378,
+      1174,    -53,    -59,    -33,  -3077,   -127,   -223,    -17,
+       -31,  -2190,     23,    317,   -169,    203,   -223,   -222,
+     -5295,    116,     80,  -2757,   -666,   3377,   -476,     85,
+      -630,   -147,   1740,   -175,   -115,    207,    240,   -248,
+       -95,  -1016,   3966,   3998,   -343,  -4751,    187,   -113,
+      -250,    111,   -510,   -203,    130,     89,    311,    608,
+      -221,   -381,   -253,   -359,  -2254,     45,    224,   -141,
+        45,    -19,    480,  -5074,    797,  -4580,   -163,    110,
+      -234,    337,      6,    707,    492,  -5493,  -2750,    -94,
+      -363,    113,   2345,    344,    379,    464,  -3222,    -56,
+      -269,   -262,    -10,   -609,    324,   3043,    209,   3092,
+      -600,     42,   -615,    -17,    -53,     30,   1123,    224,
+       593,    632,    -90,    428,   1117,  -1429,  -6741,    -95,
+      -293,   -103,  -2784,    251,   1688,    621,   -349,   1059,
+     -1093,   -148,    447,    149,     88,     92,    687,   1249,
+        80,    289,  -1841,    221,    -10,    -92,  -1736,    118,
+       136,    138,   -162,  -4162,   -111,     62,     95,    166,
+      -172,   -695,  -3685,   5694,   -527,   2032,   -549,     43,
+      -101,    221,    181,   -479,   7697,   2007,   -127,    805,
+       -83,   -535,   1354,   -383,    253,   -622,   2910,   1249,
+       782,     13,     42,    994,   -545,     75,   -485,    330,
+       -16,    343,    272,   -781,    360,    -97,    -25,   -875,
+    -12689,   -623,   -307,    195,   -256, -11644,    229,    180,
+       -42,   -361,   -124,    -81,    -23,   -460,  -1993,    212,
+      -634,   -847,   1616,   -546,   -583,     99,   3800,     10,
+       177,    366,   6106,   -173,    265,   -213,     10,   1108,
+      -288,  -1690,   -237,   -312,     38,  -2272,    431,    -26,
+      -178,   -764,    507,    355,    677,   -214,   -816, -12411,
+        47,     12,    294,   -295,  -3916,   -677,  -4885,   -250,
+      -453,  -7716,    478,    231,     17,   -248,    147,   1064,
+       637,    -80,    -41,    265,   -383,    142,    116,   2991,
+     -3060,    809,   2056,   -119,   -866,    -22,   -660,    233,
+       306,  -1873,  -1141,   6995,    186,  -8678,   -109,    -39,
+      -105,    730,     18,   -846,    273,  -2922,    210,     26,
+      -174,   -142,    990,    131,   -436,   1422,   -217,  -3152,
+      3224,     35,    315,    -47,     48,   -221,    568,     44,
+       182,   1696,  -1755,   -193,    527,    158,   -555,  -3485,
+       171,  -4552,    -47,  -4680,     95,   -112,    184,     80,
+       -36,   -915,     87,     24,   -259,  -1743,     68,   -117,
+       405,     11,     40,   -320,    -17,   -158,   -134,   -186,
+     -1206,   -466,   1262,    133,   -254,   -100,    210,  -1735,
+      -636,    319,   -978,     69,    197,   -521,  -5503,    -78,
+      -544,  -1011,    101,   -489,   -371,    -79,   -196,    -18,
+      -839,   1091,    682,  -1441,  -2375,  -1127,     54,    829,
+      -306,   -255,    641,  -3665,    473,   3504,  -1035,   -160,
+      -467,   -275,   -437,     79, -13513,    326,    132,     82,
+       188,    362,    -74,   1406,    -46,   2864,    351,   -558,
+     -1277,    108,    -92,    -53,     72,    -41,    -31,    -97,
+       353,     73,   1864,   -207,    106,    -81,  -3930,    173,
+        41,   -539,   -497,    135,   -526,   -823,     69,    -10,
+       176,    648,  -1710,    564,     80,    237,  -1956,    234,
+        11,    142,   -849,   4116,   -473,    110,    129,   2137,
+      -170,   3193,     10,    245,   -953,   -827,    -30,   1235,
+       366,    -67,     54,   -567,  -7377,   2461,    582,     74,
+     -1988,    -33,   -296,   3090,    -54,    145,    564,   -295,
+};
+
+static const uint16_t bark_tab_l8_512[] = {
+    4,  5,  4,  5,  4,  5,  5,  5,  5,  6,  6,  6,  6,  8,  7,  9,
+    9, 11, 11, 14, 15, 17, 20, 24, 28, 34, 41, 51, 64, 83,
+};
+
+static const uint16_t bark_tab_m8_256[] = {
+    3, 4, 3, 4, 3, 4, 4, 5, 5, 6, 6, 8, 9, 11, 13, 17, 23, 29, 41, 58
+};
+
+static const uint16_t bark_tab_s8_64[] = {
+    2, 1, 2, 2, 3, 4, 5, 7, 13, 25
+};
+
+static const uint16_t bark_tab_l16_1024[] = {
+     5,  5,  5,  5,  5,  5,  5,  6,  6,  7,  7,   7,   8,   9, 10, 11,
+    12, 14, 17, 19, 22, 27, 33, 40, 51, 64, 84, 114, 164, 257
+};
+
+static const uint16_t bark_tab_m16_512[] = {
+     3,  3,  3,  3,  4,  3,  4,   4,  4,  5,  5,  6,  7,  8, 10, 12,
+    14, 18, 24, 30, 42, 59, 89, 152
+};
+
+static const uint16_t bark_tab_s16_128[] = {
+    2, 2, 2, 3, 3, 5, 7, 12, 25, 67
+};
+
+static const uint16_t bark_tab_s16_64[] = {
+    1, 1, 2, 2, 3, 6, 11, 38
+};
+
+static const uint16_t bark_tab_l44_2048[] = {
+     5,  6,  5,   6,   5,   6,   6,   6,  6,  6,  7,  7,  7,  8,  8,  9,
+     9, 10, 11,  11,  13,  14,  16,  17, 19, 22, 25, 29, 33, 39, 46, 54,
+    64, 79, 98, 123, 161, 220, 320, 512,
+};
+
+static const uint16_t bark_tab_m44_512[] = {
+     3,  2,  3,   3,  3,  4,  3,  5,  4,  6,  7,  8, 10, 14, 18, 25,
+    36, 55, 95, 208,
+};
+
+static const uint16_t bark_tab_s44_128[] = {
+    1, 2, 1, 2, 3, 4, 6, 10, 23, 76
+};
+
+const TwinVQModeTab ff_metasound_mode0808 = {
+    {
+        { 8, bark_tab_s8_64,  10, fcb8s, 1, 5, cb0808s0, cb0808s1, 18 },
+        { 2, bark_tab_m8_256, 20, fcb8m, 2, 5, cb0808m0, cb0808m1, 16 },
+        { 1, bark_tab_l8_512, 30, fcb8l, 3, 6, cb0808l0, cb0808l1, 17 }
+    },
+    512, 12, lsp8, 1, 5, 3, 3, shape8, 8, 28, 20, 6, 200
+};
+
+const TwinVQModeTab ff_metasound_mode1616 = {
+    {
+        { 8, bark_tab_s16_128,  10, fcb16s, 1, 5, cb1616s0, cb1616s1, 16 },
+        { 2, bark_tab_m16_512,  24, fcb16m, 2, 5, cb1616m0, cb1616m1, 15 },
+        { 1, bark_tab_l16_1024, 30, fcb16l, 3, 6, cb1616l0, cb1616l1, 16 }
+    },
+    1024, 16, lsp16, 1, 6, 4, 3, shape16, 9, 28, 30, 7, 200
+};
+
+const TwinVQModeTab ff_metasound_mode4432 = {
+    {
+        { 16, bark_tab_s44_128,  10, fcb44ss, 1, 6, cb4432s0, cb4432s1, 23 },
+        {  4, bark_tab_m44_512,  20, fcb44sm, 2, 6, cb4432m0, cb4432m1, 21 },
+        {  1, bark_tab_l44_2048, 40, fcb44sl, 4, 6, cb4432l0, cb4432l1, 22 }
+    },
+    2048, 20, lsp44s, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200,
+};
+
+const TwinVQModeTab ff_metasound_mode4448s = {
+    {
+        { 16, bark_tab_s44_128,  10, fcb44ss, 1, 6, cb4448ss0, cb4448ss1, 15 },
+        {  4, bark_tab_m44_512,  20, fcb44sm, 2, 6, cb4448sm0, cb4448sm1, 14 },
+        {  1, bark_tab_l44_2048, 40, fcb44sl, 4, 6, cb4448sl0, cb4448sl1, 14 }
+    },
+    2048, 20, lsp44s, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200
+};
diff --git a/libavcodec/metasound_data.h b/libavcodec/metasound_data.h
new file mode 100644
index 0000000..5c33411
--- /dev/null
+++ b/libavcodec/metasound_data.h
@@ -0,0 +1,49 @@
+/*
+ * MetaSound decoder
+ * Copyright (c) 2013 Konstantin Shishkov
+ *
+ * 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
+ */
+
+#ifndef AVCODEC_METASOUND_DATA_H
+#define AVCODEC_METASOUND_DATA_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "twinvq.h"
+
+extern const TwinVQModeTab ff_metasound_mode0806;
+extern const TwinVQModeTab ff_metasound_mode0806s;
+extern const TwinVQModeTab ff_metasound_mode0808;
+extern const TwinVQModeTab ff_metasound_mode0808s;
+extern const TwinVQModeTab ff_metasound_mode1110;
+extern const TwinVQModeTab ff_metasound_mode1110s;
+extern const TwinVQModeTab ff_metasound_mode1616;
+extern const TwinVQModeTab ff_metasound_mode1616s;
+extern const TwinVQModeTab ff_metasound_mode2224;
+extern const TwinVQModeTab ff_metasound_mode2224s;
+extern const TwinVQModeTab ff_metasound_mode2232;
+extern const TwinVQModeTab ff_metasound_mode2232s;
+extern const TwinVQModeTab ff_metasound_mode4432;
+extern const TwinVQModeTab ff_metasound_mode4432s;
+extern const TwinVQModeTab ff_metasound_mode4440;
+extern const TwinVQModeTab ff_metasound_mode4440s;
+extern const TwinVQModeTab ff_metasound_mode4448;
+extern const TwinVQModeTab ff_metasound_mode4448s;
+
+#endif /* AVCODEC_METASOUND_DATA_H */
diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c
index 85c6a1a..e2c9369 100644
--- a/libavcodec/mimic.c
+++ b/libavcodec/mimic.c
@@ -175,7 +175,7 @@
 
     for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) {
         ff_thread_release_buffer(avctx, &dst->frames[i]);
-        if (src->frames[i].f->data[0]) {
+        if (i != src->next_cur_index && src->frames[i].f->data[0]) {
             ret = ff_thread_ref_frame(&dst->frames[i], &src->frames[i]);
             if (ret < 0)
                 return ret;
@@ -388,8 +388,8 @@
         avctx->height  = height;
         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
         for (i = 0; i < 3; i++) {
-            ctx->num_vblocks[i] = -((-height) >> (3 + !!i));
-            ctx->num_hblocks[i] =     width   >> (3 + !!i);
+            ctx->num_vblocks[i] = FF_CEIL_RSHIFT(height,   3 + !!i);
+            ctx->num_hblocks[i] =                width >> (3 + !!i);
         }
     } else if (width != ctx->avctx->width || height != ctx->avctx->height) {
         avpriv_request_sample(avctx, "Resolution changing");
diff --git a/libavcodec/mips/Makefile b/libavcodec/mips/Makefile
index a2ea412..6537b43 100644
--- a/libavcodec/mips/Makefile
+++ b/libavcodec/mips/Makefile
@@ -9,7 +9,6 @@
                                              mips/acelp_vectors_mips.o
 MIPSFPU-OBJS-$(CONFIG_MPEGAUDIODSP)       += mips/mpegaudiodsp_mips_float.o
 MIPSDSPR1-OBJS-$(CONFIG_MPEGAUDIODSP)     += mips/mpegaudiodsp_mips_fixed.o
-OBJS-$(CONFIG_FFT)                        += mips/fft_init_table.o
 MIPSFPU-OBJS-$(CONFIG_FFT)                += mips/fft_mips.o
 MIPSFPU-OBJS                              += mips/fmtconvert_mips.o
 OBJS-$(CONFIG_AC3DSP)                     += mips/ac3dsp_mips.o
diff --git a/libavcodec/mips/fft_init_table.c b/libavcodec/mips/fft_init_table.c
deleted file mode 100644
index 9c2e998..0000000
--- a/libavcodec/mips/fft_init_table.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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)
- *
- * 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
- */
-
-/**
- * @file
- * definitions and initialization of LUT table for MIPS FFT
- */
-#include "fft_table.h"
-
-uint16_t fft_offsets_lut[0x2aab];
-
-void ff_fft_lut_init(uint16_t *table, int off, int size, int *index)
-{
-    if (size < 16) {
-        table[*index] = off >> 2;
-        (*index)++;
-    }
-    else {
-        ff_fft_lut_init(table, off, size>>1, index);
-        ff_fft_lut_init(table, off+(size>>1), size>>2, index);
-        ff_fft_lut_init(table, off+3*(size>>2), size>>2, index);
-    }
-}
diff --git a/libavcodec/mips/fft_mips.c b/libavcodec/mips/fft_mips.c
index ae4ed30..d240f1f 100644
--- a/libavcodec/mips/fft_mips.c
+++ b/libavcodec/mips/fft_mips.c
@@ -49,7 +49,7 @@
  */
 #include "config.h"
 #include "libavcodec/fft.h"
-#include "fft_table.h"
+#include "libavcodec/fft_table.h"
 
 /**
  * FFT transform
diff --git a/libavcodec/mjpeg.c b/libavcodec/mjpeg.c
index a5b1a80..bdd7b19 100644
--- a/libavcodec/mjpeg.c
+++ b/libavcodec/mjpeg.c
@@ -38,7 +38,7 @@
  * The spec says that the values given produce "good" quality, and
  * when divided by 2, "very good" quality.
  */
-const unsigned char std_luminance_quant_tbl[64] = {
+static const unsigned char std_luminance_quant_tbl[64] = {
     16,  11,  10,  16,  24,  40,  51,  61,
     12,  12,  14,  19,  26,  58,  60,  55,
     14,  13,  16,  24,  40,  57,  69,  56,
@@ -48,7 +48,7 @@
     49,  64,  78,  87, 103, 121, 120, 101,
     72,  92,  95,  98, 112, 100, 103,  99
 };
-const unsigned char std_chrominance_quant_tbl[64] = {
+static const unsigned char std_chrominance_quant_tbl[64] = {
     17,  18,  24,  47,  99,  99,  99,  99,
     18,  21,  26,  66,  99,  99,  99,  99,
     24,  26,  56,  99,  99,  99,  99,  99,
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index b439547..6e16152 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -39,6 +39,9 @@
 #include "mjpeg.h"
 #include "mjpegdec.h"
 #include "jpeglsdec.h"
+#include "tiff.h"
+#include "exif.h"
+#include "bytestream.h"
 
 
 static int build_vlc(VLC *vlc, const uint8_t *bits_table,
@@ -221,6 +224,7 @@
 
     /* XXX: verify len field validity */
     len     = get_bits(&s->gb, 16);
+    s->avctx->bits_per_raw_sample =
     s->bits = get_bits(&s->gb, 8);
 
     if (s->pegasus_rct)
@@ -280,15 +284,18 @@
             s->h_max = h_count[i];
         if (v_count[i] > s->v_max)
             s->v_max = v_count[i];
-        if (!h_count[i] || !v_count[i]) {
-            av_log(s->avctx, AV_LOG_ERROR, "h/v_count is 0\n");
-            return -1;
-        }
         s->quant_index[i] = get_bits(&s->gb, 8);
         if (s->quant_index[i] >= 4) {
             av_log(s->avctx, AV_LOG_ERROR, "quant_index is invalid\n");
             return AVERROR_INVALIDDATA;
         }
+        if (!h_count[i] || !v_count[i]) {
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "Invalid sampling factor in component %d %d:%d\n",
+                   i, h_count[i], v_count[i]);
+            return AVERROR_INVALIDDATA;
+        }
+
         av_log(s->avctx, AV_LOG_DEBUG, "component %d %d:%d id: %d quant:%d\n",
                i, h_count[i], v_count[i],
                s->component_id[i], s->quant_index[i]);
@@ -334,7 +341,7 @@
             return AVERROR_INVALIDDATA;
         }
     } else{
-        if (s->v_max == 1 && s->h_max == 1 && s->lossless==1 && nb_components==3)
+        if (s->v_max == 1 && s->h_max == 1 && s->lossless==1 && (nb_components==3 || nb_components==4))
             s->rgb = 1;
         else if (!s->lossless)
             s->rgb = 0;
@@ -365,6 +372,15 @@
         }
         av_assert0(s->nb_components == 3);
         break;
+    case 0x11111111:
+        if (s->rgb)
+            s->avctx->pix_fmt = AV_PIX_FMT_ABGR;
+        else {
+            s->avctx->pix_fmt = /*s->cs_itu601 ?*/ AV_PIX_FMT_YUVA444P/* : AV_PIX_FMT_YUVJA444P*/;
+            s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+        }
+        av_assert0(s->nb_components == 4);
+        break;
     case 0x12121100:
     case 0x22122100:
         s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
@@ -425,7 +441,7 @@
         s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
         break;
     case 0x41111100:
-        s->avctx->pix_fmt = AV_PIX_FMT_YUV411P;
+        s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV411P : AV_PIX_FMT_YUVJ411P;
         s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
         break;
     default:
@@ -490,7 +506,7 @@
 {
     int code;
     code = get_vlc2(&s->gb, s->vlcs[0][dc_index].table, 9, 2);
-    if (code < 0) {
+    if (code < 0 || code > 16) {
         av_log(s->avctx, AV_LOG_WARNING,
                "mjpeg_decode_dc: bad vlc: %d:%d (%p)\n",
                0, dc_index, &s->vlcs[0][dc_index]);
@@ -733,9 +749,11 @@
 #undef REFINE_BIT
 #undef ZERO_RUN
 
-static void handle_rstn(MJpegDecodeContext *s, int nb_components)
+static int handle_rstn(MJpegDecodeContext *s, int nb_components)
 {
     int i;
+    int reset = 0;
+
     if (s->restart_interval) {
         s->restart_count--;
         if(s->restart_count == 0 && s->avctx->codec_id == AV_CODEC_ID_THP){
@@ -756,18 +774,20 @@
                 if (get_bits_left(&s->gb) >= 8 && (get_bits(&s->gb, 8) & 0xF8) == 0xD0) {
                     for (i = 0; i < nb_components; i++) /* reset dc */
                         s->last_dc[i] = 1024;
+                    reset = 1;
                 } else
                     skip_bits_long(&s->gb, pos - get_bits_count(&s->gb));
             }
         }
     }
+    return reset;
 }
 
 static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int predictor, int point_transform)
 {
     int i, mb_x, mb_y;
     uint16_t (*buffer)[4];
-    int left[3], top[3], topleft[3];
+    int left[4], top[4], topleft[4];
     const int linesize = s->linesize[0];
     const int mask     = (1 << s->bits) - 1;
     int resync_mb_y = 0;
@@ -779,7 +799,7 @@
                    (unsigned)s->mb_width * 4 * sizeof(s->ljpeg_buffer[0][0]));
     buffer = s->ljpeg_buffer;
 
-    for (i = 0; i < 3; i++)
+    for (i = 0; i < 4; i++)
         buffer[0][i] = 1 << (s->bits - 1);
 
     for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
@@ -788,7 +808,7 @@
         if (s->interlaced && s->bottom_field)
             ptr += linesize >> 1;
 
-        for (i = 0; i < 3; i++)
+        for (i = 0; i < 4; i++)
             top[i] = left[i] = topleft[i] = buffer[0][i];
 
         for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
@@ -798,7 +818,7 @@
                 s->restart_count = s->restart_interval;
                 resync_mb_x = mb_x;
                 resync_mb_y = mb_y;
-                for(i=0; i<3; i++)
+                for(i=0; i<4; i++)
                     top[i] = left[i]= topleft[i]= 1 << (s->bits - 1);
             }
             if (mb_y == resync_mb_y || mb_y == resync_mb_y+1 && mb_x < resync_mb_x || !mb_x)
@@ -825,8 +845,14 @@
                 skip_bits(&s->gb, 16); /* skip RSTn */
             }
         }
-
-        if (s->rct) {
+        if (s->nb_components == 4) {
+            for(i=0; i<nb_components; i++) {
+                int c= s->comp_index[i];
+                for(mb_x = 0; mb_x < s->mb_width; mb_x++) {
+                    ptr[4*mb_x+3-c] = buffer[mb_x][i];
+                }
+            }
+        } else if (s->rct) {
             for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
                 ptr[3*mb_x + 1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2] - 0x200) >> 2);
                 ptr[3*mb_x + 0] = buffer[mb_x][1] + ptr[3*mb_x + 1];
@@ -850,8 +876,8 @@
     return 0;
 }
 
-static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int nb_components, int predictor,
-                                 int point_transform)
+static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor,
+                                 int point_transform, int nb_components)
 {
     int i, mb_x, mb_y;
     int bits= (s->bits+7)&~7;
@@ -860,7 +886,7 @@
 
     point_transform += bits - s->bits;
 
-    av_assert0(nb_components>=1 && nb_components<=3);
+    av_assert0(nb_components>=1 && nb_components<=4);
 
     for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
         for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
@@ -1026,7 +1052,7 @@
         av_log(s->avctx, AV_LOG_ERROR, "Can not flip image with lowres\n");
         s->flipped = 0;
     }
-
+    s->restart_count = 0;
     for (i = 0; i < nb_components; i++) {
         int c   = s->comp_index[i];
         data[c] = s->picture_ptr->data[c];
@@ -1081,7 +1107,7 @@
                             s->dsp.clear_block(s->block);
                             if (decode_block(s, s->block, i,
                                              s->dc_index[i], s->ac_index[i],
-                                             s->quant_matrixes[s->quant_index[c]]) < 0) {
+                                             s->quant_matrixes[s->quant_sindex[i]]) < 0) {
                                 av_log(s->avctx, AV_LOG_ERROR,
                                        "error y=%d x=%d\n", mb_y, mb_x);
                                 return AVERROR_INVALIDDATA;
@@ -1094,9 +1120,9 @@
                         int16_t *block = s->blocks[c][block_idx];
                         if (Ah)
                             block[0] += get_bits1(&s->gb) *
-                                        s->quant_matrixes[s->quant_index[c]][0] << Al;
+                                        s->quant_matrixes[s->quant_sindex[i]][0] << Al;
                         else if (decode_dc_progressive(s, block, i, s->dc_index[i],
-                                                       s->quant_matrixes[s->quant_index[c]],
+                                                       s->quant_matrixes[s->quant_sindex[i]],
                                                        Al) < 0) {
                             av_log(s->avctx, AV_LOG_ERROR,
                                    "error y=%d x=%d\n", mb_y, mb_x);
@@ -1129,10 +1155,11 @@
     uint8_t *data = s->picture.data[c];
     int linesize  = s->linesize[c];
     int last_scan = 0;
-    int16_t *quant_matrix = s->quant_matrixes[s->quant_index[c]];
+    int16_t *quant_matrix = s->quant_matrixes[s->quant_sindex[0]];
 
-    if (se > 63) {
-        av_log(s->avctx, AV_LOG_ERROR, "SE %d is too large\n", se);
+    av_assert0(ss>=0 && Ah>=0 && Al>=0);
+    if (se < ss || se > 63) {
+        av_log(s->avctx, AV_LOG_ERROR, "SS/SE %d/%d is invalid\n", ss, se);
         return AVERROR_INVALIDDATA;
     }
 
@@ -1172,7 +1199,8 @@
                     s->dsp.idct_put(ptr, linesize, *block);
                     ptr += 8 >> s->avctx->lowres;
             }
-            handle_rstn(s, 0);
+            if (handle_rstn(s, 0))
+                EOBRUN = 0;
         }
     }
     return 0;
@@ -1222,6 +1250,11 @@
             && nb_components == 3 && s->nb_components == 3 && i)
             index = 3 - i;
 
+        s->quant_sindex[i] = s->quant_index[index];
+        s->nb_blocks[i] = s->h_count[index] * s->v_count[index];
+        s->h_scount[i]  = s->h_count[index];
+        s->v_scount[i]  = s->v_count[index];
+
         if(nb_components == 3 && s->nb_components == 3 && s->avctx->pix_fmt == AV_PIX_FMT_GBR24P)
             index = (i+2)%3;
         if(nb_components == 1 && s->nb_components == 3 && s->avctx->pix_fmt == AV_PIX_FMT_GBR24P)
@@ -1229,10 +1262,6 @@
 
         s->comp_index[i] = index;
 
-        s->nb_blocks[i] = s->h_count[index] * s->v_count[index];
-        s->h_scount[i]  = s->h_count[index];
-        s->v_scount[i]  = s->v_count[index];
-
         s->dc_index[i] = get_bits(&s->gb, 4);
         s->ac_index[i] = get_bits(&s->gb, 4);
 
@@ -1294,7 +1323,9 @@
                 if ((ret = ljpeg_decode_rgb_scan(s, nb_components, predictor, point_transform)) < 0)
                     return ret;
             } else {
-                if ((ret = ljpeg_decode_yuv_scan(s, nb_components, predictor, point_transform)) < 0)
+                if ((ret = ljpeg_decode_yuv_scan(s, predictor,
+                                                 point_transform,
+                                                 nb_components)) < 0)
                     return ret;
             }
         }
@@ -1361,7 +1392,7 @@
     len -= 6;
 
     if (s->avctx->debug & FF_DEBUG_STARTCODE)
-        av_log(s->avctx, AV_LOG_DEBUG, "APPx %8X\n", id);
+        av_log(s->avctx, AV_LOG_DEBUG, "APPx %8X len=%d\n", id, len);
 
     /* Buggy AVID, it puts EOI only at every 10th frame. */
     /* Also, this fourcc is used by non-avid files too, it holds some
@@ -1450,6 +1481,57 @@
         len -= 9;
         goto out;
     }
+    if (id == AV_RL32("colr") && len > 0) {
+        s->colr = get_bits(&s->gb, 8);
+        if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+            av_log(s->avctx, AV_LOG_INFO, "COLR %d\n", s->colr);
+        len --;
+        goto out;
+    }
+    if (id == AV_RL32("xfrm") && len > 0) {
+        s->xfrm = get_bits(&s->gb, 8);
+        if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+            av_log(s->avctx, AV_LOG_INFO, "XFRM %d\n", s->xfrm);
+        len --;
+        goto out;
+    }
+
+    /* EXIF metadata */
+    if (s->start_code == APP1 && id == AV_RB32("Exif")) {
+        GetByteContext gbytes;
+        int ret, le, ifd_offset, bytes_read;
+        const uint8_t *aligned;
+
+        skip_bits(&s->gb, 16); // skip padding
+        len -= 2;
+
+        // init byte wise reading
+        aligned = align_get_bits(&s->gb);
+        bytestream2_init(&gbytes, aligned, len);
+
+        // read TIFF header
+        ret = ff_tdecode_header(&gbytes, &le, &ifd_offset);
+        if (ret) {
+            av_log(s->avctx, AV_LOG_ERROR, "mjpeg: invalid TIFF header in EXIF data\n");
+            return ret;
+        }
+
+        bytestream2_seek(&gbytes, ifd_offset, SEEK_SET);
+
+        // read 0th IFD and store the metadata
+        // (return values > 0 indicate the presence of subimage metadata)
+        ret = ff_exif_decode_ifd(s->avctx, &gbytes, le, 0, &s->exif_metadata);
+        if (ret < 0) {
+            av_log(s->avctx, AV_LOG_ERROR, "mjpeg: error decoding EXIF data\n");
+            return ret;
+        }
+
+        bytes_read = bytestream2_tell(&gbytes);
+        skip_bits(&s->gb, bytes_read << 3);
+        len -= bytes_read;
+
+        goto out;
+    }
 
     /* Apple MJPEG-A */
     if ((s->start_code == APP1) && (len > (0x28 - 8))) {
@@ -1501,12 +1583,14 @@
                 av_log(s->avctx, AV_LOG_INFO, "comment: '%s'\n", cbuf);
 
             /* buggy avid, it puts EOI only at every 10th frame */
-            if (!strcmp(cbuf, "AVID")) {
+            if (!strncmp(cbuf, "AVID", 4)) {
                 s->buggy_avid = 1;
+                if (len > 14 && cbuf[12] == 1) /* 1 - NTSC, 2 - PAL */
+                    s->interlace_polarity = 1;
             } else if (!strcmp(cbuf, "CS=ITU601"))
                 s->cs_itu601 = 1;
-            else if ((len > 31 && !strncmp(cbuf, "Intel(R) JPEG Library, version 1", 32)) ||
-                     (len > 19 && !strncmp(cbuf, "Metasoft MJPEG Codec", 20)))
+            else if ((!strncmp(cbuf, "Intel(R) JPEG Library, version 1", 32)) ||
+                     (!strncmp(cbuf, "Metasoft MJPEG Codec", 20)))
                 s->flipped = 1;
 
             av_free(cbuf);
@@ -1644,6 +1728,8 @@
     int i, index;
     int ret = 0;
 
+    av_dict_free(&s->exif_metadata);
+
     buf_ptr = buf;
     buf_end = buf + buf_size;
     while (buf_ptr < buf_end) {
@@ -1654,147 +1740,157 @@
         /* EOF */
         if (start_code < 0) {
             goto the_end;
-        } else if (unescaped_buf_size > (1U<<28)) {
-            av_log(avctx, AV_LOG_ERROR, "MJPEG packet 0x%x too big (0x%x/0x%x), corrupt data?\n",
+        } else if (unescaped_buf_size > INT_MAX / 8) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "MJPEG packet 0x%x too big (%d/%d), corrupt data?\n",
                    start_code, unescaped_buf_size, buf_size);
             return AVERROR_INVALIDDATA;
-        } else {
-            av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%td\n",
-                   start_code, buf_end - buf_ptr);
-            if ((ret = init_get_bits8(&s->gb, unescaped_buf_ptr, unescaped_buf_size)) < 0) {
-                av_log(avctx, AV_LOG_ERROR, "invalid buffer\n");
+        }
+        av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%td\n",
+               start_code, buf_end - buf_ptr);
+
+        ret = init_get_bits8(&s->gb, unescaped_buf_ptr, unescaped_buf_size);
+
+        if (ret < 0) {
+            av_log(avctx, AV_LOG_ERROR, "invalid buffer\n");
+            goto fail;
+        }
+
+        s->start_code = start_code;
+        if (s->avctx->debug & FF_DEBUG_STARTCODE)
+            av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code);
+
+        /* process markers */
+        if (start_code >= 0xd0 && start_code <= 0xd7)
+            av_log(avctx, AV_LOG_DEBUG,
+                   "restart marker: %d\n", start_code & 0x0f);
+            /* APP fields */
+        else if (start_code >= APP0 && start_code <= APP15)
+            mjpeg_decode_app(s);
+            /* Comment */
+        else if (start_code == COM)
+            mjpeg_decode_com(s);
+
+        ret = -1;
+
+        if (!CONFIG_JPEGLS_DECODER &&
+            (start_code == SOF48 || start_code == LSE)) {
+            av_log(avctx, AV_LOG_ERROR, "JPEG-LS support not enabled.\n");
+            return AVERROR(ENOSYS);
+        }
+
+        switch (start_code) {
+        case SOI:
+            s->restart_interval = 0;
+            s->restart_count    = 0;
+            /* nothing to do on SOI */
+            break;
+        case DQT:
+            ff_mjpeg_decode_dqt(s);
+            break;
+        case DHT:
+            if ((ret = ff_mjpeg_decode_dht(s)) < 0) {
+                av_log(avctx, AV_LOG_ERROR, "huffman table decode error\n");
                 goto fail;
             }
-
-            s->start_code = start_code;
-            if (s->avctx->debug & FF_DEBUG_STARTCODE)
-                av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code);
-
-            /* process markers */
-            if (start_code >= 0xd0 && start_code <= 0xd7)
-                av_log(avctx, AV_LOG_DEBUG,
-                       "restart marker: %d\n", start_code & 0x0f);
-                /* APP fields */
-            else if (start_code >= APP0 && start_code <= APP15)
-                mjpeg_decode_app(s);
-                /* Comment */
-            else if (start_code == COM)
-                mjpeg_decode_com(s);
-
-            ret = -1;
-            switch (start_code) {
-            case SOI:
-                s->restart_interval = 0;
-                s->restart_count    = 0;
-                /* nothing to do on SOI */
-                break;
-            case DQT:
-                ff_mjpeg_decode_dqt(s);
-                break;
-            case DHT:
-                if ((ret = ff_mjpeg_decode_dht(s)) < 0) {
-                    av_log(avctx, AV_LOG_ERROR, "huffman table decode error\n");
-                    goto fail;
-                }
-                break;
-            case SOF0:
-            case SOF1:
-                s->lossless    = 0;
-                s->ls          = 0;
-                s->progressive = 0;
-                if ((ret = ff_mjpeg_decode_sof(s)) < 0)
-                    goto fail;
-                break;
-            case SOF2:
-                s->lossless    = 0;
-                s->ls          = 0;
-                s->progressive = 1;
-                if ((ret = ff_mjpeg_decode_sof(s)) < 0)
-                    goto fail;
-                break;
-            case SOF3:
-                s->lossless    = 1;
-                s->ls          = 0;
-                s->progressive = 0;
-                if ((ret = ff_mjpeg_decode_sof(s)) < 0)
-                    goto fail;
-                break;
-            case SOF48:
-                s->lossless    = 1;
-                s->ls          = 1;
-                s->progressive = 0;
-                if ((ret = ff_mjpeg_decode_sof(s)) < 0)
-                    goto fail;
-                break;
-            case LSE:
-                if (!CONFIG_JPEGLS_DECODER ||
-                    (ret = ff_jpegls_decode_lse(s)) < 0)
-                    goto fail;
-                break;
-            case EOI:
+            break;
+        case SOF0:
+        case SOF1:
+            s->lossless    = 0;
+            s->ls          = 0;
+            s->progressive = 0;
+            if ((ret = ff_mjpeg_decode_sof(s)) < 0)
+                goto fail;
+            break;
+        case SOF2:
+            s->lossless    = 0;
+            s->ls          = 0;
+            s->progressive = 1;
+            if ((ret = ff_mjpeg_decode_sof(s)) < 0)
+                goto fail;
+            break;
+        case SOF3:
+            s->lossless    = 1;
+            s->ls          = 0;
+            s->progressive = 0;
+            if ((ret = ff_mjpeg_decode_sof(s)) < 0)
+                goto fail;
+            break;
+        case SOF48:
+            s->lossless    = 1;
+            s->ls          = 1;
+            s->progressive = 0;
+            if ((ret = ff_mjpeg_decode_sof(s)) < 0)
+                goto fail;
+            break;
+        case LSE:
+            if (!CONFIG_JPEGLS_DECODER ||
+                (ret = ff_jpegls_decode_lse(s)) < 0)
+                goto fail;
+            break;
+        case EOI:
 eoi_parser:
-                s->cur_scan = 0;
-                if (!s->got_picture) {
-                    av_log(avctx, AV_LOG_WARNING,
-                           "Found EOI before any SOF, ignoring\n");
-                    break;
-                }
-                if (s->interlaced) {
-                    s->bottom_field ^= 1;
-                    /* if not bottom field, do not output image yet */
-                    if (s->bottom_field == !s->interlace_polarity)
-                        break;
-                }
-                if ((ret = av_frame_ref(data, s->picture_ptr)) < 0)
-                    return ret;
-                *got_frame = 1;
-                s->got_picture = 0;
-
-                if (!s->lossless) {
-                    int qp = FFMAX3(s->qscale[0],
-                                    s->qscale[1],
-                                    s->qscale[2]);
-                    int qpw = (s->width + 15) / 16;
-                    AVBufferRef *qp_table_buf = av_buffer_alloc(qpw);
-                    if (qp_table_buf) {
-                        memset(qp_table_buf->data, qp, qpw);
-                        av_frame_set_qp_table(data, qp_table_buf, 0, FF_QSCALE_TYPE_MPEG1);
-                    }
-
-                    if(avctx->debug & FF_DEBUG_QP)
-                        av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", qp);
-                }
-
-                goto the_end;
-            case SOS:
-                if ((ret = ff_mjpeg_decode_sos(s, NULL, NULL)) < 0 &&
-                    (avctx->err_recognition & AV_EF_EXPLODE))
-                    goto fail;
-                break;
-            case DRI:
-                mjpeg_decode_dri(s);
-                break;
-            case SOF5:
-            case SOF6:
-            case SOF7:
-            case SOF9:
-            case SOF10:
-            case SOF11:
-            case SOF13:
-            case SOF14:
-            case SOF15:
-            case JPG:
-                av_log(avctx, AV_LOG_ERROR,
-                       "mjpeg: unsupported coding type (%x)\n", start_code);
+            s->cur_scan = 0;
+            if (!s->got_picture) {
+                av_log(avctx, AV_LOG_WARNING,
+                       "Found EOI before any SOF, ignoring\n");
                 break;
             }
+            if (s->interlaced) {
+                s->bottom_field ^= 1;
+                /* if not bottom field, do not output image yet */
+                if (s->bottom_field == !s->interlace_polarity)
+                    break;
+            }
+            if ((ret = av_frame_ref(data, s->picture_ptr)) < 0)
+                return ret;
+            *got_frame = 1;
+            s->got_picture = 0;
 
-            /* eof process start code */
-            buf_ptr += (get_bits_count(&s->gb) + 7) / 8;
-            av_log(avctx, AV_LOG_DEBUG,
-                   "marker parser used %d bytes (%d bits)\n",
-                   (get_bits_count(&s->gb) + 7) / 8, get_bits_count(&s->gb));
+            if (!s->lossless) {
+                int qp = FFMAX3(s->qscale[0],
+                                s->qscale[1],
+                                s->qscale[2]);
+                int qpw = (s->width + 15) / 16;
+                AVBufferRef *qp_table_buf = av_buffer_alloc(qpw);
+                if (qp_table_buf) {
+                    memset(qp_table_buf->data, qp, qpw);
+                    av_frame_set_qp_table(data, qp_table_buf, 0, FF_QSCALE_TYPE_MPEG1);
+                }
+
+                if(avctx->debug & FF_DEBUG_QP)
+                    av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", qp);
+            }
+
+            goto the_end;
+        case SOS:
+            if ((ret = ff_mjpeg_decode_sos(s, NULL, NULL)) < 0 &&
+                (avctx->err_recognition & AV_EF_EXPLODE))
+                goto fail;
+            break;
+        case DRI:
+            mjpeg_decode_dri(s);
+            break;
+        case SOF5:
+        case SOF6:
+        case SOF7:
+        case SOF9:
+        case SOF10:
+        case SOF11:
+        case SOF13:
+        case SOF14:
+        case SOF15:
+        case JPG:
+            av_log(avctx, AV_LOG_ERROR,
+                   "mjpeg: unsupported coding type (%x)\n", start_code);
+            break;
         }
+
+        /* eof process start code */
+        buf_ptr += (get_bits_count(&s->gb) + 7) / 8;
+        av_log(avctx, AV_LOG_DEBUG,
+               "marker parser used %d bytes (%d bits)\n",
+               (get_bits_count(&s->gb) + 7) / 8, get_bits_count(&s->gb));
     }
     if (s->got_picture) {
         av_log(avctx, AV_LOG_WARNING, "EOI missing, emulating\n");
@@ -1847,8 +1943,8 @@
             int w = s->width;
             int h = s->height;
             if(index && index<3){
-                w = -((-w) >> hshift);
-                h = -((-h) >> vshift);
+                w = FF_CEIL_RSHIFT(w, hshift);
+                h = FF_CEIL_RSHIFT(h, vshift);
             }
             if(dst){
                 uint8_t *dst2 = dst + s->linesize[index]*(h-1);
@@ -1862,6 +1958,9 @@
         }
     }
 
+    av_dict_copy(avpriv_frame_get_metadatap(data), s->exif_metadata, 0);
+    av_dict_free(&s->exif_metadata);
+
     av_log(avctx, AV_LOG_DEBUG, "decode frame unused %td bytes\n",
            buf_end - buf_ptr);
 //  return buf_end - buf_ptr;
@@ -1873,6 +1972,10 @@
     MJpegDecodeContext *s = avctx->priv_data;
     int i, j;
 
+    if (s->interlaced && s->bottom_field == !s->interlace_polarity && s->got_picture && !avctx->frame_number) {
+        av_log(avctx, AV_LOG_INFO, "Single field\n");
+    }
+
     if (s->picture_ptr)
         av_frame_unref(s->picture_ptr);
 
@@ -1888,6 +1991,7 @@
         av_freep(&s->blocks[i]);
         av_freep(&s->last_nnz[i]);
     }
+    av_dict_free(&s->exif_metadata);
     return 0;
 }
 
diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h
index 17665e4..fa69d50 100644
--- a/libavcodec/mjpegdec.h
+++ b/libavcodec/mjpegdec.h
@@ -65,6 +65,8 @@
     int rct;            /* standard rct */
     int pegasus_rct;    /* pegasus reversible colorspace transform */
     int bits;           /* bits per component */
+    int colr;
+    int xfrm;
 
     int maxval;
     int near;         ///< near lossless bound (si 0 for lossless)
@@ -84,6 +86,7 @@
     int nb_blocks[MAX_COMPONENTS];
     int h_scount[MAX_COMPONENTS];
     int v_scount[MAX_COMPONENTS];
+    int quant_sindex[MAX_COMPONENTS];
     int h_max, v_max; /* maximum h and v counts */
     int quant_index[4];   /* quant table index for each component */
     int last_dc[MAX_COMPONENTS]; /* last DEQUANTIZED dc (XXX: am I right to do that ?) */
@@ -116,6 +119,7 @@
     unsigned int ljpeg_buffer_size;
 
     int extern_huff;
+    AVDictionary *exif_metadata;
 } MJpegDecodeContext;
 
 int ff_mjpeg_decode_init(AVCodecContext *avctx);
diff --git a/libavcodec/mlp_parser.c b/libavcodec/mlp_parser.c
index 2cc4b91..fcd1168 100644
--- a/libavcodec/mlp_parser.c
+++ b/libavcodec/mlp_parser.c
@@ -28,6 +28,7 @@
 
 #include "libavutil/channel_layout.h"
 #include "libavutil/crc.h"
+#include "libavutil/internal.h"
 #include "get_bits.h"
 #include "parser.h"
 #include "mlp_parser.h"
@@ -331,10 +332,12 @@
         if (mh.stream_type == 0xbb) {
             /* MLP stream */
 #if FF_API_REQUEST_CHANNELS
+FF_DISABLE_DEPRECATION_WARNINGS
             if (avctx->request_channels > 0 && avctx->request_channels <= 2 &&
                 mh.num_substreams > 1) {
                 avctx->channels       = 2;
                 avctx->channel_layout = AV_CH_LAYOUT_STEREO;
+FF_ENABLE_DEPRECATION_WARNINGS
             } else
 #endif
             if (avctx->request_channel_layout == AV_CH_LAYOUT_STEREO &&
@@ -348,6 +351,7 @@
         } else { /* mh.stream_type == 0xba */
             /* TrueHD stream */
 #if FF_API_REQUEST_CHANNELS
+FF_DISABLE_DEPRECATION_WARNINGS
             if (avctx->request_channels > 0 && avctx->request_channels <= 2 &&
                 mh.num_substreams > 1) {
                 avctx->channels       = 2;
@@ -356,6 +360,7 @@
                        avctx->request_channels <= mh.channels_thd_stream1) {
                 avctx->channels       = mh.channels_thd_stream1;
                 avctx->channel_layout = mh.channel_layout_thd_stream1;
+FF_ENABLE_DEPRECATION_WARNINGS
             } else
 #endif
             if (avctx->request_channel_layout == AV_CH_LAYOUT_STEREO &&
diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c
index a4d5378..059e4d0 100644
--- a/libavcodec/mlpdec.c
+++ b/libavcodec/mlpdec.c
@@ -27,6 +27,7 @@
 #include <stdint.h>
 
 #include "avcodec.h"
+#include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/channel_layout.h"
 #include "get_bits.h"
@@ -401,10 +402,10 @@
     uint8_t checksum;
     uint8_t lossless_check;
     int start_count = get_bits_count(gbp);
-    const int max_matrix_channel = m->avctx->codec_id == AV_CODEC_ID_MLP
-                                 ? MAX_MATRIX_CHANNEL_MLP
-                                 : MAX_MATRIX_CHANNEL_TRUEHD;
-    int max_channel, min_channel, matrix_channel;
+    int min_channel, max_channel, max_matrix_channel;
+    const int std_max_matrix_channel = m->avctx->codec_id == AV_CODEC_ID_MLP
+                                     ? MAX_MATRIX_CHANNEL_MLP
+                                     : MAX_MATRIX_CHANNEL_TRUEHD;
 
     sync_word = get_bits(gbp, 13);
 
@@ -423,18 +424,18 @@
 
     skip_bits(gbp, 16); /* Output timestamp */
 
-    min_channel    = get_bits(gbp, 4);
-    max_channel    = get_bits(gbp, 4);
-    matrix_channel = get_bits(gbp, 4);
+    min_channel        = get_bits(gbp, 4);
+    max_channel        = get_bits(gbp, 4);
+    max_matrix_channel = get_bits(gbp, 4);
 
-    if (matrix_channel > max_matrix_channel) {
+    if (max_matrix_channel > std_max_matrix_channel) {
         av_log(m->avctx, AV_LOG_ERROR,
                "Max matrix channel cannot be greater than %d.\n",
-               max_matrix_channel);
+               std_max_matrix_channel);
         return AVERROR_INVALIDDATA;
     }
 
-    if (max_channel != matrix_channel) {
+    if (max_channel != max_matrix_channel) {
         av_log(m->avctx, AV_LOG_ERROR,
                "Max channel must be equal max matrix channel.\n");
         return AVERROR_INVALIDDATA;
@@ -456,11 +457,12 @@
         return AVERROR_INVALIDDATA;
     }
 
-    s->min_channel = min_channel;
-    s->max_channel = max_channel;
-    s->max_matrix_channel = matrix_channel;
+    s->min_channel        = min_channel;
+    s->max_channel        = max_channel;
+    s->max_matrix_channel = max_matrix_channel;
 
 #if FF_API_REQUEST_CHANNELS
+FF_DISABLE_DEPRECATION_WARNINGS
     if (m->avctx->request_channels > 0 &&
         m->avctx->request_channels <= s->max_channel + 1 &&
         m->max_decoded_substream > substr) {
@@ -469,6 +471,7 @@
                "Further substreams will be skipped.\n",
                s->max_channel + 1, substr);
         m->max_decoded_substream = substr;
+FF_ENABLE_DEPRECATION_WARNINGS
     } else
 #endif
     if (m->avctx->request_channel_layout == s->ch_layout &&
diff --git a/libavcodec/mlpdsp.c b/libavcodec/mlpdsp.c
index 9a376e2..b413e86 100644
--- a/libavcodec/mlpdsp.c
+++ b/libavcodec/mlpdsp.c
@@ -20,13 +20,14 @@
  */
 
 #include "config.h"
+#include "libavutil/attributes.h"
 #include "mlpdsp.h"
 #include "mlp.h"
 
-static void ff_mlp_filter_channel(int32_t *state, const int32_t *coeff,
-                                  int firorder, int iirorder,
-                                  unsigned int filter_shift, int32_t mask, int blocksize,
-                                  int32_t *sample_buffer)
+static void mlp_filter_channel(int32_t *state, const int32_t *coeff,
+                               int firorder, int iirorder,
+                               unsigned int filter_shift, int32_t mask,
+                               int blocksize, int32_t *sample_buffer)
 {
     int32_t *firbuf = state;
     int32_t *iirbuf = state + MAX_BLOCKSIZE + MAX_FIR_ORDER;
@@ -56,9 +57,9 @@
     }
 }
 
-void ff_mlpdsp_init(MLPDSPContext *c)
+av_cold void ff_mlpdsp_init(MLPDSPContext *c)
 {
-    c->mlp_filter_channel = ff_mlp_filter_channel;
+    c->mlp_filter_channel = mlp_filter_channel;
     if (ARCH_X86)
         ff_mlpdsp_init_x86(c);
 }
diff --git a/libavcodec/mmvideo.c b/libavcodec/mmvideo.c
index bf47f65..292ebe6 100644
--- a/libavcodec/mmvideo.c
+++ b/libavcodec/mmvideo.c
@@ -104,6 +104,9 @@
         if (half_horiz)
             run_length *=2;
 
+        if (run_length > s->avctx->width - x)
+            return AVERROR_INVALIDDATA;
+
         if (color) {
             memset(s->frame.data[0] + y*s->frame.linesize[0] + x, color, run_length);
             if (half_vert)
@@ -151,6 +154,8 @@
             int replace_array = bytestream2_get_byte(&s->gb);
             for(j=0; j<8; j++) {
                 int replace = (replace_array >> (7-j)) & 1;
+                if (x + half_horiz >= s->avctx->width)
+                    return AVERROR_INVALIDDATA;
                 if (replace) {
                     int color = bytestream2_get_byte(&data_ptr);
                     s->frame.data[0][y*s->frame.linesize[0] + x] = color;
diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index 9c36ab6..f4d217b 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -1123,8 +1123,8 @@
     return dmin;
 }
 
-static int ff_estimate_motion_b(MpegEncContext * s,
-                       int mb_x, int mb_y, int16_t (*mv_table)[2], int ref_index, int f_code)
+static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y,
+                             int16_t (*mv_table)[2], int ref_index, int f_code)
 {
     MotionEstContext * const c= &s->me;
     int mx, my, dmin;
@@ -1541,10 +1541,12 @@
         dmin= INT_MAX;
 //FIXME penalty stuff for non mpeg4
     c->skip=0;
-    fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->f_code) + 3*penalty_factor;
+    fmin = estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->f_code) +
+           3 * penalty_factor;
 
     c->skip=0;
-    bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code) + 2*penalty_factor;
+    bmin = estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code) +
+           2 * penalty_factor;
     av_dlog(s, " %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]);
 
     c->skip=0;
diff --git a/libavcodec/mpc.c b/libavcodec/mpc.c
index 3bd2d35..7af30bd 100644
--- a/libavcodec/mpc.c
+++ b/libavcodec/mpc.c
@@ -26,6 +26,7 @@
  * divided into 32 subbands.
  */
 
+#include "libavutil/attributes.h"
 #include "avcodec.h"
 #include "get_bits.h"
 #include "mpegaudiodsp.h"
@@ -34,7 +35,7 @@
 #include "mpc.h"
 #include "mpcdata.h"
 
-void ff_mpc_init(void)
+av_cold void ff_mpc_init(void)
 {
     ff_mpa_synth_init_fixed(ff_mpa_synth_window_fixed);
 }
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index ecb67ed..383d5c2 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -25,7 +25,7 @@
  * MPEG-1/2 decoder
  */
 
-//#define DEBUG
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "libavutil/timecode.h"
 
@@ -36,15 +36,37 @@
 #include "error_resilience.h"
 #include "mpeg12.h"
 #include "mpeg12data.h"
-#include "mpeg12decdata.h"
 #include "bytestream.h"
 #include "vdpau_internal.h"
 #include "xvmc_internal.h"
 #include "thread.h"
 
-
 uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
 
+static const uint8_t table_mb_ptype[7][2] = {
+    { 3, 5 }, // 0x01 MB_INTRA
+    { 1, 2 }, // 0x02 MB_PAT
+    { 1, 3 }, // 0x08 MB_FOR
+    { 1, 1 }, // 0x0A MB_FOR|MB_PAT
+    { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA
+    { 1, 5 }, // 0x12 MB_QUANT|MB_PAT
+    { 2, 5 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT
+};
+
+static const uint8_t table_mb_btype[11][2] = {
+    { 3, 5 }, // 0x01 MB_INTRA
+    { 2, 3 }, // 0x04 MB_BACK
+    { 3, 3 }, // 0x06 MB_BACK|MB_PAT
+    { 2, 4 }, // 0x08 MB_FOR
+    { 3, 4 }, // 0x0A MB_FOR|MB_PAT
+    { 2, 2 }, // 0x0C MB_FOR|MB_BACK
+    { 3, 2 }, // 0x0E MB_FOR|MB_BACK|MB_PAT
+    { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA
+    { 2, 6 }, // 0x16 MB_QUANT|MB_BACK|MB_PAT
+    { 3, 6 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT
+    { 2, 5 }, // 0x1E MB_QUANT|MB_FOR|MB_BACK|MB_PAT
+};
+
 #define INIT_2D_VLC_RL(rl, static_size)\
 {\
     static RL_VLC_ELEM rl_vlc_table[static_size];\
@@ -56,7 +78,7 @@
     init_2d_vlc_rl(&rl);\
 }
 
-static void init_2d_vlc_rl(RLTable *rl)
+static av_cold void init_2d_vlc_rl(RLTable *rl)
 {
     int i;
 
@@ -89,7 +111,7 @@
     }
 }
 
-void ff_mpeg12_common_init(MpegEncContext *s)
+av_cold void ff_mpeg12_common_init(MpegEncContext *s)
 {
 
     s->y_dc_scale_table =
diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index e969893..3df8bf7 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -25,7 +25,7 @@
  * MPEG-1/2 decoder
  */
 
-//#define DEBUG
+#include "libavutil/attributes.h"
 #include "libavutil/internal.h"
 #include "internal.h"
 #include "avcodec.h"
@@ -34,7 +34,6 @@
 #include "error_resilience.h"
 #include "mpeg12.h"
 #include "mpeg12data.h"
-#include "mpeg12decdata.h"
 #include "bytestream.h"
 #include "vdpau_internal.h"
 #include "xvmc_internal.h"
@@ -55,6 +54,39 @@
     int extradata_decoded;
 } Mpeg1Context;
 
+#define MB_TYPE_ZERO_MV   0x20000000
+
+static const uint32_t ptype2mb_type[7] = {
+                    MB_TYPE_INTRA,
+                    MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
+                    MB_TYPE_L0,
+                    MB_TYPE_L0 | MB_TYPE_CBP,
+    MB_TYPE_QUANT | MB_TYPE_INTRA,
+    MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
+    MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP,
+};
+
+static const uint32_t btype2mb_type[11] = {
+                    MB_TYPE_INTRA,
+                    MB_TYPE_L1,
+                    MB_TYPE_L1   | MB_TYPE_CBP,
+                    MB_TYPE_L0,
+                    MB_TYPE_L0   | MB_TYPE_CBP,
+                    MB_TYPE_L0L1,
+                    MB_TYPE_L0L1 | MB_TYPE_CBP,
+    MB_TYPE_QUANT | MB_TYPE_INTRA,
+    MB_TYPE_QUANT | MB_TYPE_L1   | MB_TYPE_CBP,
+    MB_TYPE_QUANT | MB_TYPE_L0   | MB_TYPE_CBP,
+    MB_TYPE_QUANT | MB_TYPE_L0L1 | MB_TYPE_CBP,
+};
+
+static const uint8_t non_linear_qscale[32] = {
+    0, 1, 2, 3, 4, 5, 6, 7,
+    8,10,12,14,16,18,20,22,
+    24,28,32,36,40,44,48,52,
+    56,64,72,80,88,96,104,112,
+};
+
 /* as H.263, but only 17 codes */
 static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred)
 {
@@ -672,8 +704,6 @@
             s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride] =
                 mb_type | MB_TYPE_SKIP;
 
-//            assert(s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1] & (MB_TYPE_16x16 | MB_TYPE_16x8));
-
             if ((s->mv[0][0][0] | s->mv[0][0][1] | s->mv[1][0][0] | s->mv[1][0][1]) == 0)
                 s->mb_skipped = 1;
         }
@@ -1098,6 +1128,7 @@
 #endif
 #if CONFIG_MPEG1_VDPAU_HWACCEL
     AV_PIX_FMT_VDPAU_MPEG1,
+    AV_PIX_FMT_VDPAU,
 #endif
     AV_PIX_FMT_YUV420P,
     AV_PIX_FMT_NONE
@@ -1110,6 +1141,7 @@
 #endif
 #if CONFIG_MPEG2_VDPAU_HWACCEL
     AV_PIX_FMT_VDPAU_MPEG2,
+    AV_PIX_FMT_VDPAU,
 #endif
 #if CONFIG_MPEG2_DXVA2_HWACCEL
     AV_PIX_FMT_DXVA2_VLD,
@@ -1170,7 +1202,7 @@
         s1->save_width           != s->width                ||
         s1->save_height          != s->height               ||
         s1->save_aspect_info     != s->aspect_ratio_info    ||
-        s1->save_progressive_seq != s->progressive_sequence ||
+        (s1->save_progressive_seq != s->progressive_sequence && (s->height&31)) ||
         0)
     {
 
@@ -1345,8 +1377,8 @@
     s->codec_id      = s->avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO;
 
     if (s->avctx->debug & FF_DEBUG_PICT_INFO)
-        av_log(s->avctx, AV_LOG_DEBUG, "profile: %d, level: %d vbv buffer: %d, bitrate:%d\n",
-               s->avctx->profile, s->avctx->level, s->avctx->rc_buffer_size, s->bit_rate);
+        av_log(s->avctx, AV_LOG_DEBUG, "profile: %d, level: %d ps: %d cf:%d vbv buffer: %d, bitrate:%d\n",
+               s->avctx->profile, s->avctx->level, s->progressive_sequence, s->chroma_format, s->avctx->rc_buffer_size, s->bit_rate);
 
 }
 
@@ -2119,7 +2151,7 @@
     const uint8_t *buf_ptr = buf;
     const uint8_t *buf_end = buf + buf_size;
     int ret, input_size;
-    int last_code = 0;
+    int last_code = 0, skip_frame = 0;
     int picture_start_code_seen = 0;
 
     for (;;) {
@@ -2127,8 +2159,9 @@
         uint32_t start_code = -1;
         buf_ptr = avpriv_find_start_code(buf_ptr, buf_end, &start_code);
         if (start_code > 0x1ff) {
-            if (s2->pict_type != AV_PICTURE_TYPE_B || avctx->skip_frame <= AVDISCARD_DEFAULT) {
-                if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE)) {
+            if (!skip_frame) {
+                if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) &&
+                    !avctx->hwaccel) {
                     int i;
                     av_assert0(avctx->thread_count > 1);
 
@@ -2192,7 +2225,8 @@
                 s2->intra_dc_precision= 3;
                 s2->intra_matrix[0]= 1;
             }
-            if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) && s->slice_count) {
+            if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) &&
+                !avctx->hwaccel && s->slice_count) {
                 int i;
 
                 avctx->execute(avctx, slice_decode_thread,
@@ -2306,6 +2340,11 @@
                 if (s2->picture_structure == PICT_BOTTOM_FIELD)
                     mb_y++;
 
+                if (buf_end - buf_ptr < 2) {
+                    av_log(s2->avctx, AV_LOG_ERROR, "slice too small\n");
+                    return AVERROR_INVALIDDATA;
+                }
+
                 if (mb_y >= s2->mb_height) {
                     av_log(s2->avctx, AV_LOG_ERROR, "slice below image (%d >= %d)\n", mb_y, s2->mb_height);
                     return -1;
@@ -2314,20 +2353,27 @@
                 if (s2->last_picture_ptr == NULL) {
                 /* Skip B-frames if we do not have reference frames and gop is not closed */
                     if (s2->pict_type == AV_PICTURE_TYPE_B) {
-                        if (!s2->closed_gop)
+                        if (!s2->closed_gop) {
+                            skip_frame = 1;
                             break;
+                        }
                     }
                 }
                 if (s2->pict_type == AV_PICTURE_TYPE_I || (s2->flags2 & CODEC_FLAG2_SHOW_ALL))
                     s->sync=1;
                 if (s2->next_picture_ptr == NULL) {
                 /* Skip P-frames if we do not have a reference frame or we have an invalid header. */
-                    if (s2->pict_type == AV_PICTURE_TYPE_P && !s->sync) break;
+                    if (s2->pict_type == AV_PICTURE_TYPE_P && !s->sync) {
+                        skip_frame = 1;
+                        break;
+                    }
                 }
                 if ((avctx->skip_frame >= AVDISCARD_NONREF && s2->pict_type == AV_PICTURE_TYPE_B) ||
                     (avctx->skip_frame >= AVDISCARD_NONKEY && s2->pict_type != AV_PICTURE_TYPE_I) ||
-                     avctx->skip_frame >= AVDISCARD_ALL)
+                     avctx->skip_frame >= AVDISCARD_ALL) {
+                    skip_frame = 1;
                     break;
+                }
 
                 if (!s->mpeg_enc_ctx_allocated)
                     break;
@@ -2345,6 +2391,7 @@
                 }
 
                 if (s2->first_slice) {
+                    skip_frame = 0;
                     s2->first_slice = 0;
                     if (mpeg_field_start(s2, buf, buf_size) < 0)
                         return -1;
@@ -2359,7 +2406,8 @@
                     break;
                 }
 
-                if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE)) {
+                if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) &&
+                    !avctx->hwaccel) {
                     int threshold = (s2->mb_height * s->slice_count +
                                      s2->slice_context_count / 2) /
                                     s2->slice_context_count;
@@ -2470,7 +2518,7 @@
     ff_mpeg_flush(avctx);
 }
 
-static int mpeg_decode_end(AVCodecContext *avctx)
+static av_cold int mpeg_decode_end(AVCodecContext *avctx)
 {
     Mpeg1Context *s = avctx->priv_data;
 
diff --git a/libavcodec/mpeg12decdata.h b/libavcodec/mpeg12decdata.h
deleted file mode 100644
index 66ca5c4..0000000
--- a/libavcodec/mpeg12decdata.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * MPEG1/2 decoder tables
- * copyright (c) 2000,2001 Fabrice Bellard
- * copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
- *
- * 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
- */
-
-/**
- * @file
- * MPEG1/2 decoder tables.
- */
-
-#ifndef AVCODEC_MPEG12DECDATA_H
-#define AVCODEC_MPEG12DECDATA_H
-
-#include <stdint.h>
-#include "mpegvideo.h"
-
-
-#define MB_TYPE_ZERO_MV   0x20000000
-#define IS_ZERO_MV(a)   ((a)&MB_TYPE_ZERO_MV)
-
-static const uint8_t table_mb_ptype[7][2] = {
-    { 3, 5 }, // 0x01 MB_INTRA
-    { 1, 2 }, // 0x02 MB_PAT
-    { 1, 3 }, // 0x08 MB_FOR
-    { 1, 1 }, // 0x0A MB_FOR|MB_PAT
-    { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA
-    { 1, 5 }, // 0x12 MB_QUANT|MB_PAT
-    { 2, 5 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT
-};
-
-static const uint32_t ptype2mb_type[7] = {
-                    MB_TYPE_INTRA,
-                    MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
-                    MB_TYPE_L0,
-                    MB_TYPE_L0 | MB_TYPE_CBP,
-    MB_TYPE_QUANT | MB_TYPE_INTRA,
-    MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
-    MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP,
-};
-
-static const uint8_t table_mb_btype[11][2] = {
-    { 3, 5 }, // 0x01 MB_INTRA
-    { 2, 3 }, // 0x04 MB_BACK
-    { 3, 3 }, // 0x06 MB_BACK|MB_PAT
-    { 2, 4 }, // 0x08 MB_FOR
-    { 3, 4 }, // 0x0A MB_FOR|MB_PAT
-    { 2, 2 }, // 0x0C MB_FOR|MB_BACK
-    { 3, 2 }, // 0x0E MB_FOR|MB_BACK|MB_PAT
-    { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA
-    { 2, 6 }, // 0x16 MB_QUANT|MB_BACK|MB_PAT
-    { 3, 6 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT
-    { 2, 5 }, // 0x1E MB_QUANT|MB_FOR|MB_BACK|MB_PAT
-};
-
-static const uint32_t btype2mb_type[11] = {
-                    MB_TYPE_INTRA,
-                    MB_TYPE_L1,
-                    MB_TYPE_L1   | MB_TYPE_CBP,
-                    MB_TYPE_L0,
-                    MB_TYPE_L0   | MB_TYPE_CBP,
-                    MB_TYPE_L0L1,
-                    MB_TYPE_L0L1 | MB_TYPE_CBP,
-    MB_TYPE_QUANT | MB_TYPE_INTRA,
-    MB_TYPE_QUANT | MB_TYPE_L1   | MB_TYPE_CBP,
-    MB_TYPE_QUANT | MB_TYPE_L0   | MB_TYPE_CBP,
-    MB_TYPE_QUANT | MB_TYPE_L0L1 | MB_TYPE_CBP,
-};
-
-static const uint8_t non_linear_qscale[32] = {
-    0, 1, 2, 3, 4, 5, 6, 7,
-    8,10,12,14,16,18,20,22,
-    24,28,32,36,40,44,48,52,
-    56,64,72,80,88,96,104,112,
-};
-
-#endif /* AVCODEC_MPEG12DECDATA_H */
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index c8e7b45..7b7dd47 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -32,6 +32,8 @@
 #include "mpeg12.h"
 #include "mpeg12data.h"
 #include "bytestream.h"
+
+#include "libavutil/attributes.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
 #include "libavutil/avassert.h"
@@ -68,7 +70,8 @@
 static uint8_t mpeg1_index_run[2][64];
 static int8_t mpeg1_max_level[2][64];
 
-static void init_uni_ac_vlc(RLTable *rl, uint8_t *uni_ac_vlc_len){
+static av_cold void init_uni_ac_vlc(RLTable *rl, uint8_t *uni_ac_vlc_len)
+{
     int i;
 
     for(i=0; i<128; i++){
@@ -741,7 +744,7 @@
     }
 }
 
-void ff_mpeg1_encode_init(MpegEncContext *s)
+av_cold void ff_mpeg1_encode_init(MpegEncContext *s)
 {
     static int done=0;
 
diff --git a/libavcodec/mpeg4video.h b/libavcodec/mpeg4video.h
index 400ce4d..c4d23c9 100644
--- a/libavcodec/mpeg4video.h
+++ b/libavcodec/mpeg4video.h
@@ -63,6 +63,9 @@
 extern const uint8_t ff_mpeg4_DCtab_chrom[13][2];
 
 extern const uint16_t ff_mpeg4_intra_vlc[103][2];
+extern const int8_t ff_mpeg4_intra_level[102];
+extern const int8_t ff_mpeg4_intra_run[102];
+
 extern RLTable ff_mpeg4_rl_intra;
 
 /* Note this is identical to the intra rvlc except that it is reordered. */
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 342707b..5387ca6 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -354,6 +354,17 @@
     return 0;
 }
 
+static int decode_new_pred(MpegEncContext *s, GetBitContext *gb){
+    int len = FFMIN(s->time_increment_bits + 3, 15);
+
+    get_bits(gb, len);
+    if (get_bits1(gb))
+        get_bits(gb, len);
+    check_marker(gb, "after new_pred");
+
+    return 0;
+}
+
 /**
  * Decode the next video packet.
  * @return <0 if something went wrong
@@ -436,7 +447,8 @@
             }
         }
     }
-    //FIXME new-pred stuff
+    if (s->new_pred)
+        decode_new_pred(s, &s->gb);
 
     return 0;
 }
@@ -1624,11 +1636,11 @@
 
     if (s->shape != BIN_ONLY_SHAPE) {
         if (s->shape == RECT_SHAPE) {
-            skip_bits1(gb);   /* marker */
+            check_marker(gb, "before width");
             width = get_bits(gb, 13);
-            skip_bits1(gb);   /* marker */
+            check_marker(gb, "before height");
             height = get_bits(gb, 13);
-            skip_bits1(gb);   /* marker */
+            check_marker(gb, "after height");
             if(width && height && !(s->width && s->codec_tag == AV_RL32("MP4S"))){ /* they should be non zero but who knows ... */
                 if (s->width && s->height &&
                     (s->width != width || s->height != height))
@@ -2022,6 +2034,9 @@
             av_log(s->avctx, AV_LOG_ERROR, "vop not coded\n");
         return FRAME_SKIPPED;
     }
+    if (s->new_pred)
+        decode_new_pred(s, gb);
+
     if (s->shape != BIN_ONLY_SHAPE && ( s->pict_type == AV_PICTURE_TYPE_P
                           || (s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE))) {
         /* rounding type for motion estimation */
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index 5662735..8454edd 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
 #include "mpegvideo.h"
@@ -1095,7 +1096,7 @@
 }
 
 
-static void init_uni_dc_tab(void)
+static av_cold void init_uni_dc_tab(void)
 {
     int level, uni_code, uni_len;
 
@@ -1147,7 +1148,9 @@
     }
 }
 
-static void init_uni_mpeg4_rl_tab(RLTable *rl, uint32_t *bits_tab, uint8_t *len_tab){
+static av_cold void init_uni_mpeg4_rl_tab(RLTable *rl, uint32_t *bits_tab,
+                                          uint8_t *len_tab)
+{
     int slevel, run, last;
 
     av_assert0(MAX_LEVEL >= 64);
diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c
index 4fffb6c..2834ba5 100644
--- a/libavcodec/mpegaudiodec.c
+++ b/libavcodec/mpegaudiodec.c
@@ -24,6 +24,7 @@
  * MPEG Audio decoder
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/float_dsp.h"
@@ -166,7 +167,7 @@
  * Convert region offsets to region sizes and truncate
  * size to big_values.
  */
-static void ff_region_offset2size(GranuleDef *g)
+static void region_offset2size(GranuleDef *g)
 {
     int i, k, j = 0;
     g->region_size[2] = 576 / 2;
@@ -177,7 +178,7 @@
     }
 }
 
-static void ff_init_short_region(MPADecodeContext *s, GranuleDef *g)
+static void init_short_region(MPADecodeContext *s, GranuleDef *g)
 {
     if (g->block_type == 2) {
         if (s->sample_rate_index != 8)
@@ -195,7 +196,8 @@
     g->region_size[1] = (576 / 2);
 }
 
-static void ff_init_long_region(MPADecodeContext *s, GranuleDef *g, int ra1, int ra2)
+static void init_long_region(MPADecodeContext *s, GranuleDef *g,
+                             int ra1, int ra2)
 {
     int l;
     g->region_size[0] = band_index_long[s->sample_rate_index][ra1 + 1] >> 1;
@@ -204,7 +206,7 @@
     g->region_size[1] = band_index_long[s->sample_rate_index][      l] >> 1;
 }
 
-static void ff_compute_band_indexes(MPADecodeContext *s, GranuleDef *g)
+static void compute_band_indexes(MPADecodeContext *s, GranuleDef *g)
 {
     if (g->block_type == 2) {
         if (g->switch_point) {
@@ -1372,7 +1374,7 @@
                     g->table_select[i] = get_bits(&s->gb, 5);
                 for (i = 0; i < 3; i++)
                     g->subblock_gain[i] = get_bits(&s->gb, 3);
-                ff_init_short_region(s, g);
+                init_short_region(s, g);
             } else {
                 int region_address1, region_address2;
                 g->block_type = 0;
@@ -1384,10 +1386,10 @@
                 region_address2 = get_bits(&s->gb, 3);
                 av_dlog(s->avctx, "region1=%d region2=%d\n",
                         region_address1, region_address2);
-                ff_init_long_region(s, g, region_address1, region_address2);
+                init_long_region(s, g, region_address1, region_address2);
             }
-            ff_region_offset2size(g);
-            ff_compute_band_indexes(s, g);
+            region_offset2size(g);
+            compute_band_indexes(s, g);
 
             g->preflag = 0;
             if (!s->lsf)
@@ -1845,7 +1847,7 @@
 }
 
 
-static int decode_init_mp3on4(AVCodecContext * avctx)
+static av_cold int decode_init_mp3on4(AVCodecContext * avctx)
 {
     MP3On4DecodeContext *s = avctx->priv_data;
     MPEG4AudioConfig cfg;
diff --git a/libavcodec/mpegaudiodecheader.c b/libavcodec/mpegaudiodecheader.c
index 7841b30..1772c2a 100644
--- a/libavcodec/mpegaudiodecheader.c
+++ b/libavcodec/mpegaudiodecheader.c
@@ -24,7 +24,6 @@
  * MPEG Audio header decoder.
  */
 
-//#define DEBUG
 #include "avcodec.h"
 #include "mpegaudio.h"
 #include "mpegaudiodata.h"
diff --git a/libavcodec/mpegaudiodsp.c b/libavcodec/mpegaudiodsp.c
index aadc747..ddb7428 100644
--- a/libavcodec/mpegaudiodsp.c
+++ b/libavcodec/mpegaudiodsp.c
@@ -19,11 +19,12 @@
  */
 
 #include "config.h"
+#include "libavutil/attributes.h"
 #include "mpegaudiodsp.h"
 #include "dct.h"
 #include "dct32.h"
 
-void ff_mpadsp_init(MPADSPContext *s)
+av_cold void ff_mpadsp_init(MPADSPContext *s)
 {
     DCTContext dct;
 
@@ -41,8 +42,8 @@
     s->imdct36_blocks_fixed = ff_imdct36_blocks_fixed;
 
     if (ARCH_ARM)     ff_mpadsp_init_arm(s);
+    if (ARCH_PPC)     ff_mpadsp_init_ppc(s);
     if (ARCH_X86)     ff_mpadsp_init_x86(s);
-    if (HAVE_ALTIVEC) ff_mpadsp_init_altivec(s);
     if (HAVE_MIPSFPU)   ff_mpadsp_init_mipsfpu(s);
     if (HAVE_MIPSDSPR1) ff_mpadsp_init_mipsdspr1(s);
 }
diff --git a/libavcodec/mpegaudiodsp.h b/libavcodec/mpegaudiodsp.h
index 623d2df..8153cb1 100644
--- a/libavcodec/mpegaudiodsp.h
+++ b/libavcodec/mpegaudiodsp.h
@@ -56,8 +56,8 @@
                                float *sb_samples);
 
 void ff_mpadsp_init_arm(MPADSPContext *s);
+void ff_mpadsp_init_ppc(MPADSPContext *s);
 void ff_mpadsp_init_x86(MPADSPContext *s);
-void ff_mpadsp_init_altivec(MPADSPContext *s);
 void ff_mpadsp_init_mipsfpu(MPADSPContext *s);
 void ff_mpadsp_init_mipsdspr1(MPADSPContext *s);
 
diff --git a/libavcodec/mpegaudiodsp_template.c b/libavcodec/mpegaudiodsp_template.c
index 03a740a..f79e068 100644
--- a/libavcodec/mpegaudiodsp_template.c
+++ b/libavcodec/mpegaudiodsp_template.c
@@ -20,6 +20,7 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/mem.h"
 #include "dct32.h"
 #include "mathops.h"
@@ -220,7 +221,7 @@
             window[512+128+16*i+j] = window[64*i+48-j];
 }
 
-void RENAME(ff_init_mpadsp_tabs)(void)
+av_cold void RENAME(ff_init_mpadsp_tabs)(void)
 {
     int i, j;
     /* compute mdct windows */
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 69b10bb..4b60900 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -27,6 +27,7 @@
  * The simplest mpeg encoder (well, it was the simplest!).
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
@@ -41,9 +42,6 @@
 #include "thread.h"
 #include <limits.h>
 
-//#undef NDEBUG
-//#include <assert.h>
-
 static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s,
                                    int16_t *block, int n, int qscale);
 static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s,
@@ -59,10 +57,6 @@
 static void dct_unquantize_h263_inter_c(MpegEncContext *s,
                                   int16_t *block, int n, int qscale);
 
-
-//#define DEBUG
-
-
 static const uint8_t ff_default_chroma_qscale_table[32] = {
 //   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15
      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
@@ -152,7 +146,8 @@
     s->dest[1] = s->current_picture.f.data[1] + (s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16 >> s->chroma_x_shift);
     s->dest[2] = s->current_picture.f.data[2] + (s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16 >> s->chroma_x_shift);
 
-    assert(ref == 0);
+    if (ref)
+        av_log(s->avctx, AV_LOG_DEBUG, "Interlaced error concealment is not fully implemented\n");
     ff_MPV_decode_mb(s, s->block);
 }
 
@@ -179,10 +174,10 @@
     ff_MPV_common_init_axp(s);
 #elif ARCH_ARM
     ff_MPV_common_init_arm(s);
-#elif HAVE_ALTIVEC
-    ff_MPV_common_init_altivec(s);
 #elif ARCH_BFIN
     ff_MPV_common_init_bfin(s);
+#elif ARCH_PPC
+    ff_MPV_common_init_ppc(s);
 #endif
 
     /* load & permutate scantables
@@ -391,10 +386,10 @@
             free_picture_tables(pic);
 
     if (shared) {
-        assert(pic->f.data[0]);
+        av_assert0(pic->f.data[0]);
         pic->shared = 1;
     } else {
-        assert(!pic->f.data[0]);
+        av_assert0(!pic->f.data[0]);
 
         if (alloc_frame_buffer(s, pic) < 0)
             return -1;
@@ -454,6 +449,9 @@
 
     av_buffer_unref(&pic->hwaccel_priv_buf);
 
+    if (pic->needs_realloc)
+        free_picture_tables(pic);
+
     memset((uint8_t*)pic + off, 0, sizeof(*pic) - off);
 }
 
@@ -1226,7 +1224,8 @@
                         (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices;
             }
         } else {
-            if (init_duplicate_context(s) < 0)
+            err = init_duplicate_context(s);
+            if (err < 0)
                 goto fail;
             s->start_mb_y = 0;
             s->end_mb_y   = s->mb_height;
@@ -1301,8 +1300,8 @@
     s->linesize = s->uvlinesize = 0;
 }
 
-void ff_init_rl(RLTable *rl,
-                uint8_t static_store[2][2 * MAX_RUN + MAX_LEVEL + 3])
+av_cold void ff_init_rl(RLTable *rl,
+                        uint8_t static_store[2][2 * MAX_RUN + MAX_LEVEL + 3])
 {
     int8_t  max_level[MAX_RUN + 1], max_run[MAX_LEVEL + 1];
     uint8_t index_run[MAX_RUN + 1];
@@ -1353,7 +1352,7 @@
     }
 }
 
-void ff_init_vlc_rl(RLTable *rl)
+av_cold void ff_init_vlc_rl(RLTable *rl)
 {
     int i, q;
 
@@ -1523,6 +1522,8 @@
         }
     }
 
+    ff_mpeg_unref_picture(s, &s->current_picture);
+
     if (!s->encoding) {
         ff_release_unused_pictures(s, 1);
 
@@ -1570,7 +1571,6 @@
     //     s->current_picture_ptr->quality = s->new_picture_ptr->quality;
     s->current_picture_ptr->f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
 
-    ff_mpeg_unref_picture(s, &s->current_picture);
     if ((ret = ff_mpeg_ref_picture(s, &s->current_picture,
                                    s->current_picture_ptr)) < 0)
         return ret;
@@ -1669,7 +1669,7 @@
             return ret;
     }
 
-    assert(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr &&
+    av_assert0(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr &&
                                                  s->last_picture_ptr->f.data[0]));
 
     if (s->picture_structure!= PICT_FRAME) {
@@ -1716,7 +1716,6 @@
  * frame has been coded/decoded. */
 void ff_MPV_frame_end(MpegEncContext *s)
 {
-    int i;
     /* redraw edges for the frame if decoding didn't complete */
     // just to make sure that all data is rendered.
     if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) {
@@ -1762,16 +1761,9 @@
             break;
         }
     }
-    assert(i < MAX_PICTURE_COUNT);
+    av_assert0(i < MAX_PICTURE_COUNT);
 #endif
 
-    if (s->encoding) {
-        /* release non-reference frames */
-        for (i = 0; i < MAX_PICTURE_COUNT; i++) {
-            if (!s->picture[i].reference)
-                ff_mpeg_unref_picture(s, &s->picture[i]);
-        }
-    }
     // clear copies, to avoid confusion
 #if 0
     memset(&s->last_picture,    0, sizeof(Picture));
@@ -2189,7 +2181,7 @@
                                      int motion_x, int motion_y)
 {
     const int lowres   = s->avctx->lowres;
-    const int op_index = FFMIN(lowres, 2);
+    const int op_index = FFMIN(lowres, 3);
     const int s_mask   = (2 << lowres) - 1;
     int emu = 0;
     int sx, sy;
@@ -2242,7 +2234,7 @@
     int mx, my, src_x, src_y, uvsrc_x, uvsrc_y, uvlinesize, linesize, sx, sy,
         uvsx, uvsy;
     const int lowres     = s->avctx->lowres;
-    const int op_index   = FFMIN(lowres-1+s->chroma_x_shift, 2);
+    const int op_index   = FFMIN(lowres-1+s->chroma_x_shift, 3);
     const int block_s    = 8>>lowres;
     const int s_mask     = (2 << lowres) - 1;
     const int h_edge_pos = s->h_edge_pos >> lowres;
@@ -2308,7 +2300,7 @@
     ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
     ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
 
-    if ((unsigned) src_x > FFMAX( h_edge_pos - (!!sx) - 2 * block_s,       0) ||
+    if ((unsigned) src_x > FFMAX( h_edge_pos - (!!sx) - 2 * block_s,       0) || uvsrc_y<0 ||
         (unsigned) src_y > FFMAX((v_edge_pos >> field_based) - (!!sy) - h, 0)) {
         s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y,
                                 linesize >> field_based, 17, 17 + field_based,
@@ -2348,11 +2340,12 @@
     pix_op[lowres - 1](dest_y, ptr_y, linesize, h, sx, sy);
 
     if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+        int hc = s->chroma_y_shift ? (h+1-bottom_field)>>1 : h;
         uvsx = (uvsx << 2) >> lowres;
         uvsy = (uvsy << 2) >> lowres;
-        if (h >> s->chroma_y_shift) {
-            pix_op[op_index](dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy);
-            pix_op[op_index](dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy);
+        if (hc) {
+            pix_op[op_index](dest_cb, ptr_cb, uvlinesize, hc, uvsx, uvsy);
+            pix_op[op_index](dest_cr, ptr_cr, uvlinesize, hc, uvsx, uvsy);
         }
     }
     // FIXME h261 lowres loop filter
@@ -2365,7 +2358,7 @@
                                             int mx, int my)
 {
     const int lowres     = s->avctx->lowres;
-    const int op_index   = FFMIN(lowres, 2);
+    const int op_index   = FFMIN(lowres, 3);
     const int block_s    = 8 >> lowres;
     const int s_mask     = (2 << lowres) - 1;
     const int h_edge_pos = s->h_edge_pos >> lowres + 1;
@@ -2996,8 +2989,8 @@
 void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h)
 {
     int draw_edges = s->unrestricted_mv && !s->intra_only;
-    ff_draw_horiz_band(s->avctx, &s->dsp, &s->current_picture,
-                       &s->last_picture, y, h, s->picture_structure,
+    ff_draw_horiz_band(s->avctx, &s->dsp, s->current_picture_ptr,
+                       s->last_picture_ptr, y, h, s->picture_structure,
                        s->first_field, draw_edges, s->low_delay,
                        s->v_edge_pos, s->h_edge_pos);
 }
@@ -3244,7 +3237,7 @@
     int i, level, qmul, qadd;
     int nCoeffs;
 
-    av_assert2(s->block_last_index[n]>=0);
+    av_assert2(s->block_last_index[n]>=0 || s->h263_aic);
 
     qmul = qscale << 1;
 
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 4fd01ae..9614e99 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -172,7 +172,7 @@
     int mb_var_sum;             ///< sum of MB variance for current frame
     int mc_mb_var_sum;          ///< motion compensated MB variance for current frame
 
-    int b_frame_score;          /* */
+    int b_frame_score;
     int needs_realloc;          ///< Picture needs to be reallocated (eg due to a frame size change)
 
     int reference;
@@ -358,7 +358,7 @@
     uint8_t *coded_block_base;
     uint8_t *coded_block;          ///< used for coded block pattern prediction (msmpeg4v3, wmv1)
     int16_t (*ac_val_base)[16];
-    int16_t (*ac_val[3])[16];      ///< used for for mpeg4 AC prediction, all 3 arrays must be continuous
+    int16_t (*ac_val[3])[16];      ///< used for mpeg4 AC prediction, all 3 arrays must be continuous
     int mb_skipped;                ///< MUST BE SET only during DECODING
     uint8_t *mbskip_table;        /**< used to avoid copy if macroblock skipped (for black regions for example)
                                    and used for b-frame encoding & decoding (contains skip table of next P Frame) */
@@ -804,8 +804,8 @@
 void ff_MPV_common_init_x86(MpegEncContext *s);
 void ff_MPV_common_init_axp(MpegEncContext *s);
 void ff_MPV_common_init_arm(MpegEncContext *s);
-void ff_MPV_common_init_altivec(MpegEncContext *s);
 void ff_MPV_common_init_bfin(MpegEncContext *s);
+void ff_MPV_common_init_ppc(MpegEncContext *s);
 void ff_clean_intra_table_entries(MpegEncContext *s);
 void ff_draw_horiz_band(AVCodecContext *avctx, DSPContext *dsp, Picture *cur,
                         Picture *last, int y, int h, int picture_structure,
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 5858865..2e6acb2 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -52,17 +52,12 @@
 #include <limits.h>
 #include "sp5x.h"
 
-//#undef NDEBUG
-//#include <assert.h>
-
 static int encode_picture(MpegEncContext *s, int picture_number);
 static int dct_quantize_refine(MpegEncContext *s, int16_t *block, int16_t *weight, int16_t *orig, int n, int qscale);
 static int sse_mb(MpegEncContext *s);
 static void denoise_dct_c(MpegEncContext *s, int16_t *block);
 static int dct_quantize_trellis_c(MpegEncContext *s, int16_t *block, int n, int qscale, int *overflow);
 
-//#define DEBUG
-
 static uint8_t default_mv_penalty[MAX_FCODE + 1][MAX_MV * 2 + 1];
 static uint8_t default_fcode_tab[MAX_MV * 2 + 1];
 
@@ -187,19 +182,6 @@
     }
 }
 
-static void copy_picture_attributes(MpegEncContext *s, AVFrame *dst,
-                                    const AVFrame *src)
-{
-    dst->pict_type              = src->pict_type;
-    dst->quality                = src->quality;
-    dst->coded_picture_number   = src->coded_picture_number;
-    dst->display_picture_number = src->display_picture_number;
-    //dst->reference              = src->reference;
-    dst->pts                    = src->pts;
-    dst->interlaced_frame       = src->interlaced_frame;
-    dst->top_field_first        = src->top_field_first;
-}
-
 static void update_duplicate_context_after_me(MpegEncContext *dst,
                                               MpegEncContext *src)
 {
@@ -540,7 +522,8 @@
     }
 
     // FIXME mpeg2 uses that too
-    if (s->mpeg_quant && s->codec_id != AV_CODEC_ID_MPEG4) {
+    if (s->mpeg_quant && (   s->codec_id != AV_CODEC_ID_MPEG4
+                          && s->codec_id != AV_CODEC_ID_MPEG2VIDEO)) {
         av_log(avctx, AV_LOG_ERROR,
                "mpeg2 style quantization not supported by codec\n");
         return -1;
@@ -960,18 +943,17 @@
 
         if (pts != AV_NOPTS_VALUE) {
             if (s->user_specified_pts != AV_NOPTS_VALUE) {
-                int64_t time = pts;
                 int64_t last = s->user_specified_pts;
 
-                if (time <= last) {
+                if (pts <= last) {
                     av_log(s->avctx, AV_LOG_ERROR,
-                           "Error, Invalid timestamp=%"PRId64", "
-                           "last=%"PRId64"\n", pts, s->user_specified_pts);
-                    return -1;
+                           "Invalid pts (%"PRId64") <= last (%"PRId64")\n",
+                           pts, last);
+                    return AVERROR(EINVAL);
                 }
 
                 if (!s->low_delay && display_picture_number == 1)
-                    s->dts_delta = time - last;
+                    s->dts_delta = pts - last;
             }
             s->user_specified_pts = pts;
         } else {
@@ -1073,7 +1055,10 @@
                 }
             }
         }
-        copy_picture_attributes(s, &pic->f, pic_arg);
+        ret = av_frame_copy_props(&pic->f, pic_arg);
+        if (ret < 0)
+            return ret;
+
         pic->f.display_picture_number = display_picture_number;
         pic->f.pts = pts; // we set this here to avoid modifiying pic_arg
     }
@@ -1413,8 +1398,9 @@
                 return -1;
             }
 
-            copy_picture_attributes(s, &pic->f,
-                                    &s->reordered_input_picture[0]->f);
+            ret = av_frame_copy_props(&pic->f, &s->reordered_input_picture[0]->f);
+            if (ret < 0)
+                return ret;
 
             /* mark us unused / free shared pic */
             av_frame_unref(&s->reordered_input_picture[0]->f);
@@ -1637,6 +1623,13 @@
     } else {
         s->frame_bits = 0;
     }
+
+    /* release non-reference frames */
+    for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+        if (!s->picture[i].reference)
+            ff_mpeg_unref_picture(s, &s->picture[i]);
+    }
+
     assert((s->frame_bits & 7) == 0);
 
     pkt->size = s->frame_bits / 8;
diff --git a/libavcodec/mpegvideo_parser.c b/libavcodec/mpegvideo_parser.c
index d36bc7a..f127218 100644
--- a/libavcodec/mpegvideo_parser.c
+++ b/libavcodec/mpegvideo_parser.c
@@ -118,6 +118,14 @@
                                 s->repeat_pict = 2;
                             }
                         }
+
+                        if (!pc->progressive_sequence) {
+                            if (top_field_first)
+                                s->field_order = AV_FIELD_TT;
+                            else
+                                s->field_order = AV_FIELD_BB;
+                        } else
+                            s->field_order = AV_FIELD_PROGRESSIVE;
                     }
                     break;
                 }
diff --git a/libavcodec/mqc.c b/libavcodec/mqc.c
index 288570d..f8294cd 100644
--- a/libavcodec/mqc.c
+++ b/libavcodec/mqc.c
@@ -92,14 +92,9 @@
 uint8_t ff_mqc_nlps[2 * 47];
 uint8_t ff_mqc_nmps[2 * 47];
 
-void ff_mqc_init_contexts(MqcState *mqc)
+void ff_mqc_init_context_tables(void)
 {
     int i;
-    memset(mqc->cx_states, 0, sizeof(mqc->cx_states));
-    mqc->cx_states[MQC_CX_UNI] = 2 * 46;
-    mqc->cx_states[MQC_CX_RL]  = 2 * 3;
-    mqc->cx_states[0]          = 2 * 4;
-
     for (i = 0; i < 47; i++) {
         ff_mqc_qe[2 * i]     =
         ff_mqc_qe[2 * i + 1] = cx_states[i].qe;
@@ -110,3 +105,11 @@
         ff_mqc_nmps[2 * i + 1] = 2 * cx_states[i].nmps + 1;
     }
 }
+
+void ff_mqc_init_contexts(MqcState *mqc)
+{
+    memset(mqc->cx_states, 0, sizeof(mqc->cx_states));
+    mqc->cx_states[MQC_CX_UNI] = 2 * 46;
+    mqc->cx_states[MQC_CX_RL]  = 2 * 3;
+    mqc->cx_states[0]          = 2 * 4;
+}
diff --git a/libavcodec/mqc.h b/libavcodec/mqc.h
index a0112d1..c0827bd 100644
--- a/libavcodec/mqc.h
+++ b/libavcodec/mqc.h
@@ -79,6 +79,11 @@
 /* common */
 
 /**
+ * MQ-coder Initialize context tables (QE, NLPS, NMPS)
+ */
+void ff_mqc_init_context_tables(void);
+
+/**
  * MQ-coder context initialisations.
  * @param mqc       MQ-coder context
  */
diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c
index 766415e..f2110e7 100644
--- a/libavcodec/msmpeg4.c
+++ b/libavcodec/msmpeg4.c
@@ -45,7 +45,6 @@
  *        - (encoding) select best mv table (two choices)
  *        - (encoding) select best vlc/dc table
  */
-//#define DEBUG
 
 /* This table is practically identical to the one from h263
  * except that it is inverted. */
@@ -176,13 +175,13 @@
     return pred;
 }
 
-static int get_dc(uint8_t *src, int stride, int scale)
+static int get_dc(uint8_t *src, int stride, int scale, int block_size)
 {
     int y;
     int sum=0;
-    for(y=0; y<8; y++){
+    for(y=0; y<block_size; y++){
         int x;
-        for(x=0; x<8; x++){
+        for(x=0; x<block_size; x++){
             sum+=src[x + y*stride];
         }
     }
@@ -277,17 +276,18 @@
                     *dir_ptr = 0;
                 }
             }else{
+                int bs = 8 >> s->avctx->lowres;
                 if(n<4){
                     wrap= s->linesize;
-                    dest= s->current_picture.f.data[0] + (((n >> 1) + 2*s->mb_y) * 8*  wrap ) + ((n & 1) + 2*s->mb_x) * 8;
+                    dest= s->current_picture.f.data[0] + (((n >> 1) + 2*s->mb_y) * bs*  wrap ) + ((n & 1) + 2*s->mb_x) * bs;
                 }else{
                     wrap= s->uvlinesize;
-                    dest= s->current_picture.f.data[n - 3] + (s->mb_y * 8 * wrap) + s->mb_x * 8;
+                    dest= s->current_picture.f.data[n - 3] + (s->mb_y * bs * wrap) + s->mb_x * bs;
                 }
                 if(s->mb_x==0) a= (1024 + (scale>>1))/scale;
-                else           a= get_dc(dest-8, wrap, scale*8);
+                else           a= get_dc(dest-bs, wrap, scale*8>>(2*s->avctx->lowres), bs);
                 if(s->mb_y==0) c= (1024 + (scale>>1))/scale;
-                else           c= get_dc(dest-8*wrap, wrap, scale*8);
+                else           c= get_dc(dest-bs*wrap, wrap, scale*8>>(2*s->avctx->lowres), bs);
 
                 if (s->h263_aic_dir==0) {
                     pred= a;
diff --git a/libavcodec/msmpeg4data.c b/libavcodec/msmpeg4data.c
index 50ba18c..8eb07e9 100644
--- a/libavcodec/msmpeg4data.c
+++ b/libavcodec/msmpeg4data.c
@@ -27,6 +27,8 @@
  * MSMPEG4 data tables.
  */
 
+#include "h263.h"
+#include "mpeg4video.h"
 #include "msmpeg4data.h"
 
 uint32_t ff_v2_dc_lum_table[512][2];
@@ -596,14 +598,6 @@
  29, 30, 31, 32, 33, 34, 35, 36,
 };
 
-extern const uint16_t ff_inter_vlc[103][2];
-extern const int8_t ff_inter_level[102];
-extern const int8_t ff_inter_run[102];
-
-extern const uint16_t ff_mpeg4_intra_vlc[103][2];
-extern const int8_t ff_mpeg4_intra_level[102];
-extern const int8_t ff_mpeg4_intra_run[102];
-
 RLTable ff_rl_table[NB_RL_TABLES] = {
     /* intra luminance tables */
     /* low motion  */
diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c
index 82e6646..74e2c4d 100644
--- a/libavcodec/msmpeg4enc.c
+++ b/libavcodec/msmpeg4enc.c
@@ -30,6 +30,7 @@
 #include <stdint.h>
 #include <string.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/avutil.h"
 #include "libavutil/mem.h"
 #include "mpegvideo.h"
@@ -45,7 +46,7 @@
 static uint8_t rl_length[NB_RL_TABLES][MAX_LEVEL+1][MAX_RUN+1][2];
 
 /* build the table which associate a (x,y) motion vector to a vlc */
-static void init_mv_table(MVTable *tab)
+static av_cold void init_mv_table(MVTable *tab)
 {
     int i, x, y;
 
diff --git a/libavcodec/mss2.c b/libavcodec/mss2.c
index fcdbbd2..1233654 100644
--- a/libavcodec/mss2.c
+++ b/libavcodec/mss2.c
@@ -34,7 +34,7 @@
 typedef struct MSS2Context {
     VC1Context     v;
     int            split_position;
-    AVFrame        last_pic;
+    AVFrame       *last_pic;
     MSS12Context   c;
     MSS2DSPContext dsp;
     SliceContext   sc[2];
@@ -388,7 +388,7 @@
 
     s->loop_filter = avctx->skip_loop_filter < AVDISCARD_ALL;
 
-    if (ff_vc1_parse_frame_header(v, &s->gb) == -1) {
+    if (ff_vc1_parse_frame_header(v, &s->gb) < 0) {
         av_log(v->s.avctx, AV_LOG_ERROR, "header error\n");
         return AVERROR_INVALIDDATA;
     }
@@ -523,8 +523,8 @@
         return AVERROR_INVALIDDATA;
 
     avctx->pix_fmt = is_555 ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_RGB24;
-    if (ctx->last_pic.format != avctx->pix_fmt)
-        av_frame_unref(&ctx->last_pic);
+    if (ctx->last_pic->format != avctx->pix_fmt)
+        av_frame_unref(ctx->last_pic);
 
     if (has_wmv9) {
         bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING);
@@ -601,18 +601,18 @@
         if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
             return ret;
 
-        if (ctx->last_pic.data[0]) {
-            av_assert0(frame->linesize[0] == ctx->last_pic.linesize[0]);
-            c->last_rgb_pic = ctx->last_pic.data[0] +
-                              ctx->last_pic.linesize[0] * (avctx->height - 1);
+        if (ctx->last_pic->data[0]) {
+            av_assert0(frame->linesize[0] == ctx->last_pic->linesize[0]);
+            c->last_rgb_pic = ctx->last_pic->data[0] +
+                              ctx->last_pic->linesize[0] * (avctx->height - 1);
         } else {
             av_log(avctx, AV_LOG_ERROR, "Missing keyframe\n");
             return AVERROR_INVALIDDATA;
         }
     } else {
-        if ((ret = ff_reget_buffer(avctx, &ctx->last_pic)) < 0)
+        if ((ret = ff_reget_buffer(avctx, ctx->last_pic)) < 0)
             return ret;
-        if ((ret = av_frame_ref(frame, &ctx->last_pic)) < 0)
+        if ((ret = av_frame_ref(frame, ctx->last_pic)) < 0)
             return ret;
 
         c->last_rgb_pic = NULL;
@@ -726,8 +726,8 @@
         av_log(avctx, AV_LOG_WARNING, "buffer not fully consumed\n");
 
     if (c->mvX < 0 || c->mvY < 0) {
-        av_frame_unref(&ctx->last_pic);
-        ret = av_frame_ref(&ctx->last_pic, frame);
+        av_frame_unref(ctx->last_pic);
+        ret = av_frame_ref(ctx->last_pic, frame);
         if (ret < 0)
             return ret;
     }
@@ -802,7 +802,7 @@
 {
     MSS2Context *const ctx = avctx->priv_data;
 
-    av_frame_unref(&ctx->last_pic);
+    av_frame_free(&ctx->last_pic);
 
     ff_mss12_decode_end(&ctx->c);
     av_freep(&ctx->c.pal_pic);
@@ -820,10 +820,11 @@
     c->avctx = avctx;
     if (ret = ff_mss12_decode_init(c, 1, &ctx->sc[0], &ctx->sc[1]))
         return ret;
+    ctx->last_pic   = av_frame_alloc();
     c->pal_stride   = c->mask_stride;
     c->pal_pic      = av_mallocz(c->pal_stride * avctx->height);
     c->last_pal_pic = av_mallocz(c->pal_stride * avctx->height);
-    if (!c->pal_pic || !c->last_pal_pic) {
+    if (!c->pal_pic || !c->last_pal_pic || !ctx->last_pic) {
         mss2_decode_end(avctx);
         return AVERROR(ENOMEM);
     }
diff --git a/libavcodec/mss3.c b/libavcodec/mss3.c
index 3cc484f..15bf77a 100644
--- a/libavcodec/mss3.c
+++ b/libavcodec/mss3.c
@@ -108,7 +108,7 @@
 
 typedef struct MSS3Context {
     AVCodecContext   *avctx;
-    AVFrame          pic;
+    AVFrame          *pic;
 
     int              got_error;
     RangeCoder       coder;
@@ -731,12 +731,12 @@
         return buf_size;
     c->got_error = 0;
 
-    if ((ret = ff_reget_buffer(avctx, &c->pic)) < 0)
+    if ((ret = ff_reget_buffer(avctx, c->pic)) < 0)
         return ret;
-    c->pic.key_frame = keyframe;
-    c->pic.pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+    c->pic->key_frame = keyframe;
+    c->pic->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
     if (!bytestream2_get_bytes_left(&gb)) {
-        if ((ret = av_frame_ref(data, &c->pic)) < 0)
+        if ((ret = av_frame_ref(data, c->pic)) < 0)
             return ret;
         *got_frame      = 1;
 
@@ -749,9 +749,9 @@
 
     mb_width  = dec_width  >> 4;
     mb_height = dec_height >> 4;
-    dst[0] = c->pic.data[0] + dec_x     +  dec_y      * c->pic.linesize[0];
-    dst[1] = c->pic.data[1] + dec_x / 2 + (dec_y / 2) * c->pic.linesize[1];
-    dst[2] = c->pic.data[2] + dec_x / 2 + (dec_y / 2) * c->pic.linesize[2];
+    dst[0] = c->pic->data[0] + dec_x     +  dec_y      * c->pic->linesize[0];
+    dst[1] = c->pic->data[1] + dec_x / 2 + (dec_y / 2) * c->pic->linesize[1];
+    dst[2] = c->pic->data[2] + dec_x / 2 + (dec_y / 2) * c->pic->linesize[2];
     for (y = 0; y < mb_height; y++) {
         for (x = 0; x < mb_width; x++) {
             for (i = 0; i < 3; i++) {
@@ -762,23 +762,23 @@
                 case FILL_BLOCK:
                     decode_fill_block(acoder, c->fill_coder + i,
                                       dst[i] + x * blk_size,
-                                      c->pic.linesize[i], blk_size);
+                                      c->pic->linesize[i], blk_size);
                     break;
                 case IMAGE_BLOCK:
                     decode_image_block(acoder, c->image_coder + i,
                                        dst[i] + x * blk_size,
-                                       c->pic.linesize[i], blk_size);
+                                       c->pic->linesize[i], blk_size);
                     break;
                 case DCT_BLOCK:
                     decode_dct_block(acoder, c->dct_coder + i,
                                      dst[i] + x * blk_size,
-                                     c->pic.linesize[i], blk_size,
+                                     c->pic->linesize[i], blk_size,
                                      c->dctblock, x, y);
                     break;
                 case HAAR_BLOCK:
                     decode_haar_block(acoder, c->haar_coder + i,
                                       dst[i] + x * blk_size,
-                                      c->pic.linesize[i], blk_size,
+                                      c->pic->linesize[i], blk_size,
                                       c->hblock);
                     break;
                 }
@@ -790,12 +790,12 @@
                 }
             }
         }
-        dst[0] += c->pic.linesize[0] * 16;
-        dst[1] += c->pic.linesize[1] * 8;
-        dst[2] += c->pic.linesize[2] * 8;
+        dst[0] += c->pic->linesize[0] * 16;
+        dst[1] += c->pic->linesize[1] * 8;
+        dst[2] += c->pic->linesize[2] * 8;
     }
 
-    if ((ret = av_frame_ref(data, &c->pic)) < 0)
+    if ((ret = av_frame_ref(data, c->pic)) < 0)
         return ret;
 
     *got_frame      = 1;
@@ -809,6 +809,9 @@
     int i;
 
     c->avctx = avctx;
+    c->pic = av_frame_alloc();
+    if (!c->pic)
+        return AVERROR(ENOMEM);
 
     if ((avctx->width & 0xF) || (avctx->height & 0xF)) {
         av_log(avctx, AV_LOG_ERROR,
@@ -826,6 +829,7 @@
                                             b_width * b_height);
         if (!c->dct_coder[i].prev_dc) {
             av_log(avctx, AV_LOG_ERROR, "Cannot allocate buffer\n");
+            av_frame_free(&c->pic);
             while (i >= 0) {
                 av_freep(&c->dct_coder[i].prev_dc);
                 i--;
@@ -846,7 +850,7 @@
     MSS3Context * const c = avctx->priv_data;
     int i;
 
-    av_frame_unref(&c->pic);
+    av_frame_free(&c->pic);
     for (i = 0; i < 3; i++)
         av_freep(&c->dct_coder[i].prev_dc);
 
diff --git a/libavcodec/nuv.c b/libavcodec/nuv.c
index edf777e..38f92e9 100644
--- a/libavcodec/nuv.c
+++ b/libavcodec/nuv.c
@@ -122,7 +122,9 @@
         get_quant_quality(c, quality);
     if (width != c->width || height != c->height) {
         // also reserve space for a possible additional header
-        int buf_size = 24 + height * width * 3 / 2 + AV_LZO_OUTPUT_PADDING;
+        int buf_size = height * width * 3 / 2
+                     + FFMAX(AV_LZO_OUTPUT_PADDING, FF_INPUT_BUFFER_PADDING_SIZE)
+                     + RTJPEG_HEADER_SIZE;
         if (buf_size > INT_MAX/8)
             return -1;
         if ((ret = av_image_check_size(height, width, 0, avctx)) < 0)
@@ -138,6 +140,7 @@
         }
         ff_rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height,
                               c->lq, c->cq);
+        av_frame_unref(&c->pic);
         return 1;
     } else if (quality != c->quality)
         ff_rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height,
@@ -207,11 +210,14 @@
     buf       = &buf[12];
     buf_size -= 12;
     if (comptype == NUV_RTJPEG_IN_LZO || comptype == NUV_LZO) {
-        int outlen = c->decomp_size - AV_LZO_OUTPUT_PADDING, inlen = buf_size;
-        if (av_lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen))
+        int outlen = c->decomp_size - FFMAX(FF_INPUT_BUFFER_PADDING_SIZE, AV_LZO_OUTPUT_PADDING);
+        int inlen  = buf_size;
+        if (av_lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen)) {
             av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n");
+            return AVERROR_INVALIDDATA;
+        }
         buf      = c->decomp_buf;
-        buf_size = c->decomp_size - AV_LZO_OUTPUT_PADDING - outlen;
+        buf_size = c->decomp_size - FFMAX(FF_INPUT_BUFFER_PADDING_SIZE, AV_LZO_OUTPUT_PADDING) - outlen;
     }
     if (c->codec_frameheader) {
         int w, h, q;
diff --git a/libavcodec/options.c b/libavcodec/options.c
index e1349dd..02fb89f 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -77,7 +77,7 @@
 static const AVClass av_codec_context_class = {
     .class_name              = "AVCodecContext",
     .item_name               = context_to_name,
-    .option                  = options,
+    .option                  = avcodec_options,
     .version                 = LIBAVUTIL_VERSION_INT,
     .log_level_offset_offset = offsetof(AVCodecContext, log_level_offset),
     .child_next              = codec_child_next,
@@ -190,6 +190,10 @@
                src, dest);
         return AVERROR(EINVAL);
     }
+
+    av_opt_free(dest);
+    av_free(dest->priv_data);
+
     memcpy(dest, src, sizeof(*dest));
 
     /* set values specific to opened codecs back to their default state */
@@ -226,6 +230,7 @@
     alloc_and_copy_or_fail(intra_matrix, 64 * sizeof(int16_t), 0);
     alloc_and_copy_or_fail(inter_matrix, 64 * sizeof(int16_t), 0);
     alloc_and_copy_or_fail(rc_override,  src->rc_override_count * sizeof(*src->rc_override), 0);
+    alloc_and_copy_or_fail(subtitle_header, src->subtitle_header_size, 1);
 #undef alloc_and_copy_or_fail
 
     return 0;
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index 1be2611..e9cdfc4 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -28,7 +28,6 @@
 #include "libavutil/opt.h"
 #include "avcodec.h"
 #include "version.h"
-#include "config.h"
 
 #define OFFSET(x) offsetof(AVCodecContext,x)
 #define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C
@@ -41,7 +40,7 @@
 
 #define AV_CODEC_DEFAULT_BITRATE 200*1000
 
-static const AVOption options[]={
+static const AVOption avcodec_options[] = {
 {"b", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE }, 0, INT_MAX, A|V|E},
 {"ab", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT, {.i64 = 128*1000 }, 0, INT_MAX, A|E},
 {"bt", "Set video bitrate tolerance (in bits/s). In 1-pass mode, bitrate tolerance specifies how far "
@@ -228,7 +227,7 @@
 {"vis_qp", "visualize quantization parameter (QP), lower QP are tinted greener", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_QP }, INT_MIN, INT_MAX, V|D, "debug"},
 {"vis_mb_type", "visualize block types", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"},
 {"buffers", "picture buffer allocations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUFFERS }, INT_MIN, INT_MAX, V|D, "debug"},
-{"thread_ops", "threading operations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|D, "debug"},
+{"thread_ops", "threading operations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|A|D, "debug"},
 {"vismv", "visualize motion vectors (MVs)", OFFSET(debug_mv), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|D, "debug_mv"},
 {"pf", "forward predicted MVs of P-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_P_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"},
 {"bf", "forward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_B_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"},
@@ -286,7 +285,7 @@
 {"rc_init_occupancy", "number of bits which should be loaded into the rc buffer before decoding starts", OFFSET(rc_initial_buffer_occupancy), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 {"flags2", NULL, OFFSET(flags2), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT}, 0, UINT_MAX, V|A|E|D, "flags2"},
 {"error", NULL, OFFSET(error_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"threads", NULL, OFFSET(thread_count), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, V|E|D, "threads"},
+{"threads", NULL, OFFSET(thread_count), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, V|A|E|D, "threads"},
 {"auto", "autodetect a suitable number of threads to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, V|E|D, "threads"},
 {"me_threshold", "motion estimation threshold", OFFSET(me_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 {"mb_threshold", "macroblock threshold", OFFSET(mb_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
@@ -304,6 +303,8 @@
 {"aac_he_v2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_HE_V2 }, INT_MIN, INT_MAX, A|E, "profile"},
 {"aac_ld", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_LD }, INT_MIN, INT_MAX, A|E, "profile"},
 {"aac_eld", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_ELD }, INT_MIN, INT_MAX, A|E, "profile"},
+{"mpeg2_aac_low", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG2_AAC_LOW }, INT_MIN, INT_MAX, A|E, "profile"},
+{"mpeg2_aac_he", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG2_AAC_HE }, INT_MIN, INT_MAX, A|E, "profile"},
 {"dts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS }, INT_MIN, INT_MAX, A|E, "profile"},
 {"dts_es", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_ES }, INT_MIN, INT_MAX, A|E, "profile"},
 {"dts_96_24", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_96_24 }, INT_MIN, INT_MAX, A|E, "profile"},
@@ -358,7 +359,7 @@
 {"chroma_sample_location", NULL, OFFSET(chroma_sample_location), AV_OPT_TYPE_INT, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, AVCHROMA_LOC_NB-1, V|E|D},
 {"log_level_offset", "set the log level offset", OFFSET(log_level_offset), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX },
 {"slices", "number of slices, used in parallelized encoding", OFFSET(slices), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|E},
-{"thread_type", "select multithreading type", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, {.i64 = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|E|D, "thread_type"},
+{"thread_type", "select multithreading type", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, {.i64 = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|A|E|D, "thread_type"},
 {"slice", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_SLICE }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
 {"frame", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_FRAME }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
 {"audio_service_type", "audio service type", OFFSET(audio_service_type), AV_OPT_TYPE_INT, {.i64 = AV_AUDIO_SERVICE_TYPE_MAIN }, 0, AV_AUDIO_SERVICE_TYPE_NB-1, A|E, "audio_service_type"},
diff --git a/libavcodec/pamenc.c b/libavcodec/pamenc.c
index 3e47278..2c4c9e0 100644
--- a/libavcodec/pamenc.c
+++ b/libavcodec/pamenc.c
@@ -25,10 +25,9 @@
 
 
 static int pam_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
-                            const AVFrame *pict, int *got_packet)
+                            const AVFrame *p, int *got_packet)
 {
     PNMContext *s     = avctx->priv_data;
-    AVFrame * const p = &s->picture;
     int i, h, w, n, linesize, depth, maxval, ret;
     const char *tuple_type;
     uint8_t *ptr;
@@ -91,10 +90,6 @@
     if ((ret = ff_alloc_packet2(avctx, pkt, n*h + 200)) < 0)
         return ret;
 
-    *p           = *pict;
-    p->pict_type = AV_PICTURE_TYPE_I;
-    p->key_frame = 1;
-
     s->bytestream_start =
     s->bytestream       = pkt->data;
     s->bytestream_end   = pkt->data + pkt->size;
@@ -134,7 +129,6 @@
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PAM,
     .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
     .encode2        = pam_encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]){
         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48BE, AV_PIX_FMT_RGBA64BE, AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY8A, AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_NONE
diff --git a/libavcodec/parser.c b/libavcodec/parser.c
index f7cb5cf..500bbb8 100644
--- a/libavcodec/parser.c
+++ b/libavcodec/parser.c
@@ -23,6 +23,7 @@
 #include <string.h>
 
 #include "parser.h"
+#include "libavutil/atomic.h"
 #include "libavutil/mem.h"
 
 static AVCodecParser *av_first_parser = NULL;
@@ -34,8 +35,9 @@
 
 void av_register_codec_parser(AVCodecParser *parser)
 {
-    parser->next = av_first_parser;
-    av_first_parser = parser;
+    do {
+        parser->next = av_first_parser;
+    } while (parser->next != avpriv_atomic_ptr_cas((void * volatile *)&av_first_parser, parser->next, parser));
 }
 
 AVCodecParserContext *av_parser_init(int codec_id)
diff --git a/libavcodec/pcm-mpeg.c b/libavcodec/pcm-mpeg.c
index aec056a..0061bc9 100644
--- a/libavcodec/pcm-mpeg.c
+++ b/libavcodec/pcm-mpeg.c
@@ -1,6 +1,6 @@
 /*
  * LPCM codecs for PCM formats found in MPEG streams
- * Copyright (c) 2009 Christian Schmidt
+ * Copyright (c) 2009, 2013 Christian Schmidt
  *
  * This file is part of FFmpeg.
  *
@@ -72,7 +72,7 @@
     avctx->bits_per_coded_sample = bits_per_samples[header[3] >> 6];
     if (!(avctx->bits_per_coded_sample == 16 || avctx->bits_per_coded_sample == 24)) {
         av_log(avctx, AV_LOG_ERROR, "unsupported sample depth (%d)\n", avctx->bits_per_coded_sample);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     avctx->sample_fmt = avctx->bits_per_coded_sample == 16 ? AV_SAMPLE_FMT_S16 :
                                                              AV_SAMPLE_FMT_S32;
@@ -94,7 +94,7 @@
         avctx->sample_rate = 0;
         av_log(avctx, AV_LOG_ERROR, "reserved sample rate (%d)\n",
                header[2] & 0x0f);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /*
@@ -108,7 +108,7 @@
     if (!avctx->channels) {
         av_log(avctx, AV_LOG_ERROR, "reserved channel configuration (%d)\n",
                channel_layout);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     avctx->bit_rate = FFALIGN(avctx->channels, 2) * avctx->sample_rate *
@@ -136,11 +136,11 @@
 
     if (buf_size < 4) {
         av_log(avctx, AV_LOG_ERROR, "PCM packet too small\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    if (pcm_bluray_parse_header(avctx, src))
-        return -1;
+    if ((retval = pcm_bluray_parse_header(avctx, src)))
+        return retval;
     src += 4;
     buf_size -= 4;
 
diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c
index 83482dd..2f256de 100644
--- a/libavcodec/pcm.c
+++ b/libavcodec/pcm.c
@@ -48,16 +48,6 @@
     avctx->bits_per_coded_sample = av_get_bits_per_sample(avctx->codec->id);
     avctx->block_align           = avctx->channels * avctx->bits_per_coded_sample / 8;
     avctx->bit_rate              = avctx->block_align * avctx->sample_rate * 8;
-    avctx->coded_frame           = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-
-    return 0;
-}
-
-static av_cold int pcm_encode_close(AVCodecContext *avctx)
-{
-    av_freep(&avctx->coded_frame);
 
     return 0;
 }
@@ -308,7 +298,7 @@
 
     /* av_get_bits_per_sample returns 0 for AV_CODEC_ID_PCM_DVD */
     samples_per_block = 1;
-    if (AV_CODEC_ID_PCM_DVD == avctx->codec_id) {
+    if (avctx->codec_id == AV_CODEC_ID_PCM_DVD) {
         if (avctx->bits_per_coded_sample != 20 &&
             avctx->bits_per_coded_sample != 24) {
             av_log(avctx, AV_LOG_ERROR,
@@ -552,7 +542,6 @@
     .id           = AV_CODEC_ID_ ## id_,                                    \
     .init         = pcm_encode_init,                                        \
     .encode2      = pcm_encode_frame,                                       \
-    .close        = pcm_encode_close,                                       \
     .capabilities = CODEC_CAP_VARIABLE_FRAME_SIZE,                          \
     .sample_fmts  = (const enum AVSampleFormat[]){ sample_fmt_,             \
                                                    AV_SAMPLE_FMT_NONE },    \
diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c
index ba92332..67bc839 100644
--- a/libavcodec/pcx.c
+++ b/libavcodec/pcx.c
@@ -28,21 +28,23 @@
 #include "get_bits.h"
 #include "internal.h"
 
-static void pcx_rle_decode(GetByteContext *gb, uint8_t *dst,
-                           unsigned int bytes_per_scanline, int compressed)
+static void pcx_rle_decode(GetByteContext *gb,
+                           uint8_t *dst,
+                           unsigned int bytes_per_scanline,
+                           int compressed)
 {
     unsigned int i = 0;
     unsigned char run, value;
 
     if (compressed) {
-        while (i<bytes_per_scanline) {
-            run = 1;
+        while (i < bytes_per_scanline && bytestream2_get_bytes_left(gb)>0) {
+            run   = 1;
             value = bytestream2_get_byte(gb);
-            if (value >= 0xc0) {
-                run = value & 0x3f;
+            if (value >= 0xc0 && bytestream2_get_bytes_left(gb)>0) {
+                run   = value & 0x3f;
                 value = bytestream2_get_byte(gb);
             }
-            while (i<bytes_per_scanline && run--)
+            while (i < bytes_per_scanline && run--)
                 dst[i++] = value;
         }
     } else {
@@ -55,17 +57,19 @@
     int i;
 
     pallen = FFMIN(pallen, bytestream2_get_bytes_left(gb) / 3);
-    for (i=0; i<pallen; i++)
+    for (i = 0; i < pallen; i++)
         *dst++ = 0xFF000000 | bytestream2_get_be24u(gb);
     if (pallen < 256)
         memset(dst, 0, (256 - pallen) * sizeof(*dst));
 }
 
 static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
-                            AVPacket *avpkt) {
+                            AVPacket *avpkt)
+{
     GetByteContext gb;
-    AVFrame * const p = data;
-    int compressed, xmin, ymin, xmax, ymax, ret;
+    AVFrame * const p  = data;
+    int compressed, xmin, ymin, xmax, ymax;
+    int ret;
     unsigned int w, h, bits_per_pixel, bytes_per_line, nplanes, stride, y, x,
                  bytes_per_scanline;
     uint8_t *ptr, *scanline;
@@ -80,12 +84,12 @@
         return AVERROR_INVALIDDATA;
     }
 
-    compressed = bytestream2_get_byteu(&gb);
-    bits_per_pixel = bytestream2_get_byteu(&gb);
-    xmin = bytestream2_get_le16u(&gb);
-    ymin = bytestream2_get_le16u(&gb);
-    xmax = bytestream2_get_le16u(&gb);
-    ymax = bytestream2_get_le16u(&gb);
+    compressed                     = bytestream2_get_byteu(&gb);
+    bits_per_pixel                 = bytestream2_get_byteu(&gb);
+    xmin                           = bytestream2_get_le16u(&gb);
+    ymin                           = bytestream2_get_le16u(&gb);
+    xmax                           = bytestream2_get_le16u(&gb);
+    ymax                           = bytestream2_get_le16u(&gb);
     avctx->sample_aspect_ratio.num = bytestream2_get_le16u(&gb);
     avctx->sample_aspect_ratio.den = bytestream2_get_le16u(&gb);
 
@@ -102,27 +106,28 @@
     bytes_per_line     = bytestream2_get_le16u(&gb);
     bytes_per_scanline = nplanes * bytes_per_line;
 
-    if (bytes_per_scanline < (w * bits_per_pixel * nplanes + 7) / 8) {
+    if (bytes_per_scanline < (w * bits_per_pixel * nplanes + 7) / 8 ||
+        (!compressed && bytes_per_scanline > bytestream2_get_bytes_left(&gb) / h)) {
         av_log(avctx, AV_LOG_ERROR, "PCX data is corrupted\n");
         return AVERROR_INVALIDDATA;
     }
 
-    switch ((nplanes<<8) + bits_per_pixel) {
-        case 0x0308:
-            avctx->pix_fmt = AV_PIX_FMT_RGB24;
-            break;
-        case 0x0108:
-        case 0x0104:
-        case 0x0102:
-        case 0x0101:
-        case 0x0401:
-        case 0x0301:
-        case 0x0201:
-            avctx->pix_fmt = AV_PIX_FMT_PAL8;
-            break;
-        default:
-            av_log(avctx, AV_LOG_ERROR, "invalid PCX file\n");
-            return AVERROR_INVALIDDATA;
+    switch ((nplanes << 8) + bits_per_pixel) {
+    case 0x0308:
+        avctx->pix_fmt = AV_PIX_FMT_RGB24;
+        break;
+    case 0x0108:
+    case 0x0104:
+    case 0x0102:
+    case 0x0101:
+    case 0x0401:
+    case 0x0301:
+    case 0x0201:
+        avctx->pix_fmt = AV_PIX_FMT_PAL8;
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR, "invalid PCX file\n");
+        return AVERROR_INVALIDDATA;
     }
 
     bytestream2_skipu(&gb, 60);
@@ -144,22 +149,21 @@
         return AVERROR(ENOMEM);
 
     if (nplanes == 3 && bits_per_pixel == 8) {
-        for (y=0; y<h; y++) {
+        for (y = 0; y < h; y++) {
             pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed);
 
-            for (x=0; x<w; x++) {
-                ptr[3*x  ] = scanline[x                    ];
-                ptr[3*x+1] = scanline[x+ bytes_per_line    ];
-                ptr[3*x+2] = scanline[x+(bytes_per_line<<1)];
+            for (x = 0; x < w; x++) {
+                ptr[3 * x]     = scanline[x];
+                ptr[3 * x + 1] = scanline[x + bytes_per_line];
+                ptr[3 * x + 2] = scanline[x + (bytes_per_line << 1)];
             }
 
             ptr += stride;
         }
-
     } else if (nplanes == 1 && bits_per_pixel == 8) {
         int palstart = avpkt->size - 769;
 
-        for (y=0; y<h; y++, ptr+=stride) {
+        for (y = 0; y < h; y++, ptr += stride) {
             pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed);
             memcpy(ptr, scanline, w);
         }
@@ -173,31 +177,29 @@
             ret = AVERROR_INVALIDDATA;
             goto end;
         }
-
     } else if (nplanes == 1) {   /* all packed formats, max. 16 colors */
         GetBitContext s;
 
-        for (y=0; y<h; y++) {
+        for (y = 0; y < h; y++) {
             init_get_bits8(&s, scanline, bytes_per_scanline);
 
             pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed);
 
-            for (x=0; x<w; x++)
+            for (x = 0; x < w; x++)
                 ptr[x] = get_bits(&s, bits_per_pixel);
             ptr += stride;
         }
-
     } else {    /* planar, 4, 8 or 16 colors */
         int i;
 
-        for (y=0; y<h; y++) {
+        for (y = 0; y < h; y++) {
             pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed);
 
-            for (x=0; x<w; x++) {
-                int m = 0x80 >> (x&7), v = 0;
-                for (i=nplanes - 1; i>=0; i--) {
+            for (x = 0; x < w; x++) {
+                int m = 0x80 >> (x & 7), v = 0;
+                for (i = nplanes - 1; i >= 0; i--) {
                     v <<= 1;
-                    v  += !!(scanline[i*bytes_per_line + (x>>3)] & m);
+                    v  += !!(scanline[i * bytes_per_line + (x >> 3)] & m);
                 }
                 ptr[x] = v;
             }
@@ -207,14 +209,14 @@
 
     ret = bytestream2_tell(&gb);
     if (nplanes == 1 && bits_per_pixel == 8) {
-        pcx_palette(&gb, (uint32_t *) p->data[1], 256);
+        pcx_palette(&gb, (uint32_t *)p->data[1], 256);
         ret += 256 * 3;
     } else if (bits_per_pixel * nplanes == 1) {
         AV_WN32A(p->data[1]  , 0xFF000000);
         AV_WN32A(p->data[1]+4, 0xFFFFFFFF);
     } else if (bits_per_pixel < 8) {
         bytestream2_seek(&gb, 16, SEEK_SET);
-        pcx_palette(&gb, (uint32_t *) p->data[1], 16);
+        pcx_palette(&gb, (uint32_t *)p->data[1], 16);
     }
 
     *got_frame = 1;
@@ -225,10 +227,10 @@
 }
 
 AVCodec ff_pcx_decoder = {
-    .name           = "pcx",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_PCX,
-    .decode         = pcx_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"),
+    .name         = "pcx",
+    .type         = AVMEDIA_TYPE_VIDEO,
+    .id           = AV_CODEC_ID_PCX,
+    .decode       = pcx_decode_frame,
+    .capabilities = CODEC_CAP_DR1,
+    .long_name    = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"),
 };
diff --git a/libavcodec/pcxenc.c b/libavcodec/pcxenc.c
index 7cb3af3..1b96d84 100644
--- a/libavcodec/pcxenc.c
+++ b/libavcodec/pcxenc.c
@@ -31,22 +31,8 @@
 #include "libavutil/imgutils.h"
 #include "internal.h"
 
-typedef struct PCXContext {
-    AVFrame picture;
-} PCXContext;
-
 static const uint32_t monoblack_pal[16] = { 0x000000, 0xFFFFFF };
 
-static av_cold int pcx_encode_init(AVCodecContext *avctx)
-{
-    PCXContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
-
-    return 0;
-}
-
 /**
  * PCX run-length encoder
  * @param dst output buffer
@@ -100,8 +86,7 @@
 static int pcx_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                             const AVFrame *frame, int *got_packet)
 {
-    PCXContext *s = avctx->priv_data;
-    AVFrame *const pict = &s->picture;
+    AVFrame *const pict = (AVFrame *) frame;
     const uint8_t *buf_end;
     uint8_t *buf;
 
@@ -110,7 +95,6 @@
     uint32_t palette256[256];
     const uint8_t *src;
 
-    *pict = *frame;
     pict->pict_type = AV_PICTURE_TYPE_I;
     pict->key_frame = 1;
 
@@ -216,8 +200,6 @@
     .name           = "pcx",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PCX,
-    .priv_data_size = sizeof(PCXContext),
-    .init           = pcx_encode_init,
     .encode2        = pcx_encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]){
         AV_PIX_FMT_RGB24,
diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c
index d0cff7b..a981c0e 100644
--- a/libavcodec/pgssubdec.c
+++ b/libavcodec/pgssubdec.c
@@ -98,7 +98,7 @@
 /**
  * Decode the RLE data.
  *
- * The subtitle is stored as an Run Length Encoded image.
+ * The subtitle is stored as a Run Length Encoded image.
  *
  * @param avctx contains the current codec context
  * @param sub pointer to the processed subtitle data
diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index 086f3b41..16225db 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -28,6 +28,7 @@
 #include "internal.h"
 #include "png.h"
 #include "pngdsp.h"
+#include "thread.h"
 
 /* TODO:
  * - add 16 bit depth support
@@ -35,14 +36,13 @@
 
 #include <zlib.h>
 
-//#define DEBUG
-
 typedef struct PNGDecContext {
     PNGDSPContext dsp;
     AVCodecContext *avctx;
 
     GetByteContext gb;
-    AVFrame *prev;
+    ThreadFrame last_picture;
+    ThreadFrame picture;
 
     int state;
     int width, height;
@@ -370,8 +370,8 @@
     while (s->zstream.avail_in > 0) {
         ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
         if (ret != Z_OK && ret != Z_STREAM_END) {
-            av_log(s->avctx, AV_LOG_ERROR, "inflate returned %d\n", ret);
-            return -1;
+            av_log(s->avctx, AV_LOG_ERROR, "inflate returned error %d\n", ret);
+            return AVERROR_EXTERNAL;
         }
         if (s->zstream.avail_out == 0) {
             if (!(s->state & PNG_ALLIMAGE)) {
@@ -507,13 +507,17 @@
     PNGDecContext * const s = avctx->priv_data;
     const uint8_t *buf      = avpkt->data;
     int buf_size            = avpkt->size;
-    AVFrame *p              = data;
+    AVFrame *p;
     AVDictionary *metadata  = NULL;
     uint8_t *crow_buf_base  = NULL;
     uint32_t tag, length;
     int64_t sig;
     int ret;
 
+    ff_thread_release_buffer(avctx, &s->last_picture);
+    FFSWAP(ThreadFrame, s->picture, s->last_picture);
+    p = s->picture.f;
+
     bytestream2_init(&s->gb, buf, buf_size);
 
     /* check signature */
@@ -521,7 +525,7 @@
     if (sig != PNGSIG &&
         sig != MNGSIG) {
         av_log(avctx, AV_LOG_ERROR, "Missing png signature\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     s->y = s->state = 0;
@@ -532,8 +536,8 @@
     s->zstream.opaque = NULL;
     ret = inflateInit(&s->zstream);
     if (ret != Z_OK) {
-        av_log(avctx, AV_LOG_ERROR, "inflateInit returned %d\n", ret);
-        return -1;
+        av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret);
+        return AVERROR_EXTERNAL;
     }
     for (;;) {
         if (bytestream2_get_bytes_left(&s->gb) <= 0) {
@@ -637,8 +641,10 @@
                     goto fail;
                 }
 
-                if (ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF) < 0)
+                if (ff_thread_get_buffer(avctx, &s->picture, AV_GET_BUFFER_FLAG_REF) < 0)
                     goto fail;
+                ff_thread_finish_setup(avctx);
+
                 p->pict_type        = AV_PICTURE_TYPE_I;
                 p->key_frame        = 1;
                 p->interlaced_frame = !!s->interlace_type;
@@ -822,16 +828,17 @@
     }
 
      /* handle p-frames only if a predecessor frame is available */
-     if (s->prev->data[0]) {
-         if (   !(avpkt->flags & AV_PKT_FLAG_KEY)
-            && s->prev->width == p->width
-            && s->prev->height== p->height
-            && s->prev->format== p->format
+     if (s->last_picture.f->data[0]) {
+         if (   !(avpkt->flags & AV_PKT_FLAG_KEY) && avctx->codec_tag != AV_RL32("MPNG")
+            && s->last_picture.f->width == p->width
+            && s->last_picture.f->height== p->height
+            && s->last_picture.f->format== p->format
          ) {
             int i, j;
             uint8_t *pd      = p->data[0];
-            uint8_t *pd_last = s->prev->data[0];
+            uint8_t *pd_last = s->last_picture.f->data[0];
 
+            ff_thread_await_progress(&s->last_picture, INT_MAX, 0);
             for (j = 0; j < s->height; j++) {
                 for (i = 0; i < s->width * s->bpp; i++) {
                     pd[i] += pd_last[i];
@@ -841,13 +848,13 @@
             }
         }
     }
+    ff_thread_report_progress(&s->picture, INT_MAX, 0);
 
     av_frame_set_metadata(p, metadata);
     metadata   = NULL;
 
-    av_frame_unref(s->prev);
-     if ((ret = av_frame_ref(s->prev, p)) < 0)
-         goto fail;
+    if ((ret = av_frame_ref(data, s->picture.f)) < 0)
+        return ret;
 
     *got_frame = 1;
 
@@ -861,21 +868,40 @@
     return ret;
  fail:
     av_dict_free(&metadata);
-    ret = -1;
+    ret = AVERROR_INVALIDDATA;
+    ff_thread_release_buffer(avctx, &s->picture);
     goto the_end;
 }
 
+static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
+{
+    PNGDecContext *psrc = src->priv_data;
+    PNGDecContext *pdst = dst->priv_data;
+
+    if (dst == src)
+        return 0;
+
+    ff_thread_release_buffer(dst, &pdst->picture);
+    if (psrc->picture.f->data[0])
+        return ff_thread_ref_frame(&pdst->picture, &psrc->picture);
+
+    return 0;
+}
+
 static av_cold int png_dec_init(AVCodecContext *avctx)
 {
     PNGDecContext *s = avctx->priv_data;
 
-    s->prev = av_frame_alloc();
-    if (!s->prev)
+    s->avctx = avctx;
+    s->last_picture.f = av_frame_alloc();
+    s->picture.f = av_frame_alloc();
+    if (!s->last_picture.f || !s->picture.f)
         return AVERROR(ENOMEM);
 
-    ff_pngdsp_init(&s->dsp);
-
-    s->avctx = avctx;
+    if (!avctx->internal->is_copy) {
+        avctx->internal->allocate_progress = 1;
+        ff_pngdsp_init(&s->dsp);
+    }
 
     return 0;
 }
@@ -884,7 +910,10 @@
 {
     PNGDecContext *s = avctx->priv_data;
 
-    av_frame_free(&s->prev);
+    ff_thread_release_buffer(avctx, &s->last_picture);
+    av_frame_free(&s->last_picture.f);
+    ff_thread_release_buffer(avctx, &s->picture);
+    av_frame_free(&s->picture.f);
 
     return 0;
 }
@@ -897,6 +926,8 @@
     .init           = png_dec_init,
     .close          = png_dec_end,
     .decode         = decode_frame,
-    .capabilities   = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
+    .init_thread_copy = ONLY_IF_THREADS_ENABLED(png_dec_init),
+    .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
     .long_name      = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"),
 };
diff --git a/libavcodec/pngdsp.c b/libavcodec/pngdsp.c
index 1ee8b57..0d24775 100644
--- a/libavcodec/pngdsp.c
+++ b/libavcodec/pngdsp.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
 #include "png.h"
 #include "pngdsp.h"
@@ -39,7 +40,7 @@
         dst[i] = src1[i] + src2[i];
 }
 
-void ff_pngdsp_init(PNGDSPContext *dsp)
+av_cold void ff_pngdsp_init(PNGDSPContext *dsp)
 {
     dsp->add_bytes_l2         = add_bytes_l2_c;
     dsp->add_paeth_prediction = ff_add_png_paeth_prediction;
diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
index 5ba5983..dc86171 100644
--- a/libavcodec/pngenc.c
+++ b/libavcodec/pngenc.c
@@ -25,6 +25,7 @@
 #include "png.h"
 
 #include "libavutil/avassert.h"
+#include "libavutil/opt.h"
 
 /* TODO:
  * - add 2, 4 and 16 bit depth support
@@ -32,11 +33,10 @@
 
 #include <zlib.h>
 
-//#define DEBUG
-
 #define IOBUF_SIZE 4096
 
 typedef struct PNGEncContext {
+    AVClass *class;
     DSPContext dsp;
 
     uint8_t *bytestream;
@@ -48,6 +48,8 @@
 
     z_stream zstream;
     uint8_t buf[IOBUF_SIZE];
+    int dpi;                     ///< Physical pixel density, in dots per inch, if set
+    int dpm;                     ///< Physical pixel density, in dots per meter, if set
 } PNGEncContext;
 
 static void png_get_interlaced_row(uint8_t *dst, int row_size,
@@ -331,9 +333,15 @@
 
     png_write_chunk(&s->bytestream, MKTAG('I', 'H', 'D', 'R'), s->buf, 13);
 
-    AV_WB32(s->buf, avctx->sample_aspect_ratio.num);
-    AV_WB32(s->buf + 4, avctx->sample_aspect_ratio.den);
-    s->buf[8] = 0; /* unit specifier is unknown */
+    if (s->dpm) {
+      AV_WB32(s->buf, s->dpm);
+      AV_WB32(s->buf + 4, s->dpm);
+      s->buf[8] = 1; /* unit specifier is meter */
+    } else {
+      AV_WB32(s->buf, avctx->sample_aspect_ratio.num);
+      AV_WB32(s->buf + 4, avctx->sample_aspect_ratio.den);
+      s->buf[8] = 0; /* unit specifier is unknown */
+    }
     png_write_chunk(&s->bytestream, MKTAG('p', 'H', 'Y', 's'), s->buf, 9);
 
     /* put the palette if needed */
@@ -458,9 +466,31 @@
     if(avctx->pix_fmt == AV_PIX_FMT_MONOBLACK)
         s->filter_type = PNG_FILTER_VALUE_NONE;
 
+    if (s->dpi && s->dpm) {
+      av_log(avctx, AV_LOG_ERROR, "Only one of 'dpi' or 'dpm' options should be set\n");
+      return AVERROR(EINVAL);
+    } else if (s->dpi) {
+      s->dpm = s->dpi * 10000 / 254;
+    }
+
     return 0;
 }
 
+#define OFFSET(x) offsetof(PNGEncContext, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    {"dpi", "Set image resolution (in dots per inch)",  OFFSET(dpi), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 0x10000, VE},
+    {"dpm", "Set image resolution (in dots per meter)", OFFSET(dpm), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 0x10000, VE},
+    { NULL }
+};
+
+static const AVClass pngenc_class = {
+    .class_name = "PNG encoder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_png_encoder = {
     .name           = "png",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -478,4 +508,5 @@
         AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_NONE
     },
     .long_name      = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"),
+    .priv_class     = &pngenc_class,
 };
diff --git a/libavcodec/pnm.c b/libavcodec/pnm.c
index 33b8896..63b77cd 100644
--- a/libavcodec/pnm.c
+++ b/libavcodec/pnm.c
@@ -116,10 +116,10 @@
         if (depth == 1) {
             if (maxval == 1) {
                 avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
-            } else if (maxval == 255) {
+            } else if (maxval < 256) {
                 avctx->pix_fmt = AV_PIX_FMT_GRAY8;
             } else {
-                avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
+                avctx->pix_fmt = AV_PIX_FMT_GRAY16;
             }
         } else if (depth == 2) {
             if (maxval == 255)
@@ -128,13 +128,13 @@
             if (maxval < 256) {
                 avctx->pix_fmt = AV_PIX_FMT_RGB24;
             } else {
-                avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
+                avctx->pix_fmt = AV_PIX_FMT_RGB48;
             }
         } else if (depth == 4) {
             if (maxval < 256) {
                 avctx->pix_fmt = AV_PIX_FMT_RGBA;
             } else {
-                avctx->pix_fmt = AV_PIX_FMT_RGBA64BE;
+                avctx->pix_fmt = AV_PIX_FMT_RGBA64;
             }
         } else {
             return AVERROR_INVALIDDATA;
@@ -162,14 +162,14 @@
         }
         if (s->maxval >= 256) {
             if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
-                avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
+                avctx->pix_fmt = AV_PIX_FMT_GRAY16;
             } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) {
-                avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
+                avctx->pix_fmt = AV_PIX_FMT_RGB48;
             } else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P && s->maxval < 65536) {
                 if (s->maxval < 512)
-                    avctx->pix_fmt = AV_PIX_FMT_YUV420P9BE;
+                    avctx->pix_fmt = AV_PIX_FMT_YUV420P9;
                 else if (s->maxval < 1024)
-                    avctx->pix_fmt = AV_PIX_FMT_YUV420P10BE;
+                    avctx->pix_fmt = AV_PIX_FMT_YUV420P10;
                 else
                     avctx->pix_fmt = AV_PIX_FMT_YUV420P16;
             } else {
@@ -181,7 +181,7 @@
     }else
         s->maxval=1;
     /* more check if YUV420 */
-    if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & PIX_FMT_PLANAR) {
+    if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_PLANAR) {
         if ((avctx->width & 1) != 0)
             return AVERROR_INVALIDDATA;
         h = (avctx->height * 2);
@@ -192,13 +192,3 @@
     }
     return 0;
 }
-
-av_cold int ff_pnm_init(AVCodecContext *avctx)
-{
-    PNMContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
-
-    return 0;
-}
diff --git a/libavcodec/pnm.h b/libavcodec/pnm.h
index 92edf8d..5bc0aad 100644
--- a/libavcodec/pnm.h
+++ b/libavcodec/pnm.h
@@ -28,12 +28,10 @@
     uint8_t *bytestream;
     uint8_t *bytestream_start;
     uint8_t *bytestream_end;
-    AVFrame picture;
     int maxval;                 ///< maximum value of a pixel
     int type;
 } PNMContext;
 
 int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s);
-int ff_pnm_init(AVCodecContext *avctx);
 
 #endif /* AVCODEC_PNM_H */
diff --git a/libavcodec/pnmdec.c b/libavcodec/pnmdec.c
index d0c7295..c7a7a44 100644
--- a/libavcodec/pnmdec.c
+++ b/libavcodec/pnmdec.c
@@ -24,6 +24,17 @@
 #include "put_bits.h"
 #include "pnm.h"
 
+static void samplecpy(void *dst, const void *src, int n, int maxval)
+{
+    if (maxval <= 255) {
+        memcpy(dst, src, n);
+    } else {
+        int i;
+        for (i=0; i<n/2; i++) {
+            ((uint16_t *)dst)[i] = av_be2ne16(((uint16_t *)src)[i]);
+        }
+    }
+}
 
 static int pnm_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame, AVPacket *avpkt)
@@ -47,19 +58,24 @@
         return ret;
     p->pict_type = AV_PICTURE_TYPE_I;
     p->key_frame = 1;
+    avctx->bits_per_raw_sample = av_log2(s->maxval) + 1;
 
     switch (avctx->pix_fmt) {
     default:
         return AVERROR(EINVAL);
-    case AV_PIX_FMT_RGBA64BE:
+    case AV_PIX_FMT_RGBA64:
         n = avctx->width * 8;
         components=4;
         sample_len=16;
+        if (s->maxval < 65535)
+            upgrade = 2;
         goto do_read;
-    case AV_PIX_FMT_RGB48BE:
+    case AV_PIX_FMT_RGB48:
         n = avctx->width * 6;
         components=3;
         sample_len=16;
+        if (s->maxval < 65535)
+            upgrade = 2;
         goto do_read;
     case AV_PIX_FMT_RGBA:
         n = avctx->width * 4;
@@ -70,6 +86,8 @@
         n = avctx->width * 3;
         components=3;
         sample_len=8;
+        if (s->maxval < 255)
+            upgrade = 1;
         goto do_read;
     case AV_PIX_FMT_GRAY8:
         n = avctx->width;
@@ -83,8 +101,7 @@
         components=2;
         sample_len=8;
         goto do_read;
-    case AV_PIX_FMT_GRAY16BE:
-    case AV_PIX_FMT_GRAY16LE:
+    case AV_PIX_FMT_GRAY16:
         n = avctx->width * 2;
         components=1;
         sample_len=16;
@@ -124,15 +141,19 @@
                             c = (*s->bytestream++) - '0';
                         } while (c <= 9);
                     }
-                    put_bits(&pb, sample_len, (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval);
+                    if (sample_len == 16) {
+                        ((uint16_t*)ptr)[j] = (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval;
+                    } else
+                        put_bits(&pb, sample_len, (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval);
                 }
-                flush_put_bits(&pb);
+                if (sample_len != 16)
+                    flush_put_bits(&pb);
                 ptr+= linesize;
             }
         }else{
         for (i = 0; i < avctx->height; i++) {
             if (!upgrade)
-                memcpy(ptr, s->bytestream, n);
+                samplecpy(ptr, s->bytestream, n, s->maxval);
             else if (upgrade == 1) {
                 unsigned int j, f = (255 * 128 + s->maxval / 2) / s->maxval;
                 for (j = 0; j < n; j++)
@@ -150,8 +171,8 @@
         }
         break;
     case AV_PIX_FMT_YUV420P:
-    case AV_PIX_FMT_YUV420P9BE:
-    case AV_PIX_FMT_YUV420P10BE:
+    case AV_PIX_FMT_YUV420P9:
+    case AV_PIX_FMT_YUV420P10:
         {
             unsigned char *ptr1, *ptr2;
 
@@ -163,7 +184,7 @@
             if (s->bytestream + n * avctx->height * 3 / 2 > s->bytestream_end)
                 return AVERROR_INVALIDDATA;
             for (i = 0; i < avctx->height; i++) {
-                memcpy(ptr, s->bytestream, n);
+                samplecpy(ptr, s->bytestream, n, s->maxval);
                 s->bytestream += n;
                 ptr           += linesize;
             }
@@ -172,9 +193,9 @@
             n >>= 1;
             h = avctx->height >> 1;
             for (i = 0; i < h; i++) {
-                memcpy(ptr1, s->bytestream, n);
+                samplecpy(ptr1, s->bytestream, n, s->maxval);
                 s->bytestream += n;
-                memcpy(ptr2, s->bytestream, n);
+                samplecpy(ptr2, s->bytestream, n, s->maxval);
                 s->bytestream += n;
                 ptr1 += p->linesize[1];
                 ptr2 += p->linesize[2];
diff --git a/libavcodec/pnmenc.c b/libavcodec/pnmenc.c
index 8cd96be..a3e1c78 100644
--- a/libavcodec/pnmenc.c
+++ b/libavcodec/pnmenc.c
@@ -26,10 +26,9 @@
 
 
 static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
-                            const AVFrame *pict, int *got_packet)
+                            const AVFrame *p, int *got_packet)
 {
     PNMContext *s     = avctx->priv_data;
-    AVFrame * const p = &s->picture;
     int i, h, h1, c, n, linesize, ret;
     uint8_t *ptr, *ptr1, *ptr2;
 
@@ -38,10 +37,6 @@
                                                        avctx->height) + 200)) < 0)
         return ret;
 
-    *p           = *pict;
-    p->pict_type = AV_PICTURE_TYPE_I;
-    p->key_frame = 1;
-
     s->bytestream_start =
     s->bytestream       = pkt->data;
     s->bytestream_end   = pkt->data + pkt->size;
@@ -132,7 +127,6 @@
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PGM,
     .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
     .encode2        = pnm_encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]){
         AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_NONE
@@ -147,7 +141,6 @@
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PGMYUV,
     .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
     .encode2        = pnm_encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]){
         AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P16BE, AV_PIX_FMT_NONE
@@ -162,7 +155,6 @@
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PPM,
     .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
     .encode2        = pnm_encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]){
         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB48BE, AV_PIX_FMT_NONE
@@ -177,7 +169,6 @@
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PBM,
     .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
     .encode2        = pnm_encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_MONOWHITE,
                                                   AV_PIX_FMT_NONE },
diff --git a/libavcodec/ppc/Makefile b/libavcodec/ppc/Makefile
index febbb0a..71b23da 100644
--- a/libavcodec/ppc/Makefile
+++ b/libavcodec/ppc/Makefile
@@ -1,24 +1,24 @@
 OBJS                                   += ppc/dsputil_ppc.o             \
+                                          ppc/fmtconvert_altivec.o      \
                                           ppc/videodsp_ppc.o            \
 
+OBJS-$(CONFIG_FFT)                     += ppc/fft_altivec.o
 OBJS-$(CONFIG_H264CHROMA)              += ppc/h264chroma_init.o
-OBJS-$(CONFIG_H264QPEL)                += ppc/h264_qpel.o
+OBJS-$(CONFIG_H264DSP)                 += ppc/h264dsp.o
+OBJS-$(CONFIG_H264QPEL)                += ppc/h264qpel.o
 OBJS-$(CONFIG_HPELDSP)                 += ppc/hpeldsp_altivec.o
+OBJS-$(CONFIG_MPEGAUDIODSP)            += ppc/mpegaudiodsp_altivec.o
+OBJS-$(CONFIG_MPEGVIDEO)               += ppc/mpegvideo_altivec.o
+OBJS-$(CONFIG_VC1_DECODER)             += ppc/vc1dsp_altivec.o
 OBJS-$(CONFIG_VORBIS_DECODER)          += ppc/vorbisdsp_altivec.o
 OBJS-$(CONFIG_VP3DSP)                  += ppc/vp3dsp_altivec.o
-
-FFT-OBJS-$(HAVE_GNU_AS)                += ppc/fft_altivec_s.o
-ALTIVEC-OBJS-$(CONFIG_FFT)             += ppc/fft_altivec.o             \
-                                          $(FFT-OBJS-yes)
-ALTIVEC-OBJS-$(CONFIG_H264DSP)         += ppc/h264_altivec.o
-ALTIVEC-OBJS-$(CONFIG_MPEGAUDIODSP)    += ppc/mpegaudiodec_altivec.o
-ALTIVEC-OBJS-$(CONFIG_MPEGVIDEO)       += ppc/mpegvideo_altivec.o
-ALTIVEC-OBJS-$(CONFIG_VC1_DECODER)     += ppc/vc1dsp_altivec.o
-ALTIVEC-OBJS-$(CONFIG_VP8_DECODER)     += ppc/vp8dsp_altivec.o
+OBJS-$(CONFIG_VP8_DECODER)             += ppc/vp8dsp_altivec.o
 
 ALTIVEC-OBJS                           += ppc/dsputil_altivec.o         \
                                           ppc/fdct_altivec.o            \
-                                          ppc/fmtconvert_altivec.o      \
                                           ppc/gmc_altivec.o             \
                                           ppc/idct_altivec.o            \
                                           ppc/int_altivec.o             \
+
+FFT-OBJS-$(HAVE_GNU_AS)                += ppc/fft_altivec_s.o
+ALTIVEC-OBJS-$(CONFIG_FFT)             += $(FFT-OBJS-yes)
diff --git a/libavcodec/ppc/fft_altivec.c b/libavcodec/ppc/fft_altivec.c
index 651ee26..92b7adb 100644
--- a/libavcodec/ppc/fft_altivec.c
+++ b/libavcodec/ppc/fft_altivec.c
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config.h"
 #include "libavutil/ppc/types_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
 #include "libavcodec/fft.h"
@@ -36,8 +37,8 @@
 void ff_fft_calc_altivec(FFTContext *s, FFTComplex *z);
 void ff_fft_calc_interleave_altivec(FFTContext *s, FFTComplex *z);
 
-#if HAVE_GNU_AS
-static void ff_imdct_half_altivec(FFTContext *s, FFTSample *output, const FFTSample *input)
+#if HAVE_GNU_AS && HAVE_ALTIVEC
+static void imdct_half_altivec(FFTContext *s, FFTSample *output, const FFTSample *input)
 {
     int j, k;
     int n = 1 << s->mdct_bits;
@@ -117,7 +118,7 @@
     } while(k >= 0);
 }
 
-static void ff_imdct_calc_altivec(FFTContext *s, FFTSample *output, const FFTSample *input)
+static void imdct_calc_altivec(FFTContext *s, FFTSample *output, const FFTSample *input)
 {
     int k;
     int n = 1 << s->mdct_bits;
@@ -127,7 +128,7 @@
     vec_u32 *p0 = (vec_u32*)(output+n4);
     vec_u32 *p1 = (vec_u32*)(output+n4*3);
 
-    ff_imdct_half_altivec(s, output+n4, input);
+    imdct_half_altivec(s, output + n4, input);
 
     for (k = 0; k < n16; k++) {
         vec_u32 a = p0[k] ^ sign;
@@ -136,15 +137,15 @@
         p1[k]    = vec_perm(b, b, vcprm(3,2,1,0));
     }
 }
-#endif /* HAVE_GNU_AS */
+#endif /* HAVE_GNU_AS && HAVE_ALTIVEC */
 
-av_cold void ff_fft_init_altivec(FFTContext *s)
+av_cold void ff_fft_init_ppc(FFTContext *s)
 {
-#if HAVE_GNU_AS
+#if HAVE_GNU_AS && HAVE_ALTIVEC
     s->fft_calc   = ff_fft_calc_interleave_altivec;
     if (s->mdct_bits >= 5) {
-        s->imdct_calc = ff_imdct_calc_altivec;
-        s->imdct_half = ff_imdct_half_altivec;
+        s->imdct_calc = imdct_calc_altivec;
+        s->imdct_half = imdct_half_altivec;
     }
-#endif
+#endif /* HAVE_GNU_AS && HAVE_ALTIVEC */
 }
diff --git a/libavcodec/ppc/fmtconvert_altivec.c b/libavcodec/ppc/fmtconvert_altivec.c
index b29c7d4..ee35754 100644
--- a/libavcodec/ppc/fmtconvert_altivec.c
+++ b/libavcodec/ppc/fmtconvert_altivec.c
@@ -18,14 +18,16 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/fmtconvert.h"
-
-#include "libavutil/ppc/util_altivec.h"
+#include "config.h"
 #include "libavutil/attributes.h"
 #include "libavutil/mem.h"
+#include "libavutil/ppc/util_altivec.h"
+#include "libavcodec/fmtconvert.h"
 #include "dsputil_altivec.h"
 
-static void int32_to_float_fmul_scalar_altivec(float *dst, const int *src,
+#if HAVE_ALTIVEC
+
+static void int32_to_float_fmul_scalar_altivec(float *dst, const int32_t *src,
                                                float mul, int len)
 {
     union {
@@ -156,11 +158,16 @@
     }
 }
 
-av_cold void ff_fmt_convert_init_altivec(FmtConvertContext *c, AVCodecContext *avctx)
+#endif /* HAVE_ALTIVEC */
+
+av_cold void ff_fmt_convert_init_ppc(FmtConvertContext *c,
+                                     AVCodecContext *avctx)
 {
+#if HAVE_ALTIVEC
     c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_altivec;
     if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
         c->float_to_int16 = float_to_int16_altivec;
         c->float_to_int16_interleave = float_to_int16_interleave_altivec;
     }
+#endif /* HAVE_ALTIVEC */
 }
diff --git a/libavcodec/ppc/h264chroma_init.c b/libavcodec/ppc/h264chroma_init.c
index f9e2a76..82385cc 100644
--- a/libavcodec/ppc/h264chroma_init.c
+++ b/libavcodec/ppc/h264chroma_init.c
@@ -20,15 +20,14 @@
 
 #include "config.h"
 #include "libavutil/attributes.h"
-#include "libavcodec/h264chroma.h"
-
-#if HAVE_ALTIVEC
 #include "libavutil/cpu.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/ppc/types_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
+#include "libavcodec/h264chroma.h"
 #include "dsputil_altivec.h"
 
+#if HAVE_ALTIVEC
 #define PUT_OP_U8_ALTIVEC(d, s, dst) d = s
 #define AVG_OP_U8_ALTIVEC(d, s, dst) d = vec_avg(dst, s)
 
diff --git a/libavcodec/ppc/h264_altivec.c b/libavcodec/ppc/h264dsp.c
similarity index 91%
rename from libavcodec/ppc/h264_altivec.c
rename to libavcodec/ppc/h264dsp.c
index 3c2bb4d..1670ece 100644
--- a/libavcodec/ppc/h264_altivec.c
+++ b/libavcodec/ppc/h264dsp.c
@@ -18,6 +18,7 @@
  * 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/intreadwrite.h"
@@ -26,6 +27,8 @@
 #include "libavcodec/h264data.h"
 #include "libavcodec/h264dsp.h"
 
+#if HAVE_ALTIVEC
+
 /****************************************************************************
  * IDCT transform:
  ****************************************************************************/
@@ -67,7 +70,7 @@
     va_u32 = vec_splat((vec_u32)va_u8, 0);                  \
     vec_ste(va_u32, element, (uint32_t*)dst);
 
-static void ff_h264_idct_add_altivec(uint8_t *dst, int16_t *block, int stride)
+static void h264_idct_add_altivec(uint8_t *dst, int16_t *block, int stride)
 {
     vec_s16 va0, va1, va2, va3;
     vec_s16 vz0, vz1, vz2, vz3;
@@ -182,7 +185,8 @@
     vec_st( hv, 0, dest );                                     \
  }
 
-static void ff_h264_idct8_add_altivec( uint8_t *dst, int16_t *dct, int stride ) {
+static void h264_idct8_add_altivec(uint8_t *dst, int16_t *dct, int stride)
+{
     vec_s16 s0, s1, s2, s3, s4, s5, s6, s7;
     vec_s16 d0, d1, d2, d3, d4, d5, d6, d7;
     vec_s16 idct0, idct1, idct2, idct3, idct4, idct5, idct6, idct7;
@@ -278,47 +282,59 @@
     h264_idct_dc_add_internal(dst, block, stride, 4);
 }
 
-static void ff_h264_idct8_dc_add_altivec(uint8_t *dst, int16_t *block, int stride)
+static void h264_idct8_dc_add_altivec(uint8_t *dst, int16_t *block, int stride)
 {
     h264_idct_dc_add_internal(dst, block, stride, 8);
 }
 
-static void ff_h264_idct_add16_altivec(uint8_t *dst, const int *block_offset, int16_t *block, int stride, const uint8_t nnzc[15*8]){
+static void h264_idct_add16_altivec(uint8_t *dst, const int *block_offset,
+                                    int16_t *block, int stride,
+                                    const uint8_t nnzc[15 * 8])
+{
     int i;
     for(i=0; i<16; i++){
         int nnz = nnzc[ scan8[i] ];
         if(nnz){
             if(nnz==1 && block[i*16]) h264_idct_dc_add_altivec(dst + block_offset[i], block + i*16, stride);
-            else                      ff_h264_idct_add_altivec(dst + block_offset[i], block + i*16, stride);
+            else                      h264_idct_add_altivec(dst + block_offset[i], block + i*16, stride);
         }
     }
 }
 
-static void ff_h264_idct_add16intra_altivec(uint8_t *dst, const int *block_offset, int16_t *block, int stride, const uint8_t nnzc[15*8]){
+static void h264_idct_add16intra_altivec(uint8_t *dst, const int *block_offset,
+                                         int16_t *block, int stride,
+                                         const uint8_t nnzc[15 * 8])
+{
     int i;
     for(i=0; i<16; i++){
-        if(nnzc[ scan8[i] ]) ff_h264_idct_add_altivec(dst + block_offset[i], block + i*16, stride);
+        if(nnzc[ scan8[i] ]) h264_idct_add_altivec(dst + block_offset[i], block + i*16, stride);
         else if(block[i*16]) h264_idct_dc_add_altivec(dst + block_offset[i], block + i*16, stride);
     }
 }
 
-static void ff_h264_idct8_add4_altivec(uint8_t *dst, const int *block_offset, int16_t *block, int stride, const uint8_t nnzc[15*8]){
+static void h264_idct8_add4_altivec(uint8_t *dst, const int *block_offset,
+                                    int16_t *block, int stride,
+                                    const uint8_t nnzc[15 * 8])
+{
     int i;
     for(i=0; i<16; i+=4){
         int nnz = nnzc[ scan8[i] ];
         if(nnz){
-            if(nnz==1 && block[i*16]) ff_h264_idct8_dc_add_altivec(dst + block_offset[i], block + i*16, stride);
-            else                      ff_h264_idct8_add_altivec   (dst + block_offset[i], block + i*16, stride);
+            if(nnz==1 && block[i*16]) h264_idct8_dc_add_altivec(dst + block_offset[i], block + i*16, stride);
+            else                      h264_idct8_add_altivec(dst + block_offset[i], block + i*16, stride);
         }
     }
 }
 
-static void ff_h264_idct_add8_altivec(uint8_t **dest, const int *block_offset, int16_t *block, int stride, const uint8_t nnzc[15*8]){
+static void h264_idct_add8_altivec(uint8_t **dest, const int *block_offset,
+                                   int16_t *block, int stride,
+                                   const uint8_t nnzc[15 * 8])
+{
     int i, j;
     for (j = 1; j < 3; j++) {
         for(i = j * 16; i < j * 16 + 4; i++){
             if(nnzc[ scan8[i] ])
-                ff_h264_idct_add_altivec(dest[j-1] + block_offset[i], block + i*16, stride);
+                h264_idct_add_altivec(dest[j-1] + block_offset[i], block + i*16, stride);
             else if(block[i*16])
                 h264_idct_dc_add_altivec(dest[j-1] + block_offset[i], block + i*16, stride);
         }
@@ -710,39 +726,44 @@
 }
 
 #define H264_WEIGHT(W) \
-static void ff_weight_h264_pixels ## W ## _altivec(uint8_t *block, int stride, int height, \
-                                                   int log2_denom, int weight, int offset){ \
+static void weight_h264_pixels ## W ## _altivec(uint8_t *block, int stride, int height, \
+                                                int log2_denom, int weight, int offset) \
+{ \
     weight_h264_W_altivec(block, stride, height, log2_denom, weight, offset, W); \
 }\
-static void ff_biweight_h264_pixels ## W ## _altivec(uint8_t *dst, uint8_t *src, int stride, int height, \
-                                                     int log2_denom, int weightd, int weights, int offset){ \
+static void biweight_h264_pixels ## W ## _altivec(uint8_t *dst, uint8_t *src, int stride, int height, \
+                                                  int log2_denom, int weightd, int weights, int offset) \
+{ \
     biweight_h264_W_altivec(dst, src, stride, height, log2_denom, weightd, weights, offset, W); \
 }
 
 H264_WEIGHT(16)
 H264_WEIGHT( 8)
+#endif /* HAVE_ALTIVEC */
 
 av_cold void ff_h264dsp_init_ppc(H264DSPContext *c, const int bit_depth,
                                  const int chroma_format_idc)
 {
+#if HAVE_ALTIVEC
     if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) {
     if (bit_depth == 8) {
-        c->h264_idct_add = ff_h264_idct_add_altivec;
+        c->h264_idct_add = h264_idct_add_altivec;
         if (chroma_format_idc == 1)
-            c->h264_idct_add8 = ff_h264_idct_add8_altivec;
-        c->h264_idct_add16 = ff_h264_idct_add16_altivec;
-        c->h264_idct_add16intra = ff_h264_idct_add16intra_altivec;
+            c->h264_idct_add8 = h264_idct_add8_altivec;
+        c->h264_idct_add16      = h264_idct_add16_altivec;
+        c->h264_idct_add16intra = h264_idct_add16intra_altivec;
         c->h264_idct_dc_add= h264_idct_dc_add_altivec;
-        c->h264_idct8_dc_add = ff_h264_idct8_dc_add_altivec;
-        c->h264_idct8_add = ff_h264_idct8_add_altivec;
-        c->h264_idct8_add4 = ff_h264_idct8_add4_altivec;
+        c->h264_idct8_dc_add = h264_idct8_dc_add_altivec;
+        c->h264_idct8_add    = h264_idct8_add_altivec;
+        c->h264_idct8_add4   = h264_idct8_add4_altivec;
         c->h264_v_loop_filter_luma= h264_v_loop_filter_luma_altivec;
         c->h264_h_loop_filter_luma= h264_h_loop_filter_luma_altivec;
 
-        c->weight_h264_pixels_tab[0] = ff_weight_h264_pixels16_altivec;
-        c->weight_h264_pixels_tab[1] = ff_weight_h264_pixels8_altivec;
-        c->biweight_h264_pixels_tab[0] = ff_biweight_h264_pixels16_altivec;
-        c->biweight_h264_pixels_tab[1] = ff_biweight_h264_pixels8_altivec;
+        c->weight_h264_pixels_tab[0]   = weight_h264_pixels16_altivec;
+        c->weight_h264_pixels_tab[1]   = weight_h264_pixels8_altivec;
+        c->biweight_h264_pixels_tab[0] = biweight_h264_pixels16_altivec;
+        c->biweight_h264_pixels_tab[1] = biweight_h264_pixels8_altivec;
     }
     }
+#endif /* HAVE_ALTIVEC */
 }
diff --git a/libavcodec/ppc/h264_qpel.c b/libavcodec/ppc/h264qpel.c
similarity index 99%
rename from libavcodec/ppc/h264_qpel.c
rename to libavcodec/ppc/h264qpel.c
index 429ae42..bda7b18 100644
--- a/libavcodec/ppc/h264_qpel.c
+++ b/libavcodec/ppc/h264qpel.c
@@ -20,15 +20,15 @@
 
 #include "config.h"
 #include "libavutil/attributes.h"
-#include "libavcodec/h264qpel.h"
-
-#if HAVE_ALTIVEC
 #include "libavutil/cpu.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/ppc/types_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
+#include "libavcodec/h264qpel.h"
 #include "dsputil_altivec.h"
 
+#if HAVE_ALTIVEC
+
 #define PUT_OP_U8_ALTIVEC(d, s, dst) d = s
 #define AVG_OP_U8_ALTIVEC(d, s, dst) d = vec_avg(dst, s)
 
@@ -39,7 +39,7 @@
 #define PREFIX_h264_qpel16_v_lowpass_num       altivec_put_h264_qpel16_v_lowpass_num
 #define PREFIX_h264_qpel16_hv_lowpass_altivec  put_h264_qpel16_hv_lowpass_altivec
 #define PREFIX_h264_qpel16_hv_lowpass_num      altivec_put_h264_qpel16_hv_lowpass_num
-#include "h264_qpel_template.c"
+#include "h264qpel_template.c"
 #undef OP_U8_ALTIVEC
 #undef PREFIX_h264_qpel16_h_lowpass_altivec
 #undef PREFIX_h264_qpel16_h_lowpass_num
@@ -55,7 +55,7 @@
 #define PREFIX_h264_qpel16_v_lowpass_num       altivec_avg_h264_qpel16_v_lowpass_num
 #define PREFIX_h264_qpel16_hv_lowpass_altivec  avg_h264_qpel16_hv_lowpass_altivec
 #define PREFIX_h264_qpel16_hv_lowpass_num      altivec_avg_h264_qpel16_hv_lowpass_num
-#include "h264_qpel_template.c"
+#include "h264qpel_template.c"
 #undef OP_U8_ALTIVEC
 #undef PREFIX_h264_qpel16_h_lowpass_altivec
 #undef PREFIX_h264_qpel16_h_lowpass_num
diff --git a/libavcodec/ppc/h264_qpel_template.c b/libavcodec/ppc/h264qpel_template.c
similarity index 100%
rename from libavcodec/ppc/h264_qpel_template.c
rename to libavcodec/ppc/h264qpel_template.c
diff --git a/libavcodec/ppc/hpeldsp_altivec.c b/libavcodec/ppc/hpeldsp_altivec.c
index 5bc812a..4f3c4fa 100644
--- a/libavcodec/ppc/hpeldsp_altivec.c
+++ b/libavcodec/ppc/hpeldsp_altivec.c
@@ -21,18 +21,19 @@
  */
 
 #include "config.h"
-#include "libavutil/attributes.h"
-#include "libavutil/cpu.h"
-#include "libavcodec/hpeldsp.h"
 
-#if HAVE_ALTIVEC
 #if HAVE_ALTIVEC_H
 #include <altivec.h>
 #endif
+
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
 #include "libavutil/ppc/types_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
+#include "libavcodec/hpeldsp.h"
 #include "dsputil_altivec.h"
 
+#if HAVE_ALTIVEC
 /* next one assumes that ((line_size % 16) == 0) */
 void ff_put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
@@ -448,9 +449,7 @@
 av_cold void ff_hpeldsp_init_ppc(HpelDSPContext *c, int flags)
 {
 #if HAVE_ALTIVEC
-    int mm_flags = av_get_cpu_flags();
-
-    if (mm_flags & AV_CPU_FLAG_ALTIVEC) {
+    if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) {
         c->avg_pixels_tab[0][0]        = ff_avg_pixels16_altivec;
         c->avg_pixels_tab[1][0]        = avg_pixels8_altivec;
         c->avg_pixels_tab[1][3]        = avg_pixels8_xy2_altivec;
diff --git a/libavcodec/ppc/int_altivec.c b/libavcodec/ppc/int_altivec.c
index 4386b13..d4e0c85 100644
--- a/libavcodec/ppc/int_altivec.c
+++ b/libavcodec/ppc/int_altivec.c
@@ -84,14 +84,12 @@
 {
     int i;
     LOAD_ZERO;
-    const vec_s16 *pv;
     register vec_s16 vec1;
     register vec_s32 res = vec_splat_s32(0), t;
     int32_t ires;
 
     for(i = 0; i < order; i += 8){
-        pv = (const vec_s16*)v1;
-        vec1 = vec_perm(pv[0], pv[1], vec_lvsl(0, v1));
+        vec1 = vec_unaligned_load(v1);
         t = vec_msum(vec1, vec_ld(0, v2), zero_s32v);
         res = vec_sums(t, res);
         v1 += 8;
@@ -129,8 +127,8 @@
         pv1[0] = vec_mladd(t0, muls, i0);
         pv1[1] = vec_mladd(t1, muls, i1);
         pv1 += 2;
-        v2  += 8;
-        v3  += 8;
+        v2  += 16;
+        v3  += 16;
     } while(--order);
     res = vec_splat(vec_sums(res, zero_s32v), 3);
     vec_ste(res, 0, &ires);
diff --git a/libavcodec/ppc/mpegaudiodec_altivec.c b/libavcodec/ppc/mpegaudiodsp_altivec.c
similarity index 95%
rename from libavcodec/ppc/mpegaudiodec_altivec.c
rename to libavcodec/ppc/mpegaudiodsp_altivec.c
index 1152fd7..1d82f74 100644
--- a/libavcodec/ppc/mpegaudiodec_altivec.c
+++ b/libavcodec/ppc/mpegaudiodsp_altivec.c
@@ -19,11 +19,14 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "dsputil_altivec.h"
+#include "config.h"
 #include "libavutil/attributes.h"
 #include "libavutil/internal.h"
 #include "libavutil/ppc/util_altivec.h"
 #include "libavcodec/mpegaudiodsp.h"
+#include "dsputil_altivec.h"
+
+#if HAVE_ALTIVEC
 
 #define MACS(rt, ra, rb) rt+=(ra)*(rb)
 #define MLSS(rt, ra, rb) rt-=(ra)*(rb)
@@ -124,7 +127,11 @@
     *out = sum;
 }
 
-av_cold void ff_mpadsp_init_altivec(MPADSPContext *s)
+#endif /* HAVE_ALTIVEC */
+
+av_cold void ff_mpadsp_init_ppc(MPADSPContext *s)
 {
+#if HAVE_ALTIVEC
     s->apply_window_float = apply_window_mp3;
+#endif /* HAVE_ALTIVEC */
 }
diff --git a/libavcodec/ppc/mpegvideo_altivec.c b/libavcodec/ppc/mpegvideo_altivec.c
index bf490b0..4e80e3a 100644
--- a/libavcodec/ppc/mpegvideo_altivec.c
+++ b/libavcodec/ppc/mpegvideo_altivec.c
@@ -24,14 +24,16 @@
 #include <stdlib.h>
 #include <stdio.h>
 
+#include "config.h"
 #include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/ppc/types_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
 #include "libavcodec/mpegvideo.h"
-
 #include "dsputil_altivec.h"
 
+#if HAVE_ALTIVEC
+
 /* AltiVec version of dct_unquantize_h263
    this code assumes `block' is 16 bytes-aligned */
 static void dct_unquantize_h263_altivec(MpegEncContext *s,
@@ -111,9 +113,11 @@
     }
 }
 
+#endif /* HAVE_ALTIVEC */
 
-av_cold void ff_MPV_common_init_altivec(MpegEncContext *s)
+av_cold void ff_MPV_common_init_ppc(MpegEncContext *s)
 {
+#if HAVE_ALTIVEC
     if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) return;
 
     if ((s->avctx->dct_algo == FF_DCT_AUTO) ||
@@ -121,4 +125,5 @@
         s->dct_unquantize_h263_intra = dct_unquantize_h263_altivec;
         s->dct_unquantize_h263_inter = dct_unquantize_h263_altivec;
     }
+#endif /* HAVE_ALTIVEC */
 }
diff --git a/libavcodec/ppc/vc1dsp_altivec.c b/libavcodec/ppc/vc1dsp_altivec.c
index 9c2ad70..1b73dd0 100644
--- a/libavcodec/ppc/vc1dsp_altivec.c
+++ b/libavcodec/ppc/vc1dsp_altivec.c
@@ -19,11 +19,14 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config.h"
 #include "libavutil/attributes.h"
 #include "libavutil/ppc/types_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
 #include "libavcodec/vc1dsp.h"
 
+#if HAVE_ALTIVEC
+
 // main steps of 8x8 transform
 #define STEP8(s0, s1, s2, s3, s4, s5, s6, s7, vec_rnd) \
 do { \
@@ -335,8 +338,11 @@
 #undef OP_U8_ALTIVEC
 #undef PREFIX_no_rnd_vc1_chroma_mc8_altivec
 
-av_cold void ff_vc1dsp_init_altivec(VC1DSPContext *dsp)
+#endif /* HAVE_ALTIVEC */
+
+av_cold void ff_vc1dsp_init_ppc(VC1DSPContext *dsp)
 {
+#if HAVE_ALTIVEC
     if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
         return;
 
@@ -344,4 +350,5 @@
     dsp->vc1_inv_trans_8x4 = vc1_inv_trans_8x4_altivec;
     dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = put_no_rnd_vc1_chroma_mc8_altivec;
     dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = avg_no_rnd_vc1_chroma_mc8_altivec;
+#endif /* HAVE_ALTIVEC */
 }
diff --git a/libavcodec/ppc/vp3dsp_altivec.c b/libavcodec/ppc/vp3dsp_altivec.c
index cc587b0..502b8b7 100644
--- a/libavcodec/ppc/vp3dsp_altivec.c
+++ b/libavcodec/ppc/vp3dsp_altivec.c
@@ -23,14 +23,13 @@
 #include "config.h"
 #include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
-#include "libavcodec/vp3dsp.h"
-
-#if HAVE_ALTIVEC
-
 #include "libavutil/ppc/types_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
+#include "libavcodec/vp3dsp.h"
 #include "dsputil_altivec.h"
 
+#if HAVE_ALTIVEC
+
 static const vec_s16 constants =
     {0, 64277, 60547, 54491, 46341, 36410, 25080, 12785};
 static const vec_u8 interleave_high =
diff --git a/libavcodec/ppc/vp8dsp_altivec.c b/libavcodec/ppc/vp8dsp_altivec.c
index 14d8784..2401d2a 100644
--- a/libavcodec/ppc/vp8dsp_altivec.c
+++ b/libavcodec/ppc/vp8dsp_altivec.c
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config.h"
 #include "libavutil/cpu.h"
 #include "libavutil/mem.h"
 #include "libavutil/ppc/types_altivec.h"
@@ -27,6 +28,7 @@
 #include "libavcodec/vp8dsp.h"
 #include "dsputil_altivec.h"
 
+#if HAVE_ALTIVEC
 #define REPT4(...) { __VA_ARGS__, __VA_ARGS__, __VA_ARGS__, __VA_ARGS__ }
 
 // h subpel filter uses msum to multiply+add 4 pixel taps at once
@@ -272,8 +274,11 @@
     ff_put_pixels16_altivec(dst, src, stride, h);
 }
 
-av_cold void ff_vp8dsp_init_altivec(VP8DSPContext *c)
+#endif /* HAVE_ALTIVEC */
+
+av_cold void ff_vp8dsp_init_ppc(VP8DSPContext *c)
 {
+#if HAVE_ALTIVEC
     if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
         return;
 
@@ -301,4 +306,5 @@
     c->put_vp8_epel_pixels_tab[2][1][1] = put_vp8_epel4_h4v4_altivec;
     c->put_vp8_epel_pixels_tab[2][1][2] = put_vp8_epel4_h6v4_altivec;
     c->put_vp8_epel_pixels_tab[2][2][1] = put_vp8_epel4_h4v6_altivec;
+#endif /* HAVE_ALTIVEC */
 }
diff --git a/libavcodec/proresdec.h b/libavcodec/proresdec.h
index f42c448..de50dae 100644
--- a/libavcodec/proresdec.h
+++ b/libavcodec/proresdec.h
@@ -49,6 +49,7 @@
     uint8_t interlaced_scan[64];
     const uint8_t *scan;
     int first_field;
+    int alpha_info;
 } ProresContext;
 
 #endif /* AVCODEC_PRORESDEC_H */
diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c
index bd6404a..5037bb8 100644
--- a/libavcodec/proresdec2.c
+++ b/libavcodec/proresdec2.c
@@ -112,6 +112,12 @@
     }
 
     ctx->frame_type = (buf[12] >> 2) & 3;
+    ctx->alpha_info = buf[17] & 0xf;
+
+    if (ctx->alpha_info > 2) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid alpha mode %d\n", ctx->alpha_info);
+        return AVERROR_INVALIDDATA;
+    }
 
     av_dlog(avctx, "frame type %d\n", ctx->frame_type);
 
@@ -123,7 +129,11 @@
         ctx->frame->top_field_first = ctx->frame_type == 1;
     }
 
-    avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUV444P10 : AV_PIX_FMT_YUV422P10;
+    if (ctx->alpha_info) {
+        avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUVA444P10 : AV_PIX_FMT_YUVA422P10;
+    } else {
+        avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUV444P10 : AV_PIX_FMT_YUV422P10;
+    }
 
     ptr   = buf + 20;
     flags = buf[19];
@@ -422,6 +432,83 @@
     }
 }
 
+static void unpack_alpha(GetBitContext *gb, uint16_t *dst, int num_coeffs,
+                         const int num_bits)
+{
+    const int mask = (1 << num_bits) - 1;
+    int i, idx, val, alpha_val;
+
+    idx       = 0;
+    alpha_val = mask;
+    do {
+        do {
+            if (get_bits1(gb)) {
+                val = get_bits(gb, num_bits);
+            } else {
+                int sign;
+                val  = get_bits(gb, num_bits == 16 ? 7 : 4);
+                sign = val & 1;
+                val  = (val + 2) >> 1;
+                if (sign)
+                    val = -val;
+            }
+            alpha_val = (alpha_val + val) & mask;
+            if (num_bits == 16) {
+                dst[idx++] = alpha_val >> 6;
+            } else {
+                dst[idx++] = (alpha_val << 2) | (alpha_val >> 6);
+            }
+            if (idx >= num_coeffs)
+                break;
+        } while (get_bits_left(gb)>0 && get_bits1(gb));
+        val = get_bits(gb, 4);
+        if (!val)
+            val = get_bits(gb, 11);
+        if (idx + val > num_coeffs)
+            val = num_coeffs - idx;
+        if (num_bits == 16) {
+            for (i = 0; i < val; i++)
+                dst[idx++] = alpha_val >> 6;
+        } else {
+            for (i = 0; i < val; i++)
+                dst[idx++] = (alpha_val << 2) | (alpha_val >> 6);
+
+        }
+    } while (idx < num_coeffs);
+}
+
+/**
+ * Decode alpha slice plane.
+ */
+static void decode_slice_alpha(ProresContext *ctx,
+                               uint16_t *dst, int dst_stride,
+                               const uint8_t *buf, int buf_size,
+                               int blocks_per_slice)
+{
+    GetBitContext gb;
+    int i;
+    LOCAL_ALIGNED_16(int16_t, blocks, [8*4*64]);
+    int16_t *block;
+
+    for (i = 0; i < blocks_per_slice<<2; i++)
+        ctx->dsp.clear_block(blocks+(i<<6));
+
+    init_get_bits(&gb, buf, buf_size << 3);
+
+    if (ctx->alpha_info == 2) {
+        unpack_alpha(&gb, blocks, blocks_per_slice * 4 * 64, 16);
+    } else {
+        unpack_alpha(&gb, blocks, blocks_per_slice * 4 * 64, 8);
+    }
+
+    block = blocks;
+    for (i = 0; i < 16; i++) {
+        memcpy(dst, block, 16 * blocks_per_slice * sizeof(*dst));
+        dst   += dst_stride >> 1;
+        block += 16 * blocks_per_slice;
+    }
+}
+
 static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr)
 {
     ProresContext *ctx = avctx->priv_data;
@@ -430,8 +517,8 @@
     AVFrame *pic = ctx->frame;
     int i, hdr_size, qscale, log2_chroma_blocks_per_mb;
     int luma_stride, chroma_stride;
-    int y_data_size, u_data_size, v_data_size;
-    uint8_t *dest_y, *dest_u, *dest_v;
+    int y_data_size, u_data_size, v_data_size, a_data_size;
+    uint8_t *dest_y, *dest_u, *dest_v, *dest_a;
     int16_t qmat_luma_scaled[64];
     int16_t qmat_chroma_scaled[64];
     int mb_x_shift;
@@ -448,6 +535,8 @@
     u_data_size = AV_RB16(buf + 4);
     v_data_size = slice->data_size - y_data_size - u_data_size - hdr_size;
     if (hdr_size > 7) v_data_size = AV_RB16(buf + 6);
+    a_data_size = slice->data_size - y_data_size - u_data_size -
+                  v_data_size - hdr_size;
 
     if (y_data_size < 0 || u_data_size < 0 || v_data_size < 0
         || hdr_size+y_data_size+u_data_size+v_data_size > slice->data_size){
@@ -470,7 +559,7 @@
         chroma_stride = pic->linesize[1] << 1;
     }
 
-    if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10) {
+    if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10 || avctx->pix_fmt == AV_PIX_FMT_YUVA444P10) {
         mb_x_shift = 5;
         log2_chroma_blocks_per_mb = 2;
     } else {
@@ -481,11 +570,13 @@
     dest_y = pic->data[0] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5);
     dest_u = pic->data[1] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift);
     dest_v = pic->data[2] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift);
+    dest_a = pic->data[3] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5);
 
     if (ctx->frame_type && ctx->first_field ^ ctx->frame->top_field_first) {
         dest_y += pic->linesize[0];
         dest_u += pic->linesize[1];
         dest_v += pic->linesize[2];
+        dest_a += pic->linesize[3];
     }
 
     decode_slice_luma(avctx, slice, (uint16_t*)dest_y, luma_stride,
@@ -499,6 +590,11 @@
                             buf + y_data_size + u_data_size, v_data_size,
                             qmat_chroma_scaled, log2_chroma_blocks_per_mb);
     }
+    /* decode alpha plane if available */
+    if (ctx->alpha_info && pic->data[3] && a_data_size)
+        decode_slice_alpha(ctx, (uint16_t*)dest_a, luma_stride,
+                           buf + y_data_size + u_data_size + v_data_size,
+                           a_data_size, slice->mb_count);
 
     slice->ret = 0;
     return 0;
diff --git a/libavcodec/proresdec_lgpl.c b/libavcodec/proresdec_lgpl.c
index 59c9843..5e98d55 100644
--- a/libavcodec/proresdec_lgpl.c
+++ b/libavcodec/proresdec_lgpl.c
@@ -134,12 +134,21 @@
     ctx->chroma_factor     = (buf[12] >> 6) & 3;
     ctx->mb_chroma_factor  = ctx->chroma_factor + 2;
     ctx->num_chroma_blocks = (1 << ctx->chroma_factor) >> 1;
+    ctx->alpha_info        = buf[17] & 0xf;
+
+    if (ctx->alpha_info > 2) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid alpha mode %d\n", ctx->alpha_info);
+        return AVERROR_INVALIDDATA;
+    }
+
     switch (ctx->chroma_factor) {
     case 2:
-        avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
+        avctx->pix_fmt = ctx->alpha_info ? AV_PIX_FMT_YUVA422P10
+                                         : AV_PIX_FMT_YUV422P10;
         break;
     case 3:
-        avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
+        avctx->pix_fmt = ctx->alpha_info ? AV_PIX_FMT_YUVA444P10
+                                         : AV_PIX_FMT_YUV444P10;
         break;
     default:
         av_log(avctx, AV_LOG_ERROR,
@@ -168,10 +177,6 @@
     avctx->color_trc       = buf[15];
     avctx->colorspace      = buf[16];
 
-    ctx->alpha_info = buf[17] & 0xf;
-    if (ctx->alpha_info)
-        avpriv_report_missing_feature(avctx, "Alpha channel");
-
     ctx->qmat_changed = 0;
     ptr   = buf + 20;
     flags = buf[19];
@@ -466,6 +471,78 @@
 }
 
 
+static void unpack_alpha(GetBitContext *gb, uint16_t *dst, int num_coeffs,
+                         const int num_bits)
+{
+    const int mask = (1 << num_bits) - 1;
+    int i, idx, val, alpha_val;
+
+    idx       = 0;
+    alpha_val = mask;
+    do {
+        do {
+            if (get_bits1(gb))
+                val = get_bits(gb, num_bits);
+            else {
+                int sign;
+                val  = get_bits(gb, num_bits == 16 ? 7 : 4);
+                sign = val & 1;
+                val  = (val + 2) >> 1;
+                if (sign)
+                    val = -val;
+            }
+            alpha_val = (alpha_val + val) & mask;
+            if (num_bits == 16)
+                dst[idx++] = alpha_val >> 6;
+            else
+                dst[idx++] = (alpha_val << 2) | (alpha_val >> 6);
+            if (idx >= num_coeffs)
+                break;
+        } while (get_bits1(gb));
+        val = get_bits(gb, 4);
+        if (!val)
+            val = get_bits(gb, 11);
+        if (idx + val > num_coeffs)
+            val = num_coeffs - idx;
+        if (num_bits == 16)
+            for (i = 0; i < val; i++)
+                dst[idx++] = alpha_val >> 6;
+        else
+            for (i = 0; i < val; i++)
+                dst[idx++] = (alpha_val << 2) | (alpha_val >> 6);
+    } while (idx < num_coeffs);
+}
+
+/**
+ * Decode alpha slice plane.
+ */
+static void decode_alpha_plane(ProresContext *ctx, ProresThreadData *td,
+                               const uint8_t *buf, int data_size,
+                               uint16_t *out_ptr, int linesize,
+                               int mbs_per_slice)
+{
+    GetBitContext gb;
+    int i;
+    uint16_t *block_ptr;
+
+    memset(td->blocks, 0, 8 * 4 * 64 * sizeof(*td->blocks));
+
+    init_get_bits(&gb, buf, data_size << 3);
+
+    if (ctx->alpha_info == 2)
+        unpack_alpha(&gb, td->blocks, mbs_per_slice * 4 * 64, 16);
+    else
+        unpack_alpha(&gb, td->blocks, mbs_per_slice * 4 * 64, 8);
+
+    block_ptr = td->blocks;
+
+    for (i = 0; i < 16; i++) {
+        memcpy(out_ptr, block_ptr, 16 * mbs_per_slice * sizeof(*out_ptr));
+        out_ptr   += linesize >> 1;
+        block_ptr += 16 * mbs_per_slice;
+    }
+}
+
 static int decode_slice(AVCodecContext *avctx, void *tdata)
 {
     ProresThreadData *td = tdata;
@@ -476,11 +553,13 @@
     int slice_num = td->slice_num;
     int mbs_per_slice = td->slice_width;
     const uint8_t *buf;
-    uint8_t *y_data, *u_data, *v_data;
+    uint8_t *y_data, *u_data, *v_data, *a_data;
     AVFrame *pic = ctx->frame;
     int i, sf, slice_width_factor;
-    int slice_data_size, hdr_size, y_data_size, u_data_size, v_data_size;
-    int y_linesize, u_linesize, v_linesize;
+    int slice_data_size, hdr_size;
+    int y_data_size, u_data_size, v_data_size, a_data_size;
+    int y_linesize, u_linesize, v_linesize, a_linesize;
+    int coff[4];
 
     buf             = ctx->slice_data[slice_num].index;
     slice_data_size = ctx->slice_data[slice_num + 1].index - buf;
@@ -490,20 +569,30 @@
     y_data     = pic->data[0];
     u_data     = pic->data[1];
     v_data     = pic->data[2];
+    a_data     = pic->data[3];
     y_linesize = pic->linesize[0];
     u_linesize = pic->linesize[1];
     v_linesize = pic->linesize[2];
+    a_linesize = pic->linesize[3];
 
     if (pic->interlaced_frame) {
         if (!(pic_num ^ pic->top_field_first)) {
             y_data += y_linesize;
             u_data += u_linesize;
             v_data += v_linesize;
+            if (a_data)
+                a_data += a_linesize;
         }
         y_linesize <<= 1;
         u_linesize <<= 1;
         v_linesize <<= 1;
+        a_linesize <<= 1;
     }
+    y_data += (mb_y_pos << 4) * y_linesize + (mb_x_pos << 5);
+    u_data += (mb_y_pos << 4) * u_linesize + (mb_x_pos << ctx->mb_chroma_factor);
+    v_data += (mb_y_pos << 4) * v_linesize + (mb_x_pos << ctx->mb_chroma_factor);
+    if (a_data)
+        a_data += (mb_y_pos << 4) * a_linesize + (mb_x_pos << 5);
 
     if (slice_data_size < 6) {
         av_log(avctx, AV_LOG_ERROR, "slice data too small\n");
@@ -512,13 +601,18 @@
 
     /* parse slice header */
     hdr_size    = buf[0] >> 3;
+    coff[0]     = hdr_size;
     y_data_size = AV_RB16(buf + 2);
+    coff[1]     = coff[0] + y_data_size;
     u_data_size = AV_RB16(buf + 4);
-    v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) :
-        slice_data_size - y_data_size - u_data_size - hdr_size;
+    coff[2]     = coff[1] + u_data_size;
+    v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) : slice_data_size - coff[2];
+    coff[3]     = coff[2] + v_data_size;
+    a_data_size = slice_data_size - coff[3];
 
-    if (hdr_size + y_data_size + u_data_size + v_data_size > slice_data_size ||
-        v_data_size < 0 || hdr_size < 6) {
+    /* if V or alpha component size is negative that means that previous
+       component sizes are too large */
+    if (v_data_size < 0 || a_data_size < 0 || hdr_size < 6) {
         av_log(avctx, AV_LOG_ERROR, "invalid data size\n");
         return AVERROR_INVALIDDATA;
     }
@@ -537,29 +631,31 @@
     }
 
     /* decode luma plane */
-    decode_slice_plane(ctx, td, buf + hdr_size, y_data_size,
-                       (uint16_t*) (y_data + (mb_y_pos << 4) * y_linesize +
-                                    (mb_x_pos << 5)), y_linesize,
+    decode_slice_plane(ctx, td, buf + coff[0], y_data_size,
+                       (uint16_t*) y_data, y_linesize,
                        mbs_per_slice, 4, slice_width_factor + 2,
                        td->qmat_luma_scaled, 0);
 
     /* decode U chroma plane */
-    decode_slice_plane(ctx, td, buf + hdr_size + y_data_size, u_data_size,
-                       (uint16_t*) (u_data + (mb_y_pos << 4) * u_linesize +
-                                    (mb_x_pos << ctx->mb_chroma_factor)),
-                       u_linesize, mbs_per_slice, ctx->num_chroma_blocks,
+    decode_slice_plane(ctx, td, buf + coff[1], u_data_size,
+                       (uint16_t*) u_data, u_linesize,
+                       mbs_per_slice, ctx->num_chroma_blocks,
                        slice_width_factor + ctx->chroma_factor - 1,
                        td->qmat_chroma_scaled, 1);
 
     /* decode V chroma plane */
-    decode_slice_plane(ctx, td, buf + hdr_size + y_data_size + u_data_size,
-                       v_data_size,
-                       (uint16_t*) (v_data + (mb_y_pos << 4) * v_linesize +
-                                    (mb_x_pos << ctx->mb_chroma_factor)),
-                       v_linesize, mbs_per_slice, ctx->num_chroma_blocks,
+    decode_slice_plane(ctx, td, buf + coff[2], v_data_size,
+                       (uint16_t*) v_data, v_linesize,
+                       mbs_per_slice, ctx->num_chroma_blocks,
                        slice_width_factor + ctx->chroma_factor - 1,
                        td->qmat_chroma_scaled, 1);
 
+    /* decode alpha plane if available */
+    if (a_data && a_data_size)
+        decode_alpha_plane(ctx, td, buf + coff[3], a_data_size,
+                           (uint16_t*) a_data, a_linesize,
+                           mbs_per_slice);
+
     return 0;
 }
 
diff --git a/libavcodec/proresdsp.c b/libavcodec/proresdsp.c
index 15e122f..95176a5 100644
--- a/libavcodec/proresdsp.c
+++ b/libavcodec/proresdsp.c
@@ -20,11 +20,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
+#include "libavutil/common.h"
 #include "dct.h"
 #include "dsputil.h"
 #include "proresdsp.h"
 #include "simple_idct.h"
-#include "libavutil/common.h"
 
 #define BIAS     (1 << (PRORES_BITS_PER_SAMPLE - 1))           ///< bias value for converting signed pixels into unsigned ones
 #define CLIP_MIN (1 << (PRORES_BITS_PER_SAMPLE - 8))           ///< minimum value for clipping resulting pixels
@@ -71,7 +72,7 @@
 }
 #endif
 
-void ff_proresdsp_init(ProresDSPContext *dsp, AVCodecContext *avctx)
+av_cold void ff_proresdsp_init(ProresDSPContext *dsp, AVCodecContext *avctx)
 {
 #if CONFIG_PRORES_DECODER | CONFIG_PRORES_LGPL_DECODER
     dsp->idct_put = prores_idct_put_c;
diff --git a/libavcodec/proresenc_kostya.c b/libavcodec/proresenc_kostya.c
index 2d6dcce..92a5f3b 100644
--- a/libavcodec/proresenc_kostya.c
+++ b/libavcodec/proresenc_kostya.c
@@ -24,6 +24,7 @@
  */
 
 #include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
 #include "avcodec.h"
 #include "dsputil.h"
 #include "put_bits.h"
@@ -37,13 +38,14 @@
 
 #define MAX_MBS_PER_SLICE 8
 
-#define MAX_PLANES 3 // should be increased to 4 when there's AV_PIX_FMT_YUV444AP10
+#define MAX_PLANES 4
 
 enum {
     PRORES_PROFILE_PROXY = 0,
     PRORES_PROFILE_LT,
     PRORES_PROFILE_STANDARD,
     PRORES_PROFILE_HQ,
+    PRORES_PROFILE_4444,
 };
 
 enum {
@@ -122,7 +124,7 @@
     int         max_quant;
     int         br_tab[NUM_MB_LIMITS];
     int         quant;
-} prores_profile_info[4] = {
+} prores_profile_info[5] = {
     {
         .full_name = "proxy",
         .tag       = MKTAG('a', 'p', 'c', 'o'),
@@ -154,8 +156,15 @@
         .max_quant = 6,
         .br_tab    = { 1566, 1216, 1070, 950 },
         .quant     = QUANT_MAT_HQ,
+    },
+    {
+        .full_name = "4444",
+        .tag       = MKTAG('a', 'p', '4', 'h'),
+        .min_quant = 1,
+        .max_quant = 6,
+        .br_tab    = { 2350, 1828, 1600, 1425 },
+        .quant     = QUANT_MAT_HQ,
     }
-// for 4444 profile bitrate numbers are { 2350, 1828, 1600, 1425 }
 };
 
 #define TRELLIS_WIDTH 16
@@ -198,6 +207,7 @@
     int num_planes;
     int bits_per_mb;
     int force_quant;
+    int alpha_bits;
 
     char *vendor;
     int quant_sel;
@@ -283,6 +293,34 @@
     }
 }
 
+static void get_alpha_data(ProresContext *ctx, const uint16_t *src,
+                           int linesize, int x, int y, int w, int h,
+                           int16_t *blocks, int mbs_per_slice, int abits)
+{
+    const int slice_width = 16 * mbs_per_slice;
+    int i, j, copy_w, copy_h;
+
+    copy_w = FFMIN(w - x, slice_width);
+    copy_h = FFMIN(h - y, 16);
+    for (i = 0; i < copy_h; i++) {
+        memcpy(blocks, src, copy_w * sizeof(*src));
+        if (abits == 8)
+            for (j = 0; j < copy_w; j++)
+                blocks[j] >>= 2;
+        else
+            for (j = 0; j < copy_w; j++)
+                blocks[j] = (blocks[j] << 6) | (blocks[j] >> 4);
+        for (j = copy_w; j < slice_width; j++)
+            blocks[j] = blocks[copy_w - 1];
+        blocks += slice_width;
+        src    += linesize >> 1;
+    }
+    for (; i < 16; i++) {
+        memcpy(blocks, blocks - slice_width, slice_width * sizeof(*blocks));
+        blocks += slice_width;
+    }
+}
+
 /**
  * Write an unsigned rice/exp golomb codeword.
  */
@@ -397,6 +435,73 @@
     return (put_bits_count(pb) - saved_pos) >> 3;
 }
 
+static void put_alpha_diff(PutBitContext *pb, int cur, int prev, int abits)
+{
+    const int mask  = (1 << abits) - 1;
+    const int dbits = (abits == 8) ? 4 : 7;
+    const int dsize = 1 << dbits - 1;
+    int diff = cur - prev;
+
+    diff &= mask;
+    if (diff >= (1 << abits) - dsize)
+        diff -= 1 << abits;
+    if (diff < -dsize || diff > dsize || !diff) {
+        put_bits(pb, 1, 1);
+        put_bits(pb, abits, diff);
+    } else {
+        put_bits(pb, 1, 0);
+        put_bits(pb, dbits - 1, FFABS(diff) - 1);
+        put_bits(pb, 1, diff < 0);
+    }
+}
+
+static void put_alpha_run(PutBitContext *pb, int run)
+{
+    if (run) {
+        put_bits(pb, 1, 0);
+        if (run < 0x10)
+            put_bits(pb, 4, run);
+        else
+            put_bits(pb, 15, run);
+    } else {
+        put_bits(pb, 1, 1);
+    }
+}
+
+// todo alpha quantisation for high quants
+static int encode_alpha_plane(ProresContext *ctx, PutBitContext *pb,
+                              const uint16_t *src, int linesize,
+                              int mbs_per_slice, uint16_t *blocks,
+                              int quant)
+{
+    const int abits = ctx->alpha_bits;
+    const int mask  = (1 << abits) - 1;
+    const int num_coeffs = mbs_per_slice * 256;
+    int saved_pos = put_bits_count(pb);
+    int prev = mask, cur;
+    int idx = 0;
+    int run = 0;
+
+    cur = blocks[idx++];
+    put_alpha_diff(pb, cur, prev, abits);
+    prev = cur;
+    do {
+        cur = blocks[idx++];
+        if (cur != prev) {
+            put_alpha_run (pb, run);
+            put_alpha_diff(pb, cur, prev, abits);
+            prev = cur;
+            run  = 0;
+        } else {
+            run++;
+        }
+    } while (idx < num_coeffs);
+    if (run)
+        put_alpha_run(pb, run);
+    flush_put_bits(pb);
+    return (put_bits_count(pb) - saved_pos) >> 3;
+}
+
 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
                         PutBitContext *pb,
                         int sizes[4], int x, int y, int quant,
@@ -447,14 +552,23 @@
         src = (const uint16_t*)(pic->data[i] + yp * linesize +
                                 line_add * pic->linesize[i]) + xp;
 
-        get_slice_data(ctx, src, linesize, xp, yp,
-                       pwidth, avctx->height / ctx->pictures_per_frame,
-                       ctx->blocks[0], ctx->emu_buf,
-                       mbs_per_slice, num_cblocks, is_chroma);
-        sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
-                                      mbs_per_slice, ctx->blocks[0],
-                                      num_cblocks, plane_factor,
-                                      qmat);
+        if (i < 3) {
+            get_slice_data(ctx, src, linesize, xp, yp,
+                           pwidth, avctx->height / ctx->pictures_per_frame,
+                           ctx->blocks[0], ctx->emu_buf,
+                           mbs_per_slice, num_cblocks, is_chroma);
+            sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
+                                          mbs_per_slice, ctx->blocks[0],
+                                          num_cblocks, plane_factor,
+                                          qmat);
+        } else {
+            get_alpha_data(ctx, src, linesize, xp, yp,
+                           pwidth, avctx->height / ctx->pictures_per_frame,
+                           ctx->blocks[0], mbs_per_slice, ctx->alpha_bits);
+            sizes[i] = encode_alpha_plane(ctx, pb, src, linesize,
+                                          mbs_per_slice, ctx->blocks[0],
+                                          quant);
+        }
         total_size += sizes[i];
     }
     return total_size;
@@ -567,6 +681,66 @@
     return FFALIGN(bits, 8);
 }
 
+static int est_alpha_diff(int cur, int prev, int abits)
+{
+    const int mask  = (1 << abits) - 1;
+    const int dbits = (abits == 8) ? 4 : 7;
+    const int dsize = 1 << dbits - 1;
+    int diff = cur - prev;
+
+    diff &= mask;
+    if (diff >= (1 << abits) - dsize)
+        diff -= 1 << abits;
+    if (diff < -dsize || diff > dsize || !diff)
+        return abits + 1;
+    else
+        return dbits + 1;
+}
+
+static int estimate_alpha_plane(ProresContext *ctx, int *error,
+                                const uint16_t *src, int linesize,
+                                int mbs_per_slice, int quant,
+                                int16_t *blocks)
+{
+    const int abits = ctx->alpha_bits;
+    const int mask  = (1 << abits) - 1;
+    const int num_coeffs = mbs_per_slice * 256;
+    int prev = mask, cur;
+    int idx = 0;
+    int run = 0;
+    int bits;
+
+    *error = 0;
+    cur = blocks[idx++];
+    bits = est_alpha_diff(cur, prev, abits);
+    prev = cur;
+    do {
+        cur = blocks[idx++];
+        if (cur != prev) {
+            if (!run)
+                bits++;
+            else if (run < 0x10)
+                bits += 4;
+            else
+                bits += 15;
+            bits += est_alpha_diff(cur, prev, abits);
+            prev = cur;
+            run  = 0;
+        } else {
+            run++;
+        }
+    } while (idx < num_coeffs);
+
+    if (run) {
+        if (run < 0x10)
+            bits += 4;
+        else
+            bits += 15;
+    }
+
+    return bits;
+}
+
 static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
                             int trellis_node, int x, int y, int mbs_per_slice,
                             ProresThreadData *td)
@@ -613,10 +787,16 @@
         src = (const uint16_t*)(pic->data[i] + yp * linesize[i] +
                                 line_add * pic->linesize[i]) + xp;
 
-        get_slice_data(ctx, src, linesize[i], xp, yp,
-                       pwidth, avctx->height / ctx->pictures_per_frame,
-                       td->blocks[i], td->emu_buf,
-                       mbs_per_slice, num_cblocks[i], is_chroma[i]);
+        if (i < 3) {
+            get_slice_data(ctx, src, linesize[i], xp, yp,
+                           pwidth, avctx->height / ctx->pictures_per_frame,
+                           td->blocks[i], td->emu_buf,
+                           mbs_per_slice, num_cblocks[i], is_chroma[i]);
+        } else {
+            get_alpha_data(ctx, src, linesize[i], xp, yp,
+                           pwidth, avctx->height / ctx->pictures_per_frame,
+                           td->blocks[i], mbs_per_slice, ctx->alpha_bits);
+        }
     }
 
     for (q = min_quant; q < max_quant + 2; q++) {
@@ -628,13 +808,16 @@
     for (q = min_quant; q <= max_quant; q++) {
         bits  = 0;
         error = 0;
-        for (i = 0; i < ctx->num_planes; i++) {
+        for (i = 0; i < ctx->num_planes - !!ctx->alpha_bits; i++) {
             bits += estimate_slice_plane(ctx, &error, i,
                                          src, linesize[i],
                                          mbs_per_slice,
                                          num_cblocks[i], plane_factor[i],
                                          ctx->quants[q], td);
         }
+        if (ctx->alpha_bits)
+            bits += estimate_alpha_plane(ctx, &error, src, linesize[3],
+                                         mbs_per_slice, q, td->blocks[3]);
         if (bits > 65000 * 8) {
             error = SCORE_LIMIT;
             break;
@@ -657,13 +840,16 @@
                 for (i = 0; i < 64; i++)
                     qmat[i] = ctx->quant_mat[i] * q;
             }
-            for (i = 0; i < ctx->num_planes; i++) {
+            for (i = 0; i < ctx->num_planes - !!ctx->alpha_bits; i++) {
                 bits += estimate_slice_plane(ctx, &error, i,
                                              src, linesize[i],
                                              mbs_per_slice,
                                              num_cblocks[i], plane_factor[i],
                                              qmat, td);
             }
+            if (ctx->alpha_bits)
+                bits += estimate_alpha_plane(ctx, &error, src, linesize[3],
+                                             mbs_per_slice, q, td->blocks[3]);
             if (bits <= ctx->bits_per_mb * mbs_per_slice)
                 break;
         }
@@ -783,7 +969,7 @@
     bytestream_put_byte  (&buf, avctx->color_primaries);
     bytestream_put_byte  (&buf, avctx->color_trc);
     bytestream_put_byte  (&buf, avctx->colorspace);
-    bytestream_put_byte  (&buf, 0x40);          // source format and alpha information
+    bytestream_put_byte  (&buf, 0x40 | (ctx->alpha_bits >> 3));
     bytestream_put_byte  (&buf, 0);             // reserved
     if (ctx->quant_sel != QUANT_MAT_DEFAULT) {
         bytestream_put_byte  (&buf, 0x03);      // matrix flags - both matrices are present
@@ -902,12 +1088,20 @@
                "there should be an integer power of two MBs per slice\n");
         return AVERROR(EINVAL);
     }
+    if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_ALPHA) {
+        if (ctx->alpha_bits & 7) {
+            av_log(avctx, AV_LOG_ERROR, "alpha bits should be 0, 8 or 16\n");
+            return AVERROR(EINVAL);
+        }
+    } else {
+        ctx->alpha_bits = 0;
+    }
 
     ctx->chroma_factor = avctx->pix_fmt == AV_PIX_FMT_YUV422P10
                          ? CFACTOR_Y422
                          : CFACTOR_Y444;
     ctx->profile_info  = prores_profile_info + ctx->profile;
-    ctx->num_planes    = 3;
+    ctx->num_planes    = 3 + !!ctx->alpha_bits;
 
     ctx->mb_width      = FFALIGN(avctx->width,  16) >> 4;
 
@@ -1023,7 +1217,7 @@
         AV_OPT_TYPE_INT, { .i64 = 8 }, 1, MAX_MBS_PER_SLICE, VE },
     { "profile",       NULL, OFFSET(profile), AV_OPT_TYPE_INT,
         { .i64 = PRORES_PROFILE_STANDARD },
-        PRORES_PROFILE_PROXY, PRORES_PROFILE_HQ, VE, "profile" },
+        PRORES_PROFILE_PROXY, PRORES_PROFILE_4444, VE, "profile" },
     { "proxy",         NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_PROXY },
         0, 0, VE, "profile" },
     { "lt",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_LT },
@@ -1032,6 +1226,8 @@
         0, 0, VE, "profile" },
     { "hq",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_HQ },
         0, 0, VE, "profile" },
+    { "4444",          NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444 },
+        0, 0, VE, "profile" },
     { "vendor", "vendor ID", OFFSET(vendor),
         AV_OPT_TYPE_STRING, { .str = "Lavc" }, CHAR_MIN, CHAR_MAX, VE },
     { "bits_per_mb", "desired bits per macroblock", OFFSET(bits_per_mb),
@@ -1050,6 +1246,8 @@
         0, 0, VE, "quant_mat" },
     { "default",       NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_DEFAULT },
         0, 0, VE, "quant_mat" },
+    { "alpha_bits", "bits for alpha plane", OFFSET(alpha_bits), AV_OPT_TYPE_INT,
+        { .i64 = 16 }, 0, 16, VE },
     { NULL }
 };
 
@@ -1071,7 +1269,8 @@
     .capabilities   = CODEC_CAP_SLICE_THREADS,
     .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"),
     .pix_fmts       = (const enum AVPixelFormat[]) {
-                          AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_NONE
+                          AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
+                          AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE
                       },
     .priv_class     = &proresenc_class,
 };
diff --git a/libavcodec/psymodel.c b/libavcodec/psymodel.c
index ea11636..bfc85b3 100644
--- a/libavcodec/psymodel.c
+++ b/libavcodec/psymodel.c
@@ -75,7 +75,7 @@
 
 av_cold void ff_psy_end(FFPsyContext *ctx)
 {
-    if (ctx->model->end)
+    if (ctx->model && ctx->model->end)
         ctx->model->end(ctx);
     av_freep(&ctx->bands);
     av_freep(&ctx->num_bands);
diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c
index 1e33fbc..8329155 100644
--- a/libavcodec/pthread.c
+++ b/libavcodec/pthread.c
@@ -31,39 +31,20 @@
 
 #include "config.h"
 
-#if HAVE_SCHED_GETAFFINITY
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif
-#include <sched.h>
-#endif
-#if HAVE_GETPROCESSAFFINITYMASK
-#include <windows.h>
-#endif
-#if HAVE_SYSCTL
-#if HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#endif
-#if HAVE_SYSCONF
-#include <unistd.h>
-#endif
-
 #include "avcodec.h"
 #include "internal.h"
 #include "thread.h"
 #include "libavutil/avassert.h"
 #include "libavutil/common.h"
+#include "libavutil/cpu.h"
+#include "libavutil/internal.h"
 
 #if HAVE_PTHREADS
 #include <pthread.h>
 #elif HAVE_W32THREADS
-#include "w32pthreads.h"
+#include "compat/w32pthreads.h"
 #elif HAVE_OS2THREADS
-#include "os2threads.h"
+#include "compat/os2threads.h"
 #endif
 
 typedef int (action_func)(AVCodecContext *c, void *arg);
@@ -166,44 +147,6 @@
  * limit the number of threads to 16 for automatic detection */
 #define MAX_AUTO_THREADS 16
 
-int ff_get_logical_cpus(AVCodecContext *avctx)
-{
-    int ret, nb_cpus = 1;
-#if HAVE_SCHED_GETAFFINITY && defined(CPU_COUNT)
-    cpu_set_t cpuset;
-
-    CPU_ZERO(&cpuset);
-
-    ret = sched_getaffinity(0, sizeof(cpuset), &cpuset);
-    if (!ret) {
-        nb_cpus = CPU_COUNT(&cpuset);
-    }
-#elif HAVE_GETPROCESSAFFINITYMASK
-    DWORD_PTR proc_aff, sys_aff;
-    ret = GetProcessAffinityMask(GetCurrentProcess(), &proc_aff, &sys_aff);
-    if (ret)
-        nb_cpus = av_popcount64(proc_aff);
-#elif HAVE_SYSCTL && defined(HW_NCPU)
-    int mib[2] = { CTL_HW, HW_NCPU };
-    size_t len = sizeof(nb_cpus);
-
-    ret = sysctl(mib, 2, &nb_cpus, &len, NULL, 0);
-    if (ret == -1)
-        nb_cpus = 0;
-#elif HAVE_SYSCONF && defined(_SC_NPROC_ONLN)
-    nb_cpus = sysconf(_SC_NPROC_ONLN);
-#elif HAVE_SYSCONF && defined(_SC_NPROCESSORS_ONLN)
-    nb_cpus = sysconf(_SC_NPROCESSORS_ONLN);
-#endif
-    av_log(avctx, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus);
-
-    if  (avctx->height)
-        nb_cpus = FFMIN(nb_cpus, (avctx->height+15)/16);
-
-    return nb_cpus;
-}
-
-
 static void* attribute_align_arg worker(void *v)
 {
     AVCodecContext *avctx = v;
@@ -307,14 +250,16 @@
     return avcodec_thread_execute(avctx, NULL, arg, ret, job_count, 0);
 }
 
-static int thread_init(AVCodecContext *avctx)
+static int thread_init_internal(AVCodecContext *avctx)
 {
     int i;
     ThreadContext *c;
     int thread_count = avctx->thread_count;
 
     if (!thread_count) {
-        int nb_cpus = ff_get_logical_cpus(avctx);
+        int nb_cpus = av_cpu_count();
+        if  (avctx->height)
+            nb_cpus = FFMIN(nb_cpus, (avctx->height+15)/16);
         // use number of cores + 1 as thread count if there is more than one
         if (nb_cpus > 1)
             thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
@@ -362,6 +307,9 @@
     return 0;
 }
 
+#define THREAD_SAFE_CALLBACKS(avctx) \
+((avctx)->thread_safe_callbacks || (!(avctx)->get_buffer && (avctx)->get_buffer2 == avcodec_default_get_buffer2))
+
 /**
  * Codec worker thread.
  *
@@ -383,11 +331,7 @@
 
         if (fctx->die) break;
 
-        if (!codec->update_thread_context && (avctx->thread_safe_callbacks || (
-#if FF_API_GET_BUFFER
-            !avctx->get_buffer &&
-#endif
-            avctx->get_buffer2 == avcodec_default_get_buffer2)))
+        if (!codec->update_thread_context && THREAD_SAFE_CALLBACKS(avctx))
             ff_thread_finish_setup(avctx);
 
         avcodec_get_frame_defaults(&p->frame);
@@ -460,6 +404,11 @@
 
         dst->hwaccel = src->hwaccel;
         dst->hwaccel_context = src->hwaccel_context;
+
+        dst->channels       = src->channels;
+        dst->sample_rate    = src->sample_rate;
+        dst->sample_fmt     = src->sample_fmt;
+        dst->channel_layout = src->channel_layout;
     }
 
     if (for_user) {
@@ -488,8 +437,10 @@
     dst->draw_horiz_band= src->draw_horiz_band;
     dst->get_buffer2    = src->get_buffer2;
 #if FF_API_GET_BUFFER
+FF_DISABLE_DEPRECATION_WARNINGS
     dst->get_buffer     = src->get_buffer;
     dst->release_buffer = src->release_buffer;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
     dst->opaque   = src->opaque;
@@ -534,7 +485,8 @@
         pthread_mutex_lock(&fctx->buffer_mutex);
 
         // fix extended data in case the caller screwed it up
-        av_assert0(p->avctx->codec_type == AVMEDIA_TYPE_VIDEO);
+        av_assert0(p->avctx->codec_type == AVMEDIA_TYPE_VIDEO ||
+                   p->avctx->codec_type == AVMEDIA_TYPE_AUDIO);
         f = &p->released_buffers[--p->num_released_buffers];
         f->extended_data = f->data;
         av_frame_unref(f);
@@ -592,12 +544,14 @@
      * and it calls back to the client here.
      */
 
+FF_DISABLE_DEPRECATION_WARNINGS
     if (!p->avctx->thread_safe_callbacks && (
          p->avctx->get_format != avcodec_default_get_format ||
 #if FF_API_GET_BUFFER
          p->avctx->get_buffer ||
 #endif
          p->avctx->get_buffer2 != avcodec_default_get_buffer2)) {
+FF_ENABLE_DEPRECATION_WARNINGS
         while (p->state != STATE_SETUP_FINISHED && p->state != STATE_INPUT_READY) {
             int call_done = 1;
             pthread_mutex_lock(&p->progress_mutex);
@@ -652,9 +606,10 @@
      * If we're still receiving the initial packets, don't return a frame.
      */
 
-    if (fctx->delaying) {
-        if (fctx->next_decoding >= (avctx->thread_count-1)) fctx->delaying = 0;
+    if (fctx->next_decoding > (avctx->thread_count-1-(avctx->codec_id == AV_CODEC_ID_FFV1)))
+        fctx->delaying = 0;
 
+    if (fctx->delaying) {
         *got_picture_ptr=0;
         if (avpkt->size)
             return avpkt->size;
@@ -843,7 +798,7 @@
     int i, err = 0;
 
     if (!thread_count) {
-        int nb_cpus = ff_get_logical_cpus(avctx);
+        int nb_cpus = av_cpu_count();
         if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || avctx->debug_mv)
             nb_cpus = 1;
         // use number of cores + 1 as thread count if there is more than one
@@ -960,11 +915,7 @@
 {
     PerThreadContext *p = avctx->thread_opaque;
     if ((avctx->active_thread_type&FF_THREAD_FRAME) && p->state != STATE_SETTING_UP &&
-        (avctx->codec->update_thread_context || (!avctx->thread_safe_callbacks && (
-#if FF_API_GET_BUFFER
-                avctx->get_buffer ||
-#endif
-                avctx->get_buffer2 != avcodec_default_get_buffer2)))) {
+        (avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) {
         return 0;
     }
     return 1;
@@ -983,11 +934,7 @@
         return ff_get_buffer(avctx, f->f, flags);
 
     if (p->state != STATE_SETTING_UP &&
-        (avctx->codec->update_thread_context || (!avctx->thread_safe_callbacks && (
-#if FF_API_GET_BUFFER
-                avctx->get_buffer ||
-#endif
-                avctx->get_buffer2 != avcodec_default_get_buffer2)))) {
+        (avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n");
         return -1;
     }
@@ -1005,11 +952,13 @@
 
     pthread_mutex_lock(&p->parent->buffer_mutex);
 
+FF_DISABLE_DEPRECATION_WARNINGS
     if (avctx->thread_safe_callbacks || (
 #if FF_API_GET_BUFFER
         !avctx->get_buffer &&
 #endif
         avctx->get_buffer2 == avcodec_default_get_buffer2)) {
+FF_ENABLE_DEPRECATION_WARNINGS
         err = ff_get_buffer(avctx, f->f, flags);
     } else {
         pthread_mutex_lock(&p->progress_mutex);
@@ -1026,7 +975,7 @@
         pthread_mutex_unlock(&p->progress_mutex);
 
     }
-    if (!avctx->thread_safe_callbacks && !avctx->codec->update_thread_context)
+    if (!THREAD_SAFE_CALLBACKS(avctx) && !avctx->codec->update_thread_context)
         ff_thread_finish_setup(avctx);
 
     if (err)
@@ -1076,6 +1025,7 @@
     PerThreadContext *p = avctx->thread_opaque;
     FrameThreadContext *fctx;
     AVFrame *dst, *tmp;
+FF_DISABLE_DEPRECATION_WARNINGS
     int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) ||
                           avctx->thread_safe_callbacks                   ||
                           (
@@ -1083,6 +1033,7 @@
                            !avctx->get_buffer &&
 #endif
                            avctx->get_buffer2 == avcodec_default_get_buffer2);
+FF_ENABLE_DEPRECATION_WARNINGS
 
     if (!f->f->data[0])
         return;
@@ -1154,23 +1105,16 @@
 
 int ff_thread_init(AVCodecContext *avctx)
 {
-    if (avctx->thread_opaque) {
-        av_log(avctx, AV_LOG_ERROR, "avcodec_thread_init is ignored after avcodec_open\n");
-        return -1;
-    }
-
 #if HAVE_W32THREADS
     w32thread_init();
 #endif
 
-    if (avctx->codec) {
-        validate_thread_parameters(avctx);
+    validate_thread_parameters(avctx);
 
-        if (avctx->active_thread_type&FF_THREAD_SLICE)
-            return thread_init(avctx);
-        else if (avctx->active_thread_type&FF_THREAD_FRAME)
-            return frame_thread_init(avctx);
-    }
+    if (avctx->active_thread_type&FF_THREAD_SLICE)
+        return thread_init_internal(avctx);
+    else if (avctx->active_thread_type&FF_THREAD_FRAME)
+        return frame_thread_init(avctx);
 
     return 0;
 }
diff --git a/libavcodec/put_bits.h b/libavcodec/put_bits.h
index 7320443..e2c4a61 100644
--- a/libavcodec/put_bits.h
+++ b/libavcodec/put_bits.h
@@ -76,6 +76,14 @@
 }
 
 /**
+ * @return the number of bits available in the bitstream.
+ */
+static inline int put_bits_left(PutBitContext* s)
+{
+    return (s->buf_end - s->buf_ptr) * 8 - 32 + s->bit_left;
+}
+
+/**
  * Pad the end of the output stream with zeros.
  */
 static inline void flush_put_bits(PutBitContext *s)
diff --git a/libavcodec/qcelpdec.c b/libavcodec/qcelpdec.c
index f8fe85d..607704d 100644
--- a/libavcodec/qcelpdec.c
+++ b/libavcodec/qcelpdec.c
@@ -29,6 +29,7 @@
 
 #include <stddef.h>
 
+#include "libavutil/avassert.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/float_dsp.h"
 #include "avcodec.h"
@@ -40,9 +41,6 @@
 #include "acelp_vectors.h"
 #include "lsp.h"
 
-#undef NDEBUG
-#include <assert.h>
-
 typedef enum {
     I_F_Q = -1,    /**< insufficient frame quality */
     SILENCE,
@@ -94,7 +92,7 @@
     avctx->sample_fmt     = AV_SAMPLE_FMT_FLT;
 
     for (i = 0; i < 10; i++)
-        q->prev_lspf[i] = (i + 1) / 11.;
+        q->prev_lspf[i] = (i + 1) / 11.0;
 
     return 0;
 }
@@ -135,7 +133,7 @@
         } else {
             erasure_coeff = QCELP_LSP_OCTAVE_PREDICTOR;
 
-            assert(q->bitrate == I_F_Q);
+            av_assert2(q->bitrate == I_F_Q);
 
             if (q->erasure_count > 1)
                 erasure_coeff *= q->erasure_count < 4 ? 0.9 : 0.7;
@@ -162,7 +160,7 @@
     } else {
         q->octave_count = 0;
 
-        tmp_lspf = 0.;
+        tmp_lspf = 0.0;
         for (i = 0; i < 5; i++) {
             lspf[2 * i + 0] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][0] * 0.0001;
             lspf[2 * i + 1] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][1] * 0.0001;
@@ -239,7 +237,7 @@
                     av_clip((q->prev_g1[0] + q->prev_g1[1]) / 2 - 5, 0, 54);
             subframes_count = 8;
         } else {
-            assert(q->bitrate == I_F_Q);
+            av_assert2(q->bitrate == I_F_Q);
 
             g1[0] = q->prev_g1[1];
             switch (q->erasure_count) {
@@ -434,7 +432,7 @@
             v_lag = memory + 143 + 40 * i - lag[i];
             for (v_len = v_in + 40; v_in < v_len; v_in++) {
                 if (pfrac[i]) { // If it is a fractional lag...
-                    for (j = 0, *v_out = 0.; j < 4; j++)
+                    for (j = 0, *v_out = 0.0; j < 4; j++)
                         *v_out += qcelp_hammsinc_table[j] * (v_lag[j - 4] + v_lag[3 - j]);
                 } else
                     *v_out = *v_lag;
@@ -486,7 +484,7 @@
                   else
                       max_pitch_gain = 0.0;
             } else {
-                assert(q->bitrate == SILENCE);
+                av_assert2(q->bitrate == SILENCE);
                 max_pitch_gain = 1.0;
             }
             for (i = 0; i < 4; i++)
diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c
index daf127e..3d5ff33 100644
--- a/libavcodec/qdm2.c
+++ b/libavcodec/qdm2.c
@@ -216,121 +216,154 @@
     0,260,566,598,894,1166,1230,1294,1678,1950,2214,2278,2310,2570,2834,3124,3448,3838,
 };
 
+static const int switchtable[23] = {
+    0, 5, 1, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 3, 5, 5, 5, 5, 5, 4
+};
+
 static av_cold void qdm2_init_vlc(void)
 {
-    static int vlcs_initialized = 0;
     static VLC_TYPE qdm2_table[3838][2];
 
-    if (!vlcs_initialized) {
+    vlc_tab_level.table           = &qdm2_table[qdm2_vlc_offs[0]];
+    vlc_tab_level.table_allocated = qdm2_vlc_offs[1] - qdm2_vlc_offs[0];
+    init_vlc(&vlc_tab_level, 8, 24,
+             vlc_tab_level_huffbits, 1, 1,
+             vlc_tab_level_huffcodes, 2, 2,
+             INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
 
-        vlc_tab_level.table = &qdm2_table[qdm2_vlc_offs[0]];
-        vlc_tab_level.table_allocated = qdm2_vlc_offs[1] - qdm2_vlc_offs[0];
-        init_vlc (&vlc_tab_level, 8, 24,
-            vlc_tab_level_huffbits, 1, 1,
-            vlc_tab_level_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
+    vlc_tab_diff.table           = &qdm2_table[qdm2_vlc_offs[1]];
+    vlc_tab_diff.table_allocated = qdm2_vlc_offs[2] - qdm2_vlc_offs[1];
+    init_vlc(&vlc_tab_diff, 8, 37,
+             vlc_tab_diff_huffbits, 1, 1,
+             vlc_tab_diff_huffcodes, 2, 2,
+             INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
 
-        vlc_tab_diff.table = &qdm2_table[qdm2_vlc_offs[1]];
-        vlc_tab_diff.table_allocated = qdm2_vlc_offs[2] - qdm2_vlc_offs[1];
-        init_vlc (&vlc_tab_diff, 8, 37,
-            vlc_tab_diff_huffbits, 1, 1,
-            vlc_tab_diff_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
+    vlc_tab_run.table           = &qdm2_table[qdm2_vlc_offs[2]];
+    vlc_tab_run.table_allocated = qdm2_vlc_offs[3] - qdm2_vlc_offs[2];
+    init_vlc(&vlc_tab_run, 5, 6,
+             vlc_tab_run_huffbits, 1, 1,
+             vlc_tab_run_huffcodes, 1, 1,
+             INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
 
-        vlc_tab_run.table = &qdm2_table[qdm2_vlc_offs[2]];
-        vlc_tab_run.table_allocated = qdm2_vlc_offs[3] - qdm2_vlc_offs[2];
-        init_vlc (&vlc_tab_run, 5, 6,
-            vlc_tab_run_huffbits, 1, 1,
-            vlc_tab_run_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
+    fft_level_exp_alt_vlc.table           = &qdm2_table[qdm2_vlc_offs[3]];
+    fft_level_exp_alt_vlc.table_allocated = qdm2_vlc_offs[4] -
+                                            qdm2_vlc_offs[3];
+    init_vlc(&fft_level_exp_alt_vlc, 8, 28,
+             fft_level_exp_alt_huffbits, 1, 1,
+             fft_level_exp_alt_huffcodes, 2, 2,
+             INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
 
-        fft_level_exp_alt_vlc.table = &qdm2_table[qdm2_vlc_offs[3]];
-        fft_level_exp_alt_vlc.table_allocated = qdm2_vlc_offs[4] - qdm2_vlc_offs[3];
-        init_vlc (&fft_level_exp_alt_vlc, 8, 28,
-            fft_level_exp_alt_huffbits, 1, 1,
-            fft_level_exp_alt_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
+    fft_level_exp_vlc.table           = &qdm2_table[qdm2_vlc_offs[4]];
+    fft_level_exp_vlc.table_allocated = qdm2_vlc_offs[5] - qdm2_vlc_offs[4];
+    init_vlc(&fft_level_exp_vlc, 8, 20,
+             fft_level_exp_huffbits, 1, 1,
+             fft_level_exp_huffcodes, 2, 2,
+             INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
 
+    fft_stereo_exp_vlc.table           = &qdm2_table[qdm2_vlc_offs[5]];
+    fft_stereo_exp_vlc.table_allocated = qdm2_vlc_offs[6] -
+                                         qdm2_vlc_offs[5];
+    init_vlc(&fft_stereo_exp_vlc, 6, 7,
+             fft_stereo_exp_huffbits, 1, 1,
+             fft_stereo_exp_huffcodes, 1, 1,
+             INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
 
-        fft_level_exp_vlc.table = &qdm2_table[qdm2_vlc_offs[4]];
-        fft_level_exp_vlc.table_allocated = qdm2_vlc_offs[5] - qdm2_vlc_offs[4];
-        init_vlc (&fft_level_exp_vlc, 8, 20,
-            fft_level_exp_huffbits, 1, 1,
-            fft_level_exp_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
+    fft_stereo_phase_vlc.table           = &qdm2_table[qdm2_vlc_offs[6]];
+    fft_stereo_phase_vlc.table_allocated = qdm2_vlc_offs[7] -
+                                           qdm2_vlc_offs[6];
+    init_vlc(&fft_stereo_phase_vlc, 6, 9,
+             fft_stereo_phase_huffbits, 1, 1,
+             fft_stereo_phase_huffcodes, 1, 1,
+             INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
 
-        fft_stereo_exp_vlc.table = &qdm2_table[qdm2_vlc_offs[5]];
-        fft_stereo_exp_vlc.table_allocated = qdm2_vlc_offs[6] - qdm2_vlc_offs[5];
-        init_vlc (&fft_stereo_exp_vlc, 6, 7,
-            fft_stereo_exp_huffbits, 1, 1,
-            fft_stereo_exp_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
+    vlc_tab_tone_level_idx_hi1.table =
+        &qdm2_table[qdm2_vlc_offs[7]];
+    vlc_tab_tone_level_idx_hi1.table_allocated = qdm2_vlc_offs[8] -
+                                                 qdm2_vlc_offs[7];
+    init_vlc(&vlc_tab_tone_level_idx_hi1, 8, 20,
+             vlc_tab_tone_level_idx_hi1_huffbits, 1, 1,
+             vlc_tab_tone_level_idx_hi1_huffcodes, 2, 2,
+             INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
 
-        fft_stereo_phase_vlc.table = &qdm2_table[qdm2_vlc_offs[6]];
-        fft_stereo_phase_vlc.table_allocated = qdm2_vlc_offs[7] - qdm2_vlc_offs[6];
-        init_vlc (&fft_stereo_phase_vlc, 6, 9,
-            fft_stereo_phase_huffbits, 1, 1,
-            fft_stereo_phase_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
+    vlc_tab_tone_level_idx_mid.table =
+        &qdm2_table[qdm2_vlc_offs[8]];
+    vlc_tab_tone_level_idx_mid.table_allocated = qdm2_vlc_offs[9] -
+                                                 qdm2_vlc_offs[8];
+    init_vlc(&vlc_tab_tone_level_idx_mid, 8, 24,
+             vlc_tab_tone_level_idx_mid_huffbits, 1, 1,
+             vlc_tab_tone_level_idx_mid_huffcodes, 2, 2,
+             INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
 
-        vlc_tab_tone_level_idx_hi1.table = &qdm2_table[qdm2_vlc_offs[7]];
-        vlc_tab_tone_level_idx_hi1.table_allocated = qdm2_vlc_offs[8] - qdm2_vlc_offs[7];
-        init_vlc (&vlc_tab_tone_level_idx_hi1, 8, 20,
-            vlc_tab_tone_level_idx_hi1_huffbits, 1, 1,
-            vlc_tab_tone_level_idx_hi1_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
+    vlc_tab_tone_level_idx_hi2.table =
+        &qdm2_table[qdm2_vlc_offs[9]];
+    vlc_tab_tone_level_idx_hi2.table_allocated = qdm2_vlc_offs[10] -
+                                                 qdm2_vlc_offs[9];
+    init_vlc(&vlc_tab_tone_level_idx_hi2, 8, 24,
+             vlc_tab_tone_level_idx_hi2_huffbits, 1, 1,
+             vlc_tab_tone_level_idx_hi2_huffcodes, 2, 2,
+             INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
 
-        vlc_tab_tone_level_idx_mid.table = &qdm2_table[qdm2_vlc_offs[8]];
-        vlc_tab_tone_level_idx_mid.table_allocated = qdm2_vlc_offs[9] - qdm2_vlc_offs[8];
-        init_vlc (&vlc_tab_tone_level_idx_mid, 8, 24,
-            vlc_tab_tone_level_idx_mid_huffbits, 1, 1,
-            vlc_tab_tone_level_idx_mid_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
+    vlc_tab_type30.table           = &qdm2_table[qdm2_vlc_offs[10]];
+    vlc_tab_type30.table_allocated = qdm2_vlc_offs[11] - qdm2_vlc_offs[10];
+    init_vlc(&vlc_tab_type30, 6, 9,
+             vlc_tab_type30_huffbits, 1, 1,
+             vlc_tab_type30_huffcodes, 1, 1,
+             INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
 
-        vlc_tab_tone_level_idx_hi2.table = &qdm2_table[qdm2_vlc_offs[9]];
-        vlc_tab_tone_level_idx_hi2.table_allocated = qdm2_vlc_offs[10] - qdm2_vlc_offs[9];
-        init_vlc (&vlc_tab_tone_level_idx_hi2, 8, 24,
-            vlc_tab_tone_level_idx_hi2_huffbits, 1, 1,
-            vlc_tab_tone_level_idx_hi2_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
+    vlc_tab_type34.table           = &qdm2_table[qdm2_vlc_offs[11]];
+    vlc_tab_type34.table_allocated = qdm2_vlc_offs[12] - qdm2_vlc_offs[11];
+    init_vlc(&vlc_tab_type34, 5, 10,
+             vlc_tab_type34_huffbits, 1, 1,
+             vlc_tab_type34_huffcodes, 1, 1,
+             INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
 
-        vlc_tab_type30.table = &qdm2_table[qdm2_vlc_offs[10]];
-        vlc_tab_type30.table_allocated = qdm2_vlc_offs[11] - qdm2_vlc_offs[10];
-        init_vlc (&vlc_tab_type30, 6, 9,
-            vlc_tab_type30_huffbits, 1, 1,
-            vlc_tab_type30_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
+    vlc_tab_fft_tone_offset[0].table =
+        &qdm2_table[qdm2_vlc_offs[12]];
+    vlc_tab_fft_tone_offset[0].table_allocated = qdm2_vlc_offs[13] -
+                                                 qdm2_vlc_offs[12];
+    init_vlc(&vlc_tab_fft_tone_offset[0], 8, 23,
+             vlc_tab_fft_tone_offset_0_huffbits, 1, 1,
+             vlc_tab_fft_tone_offset_0_huffcodes, 2, 2,
+             INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
 
-        vlc_tab_type34.table = &qdm2_table[qdm2_vlc_offs[11]];
-        vlc_tab_type34.table_allocated = qdm2_vlc_offs[12] - qdm2_vlc_offs[11];
-        init_vlc (&vlc_tab_type34, 5, 10,
-            vlc_tab_type34_huffbits, 1, 1,
-            vlc_tab_type34_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
+    vlc_tab_fft_tone_offset[1].table =
+        &qdm2_table[qdm2_vlc_offs[13]];
+    vlc_tab_fft_tone_offset[1].table_allocated = qdm2_vlc_offs[14] -
+                                                 qdm2_vlc_offs[13];
+    init_vlc(&vlc_tab_fft_tone_offset[1], 8, 28,
+             vlc_tab_fft_tone_offset_1_huffbits, 1, 1,
+             vlc_tab_fft_tone_offset_1_huffcodes, 2, 2,
+             INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
 
-        vlc_tab_fft_tone_offset[0].table = &qdm2_table[qdm2_vlc_offs[12]];
-        vlc_tab_fft_tone_offset[0].table_allocated = qdm2_vlc_offs[13] - qdm2_vlc_offs[12];
-        init_vlc (&vlc_tab_fft_tone_offset[0], 8, 23,
-            vlc_tab_fft_tone_offset_0_huffbits, 1, 1,
-            vlc_tab_fft_tone_offset_0_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
+    vlc_tab_fft_tone_offset[2].table =
+        &qdm2_table[qdm2_vlc_offs[14]];
+    vlc_tab_fft_tone_offset[2].table_allocated = qdm2_vlc_offs[15] -
+                                                 qdm2_vlc_offs[14];
+    init_vlc(&vlc_tab_fft_tone_offset[2], 8, 32,
+             vlc_tab_fft_tone_offset_2_huffbits, 1, 1,
+             vlc_tab_fft_tone_offset_2_huffcodes, 2, 2,
+             INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
 
-        vlc_tab_fft_tone_offset[1].table = &qdm2_table[qdm2_vlc_offs[13]];
-        vlc_tab_fft_tone_offset[1].table_allocated = qdm2_vlc_offs[14] - qdm2_vlc_offs[13];
-        init_vlc (&vlc_tab_fft_tone_offset[1], 8, 28,
-            vlc_tab_fft_tone_offset_1_huffbits, 1, 1,
-            vlc_tab_fft_tone_offset_1_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
+    vlc_tab_fft_tone_offset[3].table =
+        &qdm2_table[qdm2_vlc_offs[15]];
+    vlc_tab_fft_tone_offset[3].table_allocated = qdm2_vlc_offs[16] -
+                                                 qdm2_vlc_offs[15];
+    init_vlc(&vlc_tab_fft_tone_offset[3], 8, 35,
+             vlc_tab_fft_tone_offset_3_huffbits, 1, 1,
+             vlc_tab_fft_tone_offset_3_huffcodes, 2, 2,
+             INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
 
-        vlc_tab_fft_tone_offset[2].table = &qdm2_table[qdm2_vlc_offs[14]];
-        vlc_tab_fft_tone_offset[2].table_allocated = qdm2_vlc_offs[15] - qdm2_vlc_offs[14];
-        init_vlc (&vlc_tab_fft_tone_offset[2], 8, 32,
-            vlc_tab_fft_tone_offset_2_huffbits, 1, 1,
-            vlc_tab_fft_tone_offset_2_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
-
-        vlc_tab_fft_tone_offset[3].table = &qdm2_table[qdm2_vlc_offs[15]];
-        vlc_tab_fft_tone_offset[3].table_allocated = qdm2_vlc_offs[16] - qdm2_vlc_offs[15];
-        init_vlc (&vlc_tab_fft_tone_offset[3], 8, 35,
-            vlc_tab_fft_tone_offset_3_huffbits, 1, 1,
-            vlc_tab_fft_tone_offset_3_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
-
-        vlc_tab_fft_tone_offset[4].table = &qdm2_table[qdm2_vlc_offs[16]];
-        vlc_tab_fft_tone_offset[4].table_allocated = qdm2_vlc_offs[17] - qdm2_vlc_offs[16];
-        init_vlc (&vlc_tab_fft_tone_offset[4], 8, 38,
-            vlc_tab_fft_tone_offset_4_huffbits, 1, 1,
-            vlc_tab_fft_tone_offset_4_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
-
-        vlcs_initialized=1;
-    }
+    vlc_tab_fft_tone_offset[4].table =
+        &qdm2_table[qdm2_vlc_offs[16]];
+    vlc_tab_fft_tone_offset[4].table_allocated = qdm2_vlc_offs[17] -
+                                                 qdm2_vlc_offs[16];
+    init_vlc(&vlc_tab_fft_tone_offset[4], 8, 38,
+             vlc_tab_fft_tone_offset_4_huffbits, 1, 1,
+             vlc_tab_fft_tone_offset_4_huffcodes, 2, 2,
+             INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
 }
 
-static int qdm2_get_vlc (GetBitContext *gb, VLC *vlc, int flag, int depth)
+static int qdm2_get_vlc(GetBitContext *gb, VLC *vlc, int flag, int depth)
 {
     int value;
 
@@ -338,7 +371,7 @@
 
     /* stage-2, 3 bits exponent escape sequence */
     if (value-- == 0)
-        value = get_bits (gb, get_bits (gb, 3) + 1);
+        value = get_bits(gb, get_bits(gb, 3) + 1);
 
     /* stage-3, optional */
     if (flag) {
@@ -352,22 +385,20 @@
         tmp= vlc_stage3_values[value];
 
         if ((value & ~3) > 0)
-            tmp += get_bits (gb, (value >> 2));
+            tmp += get_bits(gb, (value >> 2));
         value = tmp;
     }
 
     return value;
 }
 
-
-static int qdm2_get_se_vlc (VLC *vlc, GetBitContext *gb, int depth)
+static int qdm2_get_se_vlc(VLC *vlc, GetBitContext *gb, int depth)
 {
-    int value = qdm2_get_vlc (gb, vlc, 0, depth);
+    int value = qdm2_get_vlc(gb, vlc, 0, depth);
 
     return (value & 1) ? ((value + 1) >> 1) : -(value >> 1);
 }
 
-
 /**
  * QDM2 checksum
  *
@@ -377,49 +408,50 @@
  *
  * @return          0 if checksum is OK
  */
-static uint16_t qdm2_packet_checksum (const uint8_t *data, int length, int value) {
+static uint16_t qdm2_packet_checksum(const uint8_t *data, int length, int value)
+{
     int i;
 
-    for (i=0; i < length; i++)
+    for (i = 0; i < length; i++)
         value -= data[i];
 
     return (uint16_t)(value & 0xffff);
 }
 
-
 /**
  * Fill a QDM2SubPacket structure with packet type, size, and data pointer.
  *
  * @param gb            bitreader context
  * @param sub_packet    packet under analysis
  */
-static void qdm2_decode_sub_packet_header (GetBitContext *gb, QDM2SubPacket *sub_packet)
+static void qdm2_decode_sub_packet_header(GetBitContext *gb,
+                                          QDM2SubPacket *sub_packet)
 {
-    sub_packet->type = get_bits (gb, 8);
+    sub_packet->type = get_bits(gb, 8);
 
     if (sub_packet->type == 0) {
         sub_packet->size = 0;
         sub_packet->data = NULL;
     } else {
-        sub_packet->size = get_bits (gb, 8);
+        sub_packet->size = get_bits(gb, 8);
 
-      if (sub_packet->type & 0x80) {
-          sub_packet->size <<= 8;
-          sub_packet->size  |= get_bits (gb, 8);
-          sub_packet->type  &= 0x7f;
-      }
+        if (sub_packet->type & 0x80) {
+            sub_packet->size <<= 8;
+            sub_packet->size  |= get_bits(gb, 8);
+            sub_packet->type  &= 0x7f;
+        }
 
-      if (sub_packet->type == 0x7f)
-          sub_packet->type |= (get_bits (gb, 8) << 8);
+        if (sub_packet->type == 0x7f)
+            sub_packet->type |= (get_bits(gb, 8) << 8);
 
-      sub_packet->data = &gb->buffer[get_bits_count(gb) / 8]; // FIXME: this depends on bitreader internal data
+        // FIXME: this depends on bitreader-internal data
+        sub_packet->data = &gb->buffer[get_bits_count(gb) / 8];
     }
 
-    av_log(NULL,AV_LOG_DEBUG,"Subpacket: type=%d size=%d start_offs=%x\n",
-        sub_packet->type, sub_packet->size, get_bits_count(gb) / 8);
+    av_log(NULL, AV_LOG_DEBUG, "Subpacket: type=%d size=%d start_offs=%x\n",
+           sub_packet->type, sub_packet->size, get_bits_count(gb) / 8);
 }
 
-
 /**
  * Return node pointer to first packet of requested type in list.
  *
@@ -427,7 +459,8 @@
  * @param type    type of searched subpacket
  * @return        node pointer for subpacket if found, else NULL
  */
-static QDM2SubPNode* qdm2_search_subpacket_type_in_list (QDM2SubPNode *list, int type)
+static QDM2SubPNode *qdm2_search_subpacket_type_in_list(QDM2SubPNode *list,
+                                                        int type)
 {
     while (list != NULL && list->packet != NULL) {
         if (list->packet->type == type)
@@ -437,14 +470,13 @@
     return NULL;
 }
 
-
 /**
  * Replace 8 elements with their average value.
  * Called by qdm2_decode_superblock before starting subblock decoding.
  *
  * @param q       context
  */
-static void average_quantized_coeffs (QDM2Context *q)
+static void average_quantized_coeffs(QDM2Context *q)
 {
     int i, j, n, ch, sum;
 
@@ -461,12 +493,11 @@
             if (sum > 0)
                 sum--;
 
-            for (j=0; j < 8; j++)
+            for (j = 0; j < 8; j++)
                 q->quantized_coeffs[ch][i][j] = sum;
         }
 }
 
-
 /**
  * Build subband samples with noise weighted by q->tone_level.
  * Called by synthfilt_build_sb_samples.
@@ -474,7 +505,7 @@
  * @param q     context
  * @param sb    subband index
  */
-static void build_sb_samples_from_noise (QDM2Context *q, int sb)
+static void build_sb_samples_from_noise(QDM2Context *q, int sb)
 {
     int ch, j;
 
@@ -483,14 +514,16 @@
     if (!q->nb_channels)
         return;
 
-    for (ch = 0; ch < q->nb_channels; ch++)
+    for (ch = 0; ch < q->nb_channels; ch++) {
         for (j = 0; j < 64; j++) {
-            q->sb_samples[ch][j * 2][sb] = SB_DITHERING_NOISE(sb,q->noise_idx) * q->tone_level[ch][sb][j];
-            q->sb_samples[ch][j * 2 + 1][sb] = SB_DITHERING_NOISE(sb,q->noise_idx) * q->tone_level[ch][sb][j];
+            q->sb_samples[ch][j * 2][sb] =
+                SB_DITHERING_NOISE(sb, q->noise_idx) * q->tone_level[ch][sb][j];
+            q->sb_samples[ch][j * 2 + 1][sb] =
+                SB_DITHERING_NOISE(sb, q->noise_idx) * q->tone_level[ch][sb][j];
         }
+    }
 }
 
-
 /**
  * Called while processing data from subpackets 11 and 12.
  * Used after making changes to coding_method array.
@@ -499,44 +532,65 @@
  * @param channels         number of channels
  * @param coding_method    q->coding_method[0][0][0]
  */
-static void fix_coding_method_array (int sb, int channels, sb_int8_array coding_method)
+static int fix_coding_method_array(int sb, int channels,
+                                   sb_int8_array coding_method)
 {
-    int j,k;
+    int j, k;
     int ch;
     int run, case_val;
-    static const int switchtable[23] = {0,5,1,5,5,5,5,5,2,5,5,5,5,5,5,5,3,5,5,5,5,5,4};
 
     for (ch = 0; ch < channels; ch++) {
         for (j = 0; j < 64; ) {
-            if((coding_method[ch][sb][j] - 8) > 22) {
-                run = 1;
+            if (coding_method[ch][sb][j] < 8)
+                return -1;
+            if ((coding_method[ch][sb][j] - 8) > 22) {
+                run      = 1;
                 case_val = 8;
             } else {
-                switch (switchtable[coding_method[ch][sb][j]-8]) {
-                    case 0: run = 10; case_val = 10; break;
-                    case 1: run = 1; case_val = 16; break;
-                    case 2: run = 5; case_val = 24; break;
-                    case 3: run = 3; case_val = 30; break;
-                    case 4: run = 1; case_val = 30; break;
-                    case 5: run = 1; case_val = 8; break;
-                    default: run = 1; case_val = 8; break;
+                switch (switchtable[coding_method[ch][sb][j] - 8]) {
+                case 0: run  = 10;
+                    case_val = 10;
+                    break;
+                case 1: run  = 1;
+                    case_val = 16;
+                    break;
+                case 2: run  = 5;
+                    case_val = 24;
+                    break;
+                case 3: run  = 3;
+                    case_val = 30;
+                    break;
+                case 4: run  = 1;
+                    case_val = 30;
+                    break;
+                case 5: run  = 1;
+                    case_val = 8;
+                    break;
+                default: run = 1;
+                    case_val = 8;
+                    break;
                 }
             }
-            for (k = 0; k < run; k++)
-                if (j + k < 128)
-                    if (coding_method[ch][sb + (j + k) / 64][(j + k) % 64] > coding_method[ch][sb][j])
+            for (k = 0; k < run; k++) {
+                if (j + k < 128) {
+                    if (coding_method[ch][sb + (j + k) / 64][(j + k) % 64] > coding_method[ch][sb][j]) {
                         if (k > 0) {
-                           SAMPLES_NEEDED
+                            SAMPLES_NEEDED
                             //not debugged, almost never used
-                            memset(&coding_method[ch][sb][j + k], case_val, k * sizeof(int8_t));
-                            memset(&coding_method[ch][sb][j + k], case_val, 3 * sizeof(int8_t));
+                            memset(&coding_method[ch][sb][j + k], case_val,
+                                   k *sizeof(int8_t));
+                            memset(&coding_method[ch][sb][j + k], case_val,
+                                   3 * sizeof(int8_t));
                         }
+                    }
+                }
+            }
             j += run;
         }
     }
+    return 0;
 }
 
-
 /**
  * Related to synthesis filter
  * Called by process_subpacket_10
@@ -544,7 +598,7 @@
  * @param q       context
  * @param flag    1 if called after getting data from subpacket 10, 0 if no subpacket 10
  */
-static void fill_tone_level_array (QDM2Context *q, int flag)
+static void fill_tone_level_array(QDM2Context *q, int flag)
 {
     int i, sb, ch, sb_used;
     int tmp, tab;
@@ -616,16 +670,14 @@
             }
         }
     }
-
-    return;
 }
 
-
 /**
  * Related to synthesis filter
  * Called by process_subpacket_11
  * c is built with data from subpacket 11
- * Most of this function is used only if superblock_type_2_3 == 0, never seen it in samples
+ * Most of this function is used only if superblock_type_2_3 == 0,
+ * never seen it in samples.
  *
  * @param tone_level_idx
  * @param tone_level_idx_temp
@@ -635,9 +687,12 @@
  * @param superblocktype_2_3   flag based on superblock packet type
  * @param cm_table_select      q->cm_table_select
  */
-static void fill_coding_method_array (sb_int8_array tone_level_idx, sb_int8_array tone_level_idx_temp,
-                sb_int8_array coding_method, int nb_channels,
-                int c, int superblocktype_2_3, int cm_table_select)
+static void fill_coding_method_array(sb_int8_array tone_level_idx,
+                                     sb_int8_array tone_level_idx_temp,
+                                     sb_int8_array coding_method,
+                                     int nb_channels,
+                                     int c, int superblocktype_2_3,
+                                     int cm_table_select)
 {
     int ch, sb, j;
     int tmp, acc, esp_40, comp;
@@ -744,15 +799,14 @@
                 for (j = 0; j < 64; j++)
                     coding_method[ch][sb][j] = coding_method_table[cm_table_select][sb];
     }
-
-    return;
 }
 
-
 /**
  *
- * Called by process_subpacket_11 to process more data from subpacket 11 with sb 0-8
- * Called by process_subpacket_12 to process data from subpacket 12 with sb 8-sb_used
+ * Called by process_subpacket_11 to process more data from subpacket 11
+ * with sb 0-8.
+ * Called by process_subpacket_12 to process data from subpacket 12 with
+ * sb 8-sb_used.
  *
  * @param q         context
  * @param gb        bitreader context
@@ -760,26 +814,26 @@
  * @param sb_min    lower subband processed (sb_min included)
  * @param sb_max    higher subband processed (sb_max excluded)
  */
-static int synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int length, int sb_min, int sb_max)
+static int synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb,
+                                       int length, int sb_min, int sb_max)
 {
     int sb, j, k, n, ch, run, channels;
-    int joined_stereo, zero_encoding, chs;
+    int joined_stereo, zero_encoding;
     int type34_first;
     float type34_div = 0;
     float type34_predictor;
-    float samples[10], sign_bits[16];
+    float samples[10];
+    int sign_bits[16] = {0};
 
     if (length == 0) {
         // If no data use noise
         for (sb=sb_min; sb < sb_max; sb++)
-            build_sb_samples_from_noise (q, sb);
+            build_sb_samples_from_noise(q, sb);
 
         return 0;
     }
 
     for (sb = sb_min; sb < sb_max; sb++) {
-        FIX_NOISE_IDX(q->noise_idx);
-
         channels = q->nb_channels;
 
         if (q->nb_channels <= 1 || sb < 12)
@@ -787,27 +841,28 @@
         else if (sb >= 24)
             joined_stereo = 1;
         else
-            joined_stereo = (get_bits_left(gb) >= 1) ? get_bits1 (gb) : 0;
+            joined_stereo = (get_bits_left(gb) >= 1) ? get_bits1(gb) : 0;
 
         if (joined_stereo) {
             if (get_bits_left(gb) >= 16)
                 for (j = 0; j < 16; j++)
-                    sign_bits[j] = get_bits1 (gb);
-
-            if (q->coding_method[0][sb][0] <= 0) {
-                av_log(NULL, AV_LOG_ERROR, "coding method invalid\n");
-                return AVERROR_INVALIDDATA;
-            }
+                    sign_bits[j] = get_bits1(gb);
 
             for (j = 0; j < 64; j++)
                 if (q->coding_method[1][sb][j] > q->coding_method[0][sb][j])
                     q->coding_method[0][sb][j] = q->coding_method[1][sb][j];
 
-            fix_coding_method_array(sb, q->nb_channels, q->coding_method);
+            if (fix_coding_method_array(sb, q->nb_channels,
+                                            q->coding_method)) {
+                av_log(NULL, AV_LOG_ERROR, "coding method invalid\n");
+                build_sb_samples_from_noise(q, sb);
+                continue;
+            }
             channels = 1;
         }
 
         for (ch = 0; ch < channels; ch++) {
+            FIX_NOISE_IDX(q->noise_idx);
             zero_encoding = (get_bits_left(gb) >= 1) ? get_bits1(gb) : 0;
             type34_predictor = 0.0;
             type34_first = 1;
@@ -940,16 +995,18 @@
                 }
 
                 if (joined_stereo) {
-                    float tmp[10][MPA_MAX_CHANNELS];
-                    for (k = 0; k < run; k++) {
-                        tmp[k][0] = samples[k];
-                        if ((j + k) < 128)
-                            tmp[k][1] = (sign_bits[(j + k) / 8]) ? -samples[k] : samples[k];
+                    for (k = 0; k < run && j + k < 128; k++) {
+                        q->sb_samples[0][j + k][sb] =
+                            q->tone_level[0][sb][(j + k) / 2] * samples[k];
+                        if (q->nb_channels == 2) {
+                            if (sign_bits[(j + k) / 8])
+                                q->sb_samples[1][j + k][sb] =
+                                    q->tone_level[1][sb][(j + k) / 2] * -samples[k];
+                            else
+                                q->sb_samples[1][j + k][sb] =
+                                    q->tone_level[1][sb][(j + k) / 2] * samples[k];
+                        }
                     }
-                    for (chs = 0; chs < q->nb_channels; chs++)
-                        for (k = 0; k < run; k++)
-                            if ((j + k) < 128)
-                                q->sb_samples[chs][j + k][sb] = q->tone_level[chs][sb][((j + k)/2)] * tmp[k][chs];
                 } else {
                     for (k = 0; k < run; k++)
                         if ((j + k) < 128)
@@ -963,16 +1020,18 @@
     return 0;
 }
 
-
 /**
- * Init the first element of a channel in quantized_coeffs with data from packet 10 (quantized_coeffs[ch][0]).
- * This is similar to process_subpacket_9, but for a single channel and for element [0]
+ * Init the first element of a channel in quantized_coeffs with data
+ * from packet 10 (quantized_coeffs[ch][0]).
+ * This is similar to process_subpacket_9, but for a single channel
+ * and for element [0]
  * same VLC tables as process_subpacket_9 are used.
  *
  * @param quantized_coeffs    pointer to quantized_coeffs[ch][0]
  * @param gb        bitreader context
  */
-static int init_quantized_coeffs_elem0 (int8_t *quantized_coeffs, GetBitContext *gb)
+static int init_quantized_coeffs_elem0(int8_t *quantized_coeffs,
+                                        GetBitContext *gb)
 {
     int i, k, run, level, diff;
 
@@ -1003,16 +1062,16 @@
     return 0;
 }
 
-
 /**
  * Related to synthesis filter, process data from packet 10
  * Init part of quantized_coeffs via function init_quantized_coeffs_elem0
- * Init tone_level_idx_hi1, tone_level_idx_hi2, tone_level_idx_mid with data from packet 10
+ * Init tone_level_idx_hi1, tone_level_idx_hi2, tone_level_idx_mid with
+ * data from packet 10
  *
  * @param q         context
  * @param gb        bitreader context
  */
-static void init_tone_level_dequantization (QDM2Context *q, GetBitContext *gb)
+static void init_tone_level_dequantization(QDM2Context *q, GetBitContext *gb)
 {
     int sb, j, k, n, ch;
 
@@ -1075,32 +1134,32 @@
  * @param q       context
  * @param node    pointer to node with packet
  */
-static int process_subpacket_9 (QDM2Context *q, QDM2SubPNode *node)
+static int process_subpacket_9(QDM2Context *q, QDM2SubPNode *node)
 {
     GetBitContext gb;
     int i, j, k, n, ch, run, level, diff;
 
-    init_get_bits(&gb, node->packet->data, node->packet->size*8);
+    init_get_bits(&gb, node->packet->data, node->packet->size * 8);
 
-    n = coeff_per_sb_for_avg[q->coeff_per_sb_select][QDM2_SB_USED(q->sub_sampling) - 1] + 1; // same as averagesomething function
+    n = coeff_per_sb_for_avg[q->coeff_per_sb_select][QDM2_SB_USED(q->sub_sampling) - 1] + 1;
 
     for (i = 1; i < n; i++)
-        for (ch=0; ch < q->nb_channels; ch++) {
+        for (ch = 0; ch < q->nb_channels; ch++) {
             level = qdm2_get_vlc(&gb, &vlc_tab_level, 0, 2);
             q->quantized_coeffs[ch][i][0] = level;
 
             for (j = 0; j < (8 - 1); ) {
-                run = qdm2_get_vlc(&gb, &vlc_tab_run, 0, 1) + 1;
+                run  = qdm2_get_vlc(&gb, &vlc_tab_run, 0, 1) + 1;
                 diff = qdm2_get_se_vlc(&vlc_tab_diff, &gb, 2);
 
                 if (j + run >= 8)
                     return -1;
 
                 for (k = 1; k <= run; k++)
-                    q->quantized_coeffs[ch][i][j + k] = (level + ((k*diff) / run));
+                    q->quantized_coeffs[ch][i][j + k] = (level + ((k * diff) / run));
 
                 level += diff;
-                j += run;
+                j     += run;
             }
         }
 
@@ -1111,14 +1170,13 @@
     return 0;
 }
 
-
 /**
  * Process subpacket 10 if not null, else
  *
  * @param q         context
  * @param node      pointer to node with packet
  */
-static void process_subpacket_10 (QDM2Context *q, QDM2SubPNode *node)
+static void process_subpacket_10(QDM2Context *q, QDM2SubPNode *node)
 {
     GetBitContext gb;
 
@@ -1131,14 +1189,13 @@
     }
 }
 
-
 /**
  * Process subpacket 11
  *
  * @param q         context
  * @param node      pointer to node with packet
  */
-static void process_subpacket_11 (QDM2Context *q, QDM2SubPNode *node)
+static void process_subpacket_11(QDM2Context *q, QDM2SubPNode *node)
 {
     GetBitContext gb;
     int length = 0;
@@ -1149,24 +1206,25 @@
     }
 
     if (length >= 32) {
-        int c = get_bits (&gb, 13);
+        int c = get_bits(&gb, 13);
 
         if (c > 3)
-            fill_coding_method_array (q->tone_level_idx, q->tone_level_idx_temp, q->coding_method,
-                                      q->nb_channels, 8*c, q->superblocktype_2_3, q->cm_table_select);
+            fill_coding_method_array(q->tone_level_idx,
+                                     q->tone_level_idx_temp, q->coding_method,
+                                     q->nb_channels, 8 * c,
+                                     q->superblocktype_2_3, q->cm_table_select);
     }
 
     synthfilt_build_sb_samples(q, &gb, length, 0, 8);
 }
 
-
 /**
  * Process subpacket 12
  *
  * @param q         context
  * @param node      pointer to node with packet
  */
-static void process_subpacket_12 (QDM2Context *q, QDM2SubPNode *node)
+static void process_subpacket_12(QDM2Context *q, QDM2SubPNode *node)
 {
     GetBitContext gb;
     int length = 0;
@@ -1185,7 +1243,7 @@
  * @param q       context
  * @param list    list with synthesis filter packets (list D)
  */
-static void process_synthesis_subpackets (QDM2Context *q, QDM2SubPNode *list)
+static void process_synthesis_subpackets(QDM2Context *q, QDM2SubPNode *list)
 {
     QDM2SubPNode *nodes[4];
 
@@ -1212,13 +1270,12 @@
         process_subpacket_12(q, NULL);
 }
 
-
 /**
  * Decode superblock, fill packet lists.
  *
  * @param q    context
  */
-static void qdm2_decode_super_block (QDM2Context *q)
+static void qdm2_decode_super_block(QDM2Context *q)
 {
     GetBitContext gb;
     QDM2SubPacket header, *packet;
@@ -1230,33 +1287,33 @@
     memset(q->tone_level_idx_hi2, 0, sizeof(q->tone_level_idx_hi2));
 
     q->sub_packets_B = 0;
-    sub_packets_D = 0;
+    sub_packets_D    = 0;
 
     average_quantized_coeffs(q); // average elements in quantized_coeffs[max_ch][10][8]
 
-    init_get_bits(&gb, q->compressed_data, q->compressed_size*8);
+    init_get_bits(&gb, q->compressed_data, q->compressed_size * 8);
     qdm2_decode_sub_packet_header(&gb, &header);
 
     if (header.type < 2 || header.type >= 8) {
         q->has_errors = 1;
-        av_log(NULL,AV_LOG_ERROR,"bad superblock type\n");
+        av_log(NULL, AV_LOG_ERROR, "bad superblock type\n");
         return;
     }
 
     q->superblocktype_2_3 = (header.type == 2 || header.type == 3);
-    packet_bytes = (q->compressed_size - get_bits_count(&gb) / 8);
+    packet_bytes          = (q->compressed_size - get_bits_count(&gb) / 8);
 
-    init_get_bits(&gb, header.data, header.size*8);
+    init_get_bits(&gb, header.data, header.size * 8);
 
     if (header.type == 2 || header.type == 4 || header.type == 5) {
-        int csum  = 257 * get_bits(&gb, 8);
-            csum +=   2 * get_bits(&gb, 8);
+        int csum = 257 * get_bits(&gb, 8);
+        csum += 2 * get_bits(&gb, 8);
 
         csum = qdm2_packet_checksum(q->compressed_data, q->checksum_size, csum);
 
         if (csum != 0) {
             q->has_errors = 1;
-            av_log(NULL,AV_LOG_ERROR,"bad packet checksum\n");
+            av_log(NULL, AV_LOG_ERROR, "bad packet checksum\n");
             return;
         }
     }
@@ -1282,8 +1339,8 @@
             q->sub_packet_list_A[i - 1].next = &q->sub_packet_list_A[i];
 
             /* seek to next block */
-            init_get_bits(&gb, header.data, header.size*8);
-            skip_bits(&gb, next_index*8);
+            init_get_bits(&gb, header.data, header.size * 8);
+            skip_bits(&gb, next_index * 8);
 
             if (next_index >= header.size)
                 break;
@@ -1292,7 +1349,7 @@
         /* decode subpacket */
         packet = &q->sub_packets[i];
         qdm2_decode_sub_packet_header(&gb, packet);
-        next_index = packet->size + get_bits_count(&gb) / 8;
+        next_index      = packet->size + get_bits_count(&gb) / 8;
         sub_packet_size = ((packet->size > 0xff) ? 1 : 0) + packet->size + 2;
 
         if (packet->type == 0)
@@ -1325,13 +1382,13 @@
         } else if (packet->type == 15) {
             SAMPLES_NEEDED_2("packet type 15")
             return;
-        } else if (packet->type >= 16 && packet->type < 48 && !fft_subpackets[packet->type - 16]) {
+        } else if (packet->type >= 16 && packet->type < 48 &&
+                   !fft_subpackets[packet->type - 16]) {
             /* packets for FFT */
             QDM2_LIST_ADD(q->sub_packet_list_B, q->sub_packets_B, packet);
         }
     } // Packet bytes loop
 
-/* **************************************************************** */
     if (q->sub_packet_list_D[0].packet != NULL) {
         process_synthesis_subpackets(q, q->sub_packet_list_D);
         q->do_synth_filter = 1;
@@ -1340,39 +1397,38 @@
         process_subpacket_11(q, NULL);
         process_subpacket_12(q, NULL);
     }
-/* **************************************************************** */
 }
 
-
-static void qdm2_fft_init_coefficient (QDM2Context *q, int sub_packet,
-                       int offset, int duration, int channel,
-                       int exp, int phase)
+static void qdm2_fft_init_coefficient(QDM2Context *q, int sub_packet,
+                                      int offset, int duration, int channel,
+                                      int exp, int phase)
 {
     if (q->fft_coefs_min_index[duration] < 0)
         q->fft_coefs_min_index[duration] = q->fft_coefs_index;
 
-    q->fft_coefs[q->fft_coefs_index].sub_packet = ((sub_packet >= 16) ? (sub_packet - 16) : sub_packet);
+    q->fft_coefs[q->fft_coefs_index].sub_packet =
+        ((sub_packet >= 16) ? (sub_packet - 16) : sub_packet);
     q->fft_coefs[q->fft_coefs_index].channel = channel;
-    q->fft_coefs[q->fft_coefs_index].offset = offset;
-    q->fft_coefs[q->fft_coefs_index].exp = exp;
-    q->fft_coefs[q->fft_coefs_index].phase = phase;
+    q->fft_coefs[q->fft_coefs_index].offset  = offset;
+    q->fft_coefs[q->fft_coefs_index].exp     = exp;
+    q->fft_coefs[q->fft_coefs_index].phase   = phase;
     q->fft_coefs_index++;
 }
 
-
-static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext *gb, int b)
+static void qdm2_fft_decode_tones(QDM2Context *q, int duration,
+                                  GetBitContext *gb, int b)
 {
     int channel, stereo, phase, exp;
-    int local_int_4,  local_int_8,  stereo_phase,  local_int_10;
+    int local_int_4, local_int_8, stereo_phase, local_int_10;
     int local_int_14, stereo_exp, local_int_20, local_int_28;
     int n, offset;
 
-    local_int_4 = 0;
+    local_int_4  = 0;
     local_int_28 = 0;
     local_int_20 = 2;
-    local_int_8 = (4 - duration);
+    local_int_8  = (4 - duration);
     local_int_10 = 1 << (q->group_order - duration - 1);
-    offset = 1;
+    offset       = 1;
 
     while (get_bits_left(gb)>0) {
         if (q->superblocktype_2_3) {
@@ -1384,10 +1440,10 @@
                 }
                 offset = 1;
                 if (n == 0) {
-                    local_int_4 += local_int_10;
+                    local_int_4  += local_int_10;
                     local_int_28 += (1 << local_int_8);
                 } else {
-                    local_int_4 += 8*local_int_10;
+                    local_int_4  += 8 * local_int_10;
                     local_int_28 += (8 << local_int_8);
                 }
             }
@@ -1395,7 +1451,7 @@
         } else {
             offset += qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2);
             while (offset >= (local_int_10 - 1)) {
-                offset += (1 - (local_int_10 - 1));
+                offset       += (1 - (local_int_10 - 1));
                 local_int_4  += local_int_10;
                 local_int_28 += (1 << local_int_8);
             }
@@ -1410,22 +1466,22 @@
 
         if (q->nb_channels > 1) {
             channel = get_bits1(gb);
-            stereo = get_bits1(gb);
+            stereo  = get_bits1(gb);
         } else {
             channel = 0;
-            stereo = 0;
+            stereo  = 0;
         }
 
-        exp = qdm2_get_vlc(gb, (b ? &fft_level_exp_vlc : &fft_level_exp_alt_vlc), 0, 2);
+        exp  = qdm2_get_vlc(gb, (b ? &fft_level_exp_vlc : &fft_level_exp_alt_vlc), 0, 2);
         exp += q->fft_level_exp[fft_level_index_table[local_int_14]];
-        exp = (exp < 0) ? 0 : exp;
+        exp  = (exp < 0) ? 0 : exp;
 
-        phase = get_bits(gb, 3);
-        stereo_exp = 0;
+        phase        = get_bits(gb, 3);
+        stereo_exp   = 0;
         stereo_phase = 0;
 
         if (stereo) {
-            stereo_exp = (exp - qdm2_get_vlc(gb, &fft_stereo_exp_vlc, 0, 1));
+            stereo_exp   = (exp - qdm2_get_vlc(gb, &fft_stereo_exp_vlc, 0, 1));
             stereo_phase = (phase - qdm2_get_vlc(gb, &fft_stereo_phase_vlc, 0, 1));
             if (stereo_phase < 0)
                 stereo_phase += 8;
@@ -1434,17 +1490,18 @@
         if (q->frequency_range > (local_int_14 + 1)) {
             int sub_packet = (local_int_20 + local_int_28);
 
-            qdm2_fft_init_coefficient(q, sub_packet, offset, duration, channel, exp, phase);
+            qdm2_fft_init_coefficient(q, sub_packet, offset, duration,
+                                      channel, exp, phase);
             if (stereo)
-                qdm2_fft_init_coefficient(q, sub_packet, offset, duration, (1 - channel), stereo_exp, stereo_phase);
+                qdm2_fft_init_coefficient(q, sub_packet, offset, duration,
+                                          1 - channel,
+                                          stereo_exp, stereo_phase);
         }
-
         offset++;
     }
 }
 
-
-static void qdm2_decode_fft_packets (QDM2Context *q)
+static void qdm2_decode_fft_packets(QDM2Context *q)
 {
     int i, j, min, max, value, type, unknown_flag;
     GetBitContext gb;
@@ -1454,18 +1511,18 @@
 
     /* reset minimum indexes for FFT coefficients */
     q->fft_coefs_index = 0;
-    for (i=0; i < 5; i++)
+    for (i = 0; i < 5; i++)
         q->fft_coefs_min_index[i] = -1;
 
     /* process subpackets ordered by type, largest type first */
     for (i = 0, max = 256; i < q->sub_packets_B; i++) {
-        QDM2SubPacket *packet= NULL;
+        QDM2SubPacket *packet = NULL;
 
         /* find subpacket with largest type less than max */
         for (j = 0, min = 0; j < q->sub_packets_B; j++) {
             value = q->sub_packet_list_B[j].packet->type;
             if (value > min && value < max) {
-                min = value;
+                min    = value;
                 packet = q->sub_packet_list_B[j].packet;
             }
         }
@@ -1476,11 +1533,13 @@
         if (!packet)
             return;
 
-        if (i == 0 && (packet->type < 16 || packet->type >= 48 || fft_subpackets[packet->type - 16]))
+        if (i == 0 &&
+            (packet->type < 16 || packet->type >= 48 ||
+             fft_subpackets[packet->type - 16]))
             return;
 
         /* decode FFT tones */
-        init_get_bits (&gb, packet->data, packet->size*8);
+        init_get_bits(&gb, packet->data, packet->size * 8);
 
         if (packet->type >= 32 && packet->type < 48 && !fft_subpackets[packet->type - 16])
             unknown_flag = 1;
@@ -1495,13 +1554,13 @@
             if (duration >= 0 && duration < 4)
                 qdm2_fft_decode_tones(q, duration, &gb, unknown_flag);
         } else if (type == 31) {
-            for (j=0; j < 4; j++)
+            for (j = 0; j < 4; j++)
                 qdm2_fft_decode_tones(q, j, &gb, unknown_flag);
         } else if (type == 46) {
-            for (j=0; j < 6; j++)
+            for (j = 0; j < 6; j++)
                 q->fft_level_exp[j] = get_bits(&gb, 6);
-            for (j=0; j < 4; j++)
-            qdm2_fft_decode_tones(q, j, &gb, unknown_flag);
+            for (j = 0; j < 4; j++)
+                qdm2_fft_decode_tones(q, j, &gb, unknown_flag);
         }
     } // Loop on B packets
 
@@ -1516,20 +1575,19 @@
         q->fft_coefs_max_index[j] = q->fft_coefs_index;
 }
 
-
-static void qdm2_fft_generate_tone (QDM2Context *q, FFTTone *tone)
+static void qdm2_fft_generate_tone(QDM2Context *q, FFTTone *tone)
 {
-   float level, f[6];
-   int i;
-   QDM2Complex c;
-   const double iscale = 2.0*M_PI / 512.0;
+    float level, f[6];
+    int i;
+    QDM2Complex c;
+    const double iscale = 2.0 * M_PI / 512.0;
 
     tone->phase += tone->phase_shift;
 
     /* calculate current level (maximum amplitude) of tone */
     level = fft_tone_envelope_table[tone->duration][tone->time_index] * tone->level;
-    c.im = level * sin(tone->phase*iscale);
-    c.re = level * cos(tone->phase*iscale);
+    c.im  = level * sin(tone->phase * iscale);
+    c.re  = level * cos(tone->phase * iscale);
 
     /* generate FFT coefficients for tone */
     if (tone->duration >= 3 || tone->cutoff >= 3) {
@@ -1539,30 +1597,31 @@
         tone->complex[1].re -= c.re;
     } else {
         f[1] = -tone->table[4];
-        f[0] =  tone->table[3] - tone->table[0];
-        f[2] =  1.0 - tone->table[2] - tone->table[3];
-        f[3] =  tone->table[1] + tone->table[4] - 1.0;
-        f[4] =  tone->table[0] - tone->table[1];
-        f[5] =  tone->table[2];
+        f[0] = tone->table[3] - tone->table[0];
+        f[2] = 1.0 - tone->table[2] - tone->table[3];
+        f[3] = tone->table[1] + tone->table[4] - 1.0;
+        f[4] = tone->table[0] - tone->table[1];
+        f[5] = tone->table[2];
         for (i = 0; i < 2; i++) {
-            tone->complex[fft_cutoff_index_table[tone->cutoff][i]].re += c.re * f[i];
-            tone->complex[fft_cutoff_index_table[tone->cutoff][i]].im += c.im *((tone->cutoff <= i) ? -f[i] : f[i]);
+            tone->complex[fft_cutoff_index_table[tone->cutoff][i]].re +=
+                c.re * f[i];
+            tone->complex[fft_cutoff_index_table[tone->cutoff][i]].im +=
+                c.im * ((tone->cutoff <= i) ? -f[i] : f[i]);
         }
         for (i = 0; i < 4; i++) {
-            tone->complex[i].re += c.re * f[i+2];
-            tone->complex[i].im += c.im * f[i+2];
+            tone->complex[i].re += c.re * f[i + 2];
+            tone->complex[i].im += c.im * f[i + 2];
         }
     }
 
     /* copy the tone if it has not yet died out */
     if (++tone->time_index < ((1 << (5 - tone->duration)) - 1)) {
-      memcpy(&q->fft_tones[q->fft_tone_end], tone, sizeof(FFTTone));
-      q->fft_tone_end = (q->fft_tone_end + 1) % 1000;
+        memcpy(&q->fft_tones[q->fft_tone_end], tone, sizeof(FFTTone));
+        q->fft_tone_end = (q->fft_tone_end + 1) % 1000;
     }
 }
 
-
-static void qdm2_fft_tone_synthesizer (QDM2Context *q, int sub_packet)
+static void qdm2_fft_tone_synthesizer(QDM2Context *q, int sub_packet)
 {
     int i, j, ch;
     const double iscale = 0.25 * M_PI;
@@ -1633,29 +1692,27 @@
         }
 }
 
-
-static void qdm2_calculate_fft (QDM2Context *q, int channel, int sub_packet)
+static void qdm2_calculate_fft(QDM2Context *q, int channel, int sub_packet)
 {
     const float gain = (q->channels == 1 && q->nb_channels == 2) ? 0.5f : 1.0f;
-    float *out = q->output_buffer + channel;
+    float *out       = q->output_buffer + channel;
     int i;
     q->fft.complex[channel][0].re *= 2.0f;
-    q->fft.complex[channel][0].im = 0.0f;
+    q->fft.complex[channel][0].im  = 0.0f;
     q->rdft_ctx.rdft_calc(&q->rdft_ctx, (FFTSample *)q->fft.complex[channel]);
     /* add samples to output buffer */
     for (i = 0; i < FFALIGN(q->fft_size, 8); i++) {
         out[0]           += q->fft.complex[channel][i].re * gain;
         out[q->channels] += q->fft.complex[channel][i].im * gain;
-        out += 2 * q->channels;
+        out              += 2 * q->channels;
     }
 }
 
-
 /**
  * @param q        context
  * @param index    subpacket number
  */
-static void qdm2_synthesis_filter (QDM2Context *q, int index)
+static void qdm2_synthesis_filter(QDM2Context *q, int index)
 {
     int i, k, ch, sb_used, sub_sampling, dither_state = 0;
 
@@ -1664,7 +1721,7 @@
 
     for (ch = 0; ch < q->channels; ch++)
         for (i = 0; i < 8; i++)
-            for (k=sb_used; k < SBLIMIT; k++)
+            for (k = sb_used; k < SBLIMIT; k++)
                 q->sb_samples[ch][(8 * index) + i][k] = 0;
 
     for (ch = 0; ch < q->nb_channels; ch++) {
@@ -1672,10 +1729,10 @@
 
         for (i = 0; i < 8; i++) {
             ff_mpa_synth_filter_float(&q->mpadsp,
-                q->synth_buf[ch], &(q->synth_buf_offset[ch]),
-                ff_mpa_synth_window_float, &dither_state,
-                samples_ptr, q->nb_channels,
-                q->sb_samples[ch][(8 * index) + i]);
+                                      q->synth_buf[ch], &(q->synth_buf_offset[ch]),
+                                      ff_mpa_synth_window_float, &dither_state,
+                                      samples_ptr, q->nb_channels,
+                                      q->sb_samples[ch][(8 * index) + i]);
             samples_ptr += 32 * q->nb_channels;
         }
     }
@@ -1688,29 +1745,19 @@
             q->output_buffer[q->channels * i + ch] += (1 << 23) * q->samples[q->nb_channels * sub_sampling * i + ch];
 }
 
-
 /**
  * Init static data (does not depend on specific file)
  *
  * @param q    context
  */
-static av_cold void qdm2_init(QDM2Context *q) {
-    static int initialized = 0;
-
-    if (initialized != 0)
-        return;
-    initialized = 1;
-
+static av_cold void qdm2_init_static_data(AVCodec *codec) {
     qdm2_init_vlc();
     ff_mpa_synth_init_float(ff_mpa_synth_window_float);
     softclip_table_init();
     rnd_table_init();
     init_noise_samples();
-
-    av_log(NULL, AV_LOG_DEBUG, "init done\n");
 }
 
-
 /**
  * Init parameters from codec extradata
  */
@@ -1760,7 +1807,7 @@
         return -1;
     }
 
-    extradata = avctx->extradata;
+    extradata      = avctx->extradata;
     extradata_size = avctx->extradata_size;
 
     while (extradata_size > 7) {
@@ -1882,14 +1929,11 @@
     ff_rdft_init(&s->rdft_ctx, s->fft_order, IDFT_C2R);
     ff_mpadsp_init(&s->mpadsp);
 
-    qdm2_init(s);
-
     avctx->sample_fmt = AV_SAMPLE_FMT_S16;
 
     return 0;
 }
 
-
 static av_cold int qdm2_decode_close(AVCodecContext *avctx)
 {
     QDM2Context *s = avctx->priv_data;
@@ -1899,8 +1943,7 @@
     return 0;
 }
 
-
-static int qdm2_decode (QDM2Context *q, const uint8_t *in, int16_t *out)
+static int qdm2_decode(QDM2Context *q, const uint8_t *in, int16_t *out)
 {
     int ch, i;
     const int frame_size = (q->frame_size * q->channels);
@@ -1962,7 +2005,6 @@
     return 0;
 }
 
-
 static int qdm2_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame_ptr, AVPacket *avpkt)
 {
@@ -1995,15 +2037,15 @@
     return s->checksum_size;
 }
 
-AVCodec ff_qdm2_decoder =
-{
-    .name           = "qdm2",
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_QDM2,
-    .priv_data_size = sizeof(QDM2Context),
-    .init           = qdm2_decode_init,
-    .close          = qdm2_decode_close,
-    .decode         = qdm2_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("QDesign Music Codec 2"),
+AVCodec ff_qdm2_decoder = {
+    .name             = "qdm2",
+    .type             = AVMEDIA_TYPE_AUDIO,
+    .id               = AV_CODEC_ID_QDM2,
+    .priv_data_size   = sizeof(QDM2Context),
+    .init             = qdm2_decode_init,
+    .init_static_data = qdm2_init_static_data,
+    .close            = qdm2_decode_close,
+    .decode           = qdm2_decode_frame,
+    .capabilities     = CODEC_CAP_DR1,
+    .long_name        = NULL_IF_CONFIG_SMALL("QDesign Music Codec 2"),
 };
diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c
index c043249..a22d776 100644
--- a/libavcodec/qtrle.c
+++ b/libavcodec/qtrle.c
@@ -41,7 +41,7 @@
 
 typedef struct QtrleContext {
     AVCodecContext *avctx;
-    AVFrame frame;
+    AVFrame *frame;
 
     GetByteContext g;
     uint32_t pal[256];
@@ -58,17 +58,17 @@
 {
     int rle_code;
     int pixel_ptr;
-    int row_inc = s->frame.linesize[0];
-    unsigned char pi0, pi1;  /* 2 8-pixel values */
-    unsigned char *rgb = s->frame.data[0];
-    int pixel_limit = s->frame.linesize[0] * s->avctx->height;
+    int row_inc = s->frame->linesize[0];
+    uint8_t pi0, pi1;  /* 2 8-pixel values */
+    uint8_t *rgb = s->frame->data[0];
+    int pixel_limit = s->frame->linesize[0] * s->avctx->height;
     int skip;
     /* skip & 0x80 appears to mean 'start a new line', which can be interpreted
      * as 'go to next line' during the decoding of a frame but is 'go to first
      * line' at the beginning. Since we always interpret it as 'go to next line'
      * in the decoding loop (which makes code simpler/faster), the first line
      * would not be counted, so we count one more.
-     * See: https://ffmpeg.org/trac/ffmpeg/ticket/226
+     * See: https://trac.ffmpeg.org/ticket/226
      * In the following decoding loop, row_ptr will be the position of the
      * current row. */
 
@@ -77,7 +77,7 @@
     lines_to_change++;
     while (lines_to_change) {
         skip     =              bytestream2_get_byte(&s->g);
-        rle_code = (signed char)bytestream2_get_byte(&s->g);
+        rle_code = (int8_t)bytestream2_get_byte(&s->g);
         if (rle_code == 0)
             break;
         if(skip & 0x80) {
@@ -110,8 +110,8 @@
             rle_code *= 2;
             CHECK_PIXEL_PTR(rle_code);
 
-            while (rle_code--)
-                rgb[pixel_ptr++] = bytestream2_get_byte(&s->g);
+            bytestream2_get_buffer(&s->g, &rgb[pixel_ptr], rle_code);
+            pixel_ptr += rle_code;
         }
     }
 }
@@ -121,17 +121,17 @@
 {
     int rle_code, i;
     int pixel_ptr;
-    int row_inc = s->frame.linesize[0];
-    unsigned char pi[16];  /* 16 palette indices */
-    unsigned char *rgb = s->frame.data[0];
-    int pixel_limit = s->frame.linesize[0] * s->avctx->height;
+    int row_inc = s->frame->linesize[0];
+    uint8_t pi[16];  /* 16 palette indices */
+    uint8_t *rgb = s->frame->data[0];
+    int pixel_limit = s->frame->linesize[0] * s->avctx->height;
     int num_pixels = (bpp == 4) ? 8 : 16;
 
     while (lines_to_change--) {
         pixel_ptr = row_ptr + (num_pixels * (bytestream2_get_byte(&s->g) - 1));
         CHECK_PIXEL_PTR(0);
 
-        while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
+        while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) {
             if (rle_code == 0) {
                 /* there's another skip code in the stream */
                 pixel_ptr += (num_pixels * (bytestream2_get_byte(&s->g) - 1));
@@ -147,8 +147,8 @@
                 }
                 CHECK_PIXEL_PTR(rle_code * num_pixels);
                 while (rle_code--) {
-                    for (i = 0; i < num_pixels; i++)
-                        rgb[pixel_ptr++] = pi[i];
+                    memcpy(&rgb[pixel_ptr], &pi, num_pixels);
+                    pixel_ptr += num_pixels;
                 }
             } else {
                 /* copy the same pixel directly to output 4 times */
@@ -177,16 +177,16 @@
 {
     int rle_code;
     int pixel_ptr;
-    int row_inc = s->frame.linesize[0];
-    unsigned char pi1, pi2, pi3, pi4;  /* 4 palette indexes */
-    unsigned char *rgb = s->frame.data[0];
-    int pixel_limit = s->frame.linesize[0] * s->avctx->height;
+    int row_inc = s->frame->linesize[0];
+    uint8_t pi1, pi2, pi3, pi4;  /* 4 palette indexes */
+    uint8_t *rgb = s->frame->data[0];
+    int pixel_limit = s->frame->linesize[0] * s->avctx->height;
 
     while (lines_to_change--) {
         pixel_ptr = row_ptr + (4 * (bytestream2_get_byte(&s->g) - 1));
         CHECK_PIXEL_PTR(0);
 
-        while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
+        while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) {
             if (rle_code == 0) {
                 /* there's another skip code in the stream */
                 pixel_ptr += (4 * (bytestream2_get_byte(&s->g) - 1));
@@ -214,9 +214,8 @@
                 rle_code *= 4;
                 CHECK_PIXEL_PTR(rle_code);
 
-                while (rle_code--) {
-                    rgb[pixel_ptr++] = bytestream2_get_byte(&s->g);
-                }
+                bytestream2_get_buffer(&s->g, &rgb[pixel_ptr], rle_code);
+                pixel_ptr += rle_code;
             }
         }
         row_ptr += row_inc;
@@ -227,16 +226,16 @@
 {
     int rle_code;
     int pixel_ptr;
-    int row_inc = s->frame.linesize[0];
-    unsigned short rgb16;
-    unsigned char *rgb = s->frame.data[0];
-    int pixel_limit = s->frame.linesize[0] * s->avctx->height;
+    int row_inc = s->frame->linesize[0];
+    uint16_t rgb16;
+    uint8_t *rgb = s->frame->data[0];
+    int pixel_limit = s->frame->linesize[0] * s->avctx->height;
 
     while (lines_to_change--) {
         pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 2;
         CHECK_PIXEL_PTR(0);
 
-        while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
+        while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) {
             if (rle_code == 0) {
                 /* there's another skip code in the stream */
                 pixel_ptr += (bytestream2_get_byte(&s->g) - 1) * 2;
@@ -249,7 +248,7 @@
                 CHECK_PIXEL_PTR(rle_code * 2);
 
                 while (rle_code--) {
-                    *(unsigned short *)(&rgb[pixel_ptr]) = rgb16;
+                    *(uint16_t *)(&rgb[pixel_ptr]) = rgb16;
                     pixel_ptr += 2;
                 }
             } else {
@@ -258,7 +257,7 @@
                 /* copy pixels directly to output */
                 while (rle_code--) {
                     rgb16 = bytestream2_get_be16(&s->g);
-                    *(unsigned short *)(&rgb[pixel_ptr]) = rgb16;
+                    *(uint16_t *)(&rgb[pixel_ptr]) = rgb16;
                     pixel_ptr += 2;
                 }
             }
@@ -271,16 +270,16 @@
 {
     int rle_code;
     int pixel_ptr;
-    int row_inc = s->frame.linesize[0];
-    unsigned char r, g, b;
-    unsigned char *rgb = s->frame.data[0];
-    int pixel_limit = s->frame.linesize[0] * s->avctx->height;
+    int row_inc = s->frame->linesize[0];
+    uint8_t r, g, b;
+    uint8_t *rgb = s->frame->data[0];
+    int pixel_limit = s->frame->linesize[0] * s->avctx->height;
 
     while (lines_to_change--) {
         pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 3;
         CHECK_PIXEL_PTR(0);
 
-        while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
+        while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) {
             if (rle_code == 0) {
                 /* there's another skip code in the stream */
                 pixel_ptr += (bytestream2_get_byte(&s->g) - 1) * 3;
@@ -318,16 +317,16 @@
 {
     int rle_code;
     int pixel_ptr;
-    int row_inc = s->frame.linesize[0];
+    int row_inc = s->frame->linesize[0];
     unsigned int argb;
-    unsigned char *rgb = s->frame.data[0];
-    int pixel_limit = s->frame.linesize[0] * s->avctx->height;
+    uint8_t *rgb = s->frame->data[0];
+    int pixel_limit = s->frame->linesize[0] * s->avctx->height;
 
     while (lines_to_change--) {
         pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 4;
         CHECK_PIXEL_PTR(0);
 
-        while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
+        while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) {
             if (rle_code == 0) {
                 /* there's another skip code in the stream */
                 pixel_ptr += (bytestream2_get_byte(&s->g) - 1) * 4;
@@ -396,7 +395,9 @@
         return AVERROR_INVALIDDATA;
     }
 
-    avcodec_get_frame_defaults(&s->frame);
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
 
     return 0;
 }
@@ -412,7 +413,7 @@
     int ret;
 
     bytestream2_init(&s->g, avpkt->data, avpkt->size);
-    if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0)
+    if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
         return ret;
 
     /* check if this frame is even supposed to change */
@@ -439,7 +440,7 @@
         start_line = 0;
         height     = s->avctx->height;
     }
-    row_ptr = s->frame.linesize[0] * start_line;
+    row_ptr = s->frame->linesize[0] * start_line;
 
     switch (avctx->bits_per_coded_sample) {
     case 1:
@@ -487,16 +488,16 @@
         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
 
         if (pal) {
-            s->frame.palette_has_changed = 1;
+            s->frame->palette_has_changed = 1;
             memcpy(s->pal, pal, AVPALETTE_SIZE);
         }
 
         /* make the palette available on the way out */
-        memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE);
+        memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE);
     }
 
 done:
-    if ((ret = av_frame_ref(data, &s->frame)) < 0)
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
         return ret;
     *got_frame      = 1;
 
@@ -508,7 +509,7 @@
 {
     QtrleContext *s = avctx->priv_data;
 
-    av_frame_unref(&s->frame);
+    av_frame_free(&s->frame);
 
     return 0;
 }
diff --git a/libavcodec/ra144.c b/libavcodec/ra144.c
index 58cf377..fe9a5bc 100644
--- a/libavcodec/ra144.c
+++ b/libavcodec/ra144.c
@@ -1504,8 +1504,8 @@
     lpc_refl_cb6, lpc_refl_cb7, lpc_refl_cb8, lpc_refl_cb9, lpc_refl_cb10
 };
 
-static void ff_add_wav(int16_t *dest, int n, int skip_first, int *m, const int16_t *s1,
-                       const int8_t *s2, const int8_t *s3)
+static void add_wav(int16_t *dest, int n, int skip_first, int *m,
+                    const int16_t *s1, const int8_t *s2, const int8_t *s3)
 {
     int i;
     int v[3];
@@ -1716,8 +1716,8 @@
 
     block = ractx->adapt_cb + BUFFERSIZE - BLOCKSIZE;
 
-    ff_add_wav(block, gain, cba_idx, m, cba_idx? buffer_a: NULL,
-               ff_cb1_vects[cb1_idx], ff_cb2_vects[cb2_idx]);
+    add_wav(block, gain, cba_idx, m, cba_idx? buffer_a: NULL,
+            ff_cb1_vects[cb1_idx], ff_cb2_vects[cb2_idx]);
 
     memcpy(ractx->curr_sblock, ractx->curr_sblock + BLOCKSIZE,
            LPC_ORDER*sizeof(*ractx->curr_sblock));
diff --git a/libavcodec/ra144.h b/libavcodec/ra144.h
index 426fea3..763495d 100644
--- a/libavcodec/ra144.h
+++ b/libavcodec/ra144.h
@@ -30,7 +30,7 @@
 #define BLOCKSIZE       40      ///< subblock size in 16-bit words
 #define BUFFERSIZE      146     ///< the size of the adaptive codebook
 #define FIXED_CB_SIZE   128     ///< size of fixed codebooks
-#define FRAMESIZE       20      ///< size of encoded frame
+#define FRAME_SIZE      20      ///< size of encoded frame
 #define LPC_ORDER       10      ///< order of LPC filter
 
 typedef struct RA144Context {
diff --git a/libavcodec/ra144dec.c b/libavcodec/ra144dec.c
index 63f77e0..0492d1f 100644
--- a/libavcodec/ra144dec.c
+++ b/libavcodec/ra144dec.c
@@ -76,7 +76,7 @@
     RA144Context *ractx = avctx->priv_data;
     GetBitContext gb;
 
-    if (buf_size < FRAMESIZE) {
+    if (buf_size < FRAME_SIZE) {
         av_log(avctx, AV_LOG_ERROR,
                "Frame too small (%d bytes). Truncated file?\n", buf_size);
         *got_frame_ptr = 0;
@@ -89,7 +89,7 @@
         return ret;
     samples = (int16_t *)frame->data[0];
 
-    init_get_bits(&gb, buf, FRAMESIZE * 8);
+    init_get_bits8(&gb, buf, FRAME_SIZE);
 
     for (i = 0; i < LPC_ORDER; i++)
         lpc_refl[i] = ff_lpc_refl_cb[i][get_bits(&gb, sizes[i])];
@@ -122,7 +122,7 @@
 
     *got_frame_ptr = 1;
 
-    return FRAMESIZE;
+    return FRAME_SIZE;
 }
 
 AVCodec ff_ra_144_decoder = {
diff --git a/libavcodec/ra144enc.c b/libavcodec/ra144enc.c
index 2eac343..cef7f6d 100644
--- a/libavcodec/ra144enc.c
+++ b/libavcodec/ra144enc.c
@@ -447,7 +447,7 @@
     if (ractx->last_frame)
         return 0;
 
-    if ((ret = ff_alloc_packet2(avctx, avpkt, FRAMESIZE)) < 0)
+    if ((ret = ff_alloc_packet2(avctx, avpkt, FRAME_SIZE)) < 0)
         return ret;
 
     /**
@@ -536,7 +536,7 @@
     ff_af_queue_remove(&ractx->afq, avctx->frame_size, &avpkt->pts,
                        &avpkt->duration);
 
-    avpkt->size = FRAMESIZE;
+    avpkt->size = FRAME_SIZE;
     *got_packet_ptr = 1;
     return 0;
 }
@@ -555,4 +555,5 @@
                                                      AV_SAMPLE_FMT_NONE },
     .supported_samplerates = (const int[]){ 8000, 0 },
     .long_name      = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"),
+    .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, 0 },
 };
diff --git a/libavcodec/ra288.c b/libavcodec/ra288.c
index 393ea0b..1f65710 100644
--- a/libavcodec/ra288.c
+++ b/libavcodec/ra288.c
@@ -95,7 +95,7 @@
     memmove(ractx->sp_hist + 70, ractx->sp_hist + 75, 36*sizeof(*block));
 
     /* block 46 of G.728 spec */
-    sum = 32.;
+    sum = 32.0;
     for (i=0; i < 10; i++)
         sum -= gain_block[9-i] * ractx->gain_lpc[i];
 
@@ -111,7 +111,7 @@
 
     sum = avpriv_scalarproduct_float_c(buffer, buffer, 5);
 
-    sum = FFMAX(sum, 5. / (1<<24));
+    sum = FFMAX(sum, 5.0 / (1<<24));
 
     /* shift and store */
     memmove(gain_block, gain_block + 1, 9 * sizeof(*gain_block));
@@ -157,7 +157,7 @@
     }
 
     /* Multiply by the white noise correcting factor (WNCF). */
-    *out *= 257./256.;
+    *out *= 257.0 / 256.0;
 }
 
 /**
@@ -202,7 +202,7 @@
         return ret;
     out = (float *)frame->data[0];
 
-    init_get_bits(&gb, buf, avctx->block_align * 8);
+    init_get_bits8(&gb, buf, avctx->block_align);
 
     for (i=0; i < RA288_BLOCKS_PER_FRAME; i++) {
         float gain = amptable[get_bits(&gb, 3)];
diff --git a/libavcodec/ralf.c b/libavcodec/ralf.c
index d3f82d6..0313d99 100644
--- a/libavcodec/ralf.c
+++ b/libavcodec/ralf.c
@@ -26,6 +26,7 @@
  * Dedicated to the mastermind behind it, Ralph Wiggum.
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/channel_layout.h"
 #include "avcodec.h"
 #include "get_bits.h"
@@ -72,7 +73,7 @@
 
 #define MAX_ELEMS 644 // no RALF table uses more than that
 
-static int init_ralf_vlc(VLC *vlc, const uint8_t *data, int elems)
+static av_cold int init_ralf_vlc(VLC *vlc, const uint8_t *data, int elems)
 {
     uint8_t  lens[MAX_ELEMS];
     uint16_t codes[MAX_ELEMS];
diff --git a/libavcodec/rangecoder.c b/libavcodec/rangecoder.c
index 7d2d14d..69150a5 100644
--- a/libavcodec/rangecoder.c
+++ b/libavcodec/rangecoder.c
@@ -33,12 +33,13 @@
 
 #include <string.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "rangecoder.h"
 #include "bytestream.h"
 
-void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size)
+av_cold void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size)
 {
     c->bytestream_start  =
     c->bytestream        = buf;
@@ -49,7 +50,8 @@
     c->outstanding_byte  = -1;
 }
 
-void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf, int buf_size)
+av_cold void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf,
+                                   int buf_size)
 {
     /* cast to avoid compiler warning */
     ff_init_range_encoder(c, (uint8_t *)buf, buf_size);
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index 5860423..bf3321d 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -25,6 +25,7 @@
  * Rate control for video encoders.
  */
 
+#include "libavutil/attributes.h"
 #include "avcodec.h"
 #include "ratecontrol.h"
 #include "mpegvideo.h"
@@ -83,7 +84,7 @@
     return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits + 1) / bits;
 }
 
-int ff_rate_control_init(MpegEncContext *s)
+av_cold int ff_rate_control_init(MpegEncContext *s)
 {
     RateControlContext *rcc = &s->rc_context;
     int i, res;
@@ -296,7 +297,7 @@
     return 0;
 }
 
-void ff_rate_control_uninit(MpegEncContext *s)
+av_cold void ff_rate_control_uninit(MpegEncContext *s)
 {
     RateControlContext *rcc = &s->rc_context;
     emms_c();
@@ -919,7 +920,7 @@
     double rate_factor          = 0;
     double step;
     const int filter_size = (int)(a->qblur * 4) | 1;
-    double expected_bits;
+    double expected_bits = 0; // init to silence gcc warning
     double *qscale, *blurred_qscale, qscale_sum;
 
     /* find complexity & const_bits & decide the pict_types */
diff --git a/libavcodec/raw.c b/libavcodec/raw.c
index e23dbea..c3f3de1 100644
--- a/libavcodec/raw.c
+++ b/libavcodec/raw.c
@@ -166,6 +166,18 @@
     { AV_PIX_FMT_YUVA444P16LE, MKTAG('Y', '4',  0 , 16 ) },
     { AV_PIX_FMT_YUVA444P16BE, MKTAG(16 ,  0 , '4', 'Y') },
 
+    { AV_PIX_FMT_GBRP,         MKTAG('G', '3', 00 ,  8 ) },
+    { AV_PIX_FMT_GBRP9LE,      MKTAG('G', '3', 00 ,  9 ) },
+    { AV_PIX_FMT_GBRP9BE,      MKTAG( 9 , 00 , '3', 'G') },
+    { AV_PIX_FMT_GBRP10LE,     MKTAG('G', '3', 00 , 10 ) },
+    { AV_PIX_FMT_GBRP10BE,     MKTAG(10 , 00 , '3', 'G') },
+    { AV_PIX_FMT_GBRP12LE,     MKTAG('G', '3', 00 , 12 ) },
+    { AV_PIX_FMT_GBRP12BE,     MKTAG(12 , 00 , '3', 'G') },
+    { AV_PIX_FMT_GBRP14LE,     MKTAG('G', '3', 00 , 14 ) },
+    { AV_PIX_FMT_GBRP14BE,     MKTAG(14 , 00 , '3', 'G') },
+    { AV_PIX_FMT_GBRP16LE,     MKTAG('G', '3', 00 , 16 ) },
+    { AV_PIX_FMT_GBRP16BE,     MKTAG(16 , 00 , '3', 'G') },
+
     /* quicktime */
     { AV_PIX_FMT_YUV420P, MKTAG('R', '4', '2', '0') }, /* Radius DV YUV PAL */
     { AV_PIX_FMT_YUV411P, MKTAG('R', '4', '1', '1') }, /* Radius DV YUV NTSC */
diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c
index f45ff4c..54ed52d 100644
--- a/libavcodec/rawdec.c
+++ b/libavcodec/rawdec.c
@@ -48,7 +48,7 @@
 {NULL}
 };
 
-static const AVClass class = {
+static const AVClass rawdec_class = {
     .class_name = "rawdec",
     .option     = options,
     .version    = LIBAVUTIL_VERSION_INT,
@@ -123,22 +123,27 @@
         return AVERROR(EINVAL);
     }
 
-    if (desc->flags & (PIX_FMT_PAL | PIX_FMT_PSEUDOPAL)) {
+    if (desc->flags & (AV_PIX_FMT_FLAG_PAL | AV_PIX_FMT_FLAG_PSEUDOPAL)) {
         context->palette = av_buffer_alloc(AVPALETTE_SIZE);
         if (!context->palette)
             return AVERROR(ENOMEM);
-        if (desc->flags & PIX_FMT_PSEUDOPAL)
+        if (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)
             avpriv_set_systematic_pal2((uint32_t*)context->palette->data, avctx->pix_fmt);
         else
             memset(context->palette->data, 0, AVPALETTE_SIZE);
     }
 
-    context->frame_size = avpicture_get_size(avctx->pix_fmt, avctx->width,
-                                             avctx->height);
     if ((avctx->bits_per_coded_sample == 4 || avctx->bits_per_coded_sample == 2) &&
         avctx->pix_fmt == AV_PIX_FMT_PAL8 &&
-       (!avctx->codec_tag || avctx->codec_tag == MKTAG('r','a','w',' ')))
+       (!avctx->codec_tag || avctx->codec_tag == MKTAG('r','a','w',' '))) {
         context->is_2_4_bpp = 1;
+        context->frame_size = avpicture_get_size(avctx->pix_fmt,
+                                                 FFALIGN(avctx->width, 16),
+                                                 avctx->height);
+    } else {
+        context->frame_size = avpicture_get_size(avctx->pix_fmt, avctx->width,
+                                                 avctx->height);
+    }
 
     if ((avctx->extradata_size >= 9 &&
          !memcmp(avctx->extradata + avctx->extradata_size - 9, "BottomUp", 9)) ||
@@ -190,7 +195,7 @@
         return res;
 
     if (need_copy)
-        frame->buf[0] = av_buffer_alloc(context->frame_size);
+        frame->buf[0] = av_buffer_alloc(FFMAX(context->frame_size, buf_size));
     else
         frame->buf[0] = av_buffer_ref(avpkt->buf);
     if (!frame->buf[0])
@@ -219,7 +224,7 @@
         }
         buf = dst;
     } else if (need_copy) {
-        memcpy(frame->buf[0]->data, buf, FFMIN(buf_size, context->frame_size));
+        memcpy(frame->buf[0]->data, buf, buf_size);
         buf = frame->buf[0]->data;
     }
 
@@ -276,7 +281,7 @@
     }
 
     if ((avctx->pix_fmt == AV_PIX_FMT_PAL8 && buf_size < context->frame_size) ||
-        (desc->flags & PIX_FMT_PSEUDOPAL)) {
+        (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) {
         frame->buf[1]  = av_buffer_ref(context->palette);
         if (!frame->buf[1]) {
             av_buffer_unref(&frame->buf[0]);
@@ -351,5 +356,5 @@
     .close          = raw_close_decoder,
     .decode         = raw_decode,
     .long_name      = NULL_IF_CONFIG_SMALL("raw video"),
-    .priv_class     = &class,
+    .priv_class     = &rawdec_class,
 };
diff --git a/libavcodec/rdft.c b/libavcodec/rdft.c
index ebddd8b..218dd4c 100644
--- a/libavcodec/rdft.c
+++ b/libavcodec/rdft.c
@@ -54,7 +54,7 @@
  * the two real FFTs into one complex FFT. Unmangle the results.
  * ref: http://www.engineeringproductivitytools.com/stuff/T0001/PT10.HTM
  */
-static void ff_rdft_calc_c(RDFTContext* s, FFTSample* data)
+static void rdft_calc_c(RDFTContext *s, FFTSample *data)
 {
     int i, i1, i2;
     FFTComplex ev, od;
@@ -120,7 +120,7 @@
         s->tsin[i] = sin(i*theta);
     }
 #endif
-    s->rdft_calc   = ff_rdft_calc_c;
+    s->rdft_calc   = rdft_calc_c;
 
     if (ARCH_ARM) ff_rdft_init_arm(s);
 
diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c
index a652c47..666c49d 100644
--- a/libavcodec/roqvideoenc.c
+++ b/libavcodec/roqvideoenc.c
@@ -56,6 +56,7 @@
 
 #include <string.h>
 
+#include "libavutil/attributes.h"
 #include "roqvideo.h"
 #include "bytestream.h"
 #include "elbg.h"
@@ -936,7 +937,7 @@
     enc->framesSinceKeyframe++;
 }
 
-static int roq_encode_end(AVCodecContext *avctx)
+static av_cold int roq_encode_end(AVCodecContext *avctx)
 {
     RoqContext *enc = avctx->priv_data;
 
@@ -952,7 +953,7 @@
     return 0;
 }
 
-static int roq_encode_init(AVCodecContext *avctx)
+static av_cold int roq_encode_init(AVCodecContext *avctx)
 {
     RoqContext *enc = avctx->priv_data;
 
diff --git a/libavcodec/rpza.c b/libavcodec/rpza.c
index 2aa0091..416f8b6 100644
--- a/libavcodec/rpza.c
+++ b/libavcodec/rpza.c
@@ -85,7 +85,7 @@
     unsigned short *pixels = (unsigned short *)s->frame.data[0];
 
     int row_ptr = 0;
-    int pixel_ptr = 0;
+    int pixel_ptr = -4;
     int block_ptr;
     int pixel_x, pixel_y;
     int total_blocks;
@@ -141,6 +141,7 @@
             colorA = AV_RB16 (&s->buf[stream_ptr]);
             stream_ptr += 2;
             while (n_blocks--) {
+                ADVANCE_BLOCK()
                 block_ptr = row_ptr + pixel_ptr;
                 for (pixel_y = 0; pixel_y < 4; pixel_y++) {
                     for (pixel_x = 0; pixel_x < 4; pixel_x++){
@@ -149,7 +150,6 @@
                     }
                     block_ptr += row_inc;
                 }
-                ADVANCE_BLOCK();
             }
             break;
 
@@ -188,6 +188,7 @@
             if (s->size - stream_ptr < n_blocks * 4)
                 return;
             while (n_blocks--) {
+                ADVANCE_BLOCK();
                 block_ptr = row_ptr + pixel_ptr;
                 for (pixel_y = 0; pixel_y < 4; pixel_y++) {
                     index = s->buf[stream_ptr++];
@@ -198,7 +199,6 @@
                     }
                     block_ptr += row_inc;
                 }
-                ADVANCE_BLOCK();
             }
             break;
 
@@ -206,6 +206,7 @@
         case 0x00:
             if (s->size - stream_ptr < 16)
                 return;
+            ADVANCE_BLOCK();
             block_ptr = row_ptr + pixel_ptr;
             for (pixel_y = 0; pixel_y < 4; pixel_y++) {
                 for (pixel_x = 0; pixel_x < 4; pixel_x++){
@@ -219,7 +220,6 @@
                 }
                 block_ptr += row_inc;
             }
-            ADVANCE_BLOCK();
             break;
 
         /* Unknown opcode */
diff --git a/libavcodec/rtjpeg.c b/libavcodec/rtjpeg.c
index fe781ce..860d958 100644
--- a/libavcodec/rtjpeg.c
+++ b/libavcodec/rtjpeg.c
@@ -56,7 +56,7 @@
     // number of non-zero coefficients
     coeff = get_bits(gb, 6);
     if (get_bits_left(gb) < (coeff << 1))
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     // normally we would only need to clear the (63 - coeff) last values,
     // but since we do not know where they are we just clear the whole block
@@ -73,7 +73,7 @@
     // 4 bits per coefficient
     ALIGN(4);
     if (get_bits_left(gb) < (coeff << 2))
-        return -1;
+        return AVERROR_INVALIDDATA;
     while (coeff) {
         ac = get_sbits(gb, 4);
         if (ac == -8)
@@ -84,7 +84,7 @@
     // 8 bits per coefficient
     ALIGN(8);
     if (get_bits_left(gb) < (coeff << 3))
-        return -1;
+        return AVERROR_INVALIDDATA;
     while (coeff) {
         ac = get_sbits(gb, 8);
         PUT_COEFF(ac);
@@ -107,10 +107,13 @@
                                   const uint8_t *buf, int buf_size) {
     GetBitContext gb;
     int w = c->w / 16, h = c->h / 16;
-    int x, y;
+    int x, y, ret;
     uint8_t *y1 = f->data[0], *y2 = f->data[0] + 8 * f->linesize[0];
     uint8_t *u = f->data[1], *v = f->data[2];
-    init_get_bits(&gb, buf, buf_size * 8);
+
+    if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0)
+        return ret;
+
     for (y = 0; y < h; y++) {
         for (x = 0; x < w; x++) {
 #define BLOCK(quant, dst, stride) do { \
diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c
index 8ee3391..8d4f759 100644
--- a/libavcodec/rv10.c
+++ b/libavcodec/rv10.c
@@ -32,8 +32,6 @@
 #include "mpeg4video.h"
 #include "h263.h"
 
-//#define DEBUG
-
 #define RV_GET_MAJOR_VER(x)  ((x) >> 28)
 #define RV_GET_MINOR_VER(x) (((x) >> 20) & 0xFF)
 #define RV_GET_MICRO_VER(x) (((x) >> 12) & 0xFF)
diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c
index f40870e..48d7691 100644
--- a/libavcodec/rv30.c
+++ b/libavcodec/rv30.c
@@ -248,9 +248,12 @@
 static av_cold int rv30_decode_init(AVCodecContext *avctx)
 {
     RV34DecContext *r = avctx->priv_data;
+    int ret;
 
     r->rv30 = 1;
-    ff_rv34_decode_init(avctx);
+    ret = ff_rv34_decode_init(avctx);
+    if (ret < 0)
+        return ret;
     if(avctx->extradata_size < 2){
         av_log(avctx, AV_LOG_ERROR, "Extradata is too small.\n");
         return -1;
diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c
index 35f9dea..9b47d2e 100644
--- a/libavcodec/rv34.c
+++ b/libavcodec/rv34.c
@@ -40,8 +40,6 @@
 #include "rv34data.h"
 #include "rv34.h"
 
-//#define DEBUG
-
 static inline void ZERO8x2(void* dst, int stride)
 {
     fill_rectangle(dst,                 1, 2, stride, 0, 4);
diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c
index d6dfc5e..57e32f3 100644
--- a/libavcodec/rv40.c
+++ b/libavcodec/rv40.c
@@ -359,7 +359,7 @@
     int uvcbp[4][2];
     /**
      * This mask represents the pattern of luma subblocks that should be filtered
-     * in addition to the coded ones because because they lie at the edge of
+     * in addition to the coded ones because they lie at the edge of
      * 8x8 block with different enough motion vectors
      */
     unsigned mvmasks[4];
@@ -547,9 +547,12 @@
 static av_cold int rv40_decode_init(AVCodecContext *avctx)
 {
     RV34DecContext *r = avctx->priv_data;
+    int ret;
 
     r->rv30 = 0;
-    ff_rv34_decode_init(avctx);
+    ret = ff_rv34_decode_init(avctx);
+    if (ret < 0)
+        return ret;
     if(!aic_top_vlc.bits)
         rv40_init_tables();
     r->parse_slice_header = rv40_parse_slice_header;
diff --git a/libavcodec/s302menc.c b/libavcodec/s302menc.c
new file mode 100644
index 0000000..6af5dfe
--- /dev/null
+++ b/libavcodec/s302menc.c
@@ -0,0 +1,177 @@
+/*
+ * SMPTE 302M encoder
+ * Copyright (c) 2010 Google, Inc.
+ * Copyright (c) 2013 Darryl Wallace <wallacdj@gmail.com>
+ *
+ * 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
+ */
+
+#include "avcodec.h"
+#include "internal.h"
+#include "put_bits.h"
+
+#define AES3_HEADER_LEN 4
+
+typedef struct S302MEncContext {
+    uint8_t framing_index; /* Set for even channels on multiple of 192 samples */
+} S302MEncContext;
+
+static av_cold int s302m_encode_init(AVCodecContext *avctx)
+{
+    S302MEncContext *s = avctx->priv_data;
+
+    if (avctx->channels & 1 || avctx->channels > 8) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Encoding %d channel(s) is not allowed. Only 2, 4, 6 and 8 channels are supported.\n",
+               avctx->channels);
+        return AVERROR(EINVAL);
+    }
+
+    switch (avctx->sample_fmt) {
+    case AV_SAMPLE_FMT_S16:
+        avctx->bits_per_raw_sample = 16;
+        break;
+    case AV_SAMPLE_FMT_S32:
+        if (avctx->bits_per_raw_sample > 20) {
+            if (avctx->bits_per_raw_sample > 24)
+                av_log(avctx, AV_LOG_WARNING, "encoding as 24 bits-per-sample\n");
+            avctx->bits_per_raw_sample = 24;
+        } else if (!avctx->bits_per_raw_sample) {
+            avctx->bits_per_raw_sample = 24;
+        } else if (avctx->bits_per_raw_sample <= 20) {
+            avctx->bits_per_raw_sample = 20;
+        }
+    }
+
+    avctx->frame_size = 0;
+    avctx->bit_rate   = 48000 * avctx->channels *
+                       (avctx->bits_per_raw_sample + 4);
+    s->framing_index  = 0;
+
+    return 0;
+}
+
+static int s302m_encode2_frame(AVCodecContext *avctx, AVPacket *avpkt,
+                               const AVFrame *frame, int *got_packet_ptr)
+{
+    S302MEncContext *s = avctx->priv_data;
+    const int buf_size = AES3_HEADER_LEN +
+                        (frame->nb_samples *
+                         avctx->channels *
+                        (avctx->bits_per_raw_sample + 4)) / 8;
+    int ret, c, channels;
+    uint8_t *o;
+    PutBitContext pb;
+
+    if ((ret = ff_alloc_packet2(avctx, avpkt, buf_size)) < 0)
+        return ret;
+
+    o = avpkt->data;
+    init_put_bits(&pb, o, buf_size * 8);
+    put_bits(&pb, 16, buf_size - AES3_HEADER_LEN);
+    put_bits(&pb, 2, (avctx->channels - 2) >> 1);   // number of channels
+    put_bits(&pb, 8, 0);                            // channel ID
+    put_bits(&pb, 2, (avctx->bits_per_raw_sample - 16) / 4); // bits per samples (0 = 16bit, 1 = 20bit, 2 = 24bit)
+    put_bits(&pb, 4, 0);                            // alignments
+    flush_put_bits(&pb);
+    o += AES3_HEADER_LEN;
+
+    if (avctx->bits_per_raw_sample == 24) {
+        const uint32_t *samples = (uint32_t *)frame->data[0];
+
+        for (c = 0; c < frame->nb_samples; c++) {
+            uint8_t vucf = s->framing_index == 0 ? 0x10: 0;
+
+            for (channels = 0; channels < avctx->channels; channels += 2) {
+                o[0] = ff_reverse[(samples[0] & 0x0000FF00) >> 8];
+                o[1] = ff_reverse[(samples[0] & 0x00FF0000) >> 16];
+                o[2] = ff_reverse[(samples[0] & 0xFF000000) >> 24];
+                o[3] = ff_reverse[(samples[1] & 0x00000F00) >> 4] | vucf;
+                o[4] = ff_reverse[(samples[1] & 0x000FF000) >> 12];
+                o[5] = ff_reverse[(samples[1] & 0x0FF00000) >> 20];
+                o[6] = ff_reverse[(samples[1] & 0xF0000000) >> 28];
+                o += 7;
+                samples += 2;
+            }
+
+            s->framing_index++;
+            if (s->framing_index >= 192)
+                s->framing_index = 0;
+        }
+    } else if (avctx->bits_per_raw_sample == 20) {
+        const uint32_t *samples = (uint32_t *)frame->data[0];
+
+        for (c = 0; c < frame->nb_samples; c++) {
+            uint8_t vucf = s->framing_index == 0 ? 0x80: 0;
+
+            for (channels = 0; channels < avctx->channels; channels += 2) {
+                o[0] = ff_reverse[ (samples[0] & 0x000FF000) >> 12];
+                o[1] = ff_reverse[ (samples[0] & 0x0FF00000) >> 20];
+                o[2] = ff_reverse[((samples[0] & 0xF0000000) >> 28) | vucf];
+                o[3] = ff_reverse[ (samples[1] & 0x000FF000) >> 12];
+                o[4] = ff_reverse[ (samples[1] & 0x0FF00000) >> 20];
+                o[5] = ff_reverse[ (samples[1] & 0xF0000000) >> 28];
+                o += 6;
+                samples += 2;
+            }
+
+            s->framing_index++;
+            if (s->framing_index >= 192)
+                s->framing_index = 0;
+        }
+    } else if (avctx->bits_per_raw_sample == 16) {
+        const uint16_t *samples = (uint16_t *)frame->data[0];
+
+        for (c = 0; c < frame->nb_samples; c++) {
+            uint8_t vucf = s->framing_index == 0 ? 0x10 : 0;
+
+            for (channels = 0; channels < avctx->channels; channels += 2) {
+                o[0] = ff_reverse[ samples[0] & 0xFF];
+                o[1] = ff_reverse[(samples[0] & 0xFF00) >>  8];
+                o[2] = ff_reverse[(samples[1] & 0x0F)   <<  4] | vucf;
+                o[3] = ff_reverse[(samples[1] & 0x0FF0) >>  4];
+                o[4] = ff_reverse[(samples[1] & 0xF000) >> 12];
+                o += 5;
+                samples += 2;
+
+            }
+
+            s->framing_index++;
+            if (s->framing_index >= 192)
+                s->framing_index = 0;
+        }
+    }
+
+    *got_packet_ptr = 1;
+
+    return 0;
+}
+
+AVCodec ff_s302m_encoder = {
+    .name                  = "s302m",
+    .type                  = AVMEDIA_TYPE_AUDIO,
+    .id                    = CODEC_ID_S302M,
+    .priv_data_size        = sizeof(S302MEncContext),
+    .init                  = s302m_encode_init,
+    .encode2               = s302m_encode2_frame,
+    .long_name             = NULL_IF_CONFIG_SMALL("SMPTE 302M"),
+    .sample_fmts           = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32,
+                                                            AV_SAMPLE_FMT_S16,
+                                                            AV_SAMPLE_FMT_NONE },
+    .capabilities          = CODEC_CAP_VARIABLE_FRAME_SIZE | CODEC_CAP_EXPERIMENTAL,
+    .supported_samplerates = (const int[]) { 48000, 0 },
+};
diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c
index f217ef3..d1ef0ce 100644
--- a/libavcodec/sanm.c
+++ b/libavcodec/sanm.c
@@ -732,6 +732,11 @@
     w     = bytestream2_get_le16u(&ctx->gb);
     h     = bytestream2_get_le16u(&ctx->gb);
 
+    if (!w || !h) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "dimensions are invalid\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     if (ctx->width < left + w || ctx->height < top + h) {
         if (av_image_check_size(FFMAX(left + w, ctx->width),
                                 FFMAX(top  + h, ctx->height), 0, ctx->avctx) < 0)
@@ -1039,8 +1044,10 @@
 #if HAVE_BIGENDIAN
     npixels = ctx->npixels;
     frm = ctx->frm0;
-    while (npixels--)
-        *frm++ = av_bswap16(*frm);
+    while (npixels--) {
+        *frm = av_bswap16(*frm);
+        frm++;
+    }
 #endif
 
     return 0;
diff --git a/libavcodec/sbrdsp.c b/libavcodec/sbrdsp.c
index 7207f3b..de961cf 100644
--- a/libavcodec/sbrdsp.c
+++ b/libavcodec/sbrdsp.c
@@ -52,41 +52,41 @@
 
 static void sbr_neg_odd_64_c(float *x)
 {
-    union av_intfloat32 *xi = (union av_intfloat32*)x;
+    union av_intfloat32 *xi = (union av_intfloat32*) x;
     int i;
-    for (i = 1; i < 64; i += 4)
-    {
-        xi[i+0].i ^= 1U<<31;
-        xi[i+2].i ^= 1U<<31;
+    for (i = 1; i < 64; i += 4) {
+        xi[i + 0].i ^= 1U << 31;
+        xi[i + 2].i ^= 1U << 31;
     }
 }
 
 static void sbr_qmf_pre_shuffle_c(float *z)
 {
-    union av_intfloat32 *zi = (union av_intfloat32*)z;
+    union av_intfloat32 *zi = (union av_intfloat32*) z;
     int k;
     zi[64].i = zi[0].i;
     zi[65].i = zi[1].i;
-    for (k = 1; k < 31; k+=2) {
-        zi[64+2*k+0].i = zi[64 - k].i ^ (1U<<31);
-        zi[64+2*k+1].i = zi[ k + 1].i;
-        zi[64+2*k+2].i = zi[63 - k].i ^ (1U<<31);
-        zi[64+2*k+3].i = zi[ k + 2].i;
+    for (k = 1; k < 31; k += 2) {
+        zi[64 + 2 * k + 0].i = zi[64 - k].i ^ (1U << 31);
+        zi[64 + 2 * k + 1].i = zi[ k + 1].i;
+        zi[64 + 2 * k + 2].i = zi[63 - k].i ^ (1U << 31);
+        zi[64 + 2 * k + 3].i = zi[ k + 2].i;
     }
-    zi[64+2*31+0].i = zi[64 - 31].i ^ (1U<<31);
-    zi[64+2*31+1].i = zi[31 + 1].i;
+
+    zi[64 + 2 * 31 + 0].i = zi[64 - 31].i ^ (1U << 31);
+    zi[64 + 2 * 31 + 1].i = zi[31 +  1].i;
 }
 
 static void sbr_qmf_post_shuffle_c(float W[32][2], const float *z)
 {
-    const union av_intfloat32 *zi = (const union av_intfloat32*)z;
-    union av_intfloat32 *Wi = (union av_intfloat32*)W;
+    const union av_intfloat32 *zi = (const union av_intfloat32*) z;
+    union av_intfloat32 *Wi       = (union av_intfloat32*) W;
     int k;
-    for (k = 0; k < 32; k+=2) {
-        Wi[2*k+0].i = zi[63-k].i ^ (1U<<31);
-        Wi[2*k+1].i = zi[k+0].i;
-        Wi[2*k+2].i = zi[62-k].i ^ (1U<<31);
-        Wi[2*k+3].i = zi[k+1].i;
+    for (k = 0; k < 32; k += 2) {
+        Wi[2 * k + 0].i = zi[63 - k].i ^ (1U << 31);
+        Wi[2 * k + 1].i = zi[ k + 0].i;
+        Wi[2 * k + 2].i = zi[62 - k].i ^ (1U << 31);
+        Wi[2 * k + 3].i = zi[ k + 1].i;
     }
 }
 
@@ -96,8 +96,8 @@
     union av_intfloat32 *vi = (union av_intfloat32*)v;
     int i;
     for (i = 0; i < 32; i++) {
-        vi[     i].i = si[63 - 2*i    ].i;
-        vi[63 - i].i = si[63 - 2*i - 1].i ^ (1U<<31);
+        vi[     i].i = si[63 - 2 * i    ].i;
+        vi[63 - i].i = si[63 - 2 * i - 1].i ^ (1U << 31);
     }
 }
 
@@ -139,32 +139,32 @@
 static void sbr_autocorrelate_c(const float x[40][2], float phi[3][2][2])
 {
 #if 0
-    // This code is slower because it multiplies memory accesses.
-    // It is left as eucational purpose and because it may offer
-    // a better reference for writing arch-specific dsp functions.
+    /* This code is slower because it multiplies memory accesses.
+     * It is left for educational purposes and because it may offer
+     * a better reference for writing arch-specific DSP functions. */
     autocorrelate(x, phi, 0);
     autocorrelate(x, phi, 1);
     autocorrelate(x, phi, 2);
 #else
-    float real_sum2 = x[ 0][0] * x[ 2][0] + x[ 0][1] * x[ 2][1];
-    float imag_sum2 = x[ 0][0] * x[ 2][1] - x[ 0][1] * x[ 2][0];
-    float real_sum1 = 0.f, imag_sum1 = 0.f, real_sum0 = 0.0f;
+    float real_sum2 = x[0][0] * x[2][0] + x[0][1] * x[2][1];
+    float imag_sum2 = x[0][0] * x[2][1] - x[0][1] * x[2][0];
+    float real_sum1 = 0.0f, imag_sum1 = 0.0f, real_sum0 = 0.0f;
     int   i;
     for (i = 1; i < 38; i++) {
-        real_sum0 += x[i][0] * x[i  ][0] + x[i][1] * x[i  ][1];
-        real_sum1 += x[i][0] * x[i+1][0] + x[i][1] * x[i+1][1];
-        imag_sum1 += x[i][0] * x[i+1][1] - x[i][1] * x[i+1][0];
-        real_sum2 += x[i][0] * x[i+2][0] + x[i][1] * x[i+2][1];
-        imag_sum2 += x[i][0] * x[i+2][1] - x[i][1] * x[i+2][0];
+        real_sum0 += x[i][0] * x[i    ][0] + x[i][1] * x[i    ][1];
+        real_sum1 += x[i][0] * x[i + 1][0] + x[i][1] * x[i + 1][1];
+        imag_sum1 += x[i][0] * x[i + 1][1] - x[i][1] * x[i + 1][0];
+        real_sum2 += x[i][0] * x[i + 2][0] + x[i][1] * x[i + 2][1];
+        imag_sum2 += x[i][0] * x[i + 2][1] - x[i][1] * x[i + 2][0];
     }
-    phi[2-2][1][0] = real_sum2;
-    phi[2-2][1][1] = imag_sum2;
-    phi[2  ][1][0] = real_sum0 + x[ 0][0] * x[ 0][0] + x[ 0][1] * x[ 0][1];
-    phi[1  ][0][0] = real_sum0 + x[38][0] * x[38][0] + x[38][1] * x[38][1];
-    phi[2-1][1][0] = real_sum1 + x[ 0][0] * x[ 1][0] + x[ 0][1] * x[ 1][1];
-    phi[2-1][1][1] = imag_sum1 + x[ 0][0] * x[ 1][1] - x[ 0][1] * x[ 1][0];
-    phi[0  ][0][0] = real_sum1 + x[38][0] * x[39][0] + x[38][1] * x[39][1];
-    phi[0  ][0][1] = imag_sum1 + x[38][0] * x[39][1] - x[38][1] * x[39][0];
+    phi[2 - 2][1][0] = real_sum2;
+    phi[2 - 2][1][1] = imag_sum2;
+    phi[2    ][1][0] = real_sum0 + x[ 0][0] * x[ 0][0] + x[ 0][1] * x[ 0][1];
+    phi[1    ][0][0] = real_sum0 + x[38][0] * x[38][0] + x[38][1] * x[38][1];
+    phi[2 - 1][1][0] = real_sum1 + x[ 0][0] * x[ 1][0] + x[ 0][1] * x[ 1][1];
+    phi[2 - 1][1][1] = imag_sum1 + x[ 0][0] * x[ 1][1] - x[ 0][1] * x[ 1][0];
+    phi[0    ][0][0] = real_sum1 + x[38][0] * x[39][0] + x[38][1] * x[39][1];
+    phi[0    ][0][1] = imag_sum1 + x[38][0] * x[39][1] - x[38][1] * x[39][0];
 #endif
 }
 
diff --git a/libavcodec/sgidec.c b/libavcodec/sgidec.c
index e7f453b..4f7f8ac 100644
--- a/libavcodec/sgidec.c
+++ b/libavcodec/sgidec.c
@@ -41,7 +41,7 @@
  * @param out_buf Points to one line after the output buffer.
  * @param out_end end of line in output buffer
  * @param pixelstride pixel stride of input buffer
- * @return size of output in bytes, -1 if buffer overflows
+ * @return size of output in bytes, else return error code.
  */
 static int expand_rle_row(SgiState *s, uint8_t *out_buf,
                           uint8_t *out_end, int pixelstride)
@@ -58,7 +58,8 @@
         }
 
         /* Check for buffer overflow. */
-        if(out_buf + pixelstride * (count-1) >= out_end) return -1;
+        if (out_end - out_buf <= pixelstride * (count - 1))
+            return AVERROR_INVALIDDATA;
 
         if (pixel & 0x80) {
             while (count--) {
@@ -81,7 +82,7 @@
  * Read a run length encoded SGI image.
  * @param out_buf output buffer
  * @param s the current image state
- * @return 0 if no error, else return error number.
+ * @return 0 if no error, else return error code.
  */
 static int read_rle_sgi(uint8_t *out_buf, SgiState *s)
 {
@@ -115,7 +116,7 @@
  * Read an uncompressed SGI image.
  * @param out_buf output buffer
  * @param s the current image state
- * @return 0 if read success, otherwise return -1.
+ * @return 0 if read success, else return error code.
  */
 static int read_uncompressed_sgi(unsigned char* out_buf, SgiState *s)
 {
@@ -181,13 +182,13 @@
 
     if (s->bytes_per_channel != 1 && (s->bytes_per_channel != 2 || rle)) {
         av_log(avctx, AV_LOG_ERROR, "wrong channel number\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* Check for supported image dimensions. */
     if (dimension != 2 && dimension != 3) {
         av_log(avctx, AV_LOG_ERROR, "wrong dimension number\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (s->depth == SGI_GRAYSCALE) {
@@ -198,11 +199,11 @@
         avctx->pix_fmt = s->bytes_per_channel == 2 ? AV_PIX_FMT_RGBA64BE : AV_PIX_FMT_RGBA;
     } else {
         av_log(avctx, AV_LOG_ERROR, "wrong picture format\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (av_image_check_size(s->width, s->height, 0, avctx))
-        return -1;
+        return AVERROR_INVALIDDATA;
     avcodec_set_dimensions(avctx, s->width, s->height);
 
     if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
@@ -223,13 +224,11 @@
     } else {
         ret = read_uncompressed_sgi(out_buf, s);
     }
-
-    if (ret == 0) {
-        *got_frame = 1;
-        return avpkt->size;
-    } else {
+    if (ret)
         return ret;
-    }
+
+    *got_frame = 1;
+    return avpkt->size;
 }
 
 AVCodec ff_sgi_decoder = {
diff --git a/libavcodec/sgienc.c b/libavcodec/sgienc.c
index d03ef52..973514c 100644
--- a/libavcodec/sgienc.c
+++ b/libavcodec/sgienc.c
@@ -28,36 +28,25 @@
 #define SGI_SINGLE_CHAN 2
 #define SGI_MULTI_CHAN 3
 
-typedef struct SgiContext {
-    AVFrame picture;
-} SgiContext;
-
 static av_cold int encode_init(AVCodecContext *avctx)
 {
-    SgiContext *s = avctx->priv_data;
-
     if (avctx->width > 65535 || avctx->height > 65535) {
         av_log(avctx, AV_LOG_ERROR, "SGI does not support resolutions above 65535x65535\n");
         return -1;
     }
 
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
-
     return 0;
 }
 
 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                         const AVFrame *frame, int *got_packet)
 {
-    SgiContext *s = avctx->priv_data;
-    AVFrame * const p = &s->picture;
+    AVFrame * const p = (AVFrame *)frame;
     uint8_t *offsettab, *lengthtab, *in_buf, *encode_buf, *buf;
     int x, y, z, length, tablesize, ret;
     unsigned int width, height, depth, dimension, bytes_per_channel, pixmax, put_be;
     unsigned char *end_buf;
 
-    *p = *frame;
     p->pict_type = AV_PICTURE_TYPE_I;
     p->key_frame = 1;
 
@@ -214,7 +203,6 @@
     .name           = "sgi",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_SGI,
-    .priv_data_size = sizeof(SgiContext),
     .init           = encode_init,
     .encode2        = encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]){
diff --git a/libavcodec/sgirledec.c b/libavcodec/sgirledec.c
index a7fdac8..af149d1 100644
--- a/libavcodec/sgirledec.c
+++ b/libavcodec/sgirledec.c
@@ -42,7 +42,7 @@
 }
 
 /**
- * Convert SGI RGB332 pixel into PIX_FMT_BGR8
+ * Convert SGI RGB332 pixel into AV_PIX_FMT_BGR8
  * SGI RGB332 is packed RGB 3:3:2, 8bpp, (msb)3R 2B 3G(lsb)
  */
 #define RGB332_TO_BGR8(x) (((x << 3) & 0xC0) | ((x << 3) & 0x38) | ((x >> 5) & 7))
diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c
index 1d3b6eb..3bba10c 100644
--- a/libavcodec/shorten.c
+++ b/libavcodec/shorten.c
@@ -424,7 +424,7 @@
         void *tmp_ptr;
         s->max_framesize = 8192; // should hopefully be enough for the first header
         tmp_ptr = av_fast_realloc(s->bitstream, &s->allocated_bitstream_size,
-                                  s->max_framesize);
+                                  s->max_framesize + FF_INPUT_BUFFER_PADDING_SIZE);
         if (!tmp_ptr) {
             av_log(avctx, AV_LOG_ERROR, "error allocating bitstream buffer\n");
             return AVERROR(ENOMEM);
@@ -437,7 +437,7 @@
         buf_size       = FFMIN(buf_size, s->max_framesize - s->bitstream_size);
         input_buf_size = buf_size;
 
-        if (s->bitstream_index + s->bitstream_size + buf_size >
+        if (s->bitstream_index + s->bitstream_size + buf_size + FF_INPUT_BUFFER_PADDING_SIZE >
             s->allocated_bitstream_size) {
             memmove(s->bitstream, &s->bitstream[s->bitstream_index],
                     s->bitstream_size);
diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c
index 35e8bf5..d524177 100644
--- a/libavcodec/sipr.c
+++ b/libavcodec/sipr.c
@@ -240,7 +240,7 @@
     float tmp1[SUBFR_SIZE+1], tmp2[LP_FILTER_ORDER+1];
     int i;
 
-    tmp1[0] = 1.;
+    tmp1[0] = 1.0;
     for (i = 0; i < LP_FILTER_ORDER; i++) {
         tmp1[i+1] = Az[i] * ff_pow_0_55[i];
         tmp2[i  ] = Az[i] * ff_pow_0_7 [i];
diff --git a/libavcodec/sipr16k.c b/libavcodec/sipr16k.c
index fbf7497..9cc5e9b 100644
--- a/libavcodec/sipr16k.c
+++ b/libavcodec/sipr16k.c
@@ -24,6 +24,7 @@
 #include <math.h>
 
 #include "sipr.h"
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
 #include "libavutil/float_dsp.h"
 #include "libavutil/mathematics.h"
@@ -268,7 +269,7 @@
     memcpy(ctx->iir_mem, Az[1], LP_FILTER_ORDER_16k * sizeof(float));
 }
 
-void ff_sipr_init_16k(SiprContext *ctx)
+av_cold void ff_sipr_init_16k(SiprContext *ctx)
 {
     int i;
 
diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c
index c070150..1425183 100644
--- a/libavcodec/smacker.c
+++ b/libavcodec/smacker.c
@@ -48,7 +48,7 @@
  */
 typedef struct SmackVContext {
     AVCodecContext *avctx;
-    AVFrame pic;
+    AVFrame *pic;
 
     int *mmap_tbl, *mclr_tbl, *full_tbl, *type_tbl;
     int mmap_last[3], mclr_last[3], full_last[3], type_last[3];
@@ -257,10 +257,12 @@
     ctx.recode2 = tmp2.values;
     ctx.last = last;
 
-    huff.length = ((size + 3) >> 2) + 3;
+    huff.length = ((size + 3) >> 2) + 4;
     huff.maxlength = 0;
     huff.current = 0;
     huff.values = av_mallocz(huff.length * sizeof(int));
+    if (!huff.values)
+        return AVERROR(ENOMEM);
 
     if (smacker_decode_bigtree(gb, &huff, &ctx) < 0)
         err = -1;
@@ -292,7 +294,7 @@
 
 static int decode_header_trees(SmackVContext *smk) {
     GetBitContext gb;
-    int mmap_size, mclr_size, full_size, type_size;
+    int mmap_size, mclr_size, full_size, type_size, ret;
 
     mmap_size = AV_RL32(smk->avctx->extradata);
     mclr_size = AV_RL32(smk->avctx->extradata + 4);
@@ -307,8 +309,9 @@
         smk->mmap_tbl[0] = 0;
         smk->mmap_last[0] = smk->mmap_last[1] = smk->mmap_last[2] = 1;
     } else {
-        if (smacker_decode_header_tree(smk, &gb, &smk->mmap_tbl, smk->mmap_last, mmap_size))
-            return AVERROR_INVALIDDATA;
+        ret = smacker_decode_header_tree(smk, &gb, &smk->mmap_tbl, smk->mmap_last, mmap_size);
+        if (ret < 0)
+            return ret;
     }
     if(!get_bits1(&gb)) {
         av_log(smk->avctx, AV_LOG_INFO, "Skipping MCLR tree\n");
@@ -316,8 +319,9 @@
         smk->mclr_tbl[0] = 0;
         smk->mclr_last[0] = smk->mclr_last[1] = smk->mclr_last[2] = 1;
     } else {
-        if (smacker_decode_header_tree(smk, &gb, &smk->mclr_tbl, smk->mclr_last, mclr_size))
-            return AVERROR_INVALIDDATA;
+        ret = smacker_decode_header_tree(smk, &gb, &smk->mclr_tbl, smk->mclr_last, mclr_size);
+        if (ret < 0)
+            return ret;
     }
     if(!get_bits1(&gb)) {
         av_log(smk->avctx, AV_LOG_INFO, "Skipping FULL tree\n");
@@ -325,8 +329,9 @@
         smk->full_tbl[0] = 0;
         smk->full_last[0] = smk->full_last[1] = smk->full_last[2] = 1;
     } else {
-        if (smacker_decode_header_tree(smk, &gb, &smk->full_tbl, smk->full_last, full_size))
-            return AVERROR_INVALIDDATA;
+        ret = smacker_decode_header_tree(smk, &gb, &smk->full_tbl, smk->full_last, full_size);
+        if (ret < 0)
+            return ret;
     }
     if(!get_bits1(&gb)) {
         av_log(smk->avctx, AV_LOG_INFO, "Skipping TYPE tree\n");
@@ -334,8 +339,9 @@
         smk->type_tbl[0] = 0;
         smk->type_last[0] = smk->type_last[1] = smk->type_last[2] = 1;
     } else {
-        if (smacker_decode_header_tree(smk, &gb, &smk->type_tbl, smk->type_last, type_size))
-            return AVERROR_INVALIDDATA;
+        ret = smacker_decode_header_tree(smk, &gb, &smk->type_tbl, smk->type_last, type_size);
+        if (ret < 0)
+            return ret;
     }
 
     return 0;
@@ -381,19 +387,19 @@
     if (avpkt->size <= 769)
         return AVERROR_INVALIDDATA;
 
-    if ((ret = ff_reget_buffer(avctx, &smk->pic)) < 0)
+    if ((ret = ff_reget_buffer(avctx, smk->pic)) < 0)
         return ret;
 
     /* make the palette available on the way out */
-    pal = (uint32_t*)smk->pic.data[1];
+    pal = (uint32_t*)smk->pic->data[1];
     bytestream2_init(&gb2, avpkt->data, avpkt->size);
     flags = bytestream2_get_byteu(&gb2);
-    smk->pic.palette_has_changed = flags & 1;
-    smk->pic.key_frame = !!(flags & 2);
-    if(smk->pic.key_frame)
-        smk->pic.pict_type = AV_PICTURE_TYPE_I;
+    smk->pic->palette_has_changed = flags & 1;
+    smk->pic->key_frame = !!(flags & 2);
+    if (smk->pic->key_frame)
+        smk->pic->pict_type = AV_PICTURE_TYPE_I;
     else
-        smk->pic.pict_type = AV_PICTURE_TYPE_P;
+        smk->pic->pict_type = AV_PICTURE_TYPE_P;
 
     for(i = 0; i < 256; i++)
         *pal++ = 0xFFU << 24 | bytestream2_get_be24u(&gb2);
@@ -408,8 +414,8 @@
     bw = avctx->width >> 2;
     bh = avctx->height >> 2;
     blocks = bw * bh;
-    out = smk->pic.data[0];
-    stride = smk->pic.linesize[0];
+    out = smk->pic->data[0];
+    stride = smk->pic->linesize[0];
     while(blk < blocks) {
         int type, run, mode;
         uint16_t pix;
@@ -423,7 +429,7 @@
                 int hi, lo;
                 clr = smk_get_code(&gb, smk->mclr_tbl, smk->mclr_last);
                 map = smk_get_code(&gb, smk->mmap_tbl, smk->mmap_last);
-                out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;
+                out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;
                 hi = clr >> 8;
                 lo = clr & 0xFF;
                 for(i = 0; i < 4; i++) {
@@ -444,7 +450,7 @@
                 else if(get_bits1(&gb)) mode = 2;
             }
             while(run-- && blk < blocks){
-                out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;
+                out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;
                 switch(mode){
                 case 0:
                     for(i = 0; i < 4; i++) {
@@ -496,7 +502,7 @@
             mode = type >> 8;
             while(run-- && blk < blocks){
                 uint32_t col;
-                out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;
+                out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;
                 col = mode * 0x01010101;
                 for(i = 0; i < 4; i++) {
                     *((uint32_t*)out) = col;
@@ -509,7 +515,7 @@
 
     }
 
-    if ((ret = av_frame_ref(data, &smk->pic)) < 0)
+    if ((ret = av_frame_ref(data, smk->pic)) < 0)
         return ret;
 
     *got_frame = 1;
@@ -528,11 +534,11 @@
 static av_cold int decode_init(AVCodecContext *avctx)
 {
     SmackVContext * const c = avctx->priv_data;
+    int ret;
 
     c->avctx = avctx;
 
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
-    avcodec_get_frame_defaults(&c->pic);
 
     /* decode huffman trees from extradata */
     if(avctx->extradata_size < 16){
@@ -540,8 +546,13 @@
         return AVERROR(EINVAL);
     }
 
-    if (decode_header_trees(c))
-        return AVERROR_INVALIDDATA;
+    ret = decode_header_trees(c);
+    if (ret < 0)
+        return ret;
+
+    c->pic = av_frame_alloc();
+    if (!c->pic)
+        return AVERROR(ENOMEM);
 
     return 0;
 }
@@ -562,7 +573,7 @@
     av_freep(&smk->full_tbl);
     av_freep(&smk->type_tbl);
 
-    av_frame_unref(&smk->pic);
+    av_frame_free(&smk->pic);
 
     return 0;
 }
@@ -646,9 +657,16 @@
         h[i].lengths = av_mallocz(256 * sizeof(int));
         h[i].values = av_mallocz(256 * sizeof(int));
         skip_bits1(&gb);
-        res = smacker_decode_tree(&gb, &h[i], 0, 0);
-        if (res < 0)
-            return res;
+        if (smacker_decode_tree(&gb, &h[i], 0, 0) < 0) {
+            for (; i >= 0; i--) {
+                if (vlc[i].table)
+                    ff_free_vlc(&vlc[i]);
+                av_free(h[i].bits);
+                av_free(h[i].lengths);
+                av_free(h[i].values);
+            }
+            return AVERROR_INVALIDDATA;
+        }
         skip_bits1(&gb);
         if(h[i].current > 1) {
             res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length,
@@ -660,6 +678,7 @@
             }
         }
     }
+    /* this codec relies on wraparound instead of clipping audio */
     if(bits) { //decode 16-bit data
         for(i = stereo; i >= 0; i--)
             pred[i] = sign_extend(av_bswap16(get_bits(&gb, 16)), 16);
@@ -688,7 +707,7 @@
                 }
                 val |= h[3].values[res] << 8;
                 pred[1] += sign_extend(val, 16);
-                *samples++ = av_clip_int16(pred[1]);
+                *samples++ = pred[1];
             } else {
                 if(vlc[0].table)
                     res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3);
@@ -709,7 +728,7 @@
                 }
                 val |= h[1].values[res] << 8;
                 pred[0] += sign_extend(val, 16);
-                *samples++ = av_clip_int16(pred[0]);
+                *samples++ = pred[0];
             }
         }
     } else { //8-bit data
@@ -730,7 +749,7 @@
                     return AVERROR_INVALIDDATA;
                 }
                 pred[1] += sign_extend(h[1].values[res], 8);
-                *samples8++ = av_clip_uint8(pred[1]);
+                *samples8++ = pred[1];
             } else {
                 if(vlc[0].table)
                     res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3);
@@ -741,7 +760,7 @@
                     return AVERROR_INVALIDDATA;
                 }
                 pred[0] += sign_extend(h[0].values[res], 8);
-                *samples8++ = av_clip_uint8(pred[0]);
+                *samples8++ = pred[0];
             }
         }
     }
diff --git a/libavcodec/smvjpegdec.c b/libavcodec/smvjpegdec.c
new file mode 100644
index 0000000..7d84839
--- /dev/null
+++ b/libavcodec/smvjpegdec.c
@@ -0,0 +1,205 @@
+/*
+ * SMV JPEG decoder
+ * Copyright (c) 2013 Ash Hughes
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * SMV JPEG decoder.
+ */
+
+// #define DEBUG
+#include "avcodec.h"
+#include "libavutil/opt.h"
+#include "libavutil/imgutils.h"
+#include "mjpegdec.h"
+#include "internal.h"
+
+typedef struct SMVJpegDecodeContext {
+    MJpegDecodeContext jpg;
+    AVFrame *picture[2]; /* pictures array */
+    AVCodecContext* avctx;
+    int frames_per_jpeg;
+    int mjpeg_data_size;
+} SMVJpegDecodeContext;
+
+static inline void smv_img_pnt_plane(uint8_t      **dst, uint8_t *src,
+                                     int src_linesize, int height, int nlines)
+{
+    if (!dst || !src)
+        return;
+    src += (nlines) * src_linesize * height;
+    *dst = src;
+}
+
+static inline void smv_img_pnt(uint8_t *dst_data[4], uint8_t *src_data[4],
+                               const int src_linesizes[4],
+                               enum PixelFormat pix_fmt, int width, int height,
+                               int nlines)
+{
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
+    int i, planes_nb = 0;
+
+    if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
+        return;
+
+    for (i = 0; i < desc->nb_components; i++)
+        planes_nb = FFMAX(planes_nb, desc->comp[i].plane + 1);
+
+    for (i = 0; i < planes_nb; i++) {
+        int h = height;
+        if (i == 1 || i == 2) {
+            h = FF_CEIL_RSHIFT(height, desc->log2_chroma_h);
+        }
+        smv_img_pnt_plane(&dst_data[i], src_data[i],
+            src_linesizes[i], h, nlines);
+    }
+    if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
+        desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)
+        dst_data[1] = src_data[1];
+}
+
+static av_cold int smvjpeg_decode_init(AVCodecContext *avctx)
+{
+    SMVJpegDecodeContext *s = avctx->priv_data;
+    AVCodec *codec;
+    AVDictionary *thread_opt = NULL;
+    int ret = 0;
+
+    s->frames_per_jpeg = 0;
+
+    s->picture[0] = av_frame_alloc();
+    if (!s->picture[0])
+        return AVERROR(ENOMEM);
+
+    s->picture[1] = av_frame_alloc();
+    if (!s->picture[1])
+        return AVERROR(ENOMEM);
+
+    s->jpg.picture_ptr      = s->picture[0];
+
+    if (avctx->extradata_size >= 4)
+        s->frames_per_jpeg = AV_RL32(avctx->extradata);
+
+    if (s->frames_per_jpeg <= 0) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid number of frames per jpeg.\n");
+        ret = -1;
+    }
+
+    codec = avcodec_find_decoder(AV_CODEC_ID_MJPEG);
+    if (!codec) {
+        av_log(avctx, AV_LOG_ERROR, "MJPEG codec not found\n");
+        ret = -1;
+    }
+
+    s->avctx = avcodec_alloc_context3(codec);
+
+    av_dict_set(&thread_opt, "threads", "1", 0);
+    s->avctx->refcounted_frames = 1;
+    s->avctx->flags = avctx->flags;
+    s->avctx->idct_algo = avctx->idct_algo;
+    if (ff_codec_open2_recursive(s->avctx, codec, &thread_opt) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "MJPEG codec failed to open\n");
+        ret = -1;
+    }
+    av_dict_free(&thread_opt);
+
+    return ret;
+}
+
+static int smvjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+                            AVPacket *avpkt)
+{
+    const AVPixFmtDescriptor *desc;
+    SMVJpegDecodeContext *s = avctx->priv_data;
+    AVFrame* mjpeg_data = s->picture[0];
+    int i, cur_frame = 0, ret = 0;
+
+    cur_frame = avpkt->pts % s->frames_per_jpeg;
+
+    /* Are we at the start of a block? */
+    if (!cur_frame) {
+        av_frame_unref(mjpeg_data);
+        ret = avcodec_decode_video2(s->avctx, mjpeg_data, &s->mjpeg_data_size, avpkt);
+    } else if (!s->mjpeg_data_size)
+        return AVERROR(EINVAL);
+
+    desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
+    if (desc && mjpeg_data->height % (s->frames_per_jpeg << desc->log2_chroma_h)) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid height\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    /*use the last lot... */
+    *data_size = s->mjpeg_data_size;
+
+    avctx->pix_fmt = s->avctx->pix_fmt;
+
+    /* We shouldn't get here if frames_per_jpeg <= 0 because this was rejected
+       in init */
+    avcodec_set_dimensions(avctx, mjpeg_data->width,
+        mjpeg_data->height / s->frames_per_jpeg);
+
+    if (*data_size) {
+        s->picture[1]->extended_data = NULL;
+        s->picture[1]->width         = avctx->width;
+        s->picture[1]->height        = avctx->height;
+        s->picture[1]->format        = avctx->pix_fmt;
+        /* ff_init_buffer_info(avctx, &s->picture[1]); */
+        smv_img_pnt(s->picture[1]->data, mjpeg_data->data, mjpeg_data->linesize,
+                    avctx->pix_fmt, avctx->width, avctx->height, cur_frame);
+        for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
+            s->picture[1]->linesize[i] = mjpeg_data->linesize[i];
+
+        ret = av_frame_ref(data, s->picture[1]);
+    }
+
+    return ret;
+}
+
+static av_cold int smvjpeg_decode_end(AVCodecContext *avctx)
+{
+    SMVJpegDecodeContext *s = avctx->priv_data;
+    MJpegDecodeContext *jpg = &s->jpg;
+
+    jpg->picture_ptr = NULL;
+    av_frame_free(&s->picture[0]);
+    av_frame_free(&s->picture[1]);
+    ff_codec_close_recursive(s->avctx);
+    av_freep(&s->avctx);
+    return 0;
+}
+
+static const AVClass smvjpegdec_class = {
+    .class_name = "SMVJPEG decoder",
+    .item_name  = av_default_item_name,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_smvjpeg_decoder = {
+    .name           = "smvjpeg",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_SMVJPEG,
+    .priv_data_size = sizeof(SMVJpegDecodeContext),
+    .init           = smvjpeg_decode_init,
+    .close          = smvjpeg_decode_end,
+    .decode         = smvjpeg_decode_frame,
+    .long_name      = NULL_IF_CONFIG_SMALL("SMV JPEG"),
+    .priv_class     = &smvjpegdec_class,
+};
diff --git a/libavcodec/snow.c b/libavcodec/snow.c
index 9f6399c..99cd5fb 100644
--- a/libavcodec/snow.c
+++ b/libavcodec/snow.c
@@ -81,8 +81,8 @@
 }
 
 int ff_snow_alloc_blocks(SnowContext *s){
-    int w= -((-s->avctx->width )>>LOG2_MB_SIZE);
-    int h= -((-s->avctx->height)>>LOG2_MB_SIZE);
+    int w= FF_CEIL_RSHIFT(s->avctx->width,  LOG2_MB_SIZE);
+    int h= FF_CEIL_RSHIFT(s->avctx->height, LOG2_MB_SIZE);
 
     s->b_width = w;
     s->b_height= h;
@@ -92,7 +92,7 @@
     return 0;
 }
 
-static void init_qexp(void){
+static av_cold void init_qexp(void){
     int i;
     double v=128;
 
@@ -618,7 +618,7 @@
 
     av_frame_move_ref(&tmp, &s->last_picture[s->max_ref_frames-1]);
     for(i=s->max_ref_frames-1; i>0; i--)
-        av_frame_move_ref(&s->last_picture[i+1], &s->last_picture[i]);
+        av_frame_move_ref(&s->last_picture[i], &s->last_picture[i-1]);
     memmove(s->halfpel_plane+1, s->halfpel_plane, (s->max_ref_frames-1)*sizeof(void*)*4*4);
     if(USE_HALFPEL_PLANE && s->current_picture.data[0])
         halfpel_interpol(s, s->halfpel_plane[0], &s->current_picture);
diff --git a/libavcodec/snowdec.c b/libavcodec/snowdec.c
index c8a0327..b222c22 100644
--- a/libavcodec/snowdec.c
+++ b/libavcodec/snowdec.c
@@ -33,9 +33,6 @@
 #include "mpegvideo.h"
 #include "h263.h"
 
-#undef NDEBUG
-#include <assert.h>
-
 static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer * sb, IDWTELEM * old_buffer, int plane_index, int add, int mb_y){
     Plane *p= &s->plane[plane_index];
     const int mb_w= s->b_width  << s->block_max_depth;
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index 7266ee1..9d4efa4 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -62,10 +62,10 @@
             int sx= (x-xo + step/2) / step / Q2_STEP;
             int sy= (y-yo + step/2) / step / Q2_STEP;
             int v= r0[x + y*p->width] - r1[x + y*p->width];
-            assert(sx>=0 && sy>=0 && sx < score_stride);
+            av_assert2(sx>=0 && sy>=0 && sx < score_stride);
             v= ((v+8)>>4)<<4;
             score[sx + sy*score_stride] += v*v;
-            assert(score[sx + sy*score_stride] >= 0);
+            av_assert2(score[sx + sy*score_stride] >= 0);
         }
     }
 }
@@ -963,10 +963,10 @@
 
                         if(run_index <= max_index)
                             put_symbol2(&s->c, b->state[1], run, 3);
-                        assert(v);
+                        av_assert2(v);
                     }else{
                         run--;
-                        assert(!v);
+                        av_assert2(!v);
                     }
                 }
                 if(v){
@@ -1770,6 +1770,11 @@
           || !(height>>(s->chroma_v_shift + s->spatial_decomposition_count)))
         s->spatial_decomposition_count--;
 
+    if (s->spatial_decomposition_count <= 0) {
+        av_log(avctx, AV_LOG_ERROR, "Resolution too low\n");
+        return AVERROR(EINVAL);
+    }
+
     s->m.pict_type = pic->pict_type;
     s->qbias = pic->pict_type == AV_PICTURE_TYPE_P ? 2 : 0;
 
diff --git a/libavcodec/sonic.c b/libavcodec/sonic.c
index b67434f..7a9db36 100644
--- a/libavcodec/sonic.c
+++ b/libavcodec/sonic.c
@@ -75,14 +75,6 @@
 #define BASE_QUANT      0.6
 #define RATE_VARIATION  3.0
 
-static inline int divide(int a, int b)
-{
-    if (a < 0)
-        return -( (-a + b/2)/b );
-    else
-        return (a + b/2)/b;
-}
-
 static inline int shift(int a,int b)
 {
     return (a+(1<<(b-1))) >> b;
@@ -90,7 +82,7 @@
 
 static inline int shift_down(int a,int b)
 {
-    return (a>>b)+((a<0)?1:0);
+    return (a>>b)+(a<0);
 }
 
 #if 1
@@ -172,9 +164,9 @@
     int step = 256, pos = 0, dominant = 0, any = 0;
     int *copy, *bits;
 
-    copy = av_mallocz(4* entries);
+    copy = av_calloc(entries, sizeof(*copy));
     if (!copy)
-        return -1;
+        return AVERROR(ENOMEM);
 
     if (base_2_part)
     {
@@ -198,11 +190,11 @@
             max = abs(copy[i]);
     }
 
-    bits = av_mallocz(4* entries*max);
+    bits = av_calloc(entries*max, sizeof(*bits));
     if (!bits)
     {
 //        av_free(copy);
-        return -1;
+        return AVERROR(ENOMEM);
     }
 
     for (i = 0; i <= max; i++)
@@ -268,10 +260,10 @@
     int i, low_bits = 0, x = 0;
     int n_zeros = 0, step = 256, dominant = 0;
     int pos = 0, level = 0;
-    int *bits = av_mallocz(4* entries);
+    int *bits = av_calloc(entries, sizeof(*bits));
 
     if (!bits)
-        return -1;
+        return AVERROR(ENOMEM);
 
     if (base_2_part)
     {
@@ -418,7 +410,7 @@
         int *out, int out_entries, int channels, int *tap_quant)
 {
     int i;
-    int *state = av_mallocz(4* window_entries);
+    int *state = av_calloc(window_entries, sizeof(*state));
 
     memcpy(state, window, 4* window_entries);
 
@@ -427,18 +419,21 @@
         int step = (i+1)*channels, k, j;
         double xx = 0.0, xy = 0.0;
 #if 1
-        int *x_ptr = &(window[step]), *state_ptr = &(state[0]);
+        int *x_ptr = &(window[step]);
+        int *state_ptr = &(state[0]);
         j = window_entries - step;
-        for (;j>=0;j--,x_ptr++,state_ptr++)
+        for (;j>0;j--,x_ptr++,state_ptr++)
         {
-            double x_value = *x_ptr, state_value = *state_ptr;
+            double x_value = *x_ptr;
+            double state_value = *state_ptr;
             xx += state_value*state_value;
             xy += x_value*state_value;
         }
 #else
         for (j = 0; j <= (window_entries - step); j++);
         {
-            double stepval = window[step+j], stateval = window[j];
+            double stepval = window[step+j];
+            double stateval = window[j];
 //            xx += (double)window[j]*(double)window[j];
 //            xy += (double)window[step+j]*(double)window[j];
             xx += stateval*stateval;
@@ -462,16 +457,18 @@
         x_ptr = &(window[step]);
         state_ptr = &(state[0]);
         j = window_entries - step;
-        for (;j>=0;j--,x_ptr++,state_ptr++)
+        for (;j>0;j--,x_ptr++,state_ptr++)
         {
-            int x_value = *x_ptr, state_value = *state_ptr;
+            int x_value = *x_ptr;
+            int state_value = *state_ptr;
             *x_ptr = x_value + shift_down(k*state_value,LATTICE_SHIFT);
             *state_ptr = state_value + shift_down(k*x_value, LATTICE_SHIFT);
         }
 #else
         for (j=0; j <= (window_entries - step); j++)
         {
-            int stepval = window[step+j], stateval=state[j];
+            int stepval = window[step+j];
+            int stateval=state[j];
             window[step+j] += shift_down(k * stateval, LATTICE_SHIFT);
             state[j] += shift_down(k * stepval, LATTICE_SHIFT);
         }
@@ -495,7 +492,7 @@
         case 16000: return 7;
         case 8000: return 8;
     }
-    return -1;
+    return AVERROR(EINVAL);
 }
 
 static av_cold int sonic_encode_init(AVCodecContext *avctx)
@@ -507,7 +504,7 @@
     if (avctx->channels > MAX_CHANNELS)
     {
         av_log(avctx, AV_LOG_ERROR, "Only mono and stereo streams are supported by now\n");
-        return -1; /* only stereo or mono for now */
+        return AVERROR(EINVAL); /* only stereo or mono for now */
     }
 
     if (avctx->channels == 2)
@@ -530,50 +527,48 @@
     }
 
     // max tap 2048
-    if ((s->num_taps < 32) || (s->num_taps > 1024) ||
-        ((s->num_taps>>5)<<5 != s->num_taps))
-    {
+    if (s->num_taps < 32 || s->num_taps > 1024 || s->num_taps % 32) {
         av_log(avctx, AV_LOG_ERROR, "Invalid number of taps\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     // generate taps
-    s->tap_quant = av_mallocz(4* s->num_taps);
+    s->tap_quant = av_calloc(s->num_taps, sizeof(*s->tap_quant));
     for (i = 0; i < s->num_taps; i++)
-        s->tap_quant[i] = (int)(sqrt(i+1));
+        s->tap_quant[i] = ff_sqrt(i+1);
 
     s->channels = avctx->channels;
     s->samplerate = avctx->sample_rate;
 
-    s->block_align = (int)(2048.0*s->samplerate/44100)/s->downsampling;
+    s->block_align = 2048LL*s->samplerate/(44100*s->downsampling);
     s->frame_size = s->channels*s->block_align*s->downsampling;
 
     s->tail_size = s->num_taps*s->channels;
-    s->tail = av_mallocz(4 * s->tail_size);
+    s->tail = av_calloc(s->tail_size, sizeof(*s->tail));
     if (!s->tail)
-        return -1;
+        return AVERROR(ENOMEM);
 
-    s->predictor_k = av_mallocz(4 * s->num_taps);
+    s->predictor_k = av_calloc(s->num_taps, sizeof(*s->predictor_k) );
     if (!s->predictor_k)
-        return -1;
+        return AVERROR(ENOMEM);
 
     for (i = 0; i < s->channels; i++)
     {
-        s->coded_samples[i] = av_mallocz(4* s->block_align);
+        s->coded_samples[i] = av_calloc(s->block_align, sizeof(**s->coded_samples));
         if (!s->coded_samples[i])
-            return -1;
+            return AVERROR(ENOMEM);
     }
 
-    s->int_samples = av_mallocz(4* s->frame_size);
+    s->int_samples = av_calloc(s->frame_size, sizeof(*s->int_samples));
 
     s->window_size = ((2*s->tail_size)+s->frame_size);
-    s->window = av_mallocz(4* s->window_size);
+    s->window = av_calloc(s->window_size, sizeof(*s->window));
     if (!s->window)
-        return -1;
+        return AVERROR(ENOMEM);
 
     avctx->extradata = av_mallocz(16);
     if (!avctx->extradata)
-        return -1;
+        return AVERROR(ENOMEM);
     init_put_bits(&pb, avctx->extradata, 16*8);
 
     put_bits(&pb, 2, version); // version
@@ -596,10 +591,6 @@
     av_log(avctx, AV_LOG_INFO, "Sonic: ver: %d ls: %d dr: %d taps: %d block: %d frame: %d downsamp: %d\n",
         version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling);
 
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-    avctx->coded_frame->key_frame = 1;
     avctx->frame_size = s->block_align*s->downsampling;
 
     return 0;
@@ -610,16 +601,14 @@
     SonicContext *s = avctx->priv_data;
     int i;
 
-    av_freep(&avctx->coded_frame);
-
     for (i = 0; i < s->channels; i++)
-        av_free(s->coded_samples[i]);
+        av_freep(&s->coded_samples[i]);
 
-    av_free(s->predictor_k);
-    av_free(s->tail);
-    av_free(s->tap_quant);
-    av_free(s->window);
-    av_free(s->int_samples);
+    av_freep(&s->predictor_k);
+    av_freep(&s->tail);
+    av_freep(&s->tap_quant);
+    av_freep(&s->window);
+    av_freep(&s->int_samples);
 
     return 0;
 }
@@ -682,8 +671,8 @@
     // generate taps
     modified_levinson_durbin(s->window, s->window_size,
                 s->predictor_k, s->num_taps, s->channels, s->tap_quant);
-    if (intlist_write(&pb, s->predictor_k, s->num_taps, 0) < 0)
-        return -1;
+    if ((ret = intlist_write(&pb, s->predictor_k, s->num_taps, 0)) < 0)
+        return ret;
 
     for (ch = 0; ch < s->channels; ch++)
     {
@@ -723,10 +712,7 @@
         quant = (int)(BASE_QUANT*s->quantization*energy2/SAMPLE_FACTOR);
 //        av_log(avctx, AV_LOG_DEBUG, "quant: %d energy: %f / %f\n", quant, energy1, energy2);
 
-        if (quant < 1)
-            quant = 1;
-        if (quant > 65534)
-            quant = 65534;
+        quant = av_clip(quant, 1, 65534);
 
         set_ue_golomb(&pb, quant);
 
@@ -738,10 +724,10 @@
     {
         if (!s->lossless)
             for (i = 0; i < s->block_align; i++)
-                s->coded_samples[ch][i] = divide(s->coded_samples[ch][i], quant);
+                s->coded_samples[ch][i] = ROUNDED_DIV(s->coded_samples[ch][i], quant);
 
-        if (intlist_write(&pb, s->coded_samples[ch], s->block_align, 1) < 0)
-            return -1;
+        if ((ret = intlist_write(&pb, s->coded_samples[ch], s->block_align, 1)) < 0)
+            return ret;
     }
 
 //    av_log(avctx, AV_LOG_DEBUG, "used bytes: %d\n", (put_bits_count(&pb)+7)/8);
@@ -769,16 +755,16 @@
     if (!avctx->extradata)
     {
         av_log(avctx, AV_LOG_ERROR, "No mandatory headers present\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    init_get_bits(&gb, avctx->extradata, avctx->extradata_size);
+    init_get_bits8(&gb, avctx->extradata, avctx->extradata_size);
 
     version = get_bits(&gb, 2);
     if (version > 1)
     {
         av_log(avctx, AV_LOG_ERROR, "Unsupported Sonic version, please report\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (version == 1)
@@ -792,7 +778,7 @@
     if (s->channels > MAX_CHANNELS)
     {
         av_log(avctx, AV_LOG_ERROR, "Only mono and stereo streams are supported by now\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     s->lossless = get_bits1(&gb);
@@ -814,7 +800,7 @@
     if (get_bits1(&gb)) // XXX FIXME
         av_log(avctx, AV_LOG_INFO, "Custom quant table\n");
 
-    s->block_align = (int)(2048.0*s->samplerate/44100)/s->downsampling;
+    s->block_align = 2048LL*s->samplerate/(44100*s->downsampling);
     s->frame_size = s->channels*s->block_align*s->downsampling;
 //    avctx->frame_size = s->block_align;
 
@@ -822,26 +808,26 @@
         version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling);
 
     // generate taps
-    s->tap_quant = av_mallocz(4* s->num_taps);
+    s->tap_quant = av_calloc(s->num_taps, sizeof(*s->tap_quant));
     for (i = 0; i < s->num_taps; i++)
-        s->tap_quant[i] = (int)(sqrt(i+1));
+        s->tap_quant[i] = ff_sqrt(i+1);
 
-    s->predictor_k = av_mallocz(4* s->num_taps);
+    s->predictor_k = av_calloc(s->num_taps, sizeof(*s->predictor_k));
 
     for (i = 0; i < s->channels; i++)
     {
-        s->predictor_state[i] = av_mallocz(4* s->num_taps);
+        s->predictor_state[i] = av_calloc(s->num_taps, sizeof(**s->predictor_state));
         if (!s->predictor_state[i])
-            return -1;
+            return AVERROR(ENOMEM);
     }
 
     for (i = 0; i < s->channels; i++)
     {
-        s->coded_samples[i] = av_mallocz(4* s->block_align);
+        s->coded_samples[i] = av_calloc(s->block_align, sizeof(**s->coded_samples));
         if (!s->coded_samples[i])
-            return -1;
+            return AVERROR(ENOMEM);
     }
-    s->int_samples = av_mallocz(4* s->frame_size);
+    s->int_samples = av_calloc(s->frame_size, sizeof(*s->int_samples));
 
     avctx->sample_fmt = AV_SAMPLE_FMT_S16;
     return 0;
@@ -852,14 +838,14 @@
     SonicContext *s = avctx->priv_data;
     int i;
 
-    av_free(s->int_samples);
-    av_free(s->tap_quant);
-    av_free(s->predictor_k);
+    av_freep(&s->int_samples);
+    av_freep(&s->tap_quant);
+    av_freep(&s->predictor_k);
 
     for (i = 0; i < s->channels; i++)
     {
-        av_free(s->predictor_state[i]);
-        av_free(s->coded_samples[i]);
+        av_freep(&s->predictor_state[i]);
+        av_freep(&s->coded_samples[i]);
     }
 
     return 0;
@@ -886,7 +872,7 @@
 
 //    av_log(NULL, AV_LOG_INFO, "buf_size: %d\n", buf_size);
 
-    init_get_bits(&gb, buf, buf_size*8);
+    init_get_bits8(&gb, buf, buf_size);
 
     intlist_read(&gb, s->predictor_k, s->num_taps, 0);
 
@@ -980,6 +966,7 @@
     .priv_data_size = sizeof(SonicContext),
     .init           = sonic_encode_init,
     .encode2        = sonic_encode_frame,
+    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE },
     .capabilities   = CODEC_CAP_EXPERIMENTAL,
     .close          = sonic_encode_close,
     .long_name = NULL_IF_CONFIG_SMALL("Sonic"),
@@ -994,6 +981,7 @@
     .priv_data_size = sizeof(SonicContext),
     .init           = sonic_encode_init,
     .encode2        = sonic_encode_frame,
+    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE },
     .capabilities   = CODEC_CAP_EXPERIMENTAL,
     .close          = sonic_encode_close,
     .long_name = NULL_IF_CONFIG_SMALL("Sonic lossless"),
diff --git a/libavcodec/sparc/vis.h b/libavcodec/sparc/vis.h
index af5b5fa..107ff96 100644
--- a/libavcodec/sparc/vis.h
+++ b/libavcodec/sparc/vis.h
@@ -150,12 +150,9 @@
 #define vis_m2r_2(op,mem1,mem2,rd) \
         __asm__ volatile (#op "\t[%0 + %1], %%f" #rd : : "r" (mem1), "r" (mem2) )
 
-static inline void vis_set_gsr(unsigned int _val)
+static inline void vis_set_gsr(unsigned int val)
 {
-        register unsigned int val __asm__("g1");
-
-        val = _val;
-        __asm__ volatile(".word 0xa7804000"
+        __asm__ volatile("mov %0,%%asr19"
                              : : "r" (val));
 }
 
@@ -173,32 +170,6 @@
 #define vis_st64(rs1,mem)               vis_r2m(std, rs1, mem)
 #define vis_st64_2(rs1,mem1,mem2)       vis_r2m_2(std, rs1, mem1, mem2)
 
-#define vis_ldblk(mem, rd) \
-do {        register void *__mem __asm__("g1"); \
-        __mem = &(mem); \
-        __asm__ volatile(".word 0xc1985e00 | %1" \
-                             : \
-                             : "r" (__mem), \
-                               "i" (vis_rd_d(rd)) \
-                             : "memory"); \
-} while (0)
-
-#define vis_stblk(rd, mem) \
-do {        register void *__mem __asm__("g1"); \
-        __mem = &(mem); \
-        __asm__ volatile(".word 0xc1b85e00 | %1" \
-                             : \
-                             : "r" (__mem), \
-                               "i" (vis_rd_d(rd)) \
-                             : "memory"); \
-} while (0)
-
-#define vis_membar_storestore()        \
-        __asm__ volatile(".word 0x8143e008" : : : "memory")
-
-#define vis_membar_sync()        \
-        __asm__ volatile(".word 0x8143e040" : : : "memory")
-
 /* 16 and 32 bit partitioned addition and subtraction.  The normal
  * versions perform 4 16-bit or 2 32-bit additions or subtractions.
  * The 's' versions perform 2 16-bit or 1 32-bit additions or
@@ -234,68 +205,19 @@
 
 /* Alignment instructions.  */
 
-static inline const void *vis_alignaddr(const void *_ptr)
+static inline const void *vis_alignaddr(const void *ptr)
 {
-        register const void *ptr __asm__("g1");
-
-        ptr = _ptr;
-
-        __asm__ volatile(".word %2"
+        __asm__ volatile("alignaddr %0, %%g0, %0"
                              : "=&r" (ptr)
-                             : "0" (ptr),
-                               "i" (vis_opc_base | vis_opf(0x18) |
-                                    vis_rs1_s(1) |
-                                    vis_rs2_s(0) |
-                                    vis_rd_s(1)));
+                             : "0" (ptr));
 
         return ptr;
 }
 
-static inline void vis_alignaddr_g0(void *_ptr)
+static inline void vis_alignaddr_g0(void *ptr)
 {
-        register void *ptr __asm__("g1");
-
-        ptr = _ptr;
-
-        __asm__ volatile(".word %2"
-                             : "=&r" (ptr)
-                             : "0" (ptr),
-                               "i" (vis_opc_base | vis_opf(0x18) |
-                                    vis_rs1_s(1) |
-                                    vis_rs2_s(0) |
-                                    vis_rd_s(0)));
-}
-
-static inline void *vis_alignaddrl(void *_ptr)
-{
-        register void *ptr __asm__("g1");
-
-        ptr = _ptr;
-
-        __asm__ volatile(".word %2"
-                             : "=&r" (ptr)
-                             : "0" (ptr),
-                               "i" (vis_opc_base | vis_opf(0x19) |
-                                    vis_rs1_s(1) |
-                                    vis_rs2_s(0) |
-                                    vis_rd_s(1)));
-
-        return ptr;
-}
-
-static inline void vis_alignaddrl_g0(void *_ptr)
-{
-        register void *ptr __asm__("g1");
-
-        ptr = _ptr;
-
-        __asm__ volatile(".word %2"
-                             : "=&r" (ptr)
-                             : "0" (ptr),
-                               "i" (vis_opc_base | vis_opf(0x19) |
-                                    vis_rs1_s(1) |
-                                    vis_rs2_s(0) |
-                                    vis_rd_s(0)));
+        __asm__ volatile("alignaddr %0, %%g0, %%g0"
+                             : : "r" (ptr));
 }
 
 #define vis_faligndata(rs1,rs2,rd)        vis_dd2d(0x48, rs1, rs2, rd)
diff --git a/libavcodec/sunrastenc.c b/libavcodec/sunrastenc.c
index 2c7e72f..7b0ffb3 100644
--- a/libavcodec/sunrastenc.c
+++ b/libavcodec/sunrastenc.c
@@ -25,7 +25,6 @@
 #include "sunrast.h"
 
 typedef struct SUNRASTContext {
-    AVFrame picture;
     PutByteContext p;
     int depth;      ///< depth of pixel
     int length;     ///< length (bytes) of image
@@ -149,9 +148,6 @@
         return AVERROR(EINVAL);
     }
 
-    avctx->coded_frame            = &s->picture;
-    avctx->coded_frame->key_frame = 1;
-    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
     s->maptype                    = RMT_NONE;
     s->maplength                  = 0;
 
diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c
index 5f43a97..e768d81 100644
--- a/libavcodec/svq1dec.c
+++ b/libavcodec/svq1dec.c
@@ -34,6 +34,7 @@
 
 #include "avcodec.h"
 #include "get_bits.h"
+#include "h263.h"
 #include "hpeldsp.h"
 #include "internal.h"
 #include "mathops.h"
@@ -42,8 +43,6 @@
 #undef NDEBUG
 #include <assert.h>
 
-extern const uint8_t ff_mvtab[33][2];
-
 static VLC svq1_block_type;
 static VLC svq1_motion_component;
 static VLC svq1_intra_multistage[6];
@@ -555,7 +554,7 @@
             svq1_parse_string(bitbuf, msg);
 
             av_log(avctx, AV_LOG_INFO,
-                   "embedded message: \"%s\"\n", (char *)msg);
+                   "embedded message:\n%s\n", (char *)msg);
         }
 
         skip_bits(bitbuf, 2);
@@ -615,7 +614,7 @@
     svq1_pmv *pmv;
 
     /* initialize bit buffer */
-    init_get_bits(&s->gb, buf, buf_size * 8);
+    init_get_bits8(&s->gb, buf, buf_size);
 
     /* decode frame header */
     s->frame_code = get_bits(&s->gb, 22);
diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index afef854..5b4748f 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -557,9 +557,9 @@
         s->scratchbuf = av_malloc(s->current_picture.linesize[0] * 16 * 2);
     }
 
-    temp               = s->current_picture;
-    s->current_picture = s->last_picture;
-    s->last_picture    = temp;
+    av_frame_move_ref(&temp, &s->current_picture);
+    av_frame_move_ref(&s->current_picture, &s->last_picture);
+    av_frame_move_ref(&s->last_picture, &temp);
 
     init_put_bits(&s->pb, pkt->data, pkt->size);
 
diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c
index f584f3a..cd21cae 100644
--- a/libavcodec/svq3.c
+++ b/libavcodec/svq3.c
@@ -39,6 +39,8 @@
  * correctly decodes this file:
  *  http://samples.mplayerhq.hu/V-codecs/SVQ3/Vertical400kbit.sorenson3.mov
  */
+
+#include "libavutil/attributes.h"
 #include "internal.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
@@ -105,6 +107,13 @@
     0 + 3 * 4, 1 + 3 * 4, 2 + 3 * 4, 3 + 3 * 4,
 };
 
+static const uint8_t luma_dc_zigzag_scan[16] = {
+    0 * 16 + 0 * 64, 1 * 16 + 0 * 64, 2 * 16 + 0 * 64, 0 * 16 + 2 * 64,
+    3 * 16 + 0 * 64, 0 * 16 + 1 * 64, 1 * 16 + 1 * 64, 2 * 16 + 1 * 64,
+    1 * 16 + 2 * 64, 2 * 16 + 2 * 64, 3 * 16 + 2 * 64, 0 * 16 + 3 * 64,
+    3 * 16 + 1 * 64, 1 * 16 + 3 * 64, 2 * 16 + 3 * 64, 3 * 16 + 3 * 64,
+};
+
 static const uint8_t svq3_pred_0[25][2] = {
     { 0, 0 },
     { 1, 0 }, { 0, 1 },
@@ -648,8 +657,8 @@
         dir = i_mb_type_info[mb_type - 8].pred_mode;
         dir = (dir >> 1) ^ 3 * (dir & 1) ^ 1;
 
-        if ((h->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, dir, 0)) == -1) {
-            av_log(h->avctx, AV_LOG_ERROR, "check_intra_pred_mode = -1\n");
+        if ((h->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, dir, 0)) < 0) {
+            av_log(h->avctx, AV_LOG_ERROR, "check_intra_pred_mode < 0\n");
             return -1;
         }
 
@@ -1310,7 +1319,7 @@
     return buf_size;
 }
 
-static int svq3_decode_end(AVCodecContext *avctx)
+static av_cold int svq3_decode_end(AVCodecContext *avctx)
 {
     SVQ3Context *s = avctx->priv_data;
     H264Context *h = &s->h;
diff --git a/libavcodec/tak.c b/libavcodec/tak.c
index 92dc44c..ed41ca8 100644
--- a/libavcodec/tak.c
+++ b/libavcodec/tak.c
@@ -19,7 +19,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/bswap.h"
 #include "libavutil/crc.h"
 #include "libavutil/intreadwrite.h"
 #include "tak.h"
@@ -73,22 +72,6 @@
     return nb_samples;
 }
 
-static int crc_init = 0;
-#if CONFIG_SMALL
-#define CRC_TABLE_SIZE 257
-#else
-#define CRC_TABLE_SIZE 1024
-#endif
-static AVCRC crc_24[CRC_TABLE_SIZE];
-
-av_cold void ff_tak_init_crc(void)
-{
-    if (!crc_init) {
-        av_crc_init(crc_24, 0, 24, 0x864CFBU, sizeof(crc_24));
-        crc_init = 1;
-    }
-}
-
 int ff_tak_check_crc(const uint8_t *buf, unsigned int buf_size)
 {
     uint32_t crc, CRC;
@@ -97,8 +80,8 @@
         return AVERROR_INVALIDDATA;
     buf_size -= 3;
 
-    CRC = av_bswap32(AV_RL24(buf + buf_size)) >> 8;
-    crc = av_crc(crc_24, 0xCE04B7U, buf, buf_size);
+    CRC = AV_RB24(buf + buf_size);
+    crc = av_crc(av_crc_get_table(AV_CRC_24_IEEE), 0xCE04B7U, buf, buf_size);
     if (CRC != crc)
         return AVERROR_INVALIDDATA;
 
diff --git a/libavcodec/tak.h b/libavcodec/tak.h
index 876468d..e8e2dac 100644
--- a/libavcodec/tak.h
+++ b/libavcodec/tak.h
@@ -140,8 +140,6 @@
     int64_t           samples;
 } TAKStreamInfo;
 
-void ff_tak_init_crc(void);
-
 int ff_tak_check_crc(const uint8_t *buf, unsigned int buf_size);
 
 /**
diff --git a/libavcodec/tak_parser.c b/libavcodec/tak_parser.c
index 0f2fbc2..5d8460c 100644
--- a/libavcodec/tak_parser.c
+++ b/libavcodec/tak_parser.c
@@ -33,12 +33,6 @@
     int           index;
 } TAKParseContext;
 
-static av_cold int tak_init(AVCodecParserContext *s)
-{
-    ff_tak_init_crc();
-    return 0;
-}
-
 static int tak_parse(AVCodecParserContext *s, AVCodecContext *avctx,
                      const uint8_t **poutbuf, int *poutbuf_size,
                      const uint8_t *buf, int buf_size)
@@ -90,6 +84,7 @@
                         s->duration           = t->ti.last_frame_samples ?
                                                 t->ti.last_frame_samples :
                                                 t->ti.frame_samples;
+                        s->key_frame          = !!(t->ti.flags & TAK_FRAME_FLAG_HAS_INFO);
                     } else {
                         pc->frame_start_found = 0;
                         next                  = t->index - pc->index;
@@ -122,7 +117,6 @@
 AVCodecParser ff_tak_parser = {
     .codec_ids      = { AV_CODEC_ID_TAK },
     .priv_data_size = sizeof(TAKParseContext),
-    .parser_init    = tak_init,
     .parser_parse   = tak_parse,
     .parser_close   = ff_parse_close,
 };
diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c
index 43382f1..0edfddd 100644
--- a/libavcodec/takdec.c
+++ b/libavcodec/takdec.c
@@ -28,6 +28,7 @@
 #include "libavutil/internal.h"
 #include "libavutil/samplefmt.h"
 #include "tak.h"
+#include "thread.h"
 #include "avcodec.h"
 #include "dsputil.h"
 #include "internal.h"
@@ -170,7 +171,6 @@
 {
     TAKDecContext *s = avctx->priv_data;
 
-    ff_tak_init_crc();
     ff_dsputil_init(&s->dsp, avctx);
 
     s->avctx = avctx;
@@ -468,27 +468,14 @@
         for (i = 0; i < tmp; i++) {
             int v = 1 << (filter_quant - 1);
 
-            if (!(filter_order & 15)) {
+            if (filter_order & -16)
                 v += s->dsp.scalarproduct_int16(&s->residues[i], s->filter,
-                                                filter_order);
-            } else if (filter_order & 4) {
-                for (j = 0; j < filter_order; j += 4) {
-                    v += s->residues[i + j + 3] * s->filter[j + 3] +
-                         s->residues[i + j + 2] * s->filter[j + 2] +
-                         s->residues[i + j + 1] * s->filter[j + 1] +
-                         s->residues[i + j    ] * s->filter[j    ];
-                }
-            } else {
-                for (j = 0; j < filter_order; j += 8) {
-                    v += s->residues[i + j + 7] * s->filter[j + 7] +
-                         s->residues[i + j + 6] * s->filter[j + 6] +
-                         s->residues[i + j + 5] * s->filter[j + 5] +
-                         s->residues[i + j + 4] * s->filter[j + 4] +
-                         s->residues[i + j + 3] * s->filter[j + 3] +
-                         s->residues[i + j + 2] * s->filter[j + 2] +
-                         s->residues[i + j + 1] * s->filter[j + 1] +
-                         s->residues[i + j    ] * s->filter[j    ];
-                }
+                                                filter_order & -16);
+            for (j = filter_order & -16; j < filter_order; j += 4) {
+                v += s->residues[i + j + 3] * s->filter[j + 3] +
+                     s->residues[i + j + 2] * s->filter[j + 2] +
+                     s->residues[i + j + 1] * s->filter[j + 1] +
+                     s->residues[i + j    ] * s->filter[j    ];
             }
             v = (av_clip(v >> filter_quant, -8192, 8191) << dshift) - *decoded;
             *decoded++ = v;
@@ -686,6 +673,7 @@
 {
     TAKDecContext *s  = avctx->priv_data;
     AVFrame *frame    = data;
+    ThreadFrame tframe = { .f = data };
     GetBitContext *gb = &s->gb;
     int chan, i, ret, hsize;
 
@@ -749,8 +737,9 @@
                                              : s->ti.frame_samples;
 
     frame->nb_samples = s->nb_samples;
-    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
         return ret;
+    ff_thread_finish_setup(avctx);
 
     if (avctx->bits_per_raw_sample <= 16) {
         int buf_size = av_samples_get_buffer_size(NULL, avctx->channels,
@@ -912,6 +901,25 @@
     return pkt->size;
 }
 
+static int init_thread_copy(AVCodecContext *avctx)
+{
+    TAKDecContext *s = avctx->priv_data;
+    s->avctx = avctx;
+    return 0;
+}
+
+static int update_thread_context(AVCodecContext *dst,
+                                 const AVCodecContext *src)
+{
+    TAKDecContext *tsrc = src->priv_data;
+    TAKDecContext *tdst = dst->priv_data;
+
+    if (dst == src)
+        return 0;
+    memcpy(&tdst->ti, &tsrc->ti, sizeof(TAKStreamInfo));
+    return 0;
+}
+
 static av_cold int tak_decode_close(AVCodecContext *avctx)
 {
     TAKDecContext *s = avctx->priv_data;
@@ -929,7 +937,9 @@
     .init             = tak_decode_init,
     .close            = tak_decode_close,
     .decode           = tak_decode_frame,
-    .capabilities     = CODEC_CAP_DR1,
+    .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
+    .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
+    .capabilities     = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
     .long_name        = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"),
     .sample_fmts      = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
                                                         AV_SAMPLE_FMT_S16P,
diff --git a/libavcodec/targa.c b/libavcodec/targa.c
index ff4390f..2e51d80 100644
--- a/libavcodec/targa.c
+++ b/libavcodec/targa.c
@@ -179,6 +179,7 @@
         avcodec_set_dimensions(avctx, w, h);
     if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
         return ret;
+    p->pict_type = AV_PICTURE_TYPE_I;
 
     if (flags & TGA_TOPTOBOTTOM) {
         dst = p->data[0];
diff --git a/libavcodec/targa_y216dec.c b/libavcodec/targa_y216dec.c
index 38694ce..d67d193 100644
--- a/libavcodec/targa_y216dec.c
+++ b/libavcodec/targa_y216dec.c
@@ -72,19 +72,12 @@
     return avpkt->size;
 }
 
-static av_cold int y216_decode_close(AVCodecContext *avctx)
-{
-
-    return 0;
-}
-
 AVCodec ff_targa_y216_decoder = {
     .name         = "targa_y216",
     .type         = AVMEDIA_TYPE_VIDEO,
     .id           = AV_CODEC_ID_TARGA_Y216,
     .init         = y216_decode_init,
     .decode       = y216_decode_frame,
-    .close        = y216_decode_close,
     .capabilities = CODEC_CAP_DR1,
     .long_name    = NULL_IF_CONFIG_SMALL("Pinnacle TARGA CineWave YUV16"),
 };
diff --git a/libavcodec/targaenc.c b/libavcodec/targaenc.c
index b2c679d..da74503 100644
--- a/libavcodec/targaenc.c
+++ b/libavcodec/targaenc.c
@@ -29,10 +29,6 @@
 #include "rle.h"
 #include "targa.h"
 
-typedef struct TargaContext {
-    AVFrame picture;
-} TargaContext;
-
 /**
  * RLE compress the image, with maximum size of out_size
  * @param outbuf Output buffer
@@ -174,24 +170,10 @@
     return 0;
 }
 
-static av_cold int targa_encode_init(AVCodecContext *avctx)
-{
-    TargaContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    s->picture.key_frame= 1;
-    s->picture.pict_type = AV_PICTURE_TYPE_I;
-    avctx->coded_frame= &s->picture;
-
-    return 0;
-}
-
 AVCodec ff_targa_encoder = {
     .name           = "targa",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TARGA,
-    .priv_data_size = sizeof(TargaContext),
-    .init           = targa_encode_init,
     .encode2        = targa_encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]){
         AV_PIX_FMT_BGR24, AV_PIX_FMT_BGRA, AV_PIX_FMT_RGB555LE, AV_PIX_FMT_GRAY8, AV_PIX_FMT_PAL8,
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 6c2dc23..0e8ddec 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -24,22 +24,24 @@
  * @author Konstantin Shishkov
  */
 
-#include "avcodec.h"
-#include "bytestream.h"
 #include "config.h"
 #if CONFIG_ZLIB
 #include <zlib.h>
 #endif
-#include "lzw.h"
-#include "tiff.h"
-#include "tiff_data.h"
-#include "faxcompr.h"
-#include "internal.h"
-#include "mathops.h"
+
 #include "libavutil/attributes.h"
+#include "libavutil/avstring.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
-#include "libavutil/avstring.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "faxcompr.h"
+#include "internal.h"
+#include "lzw.h"
+#include "mathops.h"
+#include "tiff.h"
+#include "tiff_data.h"
+#include "thread.h"
 
 typedef struct TiffContext {
     AVCodecContext *avctx;
@@ -52,6 +54,7 @@
     int le;
     enum TiffCompr compr;
     int invert;
+    int planar;
     int fax_opts;
     int predictor;
     int fill_order;
@@ -68,34 +71,6 @@
     TiffGeoTag *geotags;
 } TiffContext;
 
-static unsigned tget_short(GetByteContext *gb, int le)
-{
-    unsigned v = le ? bytestream2_get_le16(gb) : bytestream2_get_be16(gb);
-    return v;
-}
-
-static unsigned tget_long(GetByteContext *gb, int le)
-{
-    unsigned v = le ? bytestream2_get_le32(gb) : bytestream2_get_be32(gb);
-    return v;
-}
-
-static double tget_double(GetByteContext *gb, int le)
-{
-    av_alias64 i = { .u64 = le ? bytestream2_get_le64(gb) : bytestream2_get_be64(gb)};
-    return i.f64;
-}
-
-static unsigned tget(GetByteContext *gb, int type, int le)
-{
-    switch (type) {
-    case TIFF_BYTE : return bytestream2_get_byte(gb);
-    case TIFF_SHORT: return tget_short(gb, le);
-    case TIFF_LONG : return tget_long(gb, le);
-    default        : return UINT_MAX;
-    }
-}
-
 static void free_geotags(TiffContext *const s)
 {
     int i;
@@ -239,138 +214,17 @@
     return ap0;
 }
 
-static char *shorts2str(int16_t *sp, int count, const char *sep)
-{
-    int i;
-    char *ap, *ap0;
-    uint64_t component_len;
-    if (!sep) sep = ", ";
-    component_len = 7LL + strlen(sep);
-    if (count >= (INT_MAX - 1)/component_len)
-        return NULL;
-    ap = av_malloc(component_len * count + 1);
-    if (!ap)
-        return NULL;
-    ap0   = ap;
-    ap[0] = '\0';
-    for (i = 0; i < count; i++) {
-        unsigned l = snprintf(ap, component_len, "%d%s", sp[i], sep);
-        if (l >= component_len) {
-            av_free(ap0);
-            return NULL;
-        }
-        ap += l;
-    }
-    ap0[strlen(ap0) - strlen(sep)] = '\0';
-    return ap0;
-}
-
-static int add_doubles_metadata(int count,
-                                const char *name, const char *sep,
-                                TiffContext *s, AVFrame *frame)
-{
-    char *ap;
-    int i;
-    double *dp;
-
-    if (count >= INT_MAX / sizeof(int64_t) || count <= 0)
-        return AVERROR_INVALIDDATA;
-    if (bytestream2_get_bytes_left(&s->gb) < count * sizeof(int64_t))
-        return AVERROR_INVALIDDATA;
-
-    dp = av_malloc(count * sizeof(double));
-    if (!dp)
-        return AVERROR(ENOMEM);
-
-    for (i = 0; i < count; i++)
-        dp[i] = tget_double(&s->gb, s->le);
-    ap = doubles2str(dp, count, sep);
-    av_freep(&dp);
-    if (!ap)
-        return AVERROR(ENOMEM);
-    av_dict_set(avpriv_frame_get_metadatap(frame), name, ap, AV_DICT_DONT_STRDUP_VAL);
-    return 0;
-}
-
-static int add_shorts_metadata(int count, const char *name,
-                               const char *sep, TiffContext *s, AVFrame *frame)
-{
-    char *ap;
-    int i;
-    int16_t *sp;
-
-    if (count >= INT_MAX / sizeof(int16_t) || count <= 0)
-        return AVERROR_INVALIDDATA;
-    if (bytestream2_get_bytes_left(&s->gb) < count * sizeof(int16_t))
-        return AVERROR_INVALIDDATA;
-
-    sp = av_malloc(count * sizeof(int16_t));
-    if (!sp)
-        return AVERROR(ENOMEM);
-
-    for (i = 0; i < count; i++)
-        sp[i] = tget_short(&s->gb, s->le);
-    ap = shorts2str(sp, count, sep);
-    av_freep(&sp);
-    if (!ap)
-        return AVERROR(ENOMEM);
-    av_dict_set(avpriv_frame_get_metadatap(frame), name, ap, AV_DICT_DONT_STRDUP_VAL);
-    return 0;
-}
-
-static int add_string_metadata(int count, const char *name,
-                               TiffContext *s, AVFrame *frame)
-{
-    char *value;
-
-    if (bytestream2_get_bytes_left(&s->gb) < count || count < 0)
-        return AVERROR_INVALIDDATA;
-
-    value = av_malloc(count + 1);
-    if (!value)
-        return AVERROR(ENOMEM);
-
-    bytestream2_get_bufferu(&s->gb, value, count);
-    value[count] = 0;
-
-    av_dict_set(avpriv_frame_get_metadatap(frame), name, value, AV_DICT_DONT_STRDUP_VAL);
-    return 0;
-}
-
 static int add_metadata(int count, int type,
                         const char *name, const char *sep, TiffContext *s, AVFrame *frame)
 {
     switch(type) {
-    case TIFF_DOUBLE: return add_doubles_metadata(count, name, sep, s, frame);
-    case TIFF_SHORT : return add_shorts_metadata(count, name, sep, s, frame);
-    case TIFF_STRING: return add_string_metadata(count, name, s, frame);
+    case TIFF_DOUBLE: return ff_tadd_doubles_metadata(count, name, sep, &s->gb, s->le, avpriv_frame_get_metadatap(frame));
+    case TIFF_SHORT : return ff_tadd_shorts_metadata(count, name, sep, &s->gb, s->le, avpriv_frame_get_metadatap(frame));
+    case TIFF_STRING: return ff_tadd_string_metadata(count, name, &s->gb, s->le, avpriv_frame_get_metadatap(frame));
     default         : return AVERROR_INVALIDDATA;
     };
 }
 
-#if CONFIG_ZLIB
-static int tiff_uncompress(uint8_t *dst, unsigned long *len, const uint8_t *src,
-                           int size)
-{
-    z_stream zstream = { 0 };
-    int zret;
-
-    zstream.next_in = (uint8_t *)src;
-    zstream.avail_in = size;
-    zstream.next_out = dst;
-    zstream.avail_out = *len;
-    zret = inflateInit(&zstream);
-    if (zret != Z_OK) {
-        av_log(NULL, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
-        return zret;
-    }
-    zret = inflate(&zstream, Z_SYNC_FLUSH);
-    inflateEnd(&zstream);
-    *len = zstream.total_out;
-    return zret == Z_STREAM_END ? Z_OK : zret;
-}
-#endif
-
 static void av_always_inline horizontal_fill(unsigned int bpp, uint8_t* dst,
                                              int usePtr, const uint8_t *src,
                                              uint8_t c, int width, int offset)
@@ -411,71 +265,147 @@
     }
 }
 
+static int deinvert_buffer(TiffContext *s, const uint8_t *src, int size)
+{
+    int i;
+
+    av_fast_padded_malloc(&s->deinvert_buf, &s->deinvert_buf_size, size);
+    if (!s->deinvert_buf)
+        return AVERROR(ENOMEM);
+    for (i = 0; i < size; i++)
+        s->deinvert_buf[i] = ff_reverse[src[i]];
+
+    return 0;
+}
+
+#if CONFIG_ZLIB
+static int tiff_uncompress(uint8_t *dst, unsigned long *len, const uint8_t *src,
+                           int size)
+{
+    z_stream zstream = { 0 };
+    int zret;
+
+    zstream.next_in   = (uint8_t *)src;
+    zstream.avail_in  = size;
+    zstream.next_out  = dst;
+    zstream.avail_out = *len;
+    zret              = inflateInit(&zstream);
+    if (zret != Z_OK) {
+        av_log(NULL, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
+        return zret;
+    }
+    zret = inflate(&zstream, Z_SYNC_FLUSH);
+    inflateEnd(&zstream);
+    *len = zstream.total_out;
+    return zret == Z_STREAM_END ? Z_OK : zret;
+}
+
+static int tiff_unpack_zlib(TiffContext *s, uint8_t *dst, int stride,
+                            const uint8_t *src, int size,
+                            int width, int lines)
+{
+    uint8_t *zbuf;
+    unsigned long outlen;
+    int ret, line;
+    outlen = width * lines;
+    zbuf   = av_malloc(outlen);
+    if (!zbuf)
+        return AVERROR(ENOMEM);
+    if (s->fill_order) {
+        if ((ret = deinvert_buffer(s, src, size)) < 0) {
+            av_free(zbuf);
+            return ret;
+        }
+        src = s->deinvert_buf;
+    }
+    ret = tiff_uncompress(zbuf, &outlen, src, size);
+    if (ret != Z_OK) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "Uncompressing failed (%lu of %lu) with error %d\n", outlen,
+               (unsigned long)width * lines, ret);
+        av_free(zbuf);
+        return AVERROR_UNKNOWN;
+    }
+    src = zbuf;
+    for (line = 0; line < lines; line++) {
+        if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8) {
+            horizontal_fill(s->bpp, dst, 1, src, 0, width, 0);
+        } else {
+            memcpy(dst, src, width);
+        }
+        dst += stride;
+        src += width;
+    }
+    av_free(zbuf);
+    return 0;
+}
+#endif
+
+
+static int tiff_unpack_fax(TiffContext *s, uint8_t *dst, int stride,
+                           const uint8_t *src, int size, int width, int lines)
+{
+    int i, ret = 0;
+    int line;
+    uint8_t *src2 = av_malloc((unsigned)size +
+                              FF_INPUT_BUFFER_PADDING_SIZE);
+
+    if (!src2) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "Error allocating temporary buffer\n");
+        return AVERROR(ENOMEM);
+    }
+    if (s->fax_opts & 2) {
+        avpriv_request_sample(s->avctx, "Uncompressed fax mode");
+        av_free(src2);
+        return AVERROR_PATCHWELCOME;
+    }
+    if (!s->fill_order) {
+        memcpy(src2, src, size);
+    } else {
+        for (i = 0; i < size; i++)
+            src2[i] = ff_reverse[src[i]];
+    }
+    memset(src2 + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+    ret = ff_ccitt_unpack(s->avctx, src2, size, dst, lines, stride,
+                          s->compr, s->fax_opts);
+    if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
+        for (line = 0; line < lines; line++) {
+            horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0);
+            dst += stride;
+        }
+    av_free(src2);
+    return ret;
+}
+
 static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride,
                              const uint8_t *src, int size, int lines)
 {
     int c, line, pixels, code, ret;
     const uint8_t *ssrc = src;
-    int width = ((s->width * s->bpp) + 7) >> 3;
+    int width           = ((s->width * s->bpp) + 7) >> 3;
+
+    if (s->planar)
+        width /= s->bppcount;
 
     if (size <= 0)
         return AVERROR_INVALIDDATA;
 
-#if CONFIG_ZLIB
     if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE) {
-        uint8_t *src2 = NULL, *zbuf;
-        unsigned long outlen;
-        int i, ret;
-        outlen = width * lines;
-        zbuf = av_malloc(outlen);
-        if (!zbuf)
-            return AVERROR(ENOMEM);
-        if (s->fill_order) {
-            src2 = av_malloc((unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE);
-            if (!src2) {
-                av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
-                av_free(zbuf);
-                return AVERROR(ENOMEM);
-            }
-            for (i = 0; i < size; i++)
-                src2[i] = ff_reverse[src[i]];
-            memset(src2 + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
-            src = src2;
-        }
-        ret = tiff_uncompress(zbuf, &outlen, src, size);
-        if (ret != Z_OK) {
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "Uncompressing failed (%lu of %lu) with error %d\n", outlen,
-                   (unsigned long)width * lines, ret);
-            av_free(src2);
-            av_free(zbuf);
-            return AVERROR_UNKNOWN;
-        }
-        src = zbuf;
-        for (line = 0; line < lines; line++) {
-            if(s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8){
-                horizontal_fill(s->bpp, dst, 1, src, 0, width, 0);
-            }else{
-                memcpy(dst, src, width);
-            }
-            dst += stride;
-            src += width;
-        }
-        av_free(src2);
-        av_free(zbuf);
-        return 0;
-    }
+#if CONFIG_ZLIB
+        return tiff_unpack_zlib(s, dst, stride, src, size, width, lines);
+#else
+        av_log(s->avctx, AV_LOG_ERROR,
+               "zlib support not enabled, "
+               "deflate compression not supported\n");
+        return AVERROR(ENOSYS);
 #endif
+    }
     if (s->compr == TIFF_LZW) {
         if (s->fill_order) {
-            int i;
-            av_fast_padded_malloc(&s->deinvert_buf, &s->deinvert_buf_size, size);
-            if (!s->deinvert_buf)
-                return AVERROR(ENOMEM);
-            for (i = 0; i < size; i++)
-                s->deinvert_buf[i] = ff_reverse[src[i]];
-            src = s->deinvert_buf;
-            ssrc = src;
+            if ((ret = deinvert_buffer(s, src, size)) < 0)
+                return ret;
+            ssrc = src = s->deinvert_buf;
         }
         if (size > 1 && !src[0] && (src[1]&1)) {
             av_log(s->avctx, AV_LOG_ERROR, "Old style LZW is unsupported\n");
@@ -485,45 +415,10 @@
             return ret;
         }
     }
-    if (s->compr == TIFF_CCITT_RLE || s->compr == TIFF_G3
-        || s->compr == TIFF_G4) {
-        int i, ret = 0;
-        uint8_t *src2 = av_malloc((unsigned)size +
-                                  FF_INPUT_BUFFER_PADDING_SIZE);
-
-        if (!src2) {
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "Error allocating temporary buffer\n");
-            return AVERROR(ENOMEM);
-        }
-        if (s->fax_opts & 2) {
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "Uncompressed fax mode is not supported (yet)\n");
-            av_free(src2);
-            return AVERROR_INVALIDDATA;
-        }
-        if (!s->fill_order) {
-            memcpy(src2, src, size);
-        } else {
-            for (i = 0; i < size; i++)
-                src2[i] = ff_reverse[src[i]];
-        }
-        memset(src2 + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
-        switch (s->compr) {
-        case TIFF_CCITT_RLE:
-        case TIFF_G3:
-        case TIFF_G4:
-            ret = ff_ccitt_unpack(s->avctx, src2, size, dst, lines, stride,
-                                  s->compr, s->fax_opts);
-            break;
-        }
-        if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
-            for (line = 0; line < lines; line++) {
-                horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0);
-                dst += stride;
-            }
-        av_free(src2);
-        return ret;
+    if (s->compr == TIFF_CCITT_RLE ||
+        s->compr == TIFF_G3        ||
+        s->compr == TIFF_G4) {
+        return tiff_unpack_fax(s, dst, stride, src, size, width, lines);
     }
     for (line = 0; line < lines; line++) {
         if (src - ssrc > size) {
@@ -550,21 +445,18 @@
                     av_log(s->avctx, AV_LOG_ERROR, "Read went out of bounds\n");
                     return AVERROR_INVALIDDATA;
                 }
-                code = (int8_t) * src++;
+                code = s->fill_order ? (int8_t) ff_reverse[*src++]: (int8_t) *src++;
                 if (code >= 0) {
                     code++;
-                    if (pixels + code > width) {
+                    if (pixels + code > width ||
+                        ssrc + size - src < code) {
                         av_log(s->avctx, AV_LOG_ERROR,
                                "Copy went out of bounds\n");
                         return AVERROR_INVALIDDATA;
                     }
-                    if (ssrc + size - src < code) {
-                        av_log(s->avctx, AV_LOG_ERROR, "Read went out of bounds\n");
-                        return AVERROR_INVALIDDATA;
-                    }
                     horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8),
                                     dst, 1, src, 0, code, pixels);
-                    src += code;
+                    src    += code;
                     pixels += code;
                 } else if (code != -128) { // -127..-1
                     code = (-code) + 1;
@@ -579,6 +471,11 @@
                     pixels += code;
                 }
             }
+            if (s->fill_order) {
+                int i;
+                for (i = 0; i < width; i++)
+                    dst[i] = ff_reverse[dst[i]];
+            }
             break;
         case TIFF_LZW:
             pixels = ff_lzw_decode(s->lzw, dst, width);
@@ -596,12 +493,12 @@
     return 0;
 }
 
-static int init_image(TiffContext *s, AVFrame *frame)
+static int init_image(TiffContext *s, ThreadFrame *frame)
 {
     int i, ret;
     uint32_t *pal;
 
-    switch (s->bpp * 10 + s->bppcount) {
+    switch (s->planar * 1000 + s->bpp * 10 + s->bppcount) {
     case 11:
         if (!s->palette_is_set) {
             s->avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
@@ -625,10 +522,22 @@
         s->avctx->pix_fmt = AV_PIX_FMT_RGBA;
         break;
     case 483:
-        s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGB48LE : AV_PIX_FMT_RGB48BE;
+        s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGB48LE  : AV_PIX_FMT_RGB48BE;
         break;
     case 644:
-        s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGBA64LE : AV_PIX_FMT_RGBA64BE;
+        s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGBA64LE  : AV_PIX_FMT_RGBA64BE;
+        break;
+    case 1243:
+        s->avctx->pix_fmt = AV_PIX_FMT_GBRP;
+        break;
+    case 1324:
+        s->avctx->pix_fmt = AV_PIX_FMT_GBRAP;
+        break;
+    case 1483:
+        s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GBRP16LE : AV_PIX_FMT_GBRP16BE;
+        break;
+    case 1644:
+        s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GBRAP16LE : AV_PIX_FMT_GBRAP16BE;
         break;
     default:
         av_log(s->avctx, AV_LOG_ERROR,
@@ -641,14 +550,14 @@
             return ret;
         avcodec_set_dimensions(s->avctx, s->width, s->height);
     }
-    if ((ret = ff_get_buffer(s->avctx, frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(s->avctx, frame, 0)) < 0)
         return ret;
     if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8) {
         if (s->palette_is_set) {
-            memcpy(frame->data[1], s->palette, sizeof(s->palette));
+            memcpy(frame->f->data[1], s->palette, sizeof(s->palette));
         } else {
             /* make default grayscale pal */
-            pal = (uint32_t *) frame->data[1];
+            pal = (uint32_t *) frame->f->data[1];
             for (i = 0; i < 1<<s->bpp; i++)
                 pal[i] = 0xFFU << 24 | i * 255 / ((1<<s->bpp) - 1) * 0x010101;
         }
@@ -664,42 +573,32 @@
     uint32_t *pal;
     double *dp;
 
-    tag   = tget_short(&s->gb, s->le);
-    type  = tget_short(&s->gb, s->le);
-    count = tget_long(&s->gb, s->le);
-    off   = tget_long(&s->gb, s->le);
-    start = bytestream2_tell(&s->gb);
-
-    if (type == 0 || type >= FF_ARRAY_ELEMS(type_sizes)) {
-        av_log(s->avctx, AV_LOG_DEBUG, "Unknown tiff type (%u) encountered\n",
-               type);
-        return 0;
+    ret = ff_tread_tag(&s->gb, s->le, &tag, &type, &count, &start);
+    if (ret < 0) {
+        goto end;
     }
 
     if (count == 1) {
         switch (type) {
         case TIFF_BYTE:
         case TIFF_SHORT:
-            bytestream2_seek(&s->gb, -4, SEEK_CUR);
-            value = tget(&s->gb, type, s->le);
+            value = ff_tget(&s->gb, type, s->le);
             break;
         case TIFF_LONG:
+            off   = ff_tget_long(&s->gb, s->le);
             value = off;
             break;
         case TIFF_STRING:
             if (count <= 4) {
-                bytestream2_seek(&s->gb, -4, SEEK_CUR);
                 break;
             }
         default:
+            off   = bytestream2_tell(&s->gb);
             value = UINT_MAX;
-            bytestream2_seek(&s->gb, off, SEEK_SET);
         }
     } else {
-        if (count <= 4 && type_sizes[type] * count <= 4) {
-            bytestream2_seek(&s->gb, -4, SEEK_CUR);
-        } else {
-            bytestream2_seek(&s->gb, off, SEEK_SET);
+        if (type_sizes[type] * count > 4) {
+            off   = bytestream2_tell(&s->gb);
         }
     }
 
@@ -732,7 +631,7 @@
                 if (bytestream2_get_bytes_left(&s->gb) < type_sizes[type] * count)
                     return AVERROR_INVALIDDATA;
                 for (i = 0; i < count; i++)
-                    s->bpp += tget(&s->gb, type, s->le);
+                    s->bpp += ff_tget(&s->gb, type, s->le);
                 break;
             default:
                 s->bpp = -1;
@@ -755,7 +654,7 @@
         s->bppcount = value;
         break;
     case TIFF_COMPR:
-        s->compr = value;
+        s->compr     = value;
         s->predictor = 0;
         switch (s->compr) {
         case TIFF_RAW:
@@ -777,8 +676,7 @@
 #endif
         case TIFF_JPEG:
         case TIFF_NEWJPEG:
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "JPEG compression is not supported\n");
+            avpriv_report_missing_feature(s->avctx, "JPEG compression");
             return AVERROR_PATCHWELCOME;
         default:
             av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n",
@@ -798,8 +696,8 @@
         break;
     case TIFF_STRIP_OFFS:
         if (count == 1) {
-            s->strippos = 0;
-            s->stripoff = value;
+            s->strippos  = 0;
+            s->stripoff  = value;
         } else
             s->strippos = off;
         s->strips = count;
@@ -815,8 +713,8 @@
     case TIFF_STRIP_SIZE:
         if (count == 1) {
             s->stripsizesoff = 0;
-            s->stripsize = value;
-            s->strips = 1;
+            s->stripsize  = value;
+            s->strips     = 1;
         } else {
             s->stripsizesoff = off;
         }
@@ -873,17 +771,14 @@
             for (i = 0; i < count / 3; i++) {
                 if (k == 2)
                     pal[i] = 0xFFU << 24;
-                j =  (tget(&s->gb, type, s->le) >> off) << (k * 8);
+                j =  (ff_tget(&s->gb, type, s->le) >> off) << (k * 8);
                 pal[i] |= j;
             }
         }
         s->palette_is_set = 1;
         break;
     case TIFF_PLANAR:
-        if (value == 2) {
-            av_log(s->avctx, AV_LOG_ERROR, "Planar format is not supported\n");
-            return AVERROR_PATCHWELCOME;
-        }
+        s->planar = value == 2;
         break;
     case TIFF_T4OPTIONS:
         if (s->compr == TIFF_G3)
@@ -896,7 +791,7 @@
 #define ADD_METADATA(count, name, sep)\
     if ((ret = add_metadata(count, type, name, sep, s, frame)) < 0) {\
         av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");\
-        return ret;\
+        goto end;\
     }
     case TIFF_MODEL_PIXEL_SCALE:
         ADD_METADATA(count, "ModelPixelScaleTag", NULL);
@@ -910,7 +805,7 @@
     case TIFF_GEO_KEY_DIRECTORY:
         ADD_METADATA(1, "GeoTIFF_Version", NULL);
         ADD_METADATA(2, "GeoTIFF_Key_Revision", ".");
-        s->geotag_count   = tget_short(&s->gb, s->le);
+        s->geotag_count   = ff_tget_short(&s->gb, s->le);
         if (s->geotag_count > count / 4 - 1) {
             s->geotag_count = count / 4 - 1;
             av_log(s->avctx, AV_LOG_WARNING, "GeoTIFF key directory buffer shorter than specified\n");
@@ -923,17 +818,17 @@
         if (!s->geotags) {
             av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
             s->geotag_count = 0;
-            return AVERROR(ENOMEM);
+            goto end;
         }
         for (i = 0; i < s->geotag_count; i++) {
-            s->geotags[i].key    = tget_short(&s->gb, s->le);
-            s->geotags[i].type   = tget_short(&s->gb, s->le);
-            s->geotags[i].count  = tget_short(&s->gb, s->le);
+            s->geotags[i].key    = ff_tget_short(&s->gb, s->le);
+            s->geotags[i].type   = ff_tget_short(&s->gb, s->le);
+            s->geotags[i].count  = ff_tget_short(&s->gb, s->le);
 
             if (!s->geotags[i].type)
-                s->geotags[i].val  = get_geokey_val(s->geotags[i].key, tget_short(&s->gb, s->le));
+                s->geotags[i].val  = get_geokey_val(s->geotags[i].key, ff_tget_short(&s->gb, s->le));
             else
-                s->geotags[i].offset = tget_short(&s->gb, s->le);
+                s->geotags[i].offset = ff_tget_short(&s->gb, s->le);
         }
         break;
     case TIFF_GEO_DOUBLE_PARAMS:
@@ -944,10 +839,10 @@
         dp = av_malloc(count * sizeof(double));
         if (!dp) {
             av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
-            return AVERROR(ENOMEM);
+            goto end;
         }
         for (i = 0; i < count; i++)
-            dp[i] = tget_double(&s->gb, s->le);
+            dp[i] = ff_tget_double(&s->gb, s->le);
         for (i = 0; i < s->geotag_count; i++) {
             if (s->geotags[i].type == TIFF_GEO_DOUBLE_PARAMS) {
                 if (s->geotags[i].count == 0
@@ -1025,9 +920,14 @@
         ADD_METADATA(count, "software", NULL);
         break;
     default:
-        av_log(s->avctx, AV_LOG_DEBUG, "Unknown or unsupported tag %d/0X%0X\n",
-               tag, tag);
+        if (s->avctx->err_recognition & AV_EF_EXPLODE) {
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "Unknown or unsupported tag %d/0X%0X\n",
+                   tag, tag);
+            return AVERROR_INVALIDDATA;
+        }
     }
+end:
     bytestream2_seek(&s->gb, start, SEEK_SET);
     return 0;
 }
@@ -1037,10 +937,10 @@
 {
     TiffContext *const s = avctx->priv_data;
     AVFrame *const p = data;
+    ThreadFrame frame = { .f = data };
     unsigned off;
-    int id, le, ret;
-    int i, j, entries;
-    int stride;
+    int le, ret, plane, planes;
+    int i, j, entries, stride;
     unsigned soff, ssize;
     uint8_t *dst;
     GetByteContext stripsizes;
@@ -1048,43 +948,27 @@
 
     bytestream2_init(&s->gb, avpkt->data, avpkt->size);
 
-    //parse image header
-    if (avpkt->size < 8)
-        return AVERROR_INVALIDDATA;
-    id = bytestream2_get_le16u(&s->gb);
-    if (id == 0x4949)
-        le = 1;
-    else if (id == 0x4D4D)
-        le = 0;
-    else {
-        av_log(avctx, AV_LOG_ERROR, "TIFF header not found\n");
-        return AVERROR_INVALIDDATA;
-    }
-    s->le = le;
-    // TIFF_BPP is not a required tag and defaults to 1
-    s->bppcount = s->bpp = 1;
-    s->invert = 0;
-    s->compr = TIFF_RAW;
-    s->fill_order = 0;
-    free_geotags(s);
-
-    // As TIFF 6.0 specification puts it "An arbitrary but carefully chosen number
-    // that further identifies the file as a TIFF file"
-    if (tget_short(&s->gb, le) != 42) {
-        av_log(avctx, AV_LOG_ERROR,
-               "The answer to life, universe and everything is not correct!\n");
-        return AVERROR_INVALIDDATA;
-    }
-    // Reset these offsets so we can tell if they were set this frame
-    s->stripsizesoff = s->strippos = 0;
-    /* parse image file directory */
-    off = tget_long(&s->gb, le);
-    if (off >= UINT_MAX - 14 || avpkt->size < off + 14) {
+    // parse image header
+    if ((ret = ff_tdecode_header(&s->gb, &le, &off))) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid TIFF header\n");
+        return ret;
+    } else if (off >= UINT_MAX - 14 || avpkt->size < off + 14) {
         av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n");
         return AVERROR_INVALIDDATA;
     }
+    s->le         = le;
+    // TIFF_BPP is not a required tag and defaults to 1
+    s->bppcount   = s->bpp = 1;
+    s->invert     = 0;
+    s->compr      = TIFF_RAW;
+    s->fill_order = 0;
+    free_geotags(s);
+
+    // Reset these offsets so we can tell if they were set this frame
+    s->stripsizesoff = s->strippos = 0;
+    /* parse image file directory */
     bytestream2_seek(&s->gb, off, SEEK_SET);
-    entries = tget_short(&s->gb, le);
+    entries = ff_tget_short(&s->gb, le);
     if (bytestream2_get_bytes_left(&s->gb) < entries * 12)
         return AVERROR_INVALIDDATA;
     for (i = 0; i < entries; i++) {
@@ -1114,15 +998,13 @@
         return AVERROR_INVALIDDATA;
     }
     /* now we have the data and may start decoding */
-    if ((ret = init_image(s, p)) < 0)
+    if ((ret = init_image(s, &frame)) < 0)
         return ret;
 
     if (s->strips == 1 && !s->stripsize) {
         av_log(avctx, AV_LOG_WARNING, "Image data size missing\n");
         s->stripsize = avpkt->size - s->stripoff;
     }
-    stride = p->linesize[0];
-    dst = p->data[0];
 
     if (s->stripsizesoff) {
         if (s->stripsizesoff >= (unsigned)avpkt->size)
@@ -1140,14 +1022,18 @@
         return AVERROR_INVALIDDATA;
     }
 
+    planes = s->planar ? s->bppcount : 1;
+    for (plane = 0; plane < planes; plane++) {
+        stride = p->linesize[plane];
+        dst    = p->data[plane];
     for (i = 0; i < s->height; i += s->rps) {
         if (s->stripsizesoff)
-            ssize = tget(&stripsizes, s->sstype, s->le);
+            ssize = ff_tget(&stripsizes, s->sstype, s->le);
         else
             ssize = s->stripsize;
 
         if (s->strippos)
-            soff = tget(&stripdata, s->sot, s->le);
+            soff = ff_tget(&stripdata, s->sot, s->le);
         else
             soff = s->stripoff;
 
@@ -1155,24 +1041,33 @@
             av_log(avctx, AV_LOG_ERROR, "Invalid strip size/offset\n");
             return AVERROR_INVALIDDATA;
         }
-        if (tiff_unpack_strip(s, dst, stride, avpkt->data + soff, ssize,
-                              FFMIN(s->rps, s->height - i)) < 0)
+        if ((ret = tiff_unpack_strip(s, dst, stride, avpkt->data + soff, ssize,
+                                     FFMIN(s->rps, s->height - i))) < 0) {
+            if (avctx->err_recognition & AV_EF_EXPLODE)
+                return ret;
             break;
+        }
         dst += s->rps * stride;
     }
     if (s->predictor == 2) {
-        dst = p->data[0];
-        soff = s->bpp >> 3;
+        dst   = p->data[plane];
+        soff  = s->bpp >> 3;
+        if (s->planar)
+            soff  = FFMAX(soff / s->bppcount, 1);
         ssize = s->width * soff;
         if (s->avctx->pix_fmt == AV_PIX_FMT_RGB48LE ||
-            s->avctx->pix_fmt == AV_PIX_FMT_RGBA64LE) {
+            s->avctx->pix_fmt == AV_PIX_FMT_RGBA64LE ||
+            s->avctx->pix_fmt == AV_PIX_FMT_GBRP16LE ||
+            s->avctx->pix_fmt == AV_PIX_FMT_GBRAP16LE) {
             for (i = 0; i < s->height; i++) {
                 for (j = soff; j < ssize; j += 2)
                     AV_WL16(dst + j, AV_RL16(dst + j) + AV_RL16(dst + j - soff));
                 dst += stride;
             }
         } else if (s->avctx->pix_fmt == AV_PIX_FMT_RGB48BE ||
-                   s->avctx->pix_fmt == AV_PIX_FMT_RGBA64BE) {
+                   s->avctx->pix_fmt == AV_PIX_FMT_RGBA64BE ||
+                   s->avctx->pix_fmt == AV_PIX_FMT_GBRP16BE ||
+                   s->avctx->pix_fmt == AV_PIX_FMT_GBRAP16BE) {
             for (i = 0; i < s->height; i++) {
                 for (j = soff; j < ssize; j += 2)
                     AV_WB16(dst + j, AV_RB16(dst + j) + AV_RB16(dst + j - soff));
@@ -1188,13 +1083,22 @@
     }
 
     if (s->invert) {
-        dst = p->data[0];
+        dst = p->data[plane];
         for (i = 0; i < s->height; i++) {
-            for (j = 0; j < p->linesize[0]; j++)
+            for (j = 0; j < p->linesize[plane]; j++)
                 dst[j] = (s->avctx->pix_fmt == AV_PIX_FMT_PAL8 ? (1<<s->bpp) - 1 : 255) - dst[j];
-            dst += p->linesize[0];
+            dst += p->linesize[plane];
         }
     }
+    }
+
+    if (s->planar && s->bppcount > 2) {
+        FFSWAP(uint8_t*, p->data[0],     p->data[2]);
+        FFSWAP(int,      p->linesize[0], p->linesize[2]);
+        FFSWAP(uint8_t*, p->data[0],     p->data[1]);
+        FFSWAP(int,      p->linesize[0], p->linesize[1]);
+    }
+
     *got_frame = 1;
 
     return avpkt->size;
@@ -1204,9 +1108,9 @@
 {
     TiffContext *s = avctx->priv_data;
 
-    s->width = 0;
+    s->width  = 0;
     s->height = 0;
-    s->avctx = avctx;
+    s->avctx  = avctx;
     ff_lzw_decode_open(&s->lzw);
     ff_ccitt_unpack_init();
 
@@ -1226,12 +1130,13 @@
 
 AVCodec ff_tiff_decoder = {
     .name           = "tiff",
+    .long_name      = NULL_IF_CONFIG_SMALL("TIFF image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TIFF,
     .priv_data_size = sizeof(TiffContext),
     .init           = tiff_init,
     .close          = tiff_end,
     .decode         = decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("TIFF image"),
+    .init_thread_copy = ONLY_IF_THREADS_ENABLED(tiff_init),
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
 };
diff --git a/libavcodec/tiff.h b/libavcodec/tiff.h
index 6d760f0..ae189b6 100644
--- a/libavcodec/tiff.h
+++ b/libavcodec/tiff.h
@@ -31,60 +31,61 @@
 #define AVCODEC_TIFF_H
 
 #include <stdint.h>
+#include "tiff_common.h"
 
 /** abridged list of TIFF tags */
-enum TiffTags{
-    TIFF_SUBFILE = 0xfe,
-    TIFF_WIDTH = 0x100,
+enum TiffTags {
+    TIFF_SUBFILE            = 0xfe,
+    TIFF_WIDTH              = 0x100,
     TIFF_HEIGHT,
     TIFF_BPP,
     TIFF_COMPR,
-    TIFF_INVERT = 0x106,
-    TIFF_FILL_ORDER = 0x10A,
-    TIFF_DOCUMENT_NAME = 0x10D,
-    TIFF_IMAGE_DESCRIPTION = 0x10E,
-    TIFF_MAKE = 0x10F,
-    TIFF_MODEL = 0x110,
-    TIFF_STRIP_OFFS = 0x111,
-    TIFF_SAMPLES_PER_PIXEL = 0x115,
-    TIFF_ROWSPERSTRIP = 0x116,
+    TIFF_INVERT             = 0x106,
+    TIFF_FILL_ORDER         = 0x10A,
+    TIFF_DOCUMENT_NAME      = 0x10D,
+    TIFF_IMAGE_DESCRIPTION  = 0x10E,
+    TIFF_MAKE               = 0x10F,
+    TIFF_MODEL              = 0x110,
+    TIFF_STRIP_OFFS         = 0x111,
+    TIFF_SAMPLES_PER_PIXEL  = 0x115,
+    TIFF_ROWSPERSTRIP       = 0x116,
     TIFF_STRIP_SIZE,
-    TIFF_XRES = 0x11A,
-    TIFF_YRES = 0x11B,
-    TIFF_PLANAR = 0x11C,
-    TIFF_PAGE_NAME = 0x11D,
-    TIFF_XPOS = 0x11E,
-    TIFF_YPOS = 0x11F,
-    TIFF_T4OPTIONS = 0x124,
+    TIFF_XRES               = 0x11A,
+    TIFF_YRES               = 0x11B,
+    TIFF_PLANAR             = 0x11C,
+    TIFF_PAGE_NAME          = 0x11D,
+    TIFF_XPOS               = 0x11E,
+    TIFF_YPOS               = 0x11F,
+    TIFF_T4OPTIONS          = 0x124,
     TIFF_T6OPTIONS,
-    TIFF_RES_UNIT = 0x128,
-    TIFF_PAGE_NUMBER = 0x129,
-    TIFF_SOFTWARE_NAME = 0x131,
-    TIFF_DATE = 0x132,
-    TIFF_ARTIST = 0x13B,
-    TIFF_HOST_COMPUTER = 0x13C,
-    TIFF_PREDICTOR = 0x13D,
-    TIFF_PAL = 0x140,
-    TIFF_TILE_WIDTH = 0x142,
-    TIFF_TILE_LENGTH = 0x143,
-    TIFF_TILE_OFFSETS = 0x144,
-    TIFF_TILE_BYTE_COUNTS = 0x145,
-    TIFF_EXTRASAMPLES = 0x152,
+    TIFF_RES_UNIT           = 0x128,
+    TIFF_PAGE_NUMBER        = 0x129,
+    TIFF_SOFTWARE_NAME      = 0x131,
+    TIFF_DATE               = 0x132,
+    TIFF_ARTIST             = 0x13B,
+    TIFF_HOST_COMPUTER      = 0x13C,
+    TIFF_PREDICTOR          = 0x13D,
+    TIFF_PAL                = 0x140,
+    TIFF_TILE_WIDTH         = 0x142,
+    TIFF_TILE_LENGTH        = 0x143,
+    TIFF_TILE_OFFSETS       = 0x144,
+    TIFF_TILE_BYTE_COUNTS   = 0x145,
+    TIFF_EXTRASAMPLES       = 0x152,
     TIFF_YCBCR_COEFFICIENTS = 0x211,
-    TIFF_YCBCR_SUBSAMPLING = 0x212,
-    TIFF_YCBCR_POSITIONING = 0x213,
-    TIFF_REFERENCE_BW = 0x214,
-    TIFF_COPYRIGHT = 0x8298,
-    TIFF_MODEL_TIEPOINT = 0x8482,
-    TIFF_MODEL_PIXEL_SCALE = 0x830E,
-    TIFF_MODEL_TRANSFORMATION = 0x8480,
-    TIFF_GEO_KEY_DIRECTORY = 0x87AF,
-    TIFF_GEO_DOUBLE_PARAMS = 0x87B0,
-    TIFF_GEO_ASCII_PARAMS = 0x87B1
+    TIFF_YCBCR_SUBSAMPLING  = 0x212,
+    TIFF_YCBCR_POSITIONING  = 0x213,
+    TIFF_REFERENCE_BW       = 0x214,
+    TIFF_COPYRIGHT          = 0x8298,
+    TIFF_MODEL_TIEPOINT     = 0x8482,
+    TIFF_MODEL_PIXEL_SCALE  = 0x830E,
+    TIFF_MODEL_TRANSFORMATION= 0x8480,
+    TIFF_GEO_KEY_DIRECTORY  = 0x87AF,
+    TIFF_GEO_DOUBLE_PARAMS  = 0x87B0,
+    TIFF_GEO_ASCII_PARAMS   = 0x87B1
 };
 
 /** list of TIFF compression types */
-enum TiffCompr{
+enum TiffCompr {
     TIFF_RAW = 1,
     TIFF_CCITT_RLE,
     TIFF_G3,
@@ -94,23 +95,7 @@
     TIFF_NEWJPEG,
     TIFF_ADOBE_DEFLATE,
     TIFF_PACKBITS = 0x8005,
-    TIFF_DEFLATE = 0x80B2
-};
-
-enum TiffTypes{
-    TIFF_BYTE = 1,
-    TIFF_STRING,
-    TIFF_SHORT,
-    TIFF_LONG,
-    TIFF_RATIONAL,
-    TIFF_SBYTE,
-    TIFF_UNDEFINED,
-    TIFF_SSHORT,
-    TIFF_SLONG,
-    TIFF_SRATIONAL,
-    TIFF_FLOAT,
-    TIFF_DOUBLE,
-    TIFF_IFD
+    TIFF_DEFLATE  = 0x80B2
 };
 
 enum TiffGeoTagKey {
@@ -167,11 +152,6 @@
     GEOTIFF_STRING = 34737
 };
 
-/** sizes of various TIFF field types (string size = 100)*/
-static const uint8_t type_sizes[14] = {
-    0, 1, 100, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4
-};
-
 typedef struct TiffGeoTag {
     enum TiffGeoTagKey key;
     enum TiffTags type;
diff --git a/libavcodec/tiff_common.c b/libavcodec/tiff_common.c
new file mode 100644
index 0000000..b7bd587
--- /dev/null
+++ b/libavcodec/tiff_common.c
@@ -0,0 +1,282 @@
+/*
+ * TIFF Common Routines
+ * Copyright (c) 2013 Thilo Borgmann <thilo.borgmann _at_ mail.de>
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * TIFF Common Routines
+ * @author Thilo Borgmann <thilo.borgmann _at_ mail.de>
+ */
+
+#include "tiff_common.h"
+
+
+int ff_tis_ifd(unsigned tag)
+{
+    int i;
+    for (i = 0; i < FF_ARRAY_ELEMS(ifd_tags); i++) {
+        if (ifd_tags[i] == tag) {
+            return i + 1;
+        }
+    }
+    return 0;
+}
+
+
+unsigned ff_tget_short(GetByteContext *gb, int le)
+{
+    unsigned v = le ? bytestream2_get_le16(gb) : bytestream2_get_be16(gb);
+    return v;
+}
+
+
+unsigned ff_tget_long(GetByteContext *gb, int le)
+{
+    unsigned v = le ? bytestream2_get_le32(gb) : bytestream2_get_be32(gb);
+    return v;
+}
+
+
+double ff_tget_double(GetByteContext *gb, int le)
+{
+    av_alias64 i = { .u64 = le ? bytestream2_get_le64(gb) : bytestream2_get_be64(gb)};
+    return i.f64;
+}
+
+
+unsigned ff_tget(GetByteContext *gb, int type, int le)
+{
+    switch (type) {
+    case TIFF_BYTE:
+        return bytestream2_get_byte(gb);
+    case TIFF_SHORT:
+        return ff_tget_short(gb, le);
+    case TIFF_LONG:
+        return ff_tget_long(gb, le);
+    default:
+        return UINT_MAX;
+    }
+}
+
+
+int ff_tadd_rational_metadata(int count, const char *name, const char *sep,
+                              GetByteContext *gb, int le, AVDictionary **metadata)
+{
+    AVBPrint bp;
+    char *ap;
+    int32_t nom, denom;
+    int i;
+
+    if (count >= INT_MAX / sizeof(int64_t) || count <= 0)
+        return AVERROR_INVALIDDATA;
+    if (bytestream2_get_bytes_left(gb) < count * sizeof(int64_t))
+        return AVERROR_INVALIDDATA;
+    if (!sep) sep = ", ";
+
+    av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_AUTOMATIC);
+
+    for (i = 0; i < count; i++) {
+        nom   = ff_tget_long(gb, le);
+        denom = ff_tget_long(gb, le);
+        av_bprintf(&bp, "%s%i:%i", (i ? sep : ""), nom, denom);
+    }
+
+    if ((i = av_bprint_finalize(&bp, &ap))) {
+        return i;
+    }
+    if (!ap) {
+        return AVERROR(ENOMEM);
+    }
+
+    av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
+
+    return 0;
+}
+
+
+int ff_tadd_long_metadata(int count, const char *name, const char *sep,
+                          GetByteContext *gb, int le, AVDictionary **metadata)
+{
+    AVBPrint bp;
+    char *ap;
+    int i;
+
+    if (count >= INT_MAX / sizeof(int32_t) || count <= 0)
+        return AVERROR_INVALIDDATA;
+    if (bytestream2_get_bytes_left(gb) < count * sizeof(int32_t))
+        return AVERROR_INVALIDDATA;
+    if (!sep) sep = ", ";
+
+    av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_AUTOMATIC);
+
+    for (i = 0; i < count; i++) {
+        av_bprintf(&bp, "%s%i", (i ? sep : ""), ff_tget_long(gb, le));
+    }
+
+    if ((i = av_bprint_finalize(&bp, &ap))) {
+        return i;
+    }
+    if (!ap) {
+        return AVERROR(ENOMEM);
+    }
+
+    av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
+
+    return 0;
+}
+
+
+int ff_tadd_doubles_metadata(int count, const char *name, const char *sep,
+                             GetByteContext *gb, int le, AVDictionary **metadata)
+{
+    AVBPrint bp;
+    char *ap;
+    int i;
+
+    if (count >= INT_MAX / sizeof(int64_t) || count <= 0)
+        return AVERROR_INVALIDDATA;
+    if (bytestream2_get_bytes_left(gb) < count * sizeof(int64_t))
+        return AVERROR_INVALIDDATA;
+    if (!sep) sep = ", ";
+
+    av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_AUTOMATIC);
+
+    for (i = 0; i < count; i++) {
+        av_bprintf(&bp, "%s%f", (i ? sep : ""), ff_tget_double(gb, le));
+    }
+
+    if ((i = av_bprint_finalize(&bp, &ap))) {
+        return i;
+    }
+    if (!ap) {
+        return AVERROR(ENOMEM);
+    }
+
+    av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
+
+    return 0;
+}
+
+
+int ff_tadd_shorts_metadata(int count, const char *name, const char *sep,
+                            GetByteContext *gb, int le, AVDictionary **metadata)
+{
+    AVBPrint bp;
+    char *ap;
+    int i;
+
+    if (count >= INT_MAX / sizeof(int16_t) || count <= 0)
+        return AVERROR_INVALIDDATA;
+    if (bytestream2_get_bytes_left(gb) < count * sizeof(int16_t))
+        return AVERROR_INVALIDDATA;
+    if (!sep) sep = ", ";
+
+    av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_AUTOMATIC);
+
+    for (i = 0; i < count; i++) {
+        av_bprintf(&bp, "%s%i", (i ? sep : ""), ff_tget_short(gb, le));
+    }
+
+    if ((i = av_bprint_finalize(&bp, &ap))) {
+        return i;
+    }
+    if (!ap) {
+        return AVERROR(ENOMEM);
+    }
+
+    av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
+
+    return 0;
+}
+
+
+int ff_tadd_string_metadata(int count, const char *name,
+                            GetByteContext *gb, int le, AVDictionary **metadata)
+{
+    char *value;
+
+    if (bytestream2_get_bytes_left(gb) < count || count < 0)
+        return AVERROR_INVALIDDATA;
+
+    value = av_malloc(count + 1);
+    if (!value)
+        return AVERROR(ENOMEM);
+
+    bytestream2_get_bufferu(gb, value, count);
+    value[count] = 0;
+
+    av_dict_set(metadata, name, value, AV_DICT_DONT_STRDUP_VAL);
+    return 0;
+}
+
+
+int ff_tdecode_header(GetByteContext *gb, int *le, int *ifd_offset)
+{
+    if (bytestream2_get_bytes_left(gb) < 8) {
+        return AVERROR_INVALIDDATA;
+    }
+
+    *le = bytestream2_get_le16u(gb);
+    if (*le == AV_RB16("II")) {
+        *le = 1;
+    } else if (*le == AV_RB16("MM")) {
+        *le = 0;
+    } else {
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (ff_tget_short(gb, *le) != 42) {
+        return AVERROR_INVALIDDATA;
+    }
+
+    *ifd_offset = ff_tget_long(gb, *le);
+
+    return 0;
+}
+
+
+int ff_tread_tag(GetByteContext *gb, int le, unsigned *tag, unsigned *type,
+                 unsigned *count, int *next)
+{
+    int ifd_tag;
+    int valid_type;
+
+    *tag    = ff_tget_short(gb, le);
+    *type   = ff_tget_short(gb, le);
+    *count  = ff_tget_long (gb, le);
+
+    ifd_tag    = ff_tis_ifd(*tag);
+    valid_type = *type != 0 && *type < FF_ARRAY_ELEMS(type_sizes);
+
+    *next = bytestream2_tell(gb) + 4;
+
+    // check for valid type
+    if (!valid_type) {
+        return AVERROR_INVALIDDATA;
+    }
+
+    // seek to offset if this is an IFD-tag or
+    // if count values do not fit into the offset value
+    if (ifd_tag || (*count > 4 || !(type_sizes[*type] * (*count) <= 4 || *type == TIFF_STRING))) {
+        bytestream2_seek(gb, ff_tget_long (gb, le), SEEK_SET);
+    }
+
+    return 0;
+}
diff --git a/libavcodec/tiff_common.h b/libavcodec/tiff_common.h
new file mode 100644
index 0000000..2e08caf
--- /dev/null
+++ b/libavcodec/tiff_common.h
@@ -0,0 +1,146 @@
+/*
+ * TIFF Common Routines
+ * Copyright (c) 2013 Thilo Borgmann <thilo.borgmann _at_ mail.de>
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * TIFF Common Routines
+ * @author Thilo Borgmann <thilo.borgmann _at_ mail.de>
+ */
+
+#ifndef AVCODEC_TIFF_COMMON_H
+#define AVCODEC_TIFF_COMMON_H
+
+#include "avcodec.h"
+#include "tiff.h"
+#include "bytestream.h"
+#include "libavutil/bprint.h"
+
+/** data type identifiers for TIFF tags */
+enum TiffTypes {
+    TIFF_BYTE = 1,
+    TIFF_STRING,
+    TIFF_SHORT,
+    TIFF_LONG,
+    TIFF_RATIONAL,
+    TIFF_SBYTE,
+    TIFF_UNDEFINED,
+    TIFF_SSHORT,
+    TIFF_SLONG,
+    TIFF_SRATIONAL,
+    TIFF_FLOAT,
+    TIFF_DOUBLE,
+    TIFF_IFD
+};
+
+/** sizes of various TIFF field types (string size = 100)*/
+static const uint8_t type_sizes[14] = {
+    0, 1, 100, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4
+};
+
+static const uint16_t ifd_tags[] = {
+    0x8769, // EXIF IFD
+    0x8825, // GPS IFD
+    0xA005  // Interoperability IFD
+};
+
+
+/** Returns a value > 0 if the tag is a known IFD-tag.
+ *  The return value is the array index + 1 within ifd_tags[].
+ */
+int ff_tis_ifd(unsigned tag);
+
+/** Reads a short from the bytestream using given endianess. */
+unsigned ff_tget_short(GetByteContext *gb, int le);
+
+/** Reads a long from the bytestream using given endianess. */
+unsigned ff_tget_long(GetByteContext *gb, int le);
+
+/** Reads a double from the bytestream using given endianess. */
+double   ff_tget_double(GetByteContext *gb, int le);
+
+/** Reads a byte from the bytestream using given endianess. */
+unsigned ff_tget(GetByteContext *gb, int type, int le);
+
+/** Returns an allocated string containing count
+ *  rational values using the given seperator.
+ */
+char *ff_trationals2str(int *rp, int count, const char *sep);
+
+/** Returns an allocated string containing count
+ *  long values using the given seperator.
+ */
+char *ff_tlongs2str(int32_t *lp, int count, const char *sep);
+
+/** Returns an allocated string containing count
+ *  double values using the given seperator.
+ */
+char *ff_tdoubles2str(double *dp, int count, const char *sep);
+
+/** Returns an allocated string containing count
+ *  short values using the given seperator.
+ */
+char *ff_tshorts2str(int16_t *sp, int count, const char *sep);
+
+/** Adds count rationals converted to a string
+ *  into the metadata dictionary.
+ */
+int ff_tadd_rational_metadata(int count, const char *name, const char *sep,
+                              GetByteContext *gb, int le, AVDictionary **metadata);
+
+/** Adds count longs converted to a string
+ *  into the metadata dictionary.
+ */
+int ff_tadd_long_metadata(int count, const char *name, const char *sep,
+                          GetByteContext *gb, int le, AVDictionary **metadata);
+
+/** Adds count doubles converted to a string
+ *  into the metadata dictionary.
+ */
+int ff_tadd_doubles_metadata(int count, const char *name, const char *sep,
+                             GetByteContext *gb, int le, AVDictionary **metadata);
+
+/** Adds count shorts converted to a string
+ *  into the metadata dictionary.
+ */
+int ff_tadd_shorts_metadata(int count, const char *name, const char *sep,
+                            GetByteContext *gb, int le, AVDictionary **metadata);
+
+/** Adds a string of count characters
+ *  into the metadata dictionary.
+ */
+int ff_tadd_string_metadata(int count, const char *name,
+                            GetByteContext *gb, int le, AVDictionary **metadata);
+
+/** Decodes a TIFF header from the input bytestream
+ *  and sets the endianess in *le and the offset to
+ *  the first IFD in *ifd_offset accordingly.
+ */
+int ff_tdecode_header(GetByteContext *gb, int *le, int *ifd_offset);
+
+/** Reads the first 3 fields of a TIFF tag, which are
+ *  the tag id, the tag type and the count of values for that tag.
+ *  Afterwards the bytestream is located at the first value to read and
+ *  *next holds the bytestream offset of the following tag.
+ */
+int ff_tread_tag(GetByteContext *gb, int le, unsigned *tag, unsigned *type,
+                 unsigned *count, int *next);
+
+#endif /* AVCODEC_TIFF_COMMON_H */
diff --git a/libavcodec/tiffenc.c b/libavcodec/tiffenc.c
index 61294b9..f5d04ea 100644
--- a/libavcodec/tiffenc.c
+++ b/libavcodec/tiffenc.c
@@ -25,22 +25,22 @@
  * @author Bartlomiej Wolowiec
  */
 
-#include "libavutil/imgutils.h"
-#include "libavutil/log.h"
-#include "libavutil/opt.h"
-#include "libavutil/pixdesc.h"
-
-#include "avcodec.h"
 #include "config.h"
 #if CONFIG_ZLIB
 #include <zlib.h>
 #endif
+
+#include "libavutil/imgutils.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "avcodec.h"
 #include "bytestream.h"
 #include "internal.h"
-#include "tiff.h"
-#include "rle.h"
 #include "lzw.h"
 #include "put_bits.h"
+#include "rle.h"
+#include "tiff.h"
 
 #define TIFF_MAX_ENTRY 32
 
@@ -50,35 +50,34 @@
 };
 
 typedef struct TiffEncoderContext {
-    AVClass *class;                     ///< for private options
+    AVClass *class;                         ///< for private options
     AVCodecContext *avctx;
     AVFrame picture;
 
-    int width;                          ///< picture width
-    int height;                         ///< picture height
-    unsigned int bpp;                   ///< bits per pixel
-    int compr;                          ///< compression level
-    int bpp_tab_size;                   ///< bpp_tab size
-    int photometric_interpretation;     ///< photometric interpretation
-    int strips;                         ///< number of strips
+    int width;                              ///< picture width
+    int height;                             ///< picture height
+    unsigned int bpp;                       ///< bits per pixel
+    int compr;                              ///< compression level
+    int bpp_tab_size;                       ///< bpp_tab size
+    int photometric_interpretation;         ///< photometric interpretation
+    int strips;                             ///< number of strips
     uint32_t *strip_sizes;
     unsigned int strip_sizes_size;
     uint32_t *strip_offsets;
     unsigned int strip_offsets_size;
     uint8_t *yuv_line;
     unsigned int yuv_line_size;
-    int rps;                            ///< row per strip
-    uint8_t entries[TIFF_MAX_ENTRY*12]; ///< entires in header
-    int num_entries;                    ///< number of entires
-    uint8_t **buf;                      ///< actual position in buffer
-    uint8_t *buf_start;                 ///< pointer to first byte in buffer
-    int buf_size;                       ///< buffer size
-    uint16_t subsampling[2];            ///< YUV subsampling factors
-    struct LZWEncodeState *lzws;        ///< LZW Encode state
-    uint32_t dpi;                       ///< image resolution in DPI
+    int rps;                                ///< row per strip
+    uint8_t entries[TIFF_MAX_ENTRY * 12];   ///< entries in header
+    int num_entries;                        ///< number of entries
+    uint8_t **buf;                          ///< actual position in buffer
+    uint8_t *buf_start;                     ///< pointer to first byte in buffer
+    int buf_size;                           ///< buffer size
+    uint16_t subsampling[2];                ///< YUV subsampling factors
+    struct LZWEncodeState *lzws;            ///< LZW encode state
+    uint32_t dpi;                           ///< image resolution in DPI
 } TiffEncoderContext;
 
-
 /**
  * Check free space in buffer.
  *
@@ -86,7 +85,7 @@
  * @param need Needed bytes
  * @return 0 - ok, 1 - no free space
  */
-static inline int check_size(TiffEncoderContext * s, uint64_t need)
+static inline int check_size(TiffEncoderContext *s, uint64_t need)
 {
     if (s->buf_size < *s->buf - s->buf_start + need) {
         *s->buf = s->buf_start + s->buf_size + 1;
@@ -105,12 +104,12 @@
  * @param type type of values
  * @param flip = 0 - normal copy, >0 - flip
  */
-static void tnput(uint8_t ** p, int n, const uint8_t * val, enum TiffTypes type,
+static void tnput(uint8_t **p, int n, const uint8_t *val, enum TiffTypes type,
                   int flip)
 {
     int i;
 #if HAVE_BIGENDIAN
-    flip ^= ((int[]) {0, 0, 0, 1, 3, 3})[type];
+    flip ^= ((int[]) { 0, 0, 0, 1, 3, 3 })[type];
 #endif
     for (i = 0; i < n * type_sizes2[type]; i++)
         *(*p)++ = val[i ^ flip];
@@ -125,9 +124,8 @@
  * @param count the number of values
  * @param ptr_val pointer to values
  */
-static void add_entry(TiffEncoderContext * s,
-                      enum TiffTags tag, enum TiffTypes type, int count,
-                      const void *ptr_val)
+static void add_entry(TiffEncoderContext *s, enum TiffTags tag,
+                      enum TiffTypes type, int count, const void *ptr_val)
 {
     uint8_t *entries_ptr = s->entries + 12 * s->num_entries;
 
@@ -148,10 +146,11 @@
     s->num_entries++;
 }
 
-static void add_entry1(TiffEncoderContext * s,
-                       enum TiffTags tag, enum TiffTypes type, int val){
-    uint16_t w = val;
-    uint32_t dw= val;
+static void add_entry1(TiffEncoderContext *s,
+                       enum TiffTags tag, enum TiffTypes type, int val)
+{
+    uint16_t w  = val;
+    uint32_t dw = val;
     add_entry(s, tag, type, 1, type == TIFF_SHORT ? (void *)&w : (void *)&dw);
 }
 
@@ -165,22 +164,21 @@
  * @param compr compression method
  * @return number of output bytes. If an output error is encountered, -1 is returned
  */
-static int encode_strip(TiffEncoderContext * s, const int8_t * src,
-                        uint8_t * dst, int n, int compr)
+static int encode_strip(TiffEncoderContext *s, const int8_t *src,
+                        uint8_t *dst, int n, int compr)
 {
-
     switch (compr) {
 #if CONFIG_ZLIB
     case TIFF_DEFLATE:
     case TIFF_ADOBE_DEFLATE:
-        {
-            unsigned long zlen = s->buf_size - (*s->buf - s->buf_start);
-            if (compress(dst, &zlen, src, n) != Z_OK) {
-                av_log(s->avctx, AV_LOG_ERROR, "Compressing failed\n");
-                return -1;
-            }
-            return zlen;
+    {
+        unsigned long zlen = s->buf_size - (*s->buf - s->buf_start);
+        if (compress(dst, &zlen, src, n) != Z_OK) {
+            av_log(s->avctx, AV_LOG_ERROR, "Compressing failed\n");
+            return -1;
         }
+        return zlen;
+    }
 #endif
     case TIFF_RAW:
         if (check_size(s, n))
@@ -188,7 +186,8 @@
         memcpy(dst, src, n);
         return n;
     case TIFF_PACKBITS:
-        return ff_rle_encode(dst, s->buf_size - (*s->buf - s->buf_start), src, 1, n, 2, 0xff, -1, 0);
+        return ff_rle_encode(dst, s->buf_size - (*s->buf - s->buf_start),
+                             src, 1, n, 2, 0xff, -1, 0);
     case TIFF_LZW:
         return ff_lzw_encode(s->lzws, src, n);
     default:
@@ -196,15 +195,15 @@
     }
 }
 
-static void pack_yuv(TiffEncoderContext * s, uint8_t * dst, int lnum)
+static void pack_yuv(TiffEncoderContext *s, uint8_t *dst, int lnum)
 {
     AVFrame *p = &s->picture;
     int i, j, k;
-    int w = (s->width - 1) / s->subsampling[0] + 1;
+    int w       = (s->width - 1) / s->subsampling[0] + 1;
     uint8_t *pu = &p->data[1][lnum / s->subsampling[1] * p->linesize[1]];
     uint8_t *pv = &p->data[2][lnum / s->subsampling[1] * p->linesize[2]];
-    if(s->width % s->subsampling[0] || s->height % s->subsampling[1]){
-        for (i = 0; i < w; i++){
+    if (s->width % s->subsampling[0] || s->height % s->subsampling[1]) {
+        for (i = 0; i < w; i++) {
             for (j = 0; j < s->subsampling[1]; j++)
                 for (k = 0; k < s->subsampling[0]; k++)
                     *dst++ = p->data[0][FFMIN(lnum + j, s->height-1) * p->linesize[0] +
@@ -213,7 +212,7 @@
             *dst++ = *pv++;
         }
     }else{
-        for (i = 0; i < w; i++){
+        for (i = 0; i < w; i++) {
             for (j = 0; j < s->subsampling[1]; j++)
                 for (k = 0; k < s->subsampling[0]; k++)
                     *dst++ = p->data[0][(lnum + j) * p->linesize[0] +
@@ -228,7 +227,7 @@
 {
     TiffEncoderContext *s = avctx->priv_data;
 
-    avctx->coded_frame= &s->picture;
+    avctx->coded_frame            = &s->picture;
     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
     avctx->coded_frame->key_frame = 1;
     s->avctx = avctx;
@@ -236,7 +235,7 @@
     return 0;
 }
 
-static int encode_frame(AVCodecContext * avctx, AVPacket *pkt,
+static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                         const AVFrame *pict, int *got_packet)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
@@ -247,7 +246,7 @@
     uint8_t *offset;
     uint32_t strips;
     int bytes_per_row;
-    uint32_t res[2] = { s->dpi, 1 };        // image resolution (72/1)
+    uint32_t res[2] = { s->dpi, 1 };    // image resolution (72/1)
     uint16_t bpp_tab[4];
     int ret = -1;
     int is_yuv = 0, alpha = 0;
@@ -255,13 +254,13 @@
 
     *p = *pict;
 
-    s->width = avctx->width;
-    s->height = avctx->height;
+    s->width          = avctx->width;
+    s->height         = avctx->height;
     s->subsampling[0] = 1;
     s->subsampling[1] = 1;
 
     avctx->bits_per_coded_sample =
-    s->bpp = av_get_bits_per_pixel(desc);
+    s->bpp          = av_get_bits_per_pixel(desc);
     s->bpp_tab_size = desc->nb_components;
 
     switch (avctx->pix_fmt) {
@@ -292,11 +291,11 @@
     case AV_PIX_FMT_YUV444P:
     case AV_PIX_FMT_YUV410P:
     case AV_PIX_FMT_YUV411P:
+        av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &shift_h, &shift_v);
         s->photometric_interpretation = 6;
-        avcodec_get_chroma_sub_sample(avctx->pix_fmt, &shift_h, &shift_v);
-        s->subsampling[0] = 1 << shift_h;
-        s->subsampling[1] = 1 << shift_v;
-        is_yuv = 1;
+        s->subsampling[0]             = 1 << shift_h;
+        s->subsampling[1]             = 1 << shift_v;
+        is_yuv                        = 1;
         break;
     default:
         av_log(s->avctx, AV_LOG_ERROR,
@@ -307,17 +306,22 @@
     for (i = 0; i < s->bpp_tab_size; i++)
         bpp_tab[i] = desc->comp[i].depth_minus1 + 1;
 
-    if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE || s->compr == TIFF_LZW)
-        //best choose for DEFLATE
+    if (s->compr == TIFF_DEFLATE       ||
+        s->compr == TIFF_ADOBE_DEFLATE ||
+        s->compr == TIFF_LZW)
+        // best choice for DEFLATE
         s->rps = s->height;
     else
-        s->rps = FFMAX(8192 / (((s->width * s->bpp) >> 3) + 1), 1);     // suggest size of strip
-    s->rps = ((s->rps - 1) / s->subsampling[1] + 1) * s->subsampling[1]; // round rps up
+        // suggest size of strip
+        s->rps = FFMAX(8192 / (((s->width * s->bpp) >> 3) + 1), 1);
+    // round rps up
+    s->rps = ((s->rps - 1) / s->subsampling[1] + 1) * s->subsampling[1];
 
     strips = (s->height - 1) / s->rps + 1;
 
-    if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width * avctx->height * s->bpp * 2 +
-                                  avctx->height * 4 + FF_MIN_BUFFER_SIZE)) < 0)
+    if ((ret = ff_alloc_packet2(avctx, pkt,
+                             avctx->width * avctx->height * s->bpp * 2 +
+                             avctx->height * 4 + FF_MIN_BUFFER_SIZE)) < 0)
         return ret;
     ptr          = pkt->data;
     s->buf_start = pkt->data;
@@ -334,7 +338,7 @@
     offset = ptr;
     bytestream_put_le32(&ptr, 0);
 
-    av_fast_padded_mallocz(&s->strip_sizes, &s->strip_sizes_size, sizeof(s->strip_sizes[0]) * strips);
+    av_fast_padded_mallocz(&s->strip_sizes  , &s->strip_sizes_size  , sizeof(s->strip_sizes  [0]) * strips);
     av_fast_padded_mallocz(&s->strip_offsets, &s->strip_offsets_size, sizeof(s->strip_offsets[0]) * strips);
 
     if (!s->strip_sizes || !s->strip_offsets) {
@@ -342,11 +346,11 @@
         goto fail;
     }
 
-    bytes_per_row = (((s->width - 1)/s->subsampling[0] + 1) * s->bpp
-                    * s->subsampling[0] * s->subsampling[1] + 7) >> 3;
-    if (is_yuv){
+    bytes_per_row = (((s->width - 1) / s->subsampling[0] + 1) * s->bpp *
+                     s->subsampling[0] * s->subsampling[1] + 7) >> 3;
+    if (is_yuv) {
         av_fast_padded_malloc(&s->yuv_line, &s->yuv_line_size, bytes_per_row);
-        if (s->yuv_line == NULL){
+        if (s->yuv_line == NULL) {
             av_log(s->avctx, AV_LOG_ERROR, "Not enough memory\n");
             ret = AVERROR(ENOMEM);
             goto fail;
@@ -366,14 +370,13 @@
             goto fail;
         }
         s->strip_offsets[0] = ptr - pkt->data;
-        zn = 0;
+        zn               = 0;
         for (j = 0; j < s->rps; j++) {
-            if (is_yuv){
+            if (is_yuv) {
                 pack_yuv(s, s->yuv_line, j);
                 memcpy(zbuf + zn, s->yuv_line, bytes_per_row);
                 j += s->subsampling[1] - 1;
-            }
-            else
+            } else
                 memcpy(zbuf + j * bytes_per_row,
                        p->data[0] + j * p->linesize[0], bytes_per_row);
             zn += bytes_per_row;
@@ -384,97 +387,99 @@
             av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
             goto fail;
         }
-        ptr += ret;
+        ptr           += ret;
         s->strip_sizes[0] = ptr - pkt->data - s->strip_offsets[0];
     } else
 #endif
     {
-        if (s->compr == TIFF_LZW) {
-            s->lzws = av_malloc(ff_lzw_encode_state_size);
-            if (!s->lzws) {
-                ret = AVERROR(ENOMEM);
-                goto fail;
-            }
+    if (s->compr == TIFF_LZW) {
+        s->lzws = av_malloc(ff_lzw_encode_state_size);
+        if (!s->lzws) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
         }
-        for (i = 0; i < s->height; i++) {
-            if (s->strip_sizes[i / s->rps] == 0) {
-                if(s->compr == TIFF_LZW){
-                    ff_lzw_encode_init(s->lzws, ptr, s->buf_size - (*s->buf - s->buf_start),
-                                       12, FF_LZW_TIFF, put_bits);
-                }
-                s->strip_offsets[i / s->rps] = ptr - pkt->data;
+    }
+    for (i = 0; i < s->height; i++) {
+        if (s->strip_sizes[i / s->rps] == 0) {
+            if (s->compr == TIFF_LZW) {
+                ff_lzw_encode_init(s->lzws, ptr,
+                                   s->buf_size - (*s->buf - s->buf_start),
+                                   12, FF_LZW_TIFF, put_bits);
             }
-            if (is_yuv){
-                 pack_yuv(s, s->yuv_line, i);
-                 ret = encode_strip(s, s->yuv_line, ptr, bytes_per_row, s->compr);
-                 i += s->subsampling[1] - 1;
-            }
-            else
-                ret = encode_strip(s, p->data[0] + i * p->linesize[0],
-                        ptr, bytes_per_row, s->compr);
-            if (ret < 0) {
-                av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
-                goto fail;
-            }
-            s->strip_sizes[i / s->rps] += ret;
-            ptr += ret;
-            if(s->compr == TIFF_LZW && (i==s->height-1 || i%s->rps == s->rps-1)){
-                ret = ff_lzw_encode_flush(s->lzws, flush_put_bits);
-                s->strip_sizes[(i / s->rps )] += ret ;
-                ptr += ret;
-            }
+            s->strip_offsets[i / s->rps] = ptr - pkt->data;
         }
-        if(s->compr == TIFF_LZW)
-            av_free(s->lzws);
+        if (is_yuv) {
+            pack_yuv(s, s->yuv_line, i);
+            ret = encode_strip(s, s->yuv_line, ptr, bytes_per_row, s->compr);
+            i  += s->subsampling[1] - 1;
+        } else
+            ret = encode_strip(s, p->data[0] + i * p->linesize[0],
+                               ptr, bytes_per_row, s->compr);
+        if (ret < 0) {
+            av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
+            goto fail;
+        }
+        s->strip_sizes[i / s->rps] += ret;
+        ptr                     += ret;
+        if (s->compr == TIFF_LZW &&
+            (i == s->height - 1 || i % s->rps == s->rps - 1)) {
+            ret = ff_lzw_encode_flush(s->lzws, flush_put_bits);
+            s->strip_sizes[(i / s->rps)] += ret;
+            ptr                          += ret;
+        }
+    }
+    if (s->compr == TIFF_LZW)
+        av_free(s->lzws);
     }
 
     s->num_entries = 0;
 
-    add_entry1(s,TIFF_SUBFILE,           TIFF_LONG,             0);
-    add_entry1(s,TIFF_WIDTH,             TIFF_LONG,             s->width);
-    add_entry1(s,TIFF_HEIGHT,            TIFF_LONG,             s->height);
+    add_entry1(s, TIFF_SUBFILE, TIFF_LONG, 0);
+    add_entry1(s, TIFF_WIDTH,   TIFF_LONG, s->width);
+    add_entry1(s, TIFF_HEIGHT,  TIFF_LONG, s->height);
 
     if (s->bpp_tab_size)
-    add_entry(s, TIFF_BPP,               TIFF_SHORT,    s->bpp_tab_size, bpp_tab);
+        add_entry(s, TIFF_BPP, TIFF_SHORT, s->bpp_tab_size, bpp_tab);
 
-    add_entry1(s,TIFF_COMPR,             TIFF_SHORT,            s->compr);
-    add_entry1(s,TIFF_INVERT,            TIFF_SHORT,            s->photometric_interpretation);
-    add_entry(s, TIFF_STRIP_OFFS,        TIFF_LONG,     strips, s->strip_offsets);
+    add_entry1(s, TIFF_COMPR,      TIFF_SHORT, s->compr);
+    add_entry1(s, TIFF_INVERT,     TIFF_SHORT, s->photometric_interpretation);
+    add_entry(s,  TIFF_STRIP_OFFS, TIFF_LONG,  strips, s->strip_offsets);
 
     if (s->bpp_tab_size)
-    add_entry1(s,TIFF_SAMPLES_PER_PIXEL, TIFF_SHORT,            s->bpp_tab_size);
+        add_entry1(s, TIFF_SAMPLES_PER_PIXEL, TIFF_SHORT, s->bpp_tab_size);
 
-    add_entry1(s,TIFF_ROWSPERSTRIP,      TIFF_LONG,             s->rps);
-    add_entry(s, TIFF_STRIP_SIZE,        TIFF_LONG,     strips, s->strip_sizes);
-    add_entry(s, TIFF_XRES,              TIFF_RATIONAL, 1,      res);
-    add_entry(s, TIFF_YRES,              TIFF_RATIONAL, 1,      res);
-    add_entry1(s,TIFF_RES_UNIT,          TIFF_SHORT,            2);
+    add_entry1(s, TIFF_ROWSPERSTRIP, TIFF_LONG,     s->rps);
+    add_entry(s,  TIFF_STRIP_SIZE,   TIFF_LONG,     strips, s->strip_sizes);
+    add_entry(s,  TIFF_XRES,         TIFF_RATIONAL, 1,      res);
+    add_entry(s,  TIFF_YRES,         TIFF_RATIONAL, 1,      res);
+    add_entry1(s, TIFF_RES_UNIT,     TIFF_SHORT,    2);
 
-    if(!(avctx->flags & CODEC_FLAG_BITEXACT))
-    add_entry(s, TIFF_SOFTWARE_NAME,     TIFF_STRING,
-              strlen(LIBAVCODEC_IDENT) + 1, LIBAVCODEC_IDENT);
+    if (!(avctx->flags & CODEC_FLAG_BITEXACT))
+        add_entry(s, TIFF_SOFTWARE_NAME, TIFF_STRING,
+                  strlen(LIBAVCODEC_IDENT) + 1, LIBAVCODEC_IDENT);
 
     if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
         uint16_t pal[256 * 3];
         for (i = 0; i < 256; i++) {
             uint32_t rgb = *(uint32_t *) (p->data[1] + i * 4);
             pal[i]       = ((rgb >> 16) & 0xff) * 257;
-            pal[i + 256] = ((rgb >> 8 ) & 0xff) * 257;
-            pal[i + 512] = ( rgb        & 0xff) * 257;
+            pal[i + 256] = ((rgb >>  8) & 0xff) * 257;
+            pal[i + 512] =  (rgb        & 0xff) * 257;
         }
         add_entry(s, TIFF_PAL, TIFF_SHORT, 256 * 3, pal);
     }
     if (alpha)
         add_entry1(s,TIFF_EXTRASAMPLES,      TIFF_SHORT,            2);
-    if (is_yuv){
+    if (is_yuv) {
         /** according to CCIR Recommendation 601.1 */
-        uint32_t refbw[12] = {15, 1, 235, 1, 128, 1, 240, 1, 128, 1, 240, 1};
+        uint32_t refbw[12] = { 15, 1, 235, 1, 128, 1, 240, 1, 128, 1, 240, 1 };
         add_entry(s, TIFF_YCBCR_SUBSAMPLING, TIFF_SHORT,    2, s->subsampling);
         if (avctx->chroma_sample_location == AVCHROMA_LOC_TOPLEFT)
             add_entry1(s, TIFF_YCBCR_POSITIONING, TIFF_SHORT, 2);
         add_entry(s, TIFF_REFERENCE_BW,      TIFF_RATIONAL, 6, refbw);
     }
-    bytestream_put_le32(&offset, ptr - pkt->data);    // write offset to dir
+    // write offset to dir
+    bytestream_put_le32(&offset, ptr - pkt->data);
 
     if (check_size(s, 6 + s->num_entries * 12)) {
         ret = AVERROR(EINVAL);
@@ -507,12 +512,12 @@
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
     {"dpi", "set the image resolution (in dpi)", OFFSET(dpi), AV_OPT_TYPE_INT, {.i64 = 72}, 1, 0x10000, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_ENCODING_PARAM},
-    { "compression_algo", NULL, OFFSET(compr), AV_OPT_TYPE_INT, {.i64 = TIFF_PACKBITS}, TIFF_RAW, TIFF_DEFLATE, VE, "compression_algo" },
-    { "packbits", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_PACKBITS}, 0, 0, VE, "compression_algo" },
-    { "raw",      NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_RAW},      0, 0, VE, "compression_algo" },
-    { "lzw",      NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_LZW},      0, 0, VE, "compression_algo" },
+    { "compression_algo", NULL, OFFSET(compr), AV_OPT_TYPE_INT,   { .i64 = TIFF_PACKBITS }, TIFF_RAW, TIFF_DEFLATE, VE, "compression_algo" },
+    { "packbits",         NULL, 0,             AV_OPT_TYPE_CONST, { .i64 = TIFF_PACKBITS }, 0,        0,            VE, "compression_algo" },
+    { "raw",              NULL, 0,             AV_OPT_TYPE_CONST, { .i64 = TIFF_RAW      }, 0,        0,            VE, "compression_algo" },
+    { "lzw",              NULL, 0,             AV_OPT_TYPE_CONST, { .i64 = TIFF_LZW      }, 0,        0,            VE, "compression_algo" },
 #if CONFIG_ZLIB
-    { "deflate",  NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_DEFLATE},  0, 0, VE, "compression_algo" },
+    { "deflate",          NULL, 0,             AV_OPT_TYPE_CONST, { .i64 = TIFF_DEFLATE  }, 0,        0,            VE, "compression_algo" },
 #endif
     { NULL },
 };
@@ -526,6 +531,7 @@
 
 AVCodec ff_tiff_encoder = {
     .name           = "tiff",
+    .long_name      = NULL_IF_CONFIG_SMALL("TIFF image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TIFF,
     .priv_data_size = sizeof(TiffEncoderContext),
@@ -541,6 +547,5 @@
         AV_PIX_FMT_RGBA, AV_PIX_FMT_RGBA64LE,
         AV_PIX_FMT_NONE
     },
-    .long_name      = NULL_IF_CONFIG_SMALL("TIFF image"),
     .priv_class     = &tiffenc_class,
 };
diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c
index 7783386..6c119ac 100644
--- a/libavcodec/truemotion2.c
+++ b/libavcodec/truemotion2.c
@@ -58,7 +58,7 @@
 
 typedef struct TM2Context {
     AVCodecContext *avctx;
-    AVFrame pic;
+    AVFrame *pic;
 
     GetBitContext gb;
     DSPContext dsp;
@@ -858,7 +858,7 @@
     TM2Context * const l = avctx->priv_data;
     const uint8_t *buf   = avpkt->data;
     int buf_size         = avpkt->size & ~3;
-    AVFrame * const p    = &l->pic;
+    AVFrame * const p    = l->pic;
     int offset           = TM2_HEADER_SIZE;
     int i, t, ret;
 
@@ -900,7 +900,7 @@
 
     l->cur = !l->cur;
     *got_frame      = 1;
-    ret = av_frame_ref(data, &l->pic);
+    ret = av_frame_ref(data, l->pic);
 
     return (ret < 0) ? ret : buf_size;
 }
@@ -916,8 +916,10 @@
     }
 
     l->avctx       = avctx;
-    avcodec_get_frame_defaults(&l->pic);
     avctx->pix_fmt = AV_PIX_FMT_BGR24;
+    l->pic = av_frame_alloc();
+    if (!l->pic)
+        return AVERROR(ENOMEM);
 
     ff_dsputil_init(&l->dsp, avctx);
 
@@ -953,6 +955,7 @@
         av_freep(l->V2_base);
         av_freep(l->last);
         av_freep(l->clast);
+        av_frame_free(&l->pic);
         return AVERROR(ENOMEM);
     }
     l->Y1 = l->Y1_base + l->y_stride  * 4 + 4;
@@ -968,7 +971,6 @@
 static av_cold int decode_end(AVCodecContext *avctx)
 {
     TM2Context * const l = avctx->priv_data;
-    AVFrame *pic = &l->pic;
     int i;
 
     av_free(l->last);
@@ -986,7 +988,7 @@
     av_freep(&l->buffer);
     l->buffer_size = 0;
 
-    av_frame_unref(pic);
+    av_frame_free(&l->pic);
 
     return 0;
 }
diff --git a/libavcodec/tta.c b/libavcodec/tta.c
index 8b4ca5a..b5ddec4 100644
--- a/libavcodec/tta.c
+++ b/libavcodec/tta.c
@@ -28,10 +28,12 @@
  */
 
 #define BITSTREAM_READER_LE
-//#define DEBUG
 #include <limits.h>
+#include "ttadata.h"
 #include "avcodec.h"
 #include "get_bits.h"
+#include "thread.h"
+#include "unary.h"
 #include "internal.h"
 #include "libavutil/crc.h"
 #include "libavutil/intreadwrite.h"
@@ -40,28 +42,9 @@
 #define FORMAT_SIMPLE    1
 #define FORMAT_ENCRYPTED 2
 
-#define MAX_ORDER 16
-typedef struct TTAFilter {
-    int32_t shift, round, error;
-    int32_t qm[MAX_ORDER];
-    int32_t dx[MAX_ORDER];
-    int32_t dl[MAX_ORDER];
-} TTAFilter;
-
-typedef struct TTARice {
-    uint32_t k0, k1, sum0, sum1;
-} TTARice;
-
-typedef struct TTAChannel {
-    int32_t predictor;
-    TTAFilter filter;
-    TTARice rice;
-} TTAChannel;
-
 typedef struct TTAContext {
     AVClass *class;
     AVCodecContext *avctx;
-    GetBitContext gb;
     const AVCRC *crc_table;
 
     int format, channels, bps;
@@ -75,40 +58,6 @@
     TTAChannel *ch_ctx;
 } TTAContext;
 
-static const uint32_t shift_1[] = {
-    0x00000001, 0x00000002, 0x00000004, 0x00000008,
-    0x00000010, 0x00000020, 0x00000040, 0x00000080,
-    0x00000100, 0x00000200, 0x00000400, 0x00000800,
-    0x00001000, 0x00002000, 0x00004000, 0x00008000,
-    0x00010000, 0x00020000, 0x00040000, 0x00080000,
-    0x00100000, 0x00200000, 0x00400000, 0x00800000,
-    0x01000000, 0x02000000, 0x04000000, 0x08000000,
-    0x10000000, 0x20000000, 0x40000000, 0x80000000,
-    0x80000000, 0x80000000, 0x80000000, 0x80000000,
-    0x80000000, 0x80000000, 0x80000000, 0x80000000
-};
-
-static const uint32_t * const shift_16 = shift_1 + 4;
-
-static const int32_t ttafilter_configs[4] = {
-    10,
-    9,
-    10,
-    12
-};
-
-static void ttafilter_init(TTAContext *s, TTAFilter *c, int32_t shift) {
-    memset(c, 0, sizeof(TTAFilter));
-    if (s->format == FORMAT_ENCRYPTED) {
-        int i;
-        for (i = 0; i < 8; i++)
-            c->qm[i] = sign_extend(s->crc_pass[i], 8);
-    }
-    c->shift = shift;
-   c->round = shift_1[shift-1];
-//    c->round = 1 << (shift - 1);
-}
-
 static inline void ttafilter_process(TTAFilter *c, int32_t *in)
 {
     register int32_t *dl = c->dl, *qm = c->qm, *dx = c->dx, sum = c->round;
@@ -140,24 +89,6 @@
     dl[5] += dl[6]; dl[4] += dl[5];
 }
 
-static void rice_init(TTARice *c, uint32_t k0, uint32_t k1)
-{
-    c->k0 = k0;
-    c->k1 = k1;
-    c->sum0 = shift_16[k0];
-    c->sum1 = shift_16[k1];
-}
-
-static int tta_get_unary(GetBitContext *gb)
-{
-    int ret = 0;
-
-    // count ones
-    while (get_bits_left(gb) > 0 && get_bits1(gb))
-        ret++;
-    return ret;
-}
-
 static const int64_t tta_channel_layouts[7] = {
     AV_CH_LAYOUT_STEREO,
     AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY,
@@ -197,29 +128,44 @@
     return crc ^ UINT64_MAX;
 }
 
+static int allocate_buffers(AVCodecContext *avctx)
+{
+    TTAContext *s = avctx->priv_data;
+
+    if (s->bps < 3) {
+        s->decode_buffer = av_mallocz(sizeof(int32_t)*s->frame_length*s->channels);
+        if (!s->decode_buffer)
+            return AVERROR(ENOMEM);
+    } else
+        s->decode_buffer = NULL;
+    s->ch_ctx = av_malloc(avctx->channels * sizeof(*s->ch_ctx));
+    if (!s->ch_ctx) {
+        av_freep(&s->decode_buffer);
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
 static av_cold int tta_decode_init(AVCodecContext * avctx)
 {
     TTAContext *s = avctx->priv_data;
+    GetBitContext gb;
     int total_frames;
 
     s->avctx = avctx;
 
-    // 30bytes includes a seektable with one frame
-    if (avctx->extradata_size < 30)
+    // 30bytes includes TTA1 header
+    if (avctx->extradata_size < 22)
         return AVERROR_INVALIDDATA;
 
-    init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size * 8);
-    if (show_bits_long(&s->gb, 32) == AV_RL32("TTA1"))
-    {
-        if (avctx->err_recognition & AV_EF_CRCCHECK) {
-            s->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE);
-            tta_check_crc(s, avctx->extradata, 18);
-        }
-
+    s->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE);
+    init_get_bits8(&gb, avctx->extradata, avctx->extradata_size);
+    if (show_bits_long(&gb, 32) == AV_RL32("TTA1")) {
         /* signature */
-        skip_bits_long(&s->gb, 32);
+        skip_bits_long(&gb, 32);
 
-        s->format = get_bits(&s->gb, 16);
+        s->format = get_bits(&gb, 16);
         if (s->format > 2) {
             av_log(avctx, AV_LOG_ERROR, "Invalid format\n");
             return AVERROR_INVALIDDATA;
@@ -231,14 +177,14 @@
             }
             AV_WL64(s->crc_pass, tta_check_crc64(s->pass));
         }
-        avctx->channels = s->channels = get_bits(&s->gb, 16);
+        avctx->channels = s->channels = get_bits(&gb, 16);
         if (s->channels > 1 && s->channels < 9)
             avctx->channel_layout = tta_channel_layouts[s->channels-2];
-        avctx->bits_per_raw_sample = get_bits(&s->gb, 16);
+        avctx->bits_per_raw_sample = get_bits(&gb, 16);
         s->bps = (avctx->bits_per_raw_sample + 7) / 8;
-        avctx->sample_rate = get_bits_long(&s->gb, 32);
-        s->data_length = get_bits_long(&s->gb, 32);
-        skip_bits_long(&s->gb, 32); // CRC32 of header
+        avctx->sample_rate = get_bits_long(&gb, 32);
+        s->data_length = get_bits_long(&gb, 32);
+        skip_bits_long(&gb, 32); // CRC32 of header
 
         if (s->channels == 0) {
             av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n");
@@ -279,48 +225,27 @@
         av_log(avctx, AV_LOG_DEBUG, "data_length: %d frame_length: %d last: %d total: %d\n",
             s->data_length, s->frame_length, s->last_frame_length, total_frames);
 
-        // FIXME: seek table
-        if (avctx->extradata_size <= 26 || total_frames > INT_MAX / 4 ||
-            avctx->extradata_size - 26 < total_frames * 4)
-            av_log(avctx, AV_LOG_WARNING, "Seek table missing or too small\n");
-        else if (avctx->err_recognition & AV_EF_CRCCHECK) {
-            if (tta_check_crc(s, avctx->extradata + 22, total_frames * 4))
-                return AVERROR_INVALIDDATA;
-        }
-        skip_bits_long(&s->gb, 32 * total_frames);
-        skip_bits_long(&s->gb, 32); // CRC32 of seektable
-
         if(s->frame_length >= UINT_MAX / (s->channels * sizeof(int32_t))){
             av_log(avctx, AV_LOG_ERROR, "frame_length too large\n");
             return AVERROR_INVALIDDATA;
         }
-
-        if (s->bps < 3) {
-            s->decode_buffer = av_mallocz(sizeof(int32_t)*s->frame_length*s->channels);
-            if (!s->decode_buffer)
-                return AVERROR(ENOMEM);
-        } else
-            s->decode_buffer = NULL;
-        s->ch_ctx = av_malloc(avctx->channels * sizeof(*s->ch_ctx));
-        if (!s->ch_ctx) {
-            av_freep(&s->decode_buffer);
-            return AVERROR(ENOMEM);
-        }
     } else {
         av_log(avctx, AV_LOG_ERROR, "Wrong extradata present\n");
         return AVERROR_INVALIDDATA;
     }
 
-    return 0;
+    return allocate_buffers(avctx);
 }
 
 static int tta_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
     AVFrame *frame     = data;
+    ThreadFrame tframe = { .f = data };
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     TTAContext *s = avctx->priv_data;
+    GetBitContext gb;
     int i, ret;
     int cur_chan = 0, framelen = s->frame_length;
     int32_t *p;
@@ -330,11 +255,12 @@
             return AVERROR_INVALIDDATA;
     }
 
-    init_get_bits(&s->gb, buf, buf_size*8);
+    if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
+        return ret;
 
     /* get output buffer */
     frame->nb_samples = framelen;
-    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
         return ret;
 
     // decode directly to output buffer for 24-bit sample format
@@ -343,9 +269,15 @@
 
     // init per channel states
     for (i = 0; i < s->channels; i++) {
+        TTAFilter *filter = &s->ch_ctx[i].filter;
         s->ch_ctx[i].predictor = 0;
-        ttafilter_init(s, &s->ch_ctx[i].filter, ttafilter_configs[s->bps-1]);
-        rice_init(&s->ch_ctx[i].rice, 10, 10);
+        ff_tta_filter_init(filter, ff_tta_filter_configs[s->bps-1]);
+        if (s->format == FORMAT_ENCRYPTED) {
+            int i;
+            for (i = 0; i < 8; i++)
+                filter->qm[i] = sign_extend(s->crc_pass[i], 8);
+        }
+        ff_tta_rice_init(&s->ch_ctx[i].rice, 10, 10);
     }
 
     i = 0;
@@ -356,7 +288,7 @@
         uint32_t unary, depth, k;
         int32_t value;
 
-        unary = tta_get_unary(&s->gb);
+        unary = get_unary(&gb, 0, get_bits_left(&gb));
 
         if (unary == 0) {
             depth = 0;
@@ -367,7 +299,7 @@
             unary--;
         }
 
-        if (get_bits_left(&s->gb) < k) {
+        if (get_bits_left(&gb) < k) {
             ret = AVERROR_INVALIDDATA;
             goto error;
         }
@@ -377,7 +309,7 @@
                 ret = AVERROR_INVALIDDATA;
                 goto error;
             }
-            value = (unary << k) + get_bits(&s->gb, k);
+            value = (unary << k) + get_bits(&gb, k);
         } else
             value = unary;
 
@@ -385,16 +317,16 @@
         switch (depth) {
         case 1:
             rice->sum1 += value - (rice->sum1 >> 4);
-            if (rice->k1 > 0 && rice->sum1 < shift_16[rice->k1])
+            if (rice->k1 > 0 && rice->sum1 < ff_tta_shift_16[rice->k1])
                 rice->k1--;
-            else if(rice->sum1 > shift_16[rice->k1 + 1])
+            else if(rice->sum1 > ff_tta_shift_16[rice->k1 + 1])
                 rice->k1++;
-            value += shift_1[rice->k0];
+            value += ff_tta_shift_1[rice->k0];
         default:
             rice->sum0 += value - (rice->sum0 >> 4);
-            if (rice->k0 > 0 && rice->sum0 < shift_16[rice->k0])
+            if (rice->k0 > 0 && rice->sum0 < ff_tta_shift_16[rice->k0])
                 rice->k0--;
-            else if(rice->sum0 > shift_16[rice->k0 + 1])
+            else if(rice->sum0 > ff_tta_shift_16[rice->k0 + 1])
                 rice->k0++;
         }
 
@@ -427,19 +359,19 @@
             cur_chan = 0;
             i++;
             // check for last frame
-            if (i == s->last_frame_length && get_bits_left(&s->gb) / 8 == 4) {
+            if (i == s->last_frame_length && get_bits_left(&gb) / 8 == 4) {
                 frame->nb_samples = framelen = s->last_frame_length;
                 break;
             }
         }
     }
 
-    align_get_bits(&s->gb);
-    if (get_bits_left(&s->gb) < 32) {
+    align_get_bits(&gb);
+    if (get_bits_left(&gb) < 32) {
         ret = AVERROR_INVALIDDATA;
         goto error;
     }
-    skip_bits_long(&s->gb, 32); // frame crc
+    skip_bits_long(&gb, 32); // frame crc
 
     // convert to output buffer
     switch (s->bps) {
@@ -458,7 +390,7 @@
     case 3: {
         // shift samples for 24-bit sample format
         int32_t *samples = (int32_t *)frame->data[0];
-        for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++)
+        for (i = 0; i < framelen * s->channels; i++)
             *samples++ <<= 8;
         // reset decode buffer
         s->decode_buffer = NULL;
@@ -476,6 +408,13 @@
     return ret;
 }
 
+static int init_thread_copy(AVCodecContext *avctx)
+{
+    TTAContext *s = avctx->priv_data;
+    s->avctx = avctx;
+    return allocate_buffers(avctx);
+}
+
 static av_cold int tta_decode_close(AVCodecContext *avctx) {
     TTAContext *s = avctx->priv_data;
 
@@ -509,7 +448,8 @@
     .init           = tta_decode_init,
     .close          = tta_decode_close,
     .decode         = tta_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
+    .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
     .long_name      = NULL_IF_CONFIG_SMALL("TTA (True Audio)"),
     .priv_class     = &tta_decoder_class,
 };
diff --git a/libavcodec/ttadata.c b/libavcodec/ttadata.c
new file mode 100644
index 0000000..bf793a4
--- /dev/null
+++ b/libavcodec/ttadata.c
@@ -0,0 +1,52 @@
+/*
+ * TTA (The Lossless True Audio) data
+ *
+ * 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
+ */
+
+#include "ttadata.h"
+
+const uint32_t ff_tta_shift_1[] = {
+    0x00000001, 0x00000002, 0x00000004, 0x00000008,
+    0x00000010, 0x00000020, 0x00000040, 0x00000080,
+    0x00000100, 0x00000200, 0x00000400, 0x00000800,
+    0x00001000, 0x00002000, 0x00004000, 0x00008000,
+    0x00010000, 0x00020000, 0x00040000, 0x00080000,
+    0x00100000, 0x00200000, 0x00400000, 0x00800000,
+    0x01000000, 0x02000000, 0x04000000, 0x08000000,
+    0x10000000, 0x20000000, 0x40000000, 0x80000000,
+    0x80000000, 0x80000000, 0x80000000, 0x80000000,
+    0x80000000, 0x80000000, 0x80000000, 0x80000000
+};
+
+const uint32_t * const ff_tta_shift_16 = ff_tta_shift_1 + 4;
+
+const uint8_t ff_tta_filter_configs[] = { 10, 9, 10, 12 };
+
+void ff_tta_rice_init(TTARice *c, uint32_t k0, uint32_t k1)
+{
+    c->k0 = k0;
+    c->k1 = k1;
+    c->sum0 = ff_tta_shift_16[k0];
+    c->sum1 = ff_tta_shift_16[k1];
+}
+
+void ff_tta_filter_init(TTAFilter *c, int32_t shift) {
+    memset(c, 0, sizeof(TTAFilter));
+    c->shift = shift;
+    c->round = ff_tta_shift_1[shift-1];
+}
diff --git a/libavcodec/ttadata.h b/libavcodec/ttadata.h
new file mode 100644
index 0000000..48c4cd0
--- /dev/null
+++ b/libavcodec/ttadata.h
@@ -0,0 +1,50 @@
+/*
+ * TTA (The Lossless True Audio) data
+ *
+ * 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
+ */
+
+#ifndef AVCODEC_TTADATA_H
+#define AVCODEC_TTADATA_H
+
+#include "internal.h"
+
+#define MAX_ORDER 16
+typedef struct TTAFilter {
+    int32_t shift, round, error;
+    int32_t qm[MAX_ORDER];
+    int32_t dx[MAX_ORDER];
+    int32_t dl[MAX_ORDER];
+} TTAFilter;
+
+typedef struct TTARice {
+    uint32_t k0, k1, sum0, sum1;
+} TTARice;
+
+typedef struct TTAChannel {
+    int32_t predictor;
+    TTAFilter filter;
+    TTARice rice;
+} TTAChannel;
+
+extern const uint32_t ff_tta_shift_1[];
+extern const uint32_t * const ff_tta_shift_16;
+extern const uint8_t ff_tta_filter_configs[];
+
+void ff_tta_rice_init(TTARice *c, uint32_t k0, uint32_t k1);
+void ff_tta_filter_init(TTAFilter *c, int32_t shift);
+#endif /* AVCODEC_TTADATA_H */
diff --git a/libavcodec/ttaenc.c b/libavcodec/ttaenc.c
new file mode 100644
index 0000000..55599cc
--- /dev/null
+++ b/libavcodec/ttaenc.c
@@ -0,0 +1,232 @@
+/*
+ * TTA (The Lossless True Audio) encoder
+ *
+ * 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 BITSTREAM_WRITER_LE
+#include "ttadata.h"
+#include "avcodec.h"
+#include "put_bits.h"
+#include "internal.h"
+#include "libavutil/crc.h"
+
+typedef struct TTAEncContext {
+    const AVCRC *crc_table;
+    int bps;
+    TTAChannel *ch_ctx;
+} TTAEncContext;
+
+static av_cold int tta_encode_init(AVCodecContext *avctx)
+{
+    TTAEncContext *s = avctx->priv_data;
+
+    s->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE);
+
+    switch (avctx->sample_fmt) {
+    case AV_SAMPLE_FMT_U8:
+        avctx->bits_per_raw_sample = 8;
+        break;
+    case AV_SAMPLE_FMT_S16:
+        avctx->bits_per_raw_sample = 16;
+        break;
+    case AV_SAMPLE_FMT_S32:
+        if (avctx->bits_per_raw_sample > 24)
+            av_log(avctx, AV_LOG_WARNING, "encoding as 24 bits-per-sample\n");
+        avctx->bits_per_raw_sample = 24;
+    }
+
+    s->bps = avctx->bits_per_raw_sample >> 3;
+    avctx->frame_size = 256 * avctx->sample_rate / 245;
+
+    s->ch_ctx = av_malloc(avctx->channels * sizeof(*s->ch_ctx));
+    if (!s->ch_ctx)
+        return AVERROR(ENOMEM);
+
+    return 0;
+}
+
+static inline void ttafilter_process(TTAFilter *c, int32_t *in)
+{
+    register int32_t *dl = c->dl, *qm = c->qm, *dx = c->dx, sum = c->round;
+
+    if (c->error < 0) {
+        qm[0] -= dx[0]; qm[1] -= dx[1]; qm[2] -= dx[2]; qm[3] -= dx[3];
+        qm[4] -= dx[4]; qm[5] -= dx[5]; qm[6] -= dx[6]; qm[7] -= dx[7];
+    } else if (c->error > 0) {
+        qm[0] += dx[0]; qm[1] += dx[1]; qm[2] += dx[2]; qm[3] += dx[3];
+        qm[4] += dx[4]; qm[5] += dx[5]; qm[6] += dx[6]; qm[7] += dx[7];
+    }
+
+    sum += dl[0] * qm[0] + dl[1] * qm[1] + dl[2] * qm[2] + dl[3] * qm[3] +
+           dl[4] * qm[4] + dl[5] * qm[5] + dl[6] * qm[6] + dl[7] * qm[7];
+
+    dx[0] = dx[1]; dx[1] = dx[2]; dx[2] = dx[3]; dx[3] = dx[4];
+    dl[0] = dl[1]; dl[1] = dl[2]; dl[2] = dl[3]; dl[3] = dl[4];
+
+    dx[4] = ((dl[4] >> 30) | 1);
+    dx[5] = ((dl[5] >> 30) | 2) & ~1;
+    dx[6] = ((dl[6] >> 30) | 2) & ~1;
+    dx[7] = ((dl[7] >> 30) | 4) & ~3;
+
+    dl[4] = -dl[5]; dl[5] = -dl[6];
+    dl[6] = *in - dl[7]; dl[7] = *in;
+    dl[5] += dl[6]; dl[4] += dl[5];
+
+    *in -= (sum >> c->shift);
+    c->error = *in;
+}
+
+static int32_t get_sample(const AVFrame *frame, int sample,
+                          enum AVSampleFormat format)
+{
+    int32_t ret;
+
+    if (format == AV_SAMPLE_FMT_U8) {
+        ret = frame->data[0][sample] - 0x80;
+    } else if (format == AV_SAMPLE_FMT_S16) {
+        const int16_t *ptr = (const int16_t *)frame->data[0];
+        ret = ptr[sample];
+    } else {
+        const int32_t *ptr = (const int32_t *)frame->data[0];
+        ret = ptr[sample] >> 8;
+    }
+
+    return ret;
+}
+
+static int tta_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
+                            const AVFrame *frame, int *got_packet_ptr)
+{
+    TTAEncContext *s = avctx->priv_data;
+    PutBitContext pb;
+    int ret, i, out_bytes, cur_chan = 0, res = 0, samples = 0;
+
+    if ((ret = ff_alloc_packet2(avctx, avpkt, frame->nb_samples * 2 * avctx->channels * s->bps)) < 0)
+        return ret;
+    init_put_bits(&pb, avpkt->data, avpkt->size);
+
+    // init per channel states
+    for (i = 0; i < avctx->channels; i++) {
+        s->ch_ctx[i].predictor = 0;
+        ff_tta_filter_init(&s->ch_ctx[i].filter, ff_tta_filter_configs[s->bps - 1]);
+        ff_tta_rice_init(&s->ch_ctx[i].rice, 10, 10);
+    }
+
+    for (i = 0; i < frame->nb_samples * avctx->channels; i++) {
+        TTAChannel *c = &s->ch_ctx[cur_chan];
+        TTAFilter *filter = &c->filter;
+        TTARice *rice = &c->rice;
+        uint32_t k, unary, outval;
+        int32_t value, temp;
+
+        value = get_sample(frame, samples++, avctx->sample_fmt);
+
+        if (avctx->channels > 1) {
+            if (cur_chan < avctx->channels - 1)
+                value  = res = get_sample(frame, samples, avctx->sample_fmt) - value;
+            else
+                value -= res / 2;
+        }
+
+        temp = value;
+#define PRED(x, k) (int32_t)((((uint64_t)x << k) - x) >> k)
+        switch (s->bps) {
+        case 1: value -= PRED(c->predictor, 4); break;
+        case 2:
+        case 3: value -= PRED(c->predictor, 5); break;
+        }
+        c->predictor = temp;
+
+        ttafilter_process(filter, &value);
+        outval = (value > 0) ? (value << 1) - 1: -value << 1;
+
+        k = rice->k0;
+
+        rice->sum0 += outval - (rice->sum0 >> 4);
+        if (rice->k0 > 0 && rice->sum0 < ff_tta_shift_16[rice->k0])
+            rice->k0--;
+        else if (rice->sum0 > ff_tta_shift_16[rice->k0 + 1])
+            rice->k0++;
+
+        if (outval >= ff_tta_shift_1[k]) {
+            outval -= ff_tta_shift_1[k];
+            k = rice->k1;
+
+            rice->sum1 += outval - (rice->sum1 >> 4);
+            if (rice->k1 > 0 && rice->sum1 < ff_tta_shift_16[rice->k1])
+                rice->k1--;
+            else if (rice->sum1 > ff_tta_shift_16[rice->k1 + 1])
+                rice->k1++;
+
+            unary = 1 + (outval >> k);
+            do {
+                if (unary > 31) {
+                    put_bits(&pb, 31, 0x7FFFFFFF);
+                    unary -= 31;
+                } else {
+                    put_bits(&pb, unary, (1 << unary) - 1);
+                    unary = 0;
+                }
+            } while (unary);
+        }
+
+        put_bits(&pb, 1, 0);
+
+        if (k)
+            put_bits(&pb, k, outval & (ff_tta_shift_1[k] - 1));
+
+        if (cur_chan < avctx->channels - 1)
+            cur_chan++;
+        else
+            cur_chan = 0;
+    }
+
+    flush_put_bits(&pb);
+    out_bytes = put_bits_count(&pb) >> 3;
+    put_bits32(&pb, av_crc(s->crc_table, UINT32_MAX, avpkt->data, out_bytes) ^ UINT32_MAX);
+    flush_put_bits(&pb);
+
+    avpkt->pts      = frame->pts;
+    avpkt->size     = out_bytes + 4;
+    avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples);
+    *got_packet_ptr = 1;
+    return 0;
+}
+
+static av_cold int tta_encode_close(AVCodecContext *avctx)
+{
+    TTAEncContext *s = avctx->priv_data;
+    av_freep(&s->ch_ctx);
+    return 0;
+}
+
+AVCodec ff_tta_encoder = {
+    .name           = "tta",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_TTA,
+    .priv_data_size = sizeof(TTAEncContext),
+    .init           = tta_encode_init,
+    .close          = tta_encode_close,
+    .encode2        = tta_encode_frame,
+    .capabilities   = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_LOSSLESS,
+    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_U8,
+                                                     AV_SAMPLE_FMT_S16,
+                                                     AV_SAMPLE_FMT_S32,
+                                                     AV_SAMPLE_FMT_NONE },
+    .long_name      = NULL_IF_CONFIG_SMALL("TTA (True Audio)"),
+};
diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c
index 8b9c79f..7c4f499 100644
--- a/libavcodec/twinvq.c
+++ b/libavcodec/twinvq.c
@@ -19,219 +19,23 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <math.h>
+#include <stdint.h>
+
 #include "libavutil/channel_layout.h"
 #include "libavutil/float_dsp.h"
 #include "avcodec.h"
-#include "get_bits.h"
 #include "fft.h"
 #include "internal.h"
 #include "lsp.h"
 #include "sinewin.h"
-
-#include <math.h>
-#include <stdint.h>
-
-#include "twinvq_data.h"
-
-enum FrameType {
-    FT_SHORT = 0,  ///< Short frame  (divided in n   sub-blocks)
-    FT_MEDIUM,     ///< Medium frame (divided in m<n sub-blocks)
-    FT_LONG,       ///< Long frame   (single sub-block + PPC)
-    FT_PPC,        ///< Periodic Peak Component (part of the long frame)
-};
-
-/**
- * Parameters and tables that are different for each frame type
- */
-struct FrameMode {
-    uint8_t         sub;      ///< Number subblocks in each frame
-    const uint16_t *bark_tab;
-
-    /** number of distinct bark scale envelope values */
-    uint8_t         bark_env_size;
-
-    const int16_t  *bark_cb;    ///< codebook for the bark scale envelope (BSE)
-    uint8_t         bark_n_coef;///< number of BSE CB coefficients to read
-    uint8_t         bark_n_bit; ///< number of bits of the BSE coefs
-
-    //@{
-    /** main codebooks for spectrum data */
-    const int16_t    *cb0;
-    const int16_t    *cb1;
-    //@}
-
-    uint8_t         cb_len_read; ///< number of spectrum coefficients to read
-};
-
-/**
- * Parameters and tables that are different for every combination of
- * bitrate/sample rate
- */
-typedef struct {
-    struct FrameMode fmode[3]; ///< frame type-dependant parameters
-
-    uint16_t     size;        ///< frame size in samples
-    uint8_t      n_lsp;       ///< number of lsp coefficients
-    const float *lspcodebook;
-
-    /* number of bits of the different LSP CB coefficients */
-    uint8_t      lsp_bit0;
-    uint8_t      lsp_bit1;
-    uint8_t      lsp_bit2;
-
-    uint8_t      lsp_split;      ///< number of CB entries for the LSP decoding
-    const int16_t *ppc_shape_cb; ///< PPC shape CB
-
-    /** number of the bits for the PPC period value */
-    uint8_t      ppc_period_bit;
-
-    uint8_t      ppc_shape_bit;  ///< number of bits of the PPC shape CB coeffs
-    uint8_t      ppc_shape_len;  ///< size of PPC shape CB
-    uint8_t      pgain_bit;      ///< bits for PPC gain
-
-    /** constant for peak period to peak width conversion */
-    uint16_t     peak_per2wid;
-} ModeTab;
-
-static const ModeTab mode_08_08 = {
-    {
-        { 8, bark_tab_s08_64,  10, tab.fcb08s  , 1, 5, tab.cb0808s0, tab.cb0808s1, 18},
-        { 2, bark_tab_m08_256, 20, tab.fcb08m  , 2, 5, tab.cb0808m0, tab.cb0808m1, 16},
-        { 1, bark_tab_l08_512, 30, tab.fcb08l  , 3, 6, tab.cb0808l0, tab.cb0808l1, 17}
-    },
-    512 , 12, tab.lsp08,   1, 5, 3, 3, tab.shape08  , 8, 28, 20, 6, 40
-};
-
-static const ModeTab mode_11_08 = {
-    {
-        { 8, bark_tab_s11_64,  10, tab.fcb11s  , 1, 5, tab.cb1108s0, tab.cb1108s1, 29},
-        { 2, bark_tab_m11_256, 20, tab.fcb11m  , 2, 5, tab.cb1108m0, tab.cb1108m1, 24},
-        { 1, bark_tab_l11_512, 30, tab.fcb11l  , 3, 6, tab.cb1108l0, tab.cb1108l1, 27}
-    },
-    512 , 16, tab.lsp11,   1, 6, 4, 3, tab.shape11  , 9, 36, 30, 7, 90
-};
-
-static const ModeTab mode_11_10 = {
-    {
-        { 8, bark_tab_s11_64,  10, tab.fcb11s  , 1, 5, tab.cb1110s0, tab.cb1110s1, 21},
-        { 2, bark_tab_m11_256, 20, tab.fcb11m  , 2, 5, tab.cb1110m0, tab.cb1110m1, 18},
-        { 1, bark_tab_l11_512, 30, tab.fcb11l  , 3, 6, tab.cb1110l0, tab.cb1110l1, 20}
-    },
-    512 , 16, tab.lsp11,   1, 6, 4, 3, tab.shape11  , 9, 36, 30, 7, 90
-};
-
-static const ModeTab mode_16_16 = {
-    {
-        { 8, bark_tab_s16_128, 10, tab.fcb16s  , 1, 5, tab.cb1616s0, tab.cb1616s1, 16},
-        { 2, bark_tab_m16_512, 20, tab.fcb16m  , 2, 5, tab.cb1616m0, tab.cb1616m1, 15},
-        { 1, bark_tab_l16_1024,30, tab.fcb16l  , 3, 6, tab.cb1616l0, tab.cb1616l1, 16}
-    },
-    1024, 16, tab.lsp16,   1, 6, 4, 3, tab.shape16  , 9, 56, 60, 7, 180
-};
-
-static const ModeTab mode_22_20 = {
-    {
-        { 8, bark_tab_s22_128, 10, tab.fcb22s_1, 1, 6, tab.cb2220s0, tab.cb2220s1, 18},
-        { 2, bark_tab_m22_512, 20, tab.fcb22m_1, 2, 6, tab.cb2220m0, tab.cb2220m1, 17},
-        { 1, bark_tab_l22_1024,32, tab.fcb22l_1, 4, 6, tab.cb2220l0, tab.cb2220l1, 18}
-    },
-    1024, 16, tab.lsp22_1, 1, 6, 4, 3, tab.shape22_1, 9, 56, 36, 7, 144
-};
-
-static const ModeTab mode_22_24 = {
-    {
-        { 8, bark_tab_s22_128, 10, tab.fcb22s_1, 1, 6, tab.cb2224s0, tab.cb2224s1, 15},
-        { 2, bark_tab_m22_512, 20, tab.fcb22m_1, 2, 6, tab.cb2224m0, tab.cb2224m1, 14},
-        { 1, bark_tab_l22_1024,32, tab.fcb22l_1, 4, 6, tab.cb2224l0, tab.cb2224l1, 15}
-    },
-    1024, 16, tab.lsp22_1, 1, 6, 4, 3, tab.shape22_1, 9, 56, 36, 7, 144
-};
-
-static const ModeTab mode_22_32 = {
-    {
-        { 4, bark_tab_s22_128, 10, tab.fcb22s_2, 1, 6, tab.cb2232s0, tab.cb2232s1, 11},
-        { 2, bark_tab_m22_256, 20, tab.fcb22m_2, 2, 6, tab.cb2232m0, tab.cb2232m1, 11},
-        { 1, bark_tab_l22_512, 32, tab.fcb22l_2, 4, 6, tab.cb2232l0, tab.cb2232l1, 12}
-    },
-    512 , 16, tab.lsp22_2, 1, 6, 4, 4, tab.shape22_2, 9, 56, 36, 7, 72
-};
-
-static const ModeTab mode_44_40 = {
-    {
-        {16, bark_tab_s44_128, 10, tab.fcb44s  , 1, 6, tab.cb4440s0, tab.cb4440s1, 18},
-        { 4, bark_tab_m44_512, 20, tab.fcb44m  , 2, 6, tab.cb4440m0, tab.cb4440m1, 17},
-        { 1, bark_tab_l44_2048,40, tab.fcb44l  , 4, 6, tab.cb4440l0, tab.cb4440l1, 17}
-    },
-    2048, 20, tab.lsp44,   1, 6, 4, 4, tab.shape44  , 9, 84, 54, 7, 432
-};
-
-static const ModeTab mode_44_48 = {
-    {
-        {16, bark_tab_s44_128, 10, tab.fcb44s  , 1, 6, tab.cb4448s0, tab.cb4448s1, 15},
-        { 4, bark_tab_m44_512, 20, tab.fcb44m  , 2, 6, tab.cb4448m0, tab.cb4448m1, 14},
-        { 1, bark_tab_l44_2048,40, tab.fcb44l  , 4, 6, tab.cb4448l0, tab.cb4448l1, 14}
-    },
-    2048, 20, tab.lsp44,   1, 6, 4, 4, tab.shape44  , 9, 84, 54, 7, 432
-};
-
-typedef struct TwinContext {
-    AVCodecContext *avctx;
-    AVFloatDSPContext fdsp;
-    FFTContext mdct_ctx[3];
-
-    const ModeTab *mtab;
-
-    // history
-    float lsp_hist[2][20];           ///< LSP coefficients of the last frame
-    float bark_hist[3][2][40];       ///< BSE coefficients of last frame
-
-    // bitstream parameters
-    int16_t permut[4][4096];
-    uint8_t length[4][2];            ///< main codebook stride
-    uint8_t length_change[4];
-    uint8_t bits_main_spec[2][4][2]; ///< bits for the main codebook
-    int bits_main_spec_change[4];
-    int n_div[4];
-
-    float *spectrum;
-    float *curr_frame;               ///< non-interleaved output
-    float *prev_frame;               ///< non-interleaved previous frame
-    int last_block_pos[2];
-    int discarded_packets;
-
-    float *cos_tabs[3];
-
-    // scratch buffers
-    float *tmp_buf;
-} TwinContext;
-
-#define PPC_SHAPE_CB_SIZE 64
-#define PPC_SHAPE_LEN_MAX 60
-#define SUB_AMP_MAX       4500.0
-#define MULAW_MU          100.0
-#define GAIN_BITS         8
-#define AMP_MAX           13000.0
-#define SUB_GAIN_BITS     5
-#define WINDOW_TYPE_BITS  4
-#define PGAIN_MU          200
-#define LSP_COEFS_MAX     20
-#define LSP_SPLIT_MAX     4
-#define CHANNELS_MAX      2
-#define SUBBLOCKS_MAX     16
-#define BARK_N_COEF_MAX   4
-
-/** @note not speed critical, hence not optimized */
-static void memset_float(float *buf, float val, int size)
-{
-    while (size--)
-        *buf++ = val;
-}
+#include "twinvq.h"
 
 /**
  * Evaluate a single LPC amplitude spectrum envelope coefficient from the line
  * spectrum pairs.
  *
- * @param lsp a vector of the cosinus of the LSP values
+ * @param lsp a vector of the cosine of the LSP values
  * @param cos_val cos(PI*i/N) where i is the index of the LPC amplitude
  * @param order the order of the LSP (and the size of the *lsp buffer). Must
  *        be a multiple of four.
@@ -242,17 +46,17 @@
 static float eval_lpc_spectrum(const float *lsp, float cos_val, int order)
 {
     int j;
-    float p = 0.5f;
-    float q = 0.5f;
-    float two_cos_w = 2.0f*cos_val;
+    float p         = 0.5f;
+    float q         = 0.5f;
+    float two_cos_w = 2.0f * cos_val;
 
-    for (j = 0; j + 1 < order; j += 2*2) {
+    for (j = 0; j + 1 < order; j += 2 * 2) {
         // Unroll the loop once since order is a multiple of four
-        q *= lsp[j  ] - two_cos_w;
-        p *= lsp[j+1] - two_cos_w;
+        q *= lsp[j]     - two_cos_w;
+        p *= lsp[j + 1] - two_cos_w;
 
-        q *= lsp[j+2] - two_cos_w;
-        p *= lsp[j+3] - two_cos_w;
+        q *= lsp[j + 2] - two_cos_w;
+        p *= lsp[j + 3] - two_cos_w;
     }
 
     p *= p * (2.0f - two_cos_w);
@@ -264,34 +68,34 @@
 /**
  * Evaluate the LPC amplitude spectrum envelope from the line spectrum pairs.
  */
-static void eval_lpcenv(TwinContext *tctx, const float *cos_vals, float *lpc)
+static void eval_lpcenv(TwinVQContext *tctx, const float *cos_vals, float *lpc)
 {
     int i;
-    const ModeTab *mtab = tctx->mtab;
-    int size_s = mtab->size / mtab->fmode[FT_SHORT].sub;
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int size_s = mtab->size / mtab->fmode[TWINVQ_FT_SHORT].sub;
 
-    for (i = 0; i < size_s/2; i++) {
+    for (i = 0; i < size_s / 2; i++) {
         float cos_i = tctx->cos_tabs[0][i];
-        lpc[i]          = eval_lpc_spectrum(cos_vals,  cos_i, mtab->n_lsp);
-        lpc[size_s-i-1] = eval_lpc_spectrum(cos_vals, -cos_i, mtab->n_lsp);
+        lpc[i]              = eval_lpc_spectrum(cos_vals,  cos_i, mtab->n_lsp);
+        lpc[size_s - i - 1] = eval_lpc_spectrum(cos_vals, -cos_i, mtab->n_lsp);
     }
 }
 
 static void interpolate(float *out, float v1, float v2, int size)
 {
     int i;
-    float step = (v1 - v2)/(size + 1);
+    float step = (v1 - v2) / (size + 1);
 
     for (i = 0; i < size; i++) {
-        v2 += step;
+        v2    += step;
         out[i] = v2;
     }
 }
 
 static inline float get_cos(int idx, int part, const float *cos_tab, int size)
 {
-    return part ? -cos_tab[size - idx - 1] :
-                   cos_tab[       idx    ];
+    return part ? -cos_tab[size - idx - 1]
+                :  cos_tab[idx];
 }
 
 /**
@@ -303,19 +107,19 @@
  * unexplained condition.
  *
  * @param step the size of a block "siiiibiiii"
- * @param in the cosinus of the LSP data
- * @param part is 0 for 0...PI (positive cossinus values) and 1 for PI...2PI
-          (negative cossinus values)
+ * @param in the cosine of the LSP data
+ * @param part is 0 for 0...PI (positive cosine values) and 1 for PI...2PI
+ *        (negative cosine values)
  * @param size the size of the whole output
  */
-static inline void eval_lpcenv_or_interp(TwinContext *tctx,
-                                         enum FrameType ftype,
+static inline void eval_lpcenv_or_interp(TwinVQContext *tctx,
+                                         enum TwinVQFrameType ftype,
                                          float *out, const float *in,
                                          int size, int step, int part)
 {
     int i;
-    const ModeTab *mtab = tctx->mtab;
-    const float *cos_tab = tctx->cos_tabs[ftype];
+    const TwinVQModeTab *mtab = tctx->mtab;
+    const float *cos_tab      = tctx->cos_tabs[ftype];
 
     // Fill the 's'
     for (i = 0; i < size; i += step)
@@ -325,33 +129,39 @@
                               mtab->n_lsp);
 
     // Fill the 'iiiibiiii'
-    for (i = step; i <= size - 2*step; i += step) {
-        if (out[i + step] + out[i - step] >  1.95*out[i] ||
-            out[i + step]                 >=  out[i - step]) {
-            interpolate(out + i - step + 1, out[i], out[i-step], step - 1);
+    for (i = step; i <= size - 2 * step; i += step) {
+        if (out[i + step] + out[i - step] > 1.95 * out[i] ||
+            out[i + step]                 >= out[i - step]) {
+            interpolate(out + i - step + 1, out[i], out[i - step], step - 1);
         } else {
-            out[i - step/2] =
+            out[i - step / 2] =
                 eval_lpc_spectrum(in,
-                                  get_cos(i-step/2, part, cos_tab, size),
+                                  get_cos(i - step / 2, part, cos_tab, size),
                                   mtab->n_lsp);
-            interpolate(out + i - step   + 1, out[i-step/2], out[i-step  ], step/2 - 1);
-            interpolate(out + i - step/2 + 1, out[i       ], out[i-step/2], step/2 - 1);
+            interpolate(out + i - step + 1, out[i - step / 2],
+                        out[i - step], step / 2 - 1);
+            interpolate(out + i - step / 2 + 1, out[i],
+                        out[i - step / 2], step / 2 - 1);
         }
     }
 
-    interpolate(out + size - 2*step + 1, out[size-step], out[size - 2*step], step - 1);
+    interpolate(out + size - 2 * step + 1, out[size - step],
+                out[size - 2 * step], step - 1);
 }
 
-static void eval_lpcenv_2parts(TwinContext *tctx, enum FrameType ftype,
+static void eval_lpcenv_2parts(TwinVQContext *tctx, enum TwinVQFrameType ftype,
                                const float *buf, float *lpc,
                                int size, int step)
 {
-    eval_lpcenv_or_interp(tctx, ftype, lpc         , buf, size/2,   step, 0);
-    eval_lpcenv_or_interp(tctx, ftype, lpc + size/2, buf, size/2, 2*step, 1);
+    eval_lpcenv_or_interp(tctx, ftype, lpc, buf, size / 2, step, 0);
+    eval_lpcenv_or_interp(tctx, ftype, lpc + size / 2, buf, size / 2,
+                          2 * step, 1);
 
-    interpolate(lpc+size/2-step+1, lpc[size/2], lpc[size/2-step], step);
+    interpolate(lpc + size / 2 - step + 1, lpc[size / 2],
+                lpc[size / 2 - step], step);
 
-    memset_float(lpc + size - 2*step + 1, lpc[size - 2*step], 2*step - 1);
+    twinvq_memset_float(lpc + size - 2 * step + 1, lpc[size - 2 * step],
+                        2 * step - 1);
 }
 
 /**
@@ -359,8 +169,8 @@
  * bitstream, sum the corresponding vectors and write the result to *out
  * after permutation.
  */
-static void dequant(TwinContext *tctx, GetBitContext *gb, float *out,
-                    enum FrameType ftype,
+static void dequant(TwinVQContext *tctx, const uint8_t *cb_bits, float *out,
+                    enum TwinVQFrameType ftype,
                     const int16_t *cb0, const int16_t *cb1, int cb_len)
 {
     int pos = 0;
@@ -375,156 +185,58 @@
         int bitstream_second_part = (i >= tctx->bits_main_spec_change[ftype]);
 
         int bits = tctx->bits_main_spec[0][ftype][bitstream_second_part];
+        tmp0 = *cb_bits++;
         if (bits == 7) {
-            if (get_bits1(gb))
+            if (tmp0 & 0x40)
                 sign0 = -1;
-            bits = 6;
+            tmp0 &= 0x3F;
         }
-        tmp0 = get_bits(gb, bits);
 
         bits = tctx->bits_main_spec[1][ftype][bitstream_second_part];
-
+        tmp1 = *cb_bits++;
         if (bits == 7) {
-            if (get_bits1(gb))
+            if (tmp1 & 0x40)
                 sign1 = -1;
-
-            bits = 6;
+            tmp1 &= 0x3F;
         }
-        tmp1 = get_bits(gb, bits);
 
-        tab0 = cb0 + tmp0*cb_len;
-        tab1 = cb1 + tmp1*cb_len;
+        tab0 = cb0 + tmp0 * cb_len;
+        tab1 = cb1 + tmp1 * cb_len;
 
         for (j = 0; j < length; j++)
-            out[tctx->permut[ftype][pos+j]] = sign0*tab0[j] + sign1*tab1[j];
+            out[tctx->permut[ftype][pos + j]] = sign0 * tab0[j] +
+                                                sign1 * tab1[j];
 
         pos += length;
     }
-
 }
 
-static inline float mulawinv(float y, float clip, float mu)
+static void dec_gain(TwinVQContext *tctx,
+                     enum TwinVQFrameType ftype, float *out)
 {
-    y = av_clipf(y/clip, -1, 1);
-    return clip * FFSIGN(y) * (exp(log(1+mu) * fabs(y)) - 1) / mu;
-}
-
-/**
- * Evaluate a*b/400 rounded to the nearest integer. When, for example,
- * a*b == 200 and the nearest integer is ill-defined, use a table to emulate
- * the following broken float-based implementation used by the binary decoder:
- *
- * @code
- * static int very_broken_op(int a, int b)
- * {
- *    static float test; // Ugh, force gcc to do the division first...
- *
- *    test = a/400.;
- *    return b * test +  0.5;
- * }
- * @endcode
- *
- * @note if this function is replaced by just ROUNDED_DIV(a*b,400.), the stddev
- * between the original file (before encoding with Yamaha encoder) and the
- * decoded output increases, which leads one to believe that the encoder expects
- * exactly this broken calculation.
- */
-static int very_broken_op(int a, int b)
-{
-    int x = a*b + 200;
-    int size;
-    const uint8_t *rtab;
-
-    if (x%400 || b%5)
-        return x/400;
-
-    x /= 400;
-
-    size = tabs[b/5].size;
-    rtab = tabs[b/5].tab;
-    return x - rtab[size*av_log2(2*(x - 1)/size)+(x - 1)%size];
-}
-
-/**
- * Sum to data a periodic peak of a given period, width and shape.
- *
- * @param period the period of the peak divised by 400.0
- */
-static void add_peak(int period, int width, const float *shape,
-                     float ppc_gain, float *speech, int len)
-{
+    const TwinVQModeTab   *mtab =  tctx->mtab;
+    const TwinVQFrameData *bits = &tctx->bits;
     int i, j;
+    int sub        = mtab->fmode[ftype].sub;
+    float step     = TWINVQ_AMP_MAX     / ((1 << TWINVQ_GAIN_BITS)     - 1);
+    float sub_step = TWINVQ_SUB_AMP_MAX / ((1 << TWINVQ_SUB_GAIN_BITS) - 1);
 
-    const float *shape_end = shape + len;
-    int center;
-
-    // First peak centered around zero
-    for (i = 0; i < width/2; i++)
-        speech[i] += ppc_gain * *shape++;
-
-    for (i = 1; i < ROUNDED_DIV(len,width) ; i++) {
-        center = very_broken_op(period, i);
-        for (j = -width/2; j < (width+1)/2; j++)
-            speech[j+center] += ppc_gain * *shape++;
-    }
-
-    // For the last block, be careful not to go beyond the end of the buffer
-    center = very_broken_op(period, i);
-    for (j = -width/2; j < (width + 1)/2 && shape < shape_end; j++)
-        speech[j+center] += ppc_gain * *shape++;
-}
-
-static void decode_ppc(TwinContext *tctx, int period_coef, const float *shape,
-                       float ppc_gain, float *speech)
-{
-    const ModeTab *mtab = tctx->mtab;
-    int isampf = tctx->avctx->sample_rate/1000;
-    int ibps = tctx->avctx->bit_rate/(1000 * tctx->avctx->channels);
-    int min_period = ROUNDED_DIV(  40*2*mtab->size, isampf);
-    int max_period = ROUNDED_DIV(6*40*2*mtab->size, isampf);
-    int period_range = max_period - min_period;
-
-    // This is actually the period multiplied by 400. It is just linearly coded
-    // between its maximum and minimum value.
-    int period = min_period +
-        ROUNDED_DIV(period_coef*period_range, (1 << mtab->ppc_period_bit) - 1);
-    int width;
-
-    if (isampf == 22 && ibps == 32) {
-        // For some unknown reason, NTT decided to code this case differently...
-        width = ROUNDED_DIV((period + 800)* mtab->peak_per2wid, 400*mtab->size);
-    } else
-        width =             (period      )* mtab->peak_per2wid/(400*mtab->size);
-
-    add_peak(period, width, shape, ppc_gain, speech, mtab->ppc_shape_len);
-}
-
-static void dec_gain(TwinContext *tctx, GetBitContext *gb, enum FrameType ftype,
-                     float *out)
-{
-    const ModeTab *mtab = tctx->mtab;
-    int i, j;
-    int sub = mtab->fmode[ftype].sub;
-    float step     = AMP_MAX     / ((1 <<     GAIN_BITS) - 1);
-    float sub_step = SUB_AMP_MAX / ((1 << SUB_GAIN_BITS) - 1);
-
-    if (ftype == FT_LONG) {
+    if (ftype == TWINVQ_FT_LONG) {
         for (i = 0; i < tctx->avctx->channels; i++)
-            out[i] = (1./(1<<13)) *
-                mulawinv(step * 0.5 + step * get_bits(gb, GAIN_BITS),
-                         AMP_MAX, MULAW_MU);
+            out[i] = (1.0 / (1 << 13)) *
+                     twinvq_mulawinv(step * 0.5 + step * bits->gain_bits[i],
+                                     TWINVQ_AMP_MAX, TWINVQ_MULAW_MU);
     } else {
         for (i = 0; i < tctx->avctx->channels; i++) {
-            float val = (1./(1<<23)) *
-                mulawinv(step * 0.5 + step * get_bits(gb, GAIN_BITS),
-                         AMP_MAX, MULAW_MU);
+            float val = (1.0 / (1 << 23)) *
+                        twinvq_mulawinv(step * 0.5 + step * bits->gain_bits[i],
+                                        TWINVQ_AMP_MAX, TWINVQ_MULAW_MU);
 
-            for (j = 0; j < sub; j++) {
-                out[i*sub + j] =
-                    val*mulawinv(sub_step* 0.5 +
-                                 sub_step* get_bits(gb, SUB_GAIN_BITS),
-                                 SUB_AMP_MAX, MULAW_MU);
-            }
+            for (j = 0; j < sub; j++)
+                out[i * sub + j] =
+                    val * twinvq_mulawinv(sub_step * 0.5 +
+                                          sub_step * bits->sub_gain_bits[i * sub + j],
+                                          TWINVQ_SUB_AMP_MAX, TWINVQ_MULAW_MU);
         }
     }
 }
@@ -540,23 +252,23 @@
     int i;
     float min_dist2 = min_dist * 0.5;
     for (i = 1; i < order; i++)
-        if (lsp[i] - lsp[i-1] < min_dist) {
-            float avg = (lsp[i] + lsp[i-1]) * 0.5;
+        if (lsp[i] - lsp[i - 1] < min_dist) {
+            float avg = (lsp[i] + lsp[i - 1]) * 0.5;
 
-            lsp[i-1] = avg - min_dist2;
-            lsp[i  ] = avg + min_dist2;
+            lsp[i - 1] = avg - min_dist2;
+            lsp[i]     = avg + min_dist2;
         }
 }
 
-static void decode_lsp(TwinContext *tctx, int lpc_idx1, uint8_t *lpc_idx2,
+static void decode_lsp(TwinVQContext *tctx, int lpc_idx1, uint8_t *lpc_idx2,
                        int lpc_hist_idx, float *lsp, float *hist)
 {
-    const ModeTab *mtab = tctx->mtab;
+    const TwinVQModeTab *mtab = tctx->mtab;
     int i, j;
 
-    const float *cb  =  mtab->lspcodebook;
-    const float *cb2 =  cb  + (1 << mtab->lsp_bit1)*mtab->n_lsp;
-    const float *cb3 =  cb2 + (1 << mtab->lsp_bit2)*mtab->n_lsp;
+    const float *cb  = mtab->lspcodebook;
+    const float *cb2 = cb  + (1 << mtab->lsp_bit1) * mtab->n_lsp;
+    const float *cb3 = cb2 + (1 << mtab->lsp_bit2) * mtab->n_lsp;
 
     const int8_t funny_rounding[4] = {
         -2,
@@ -567,17 +279,18 @@
 
     j = 0;
     for (i = 0; i < mtab->lsp_split; i++) {
-        int chunk_end = ((i + 1)*mtab->n_lsp + funny_rounding[i])/mtab->lsp_split;
+        int chunk_end = ((i + 1) * mtab->n_lsp + funny_rounding[i]) /
+                        mtab->lsp_split;
         for (; j < chunk_end; j++)
-            lsp[j] = cb [lpc_idx1    * mtab->n_lsp + j] +
+            lsp[j] = cb[lpc_idx1     * mtab->n_lsp + j] +
                      cb2[lpc_idx2[i] * mtab->n_lsp + j];
     }
 
     rearrange_lsp(mtab->n_lsp, lsp, 0.0001);
 
     for (i = 0; i < mtab->n_lsp; i++) {
-        float tmp1 = 1. -          cb3[lpc_hist_idx*mtab->n_lsp + i];
-        float tmp2 =     hist[i] * cb3[lpc_hist_idx*mtab->n_lsp + i];
+        float tmp1 = 1.0     - cb3[lpc_hist_idx * mtab->n_lsp + i];
+        float tmp2 = hist[i] * cb3[lpc_hist_idx * mtab->n_lsp + i];
         hist[i] = lsp[i];
         lsp[i]  = lsp[i] * tmp1 + tmp2;
     }
@@ -587,96 +300,93 @@
     ff_sort_nearly_sorted_floats(lsp, mtab->n_lsp);
 }
 
-static void dec_lpc_spectrum_inv(TwinContext *tctx, float *lsp,
-                                 enum FrameType ftype, float *lpc)
+static void dec_lpc_spectrum_inv(TwinVQContext *tctx, float *lsp,
+                                 enum TwinVQFrameType ftype, float *lpc)
 {
     int i;
     int size = tctx->mtab->size / tctx->mtab->fmode[ftype].sub;
 
     for (i = 0; i < tctx->mtab->n_lsp; i++)
-        lsp[i] =  2*cos(lsp[i]);
+        lsp[i] = 2 * cos(lsp[i]);
 
     switch (ftype) {
-    case FT_LONG:
+    case TWINVQ_FT_LONG:
         eval_lpcenv_2parts(tctx, ftype, lsp, lpc, size, 8);
         break;
-    case FT_MEDIUM:
+    case TWINVQ_FT_MEDIUM:
         eval_lpcenv_2parts(tctx, ftype, lsp, lpc, size, 2);
         break;
-    case FT_SHORT:
+    case TWINVQ_FT_SHORT:
         eval_lpcenv(tctx, lsp, lpc);
         break;
     }
 }
 
-static void imdct_and_window(TwinContext *tctx, enum FrameType ftype, int wtype,
-                            float *in, float *prev, int ch)
+static const uint8_t wtype_to_wsize[] = { 0, 0, 2, 2, 2, 1, 0, 1, 1 };
+
+static void imdct_and_window(TwinVQContext *tctx, enum TwinVQFrameType ftype,
+                             int wtype, float *in, float *prev, int ch)
 {
     FFTContext *mdct = &tctx->mdct_ctx[ftype];
-    const ModeTab *mtab = tctx->mtab;
+    const TwinVQModeTab *mtab = tctx->mtab;
     int bsize = mtab->size / mtab->fmode[ftype].sub;
     int size  = mtab->size;
     float *buf1 = tctx->tmp_buf;
-    int j;
-    int wsize; // Window size
-    float *out = tctx->curr_frame + 2*ch*mtab->size;
+    int j, first_wsize, wsize; // Window size
+    float *out  = tctx->curr_frame + 2 * ch * mtab->size;
     float *out2 = out;
     float *prev_buf;
-    int first_wsize;
-
-    static const uint8_t wtype_to_wsize[]      = {0, 0, 2, 2, 2, 1, 0, 1, 1};
     int types_sizes[] = {
-        mtab->size /    mtab->fmode[FT_LONG  ].sub,
-        mtab->size /    mtab->fmode[FT_MEDIUM].sub,
-        mtab->size / (2*mtab->fmode[FT_SHORT ].sub),
+        mtab->size /  mtab->fmode[TWINVQ_FT_LONG].sub,
+        mtab->size /  mtab->fmode[TWINVQ_FT_MEDIUM].sub,
+        mtab->size / (mtab->fmode[TWINVQ_FT_SHORT].sub * 2),
     };
 
-    wsize = types_sizes[wtype_to_wsize[wtype]];
+    wsize       = types_sizes[wtype_to_wsize[wtype]];
     first_wsize = wsize;
-    prev_buf = prev + (size - bsize)/2;
+    prev_buf    = prev + (size - bsize) / 2;
 
     for (j = 0; j < mtab->fmode[ftype].sub; j++) {
-        int sub_wtype = ftype == FT_MEDIUM ? 8 : wtype;
+        int sub_wtype = ftype == TWINVQ_FT_MEDIUM ? 8 : wtype;
 
         if (!j && wtype == 4)
             sub_wtype = 4;
-        else if (j == mtab->fmode[ftype].sub-1 && wtype == 7)
+        else if (j == mtab->fmode[ftype].sub - 1 && wtype == 7)
             sub_wtype = 7;
 
         wsize = types_sizes[wtype_to_wsize[sub_wtype]];
 
-        mdct->imdct_half(mdct, buf1 + bsize*j, in + bsize*j);
+        mdct->imdct_half(mdct, buf1 + bsize * j, in + bsize * j);
 
-        tctx->fdsp.vector_fmul_window(out2, prev_buf + (bsize-wsize) / 2,
+        tctx->fdsp.vector_fmul_window(out2, prev_buf + (bsize - wsize) / 2,
                                       buf1 + bsize * j,
                                       ff_sine_windows[av_log2(wsize)],
                                       wsize / 2);
         out2 += wsize;
 
-        memcpy(out2, buf1 + bsize*j + wsize/2, (bsize - wsize/2)*sizeof(float));
+        memcpy(out2, buf1 + bsize * j + wsize / 2,
+               (bsize - wsize / 2) * sizeof(float));
 
-        out2 += ftype == FT_MEDIUM ? (bsize-wsize)/2 : bsize - wsize;
+        out2 += ftype == TWINVQ_FT_MEDIUM ? (bsize - wsize) / 2 : bsize - wsize;
 
-        prev_buf = buf1 + bsize*j + bsize/2;
+        prev_buf = buf1 + bsize * j + bsize / 2;
     }
 
-    tctx->last_block_pos[ch] = (size + first_wsize)/2;
+    tctx->last_block_pos[ch] = (size + first_wsize) / 2;
 }
 
-static void imdct_output(TwinContext *tctx, enum FrameType ftype, int wtype,
-                         float **out)
+static void imdct_output(TwinVQContext *tctx, enum TwinVQFrameType ftype,
+                         int wtype, float **out)
 {
-    const ModeTab *mtab = tctx->mtab;
-    int size1, size2;
-    float *prev_buf = tctx->prev_frame + tctx->last_block_pos[0];
-    int i;
+    const TwinVQModeTab *mtab = tctx->mtab;
+    float *prev_buf           = tctx->prev_frame + tctx->last_block_pos[0];
+    int size1, size2, i;
 
-    for (i = 0; i < tctx->avctx->channels; i++) {
+    for (i = 0; i < tctx->avctx->channels; i++)
         imdct_and_window(tctx, ftype, wtype,
-                         tctx->spectrum + i*mtab->size,
-                         prev_buf + 2*i*mtab->size,
+                         tctx->spectrum + i * mtab->size,
+                         prev_buf + 2 * i * mtab->size,
                          i);
-    }
 
     if (!out)
         return;
@@ -684,118 +394,66 @@
     size2 = tctx->last_block_pos[0];
     size1 = mtab->size - size2;
 
-    memcpy(&out[0][0    ], prev_buf,         size1 * sizeof(out[0][0]));
+    memcpy(&out[0][0],     prev_buf,         size1 * sizeof(out[0][0]));
     memcpy(&out[0][size1], tctx->curr_frame, size2 * sizeof(out[0][0]));
 
     if (tctx->avctx->channels == 2) {
-        memcpy(&out[1][0],     &prev_buf[2*mtab->size],         size1 * sizeof(out[1][0]));
-        memcpy(&out[1][size1], &tctx->curr_frame[2*mtab->size], size2 * sizeof(out[1][0]));
+        memcpy(&out[1][0], &prev_buf[2 * mtab->size],
+               size1 * sizeof(out[1][0]));
+        memcpy(&out[1][size1], &tctx->curr_frame[2 * mtab->size],
+               size2 * sizeof(out[1][0]));
         tctx->fdsp.butterflies_float(out[0], out[1], mtab->size);
     }
 }
 
-static void dec_bark_env(TwinContext *tctx, const uint8_t *in, int use_hist,
-                         int ch, float *out, float gain, enum FrameType ftype)
+static void read_and_decode_spectrum(TwinVQContext *tctx, float *out,
+                                     enum TwinVQFrameType ftype)
 {
-    const ModeTab *mtab = tctx->mtab;
-    int i,j;
-    float *hist = tctx->bark_hist[ftype][ch];
-    float val = ((const float []) {0.4, 0.35, 0.28})[ftype];
-    int bark_n_coef  = mtab->fmode[ftype].bark_n_coef;
-    int fw_cb_len = mtab->fmode[ftype].bark_env_size / bark_n_coef;
-    int idx = 0;
-
-    for (i = 0; i < fw_cb_len; i++)
-        for (j = 0; j < bark_n_coef; j++, idx++) {
-            float tmp2 =
-                mtab->fmode[ftype].bark_cb[fw_cb_len*in[j] + i] * (1./4096);
-            float st = use_hist ?
-                (1. - val) * tmp2 + val*hist[idx] + 1. : tmp2 + 1.;
-
-            hist[idx] = tmp2;
-            if (st < -1.) st = 1.;
-
-            memset_float(out, st * gain, mtab->fmode[ftype].bark_tab[idx]);
-            out += mtab->fmode[ftype].bark_tab[idx];
-        }
-
-}
-
-static void read_and_decode_spectrum(TwinContext *tctx, GetBitContext *gb,
-                                     float *out, enum FrameType ftype)
-{
-    const ModeTab *mtab = tctx->mtab;
-    int channels = tctx->avctx->channels;
-    int sub = mtab->fmode[ftype].sub;
+    const TwinVQModeTab *mtab = tctx->mtab;
+    TwinVQFrameData *bits     = &tctx->bits;
+    int channels              = tctx->avctx->channels;
+    int sub        = mtab->fmode[ftype].sub;
     int block_size = mtab->size / sub;
-    float gain[CHANNELS_MAX*SUBBLOCKS_MAX];
-    float ppc_shape[PPC_SHAPE_LEN_MAX * CHANNELS_MAX * 4];
-    uint8_t bark1[CHANNELS_MAX][SUBBLOCKS_MAX][BARK_N_COEF_MAX];
-    uint8_t bark_use_hist[CHANNELS_MAX][SUBBLOCKS_MAX];
+    float gain[TWINVQ_CHANNELS_MAX * TWINVQ_SUBBLOCKS_MAX];
+    float ppc_shape[TWINVQ_PPC_SHAPE_LEN_MAX * TWINVQ_CHANNELS_MAX * 4];
 
-    uint8_t lpc_idx1[CHANNELS_MAX];
-    uint8_t lpc_idx2[CHANNELS_MAX][LSP_SPLIT_MAX];
-    uint8_t lpc_hist_idx[CHANNELS_MAX];
+    int i, j;
 
-    int i, j, k;
-
-    dequant(tctx, gb, out, ftype,
+    dequant(tctx, bits->main_coeffs, out, ftype,
             mtab->fmode[ftype].cb0, mtab->fmode[ftype].cb1,
             mtab->fmode[ftype].cb_len_read);
 
-    for (i = 0; i < channels; i++)
-        for (j = 0; j < sub; j++)
-            for (k = 0; k < mtab->fmode[ftype].bark_n_coef; k++)
-                bark1[i][j][k] =
-                    get_bits(gb, mtab->fmode[ftype].bark_n_bit);
+    dec_gain(tctx, ftype, gain);
 
-    for (i = 0; i < channels; i++)
-        for (j = 0; j < sub; j++)
-            bark_use_hist[i][j] = get_bits1(gb);
-
-    dec_gain(tctx, gb, ftype, gain);
-
-    for (i = 0; i < channels; i++) {
-        lpc_hist_idx[i] = get_bits(gb, tctx->mtab->lsp_bit0);
-        lpc_idx1    [i] = get_bits(gb, tctx->mtab->lsp_bit1);
-
-        for (j = 0; j < tctx->mtab->lsp_split; j++)
-            lpc_idx2[i][j] = get_bits(gb, tctx->mtab->lsp_bit2);
-    }
-
-    if (ftype == FT_LONG) {
-        int cb_len_p = (tctx->n_div[3] + mtab->ppc_shape_len*channels - 1)/
-            tctx->n_div[3];
-        dequant(tctx, gb, ppc_shape, FT_PPC, mtab->ppc_shape_cb,
-                mtab->ppc_shape_cb + cb_len_p*PPC_SHAPE_CB_SIZE, cb_len_p);
+    if (ftype == TWINVQ_FT_LONG) {
+        int cb_len_p = (tctx->n_div[3] + mtab->ppc_shape_len * channels - 1) /
+                       tctx->n_div[3];
+        dequant(tctx, bits->ppc_coeffs, ppc_shape,
+                TWINVQ_FT_PPC, mtab->ppc_shape_cb,
+                mtab->ppc_shape_cb + cb_len_p * TWINVQ_PPC_SHAPE_CB_SIZE,
+                cb_len_p);
     }
 
     for (i = 0; i < channels; i++) {
         float *chunk = out + mtab->size * i;
-        float lsp[LSP_COEFS_MAX];
+        float lsp[TWINVQ_LSP_COEFS_MAX];
 
         for (j = 0; j < sub; j++) {
-            dec_bark_env(tctx, bark1[i][j], bark_use_hist[i][j], i,
-                         tctx->tmp_buf, gain[sub*i+j], ftype);
+            tctx->dec_bark_env(tctx, bits->bark1[i][j],
+                               bits->bark_use_hist[i][j], i,
+                               tctx->tmp_buf, gain[sub * i + j], ftype);
 
-            tctx->fdsp.vector_fmul(chunk + block_size*j, chunk + block_size*j,
+            tctx->fdsp.vector_fmul(chunk + block_size * j,
+                                   chunk + block_size * j,
                                    tctx->tmp_buf, block_size);
-
         }
 
-        if (ftype == FT_LONG) {
-            float pgain_step = 25000. / ((1 << mtab->pgain_bit) - 1);
-            int p_coef = get_bits(gb, tctx->mtab->ppc_period_bit);
-            int g_coef = get_bits(gb, tctx->mtab->pgain_bit);
-            float v = 1./8192*
-                mulawinv(pgain_step*g_coef+ pgain_step/2, 25000., PGAIN_MU);
+        if (ftype == TWINVQ_FT_LONG)
+            tctx->decode_ppc(tctx, bits->p_coef[i], bits->g_coef[i],
+                             ppc_shape + i * mtab->ppc_shape_len, chunk);
 
-            decode_ppc(tctx, p_coef, ppc_shape + i*mtab->ppc_shape_len, v,
-                       chunk);
-        }
-
-        decode_lsp(tctx, lpc_idx1[i], lpc_idx2[i], lpc_hist_idx[i], lsp,
-                   tctx->lsp_hist[i]);
+        decode_lsp(tctx, bits->lpc_idx1[i], bits->lpc_idx2[i],
+                   bits->lpc_hist_idx[i], lsp, tctx->lsp_hist[i]);
 
         dec_lpc_spectrum_inv(tctx, lsp, ftype, tctx->tmp_buf);
 
@@ -806,28 +464,22 @@
     }
 }
 
-static int twin_decode_frame(AVCodecContext * avctx, void *data,
-                             int *got_frame_ptr, AVPacket *avpkt)
+const enum TwinVQFrameType ff_twinvq_wtype_to_ftype_table[] = {
+    TWINVQ_FT_LONG,   TWINVQ_FT_LONG, TWINVQ_FT_SHORT, TWINVQ_FT_LONG,
+    TWINVQ_FT_MEDIUM, TWINVQ_FT_LONG, TWINVQ_FT_LONG,  TWINVQ_FT_MEDIUM,
+    TWINVQ_FT_MEDIUM
+};
+
+int ff_twinvq_decode_frame(AVCodecContext *avctx, void *data,
+                           int *got_frame_ptr, AVPacket *avpkt)
 {
     AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    TwinContext *tctx = avctx->priv_data;
-    GetBitContext gb;
-    const ModeTab *mtab = tctx->mtab;
+    int buf_size       = avpkt->size;
+    TwinVQContext *tctx = avctx->priv_data;
+    const TwinVQModeTab *mtab = tctx->mtab;
     float **out = NULL;
-    enum FrameType ftype;
-    int window_type, ret;
-    static const enum FrameType wtype_to_ftype_table[] = {
-        FT_LONG,   FT_LONG, FT_SHORT, FT_LONG,
-        FT_MEDIUM, FT_LONG, FT_LONG,  FT_MEDIUM, FT_MEDIUM
-    };
-
-    if (buf_size*8 < avctx->bit_rate*mtab->size/avctx->sample_rate + 8) {
-        av_log(avctx, AV_LOG_ERROR,
-               "Frame too small (%d bytes). Truncated file?\n", buf_size);
-        return AVERROR(EINVAL);
-    }
+    int ret;
 
     /* get output buffer */
     if (tctx->discarded_packets >= 2) {
@@ -837,22 +489,14 @@
         out = (float **)frame->extended_data;
     }
 
-    init_get_bits(&gb, buf, buf_size * 8);
-    skip_bits(&gb, get_bits(&gb, 8));
-    window_type = get_bits(&gb, WINDOW_TYPE_BITS);
+    if ((ret = tctx->read_bitstream(avctx, tctx, buf, buf_size)) < 0)
+        return ret;
 
-    if (window_type > 8) {
-        av_log(avctx, AV_LOG_ERROR, "Invalid window type, broken sample?\n");
-        return -1;
-    }
+    read_and_decode_spectrum(tctx, tctx->spectrum, tctx->bits.ftype);
 
-    ftype = wtype_to_ftype_table[window_type];
+    imdct_output(tctx, tctx->bits.ftype, tctx->bits.window_type, out);
 
-    read_and_decode_spectrum(tctx, &gb, tctx->spectrum, ftype);
-
-    imdct_output(tctx, ftype, window_type, out);
-
-    FFSWAP(float*, tctx->curr_frame, tctx->prev_frame);
+    FFSWAP(float *, tctx->curr_frame, tctx->prev_frame);
 
     if (tctx->discarded_packets < 2) {
         tctx->discarded_packets++;
@@ -868,19 +512,19 @@
 /**
  * Init IMDCT and windowing tables
  */
-static av_cold int init_mdct_win(TwinContext *tctx)
+static av_cold int init_mdct_win(TwinVQContext *tctx)
 {
     int i, j, ret;
-    const ModeTab *mtab = tctx->mtab;
-    int size_s = mtab->size / mtab->fmode[FT_SHORT].sub;
-    int size_m = mtab->size / mtab->fmode[FT_MEDIUM].sub;
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int size_s = mtab->size / mtab->fmode[TWINVQ_FT_SHORT].sub;
+    int size_m = mtab->size / mtab->fmode[TWINVQ_FT_MEDIUM].sub;
     int channels = tctx->avctx->channels;
-    float norm = channels == 1 ? 2. : 1.;
+    float norm = channels == 1 ? 2.0 : 1.0;
 
     for (i = 0; i < 3; i++) {
-        int bsize = tctx->mtab->size/tctx->mtab->fmode[i].sub;
+        int bsize = tctx->mtab->size / tctx->mtab->fmode[i].sub;
         if ((ret = ff_mdct_init(&tctx->mdct_ctx[i], av_log2(bsize) + 1, 1,
-                                -sqrt(norm/bsize) / (1<<15))))
+                                -sqrt(norm / bsize) / (1 << 15))))
             return ret;
     }
 
@@ -898,23 +542,23 @@
                      alloc_fail);
 
     for (i = 0; i < 3; i++) {
-        int m = 4*mtab->size/mtab->fmode[i].sub;
-        double freq = 2*M_PI/m;
+        int m       = 4 * mtab->size / mtab->fmode[i].sub;
+        double freq = 2 * M_PI / m;
         FF_ALLOC_OR_GOTO(tctx->avctx, tctx->cos_tabs[i],
                          (m / 4) * sizeof(*tctx->cos_tabs[i]), alloc_fail);
 
-        for (j = 0; j <= m/8; j++)
-            tctx->cos_tabs[i][j] = cos((2*j + 1)*freq);
-        for (j = 1; j <  m/8; j++)
-            tctx->cos_tabs[i][m/4-j] = tctx->cos_tabs[i][j];
+        for (j = 0; j <= m / 8; j++)
+            tctx->cos_tabs[i][j] = cos((2 * j + 1) * freq);
+        for (j = 1; j < m / 8; j++)
+            tctx->cos_tabs[i][m / 4 - j] = tctx->cos_tabs[i][j];
     }
 
-
     ff_init_ff_sine_windows(av_log2(size_m));
-    ff_init_ff_sine_windows(av_log2(size_s/2));
+    ff_init_ff_sine_windows(av_log2(size_s / 2));
     ff_init_ff_sine_windows(av_log2(mtab->size));
 
     return 0;
+
 alloc_fail:
     return AVERROR(ENOMEM);
 }
@@ -928,26 +572,25 @@
 static void permutate_in_line(int16_t *tab, int num_vect, int num_blocks,
                               int block_size,
                               const uint8_t line_len[2], int length_div,
-                              enum FrameType ftype)
-
+                              enum TwinVQFrameType ftype)
 {
-    int i,j;
+    int i, j;
 
     for (i = 0; i < line_len[0]; i++) {
         int shift;
 
-        if (num_blocks == 1 ||
-            (ftype == FT_LONG && num_vect % num_blocks) ||
-            (ftype != FT_LONG && num_vect & 1         ) ||
+        if (num_blocks == 1                                    ||
+            (ftype == TWINVQ_FT_LONG && num_vect % num_blocks) ||
+            (ftype != TWINVQ_FT_LONG && num_vect & 1)          ||
             i == line_len[1]) {
             shift = 0;
-        } else if (ftype == FT_LONG) {
+        } else if (ftype == TWINVQ_FT_LONG) {
             shift = i;
         } else
-            shift = i*i;
+            shift = i * i;
 
-        for (j = 0; j < num_vect && (j+num_vect*i < block_size*num_blocks); j++)
-            tab[i*num_vect+j] = i*num_vect + (j + shift) % num_vect;
+        for (j = 0; j < num_vect && (j + num_vect * i < block_size * num_blocks); j++)
+            tab[i * num_vect + j] = i * num_vect + (j + shift) % num_vect;
     }
 }
 
@@ -969,31 +612,32 @@
 static void transpose_perm(int16_t *out, int16_t *in, int num_vect,
                            const uint8_t line_len[2], int length_div)
 {
-    int i,j;
-    int cont= 0;
+    int i, j;
+    int cont = 0;
+
     for (i = 0; i < num_vect; i++)
         for (j = 0; j < line_len[i >= length_div]; j++)
-            out[cont++] = in[j*num_vect + i];
+            out[cont++] = in[j * num_vect + i];
 }
 
 static void linear_perm(int16_t *out, int16_t *in, int n_blocks, int size)
 {
-    int block_size = size/n_blocks;
+    int block_size = size / n_blocks;
     int i;
 
     for (i = 0; i < size; i++)
         out[i] = block_size * (in[i] % n_blocks) + in[i] / n_blocks;
 }
 
-static av_cold void construct_perm_table(TwinContext *tctx,enum FrameType ftype)
+static av_cold void construct_perm_table(TwinVQContext *tctx,
+                                         enum TwinVQFrameType ftype)
 {
-    int block_size;
-    const ModeTab *mtab = tctx->mtab;
-    int size;
-    int16_t *tmp_perm = (int16_t *) tctx->tmp_buf;
+    int block_size, size;
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int16_t *tmp_perm = (int16_t *)tctx->tmp_buf;
 
-    if (ftype == FT_PPC) {
-        size  = tctx->avctx->channels;
+    if (ftype == TWINVQ_FT_PPC) {
+        size       = tctx->avctx->channels;
         block_size = mtab->ppc_shape_len;
     } else {
         size       = tctx->avctx->channels * mtab->fmode[ftype].sub;
@@ -1008,81 +652,87 @@
                    tctx->length[ftype], tctx->length_change[ftype]);
 
     linear_perm(tctx->permut[ftype], tctx->permut[ftype], size,
-                size*block_size);
+                size * block_size);
 }
 
-static av_cold void init_bitstream_params(TwinContext *tctx)
+static av_cold void init_bitstream_params(TwinVQContext *tctx)
 {
-    const ModeTab *mtab = tctx->mtab;
-    int n_ch = tctx->avctx->channels;
-    int total_fr_bits = tctx->avctx->bit_rate*mtab->size/
-                             tctx->avctx->sample_rate;
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int n_ch                  = tctx->avctx->channels;
+    int total_fr_bits         = tctx->avctx->bit_rate * mtab->size /
+                                tctx->avctx->sample_rate;
 
-    int lsp_bits_per_block = n_ch*(mtab->lsp_bit0 + mtab->lsp_bit1 +
-                                   mtab->lsp_split*mtab->lsp_bit2);
+    int lsp_bits_per_block = n_ch * (mtab->lsp_bit0 + mtab->lsp_bit1 +
+                                     mtab->lsp_split * mtab->lsp_bit2);
 
-    int ppc_bits = n_ch*(mtab->pgain_bit + mtab->ppc_shape_bit +
-                         mtab->ppc_period_bit);
+    int ppc_bits = n_ch * (mtab->pgain_bit + mtab->ppc_shape_bit +
+                           mtab->ppc_period_bit);
 
-    int bsize_no_main_cb[3];
-    int bse_bits[3];
-    int i;
-    enum FrameType frametype;
+    int bsize_no_main_cb[3], bse_bits[3], i;
+    enum TwinVQFrameType frametype;
 
     for (i = 0; i < 3; i++)
         // +1 for history usage switch
         bse_bits[i] = n_ch *
-            (mtab->fmode[i].bark_n_coef * mtab->fmode[i].bark_n_bit + 1);
+                      (mtab->fmode[i].bark_n_coef *
+                       mtab->fmode[i].bark_n_bit + 1);
 
     bsize_no_main_cb[2] = bse_bits[2] + lsp_bits_per_block + ppc_bits +
-                          WINDOW_TYPE_BITS + n_ch*GAIN_BITS;
+                          TWINVQ_WINDOW_TYPE_BITS + n_ch * TWINVQ_GAIN_BITS;
 
     for (i = 0; i < 2; i++)
         bsize_no_main_cb[i] =
-            lsp_bits_per_block + n_ch*GAIN_BITS + WINDOW_TYPE_BITS +
-            mtab->fmode[i].sub*(bse_bits[i] + n_ch*SUB_GAIN_BITS);
+            lsp_bits_per_block + n_ch * TWINVQ_GAIN_BITS +
+            TWINVQ_WINDOW_TYPE_BITS +
+            mtab->fmode[i].sub * (bse_bits[i] + n_ch * TWINVQ_SUB_GAIN_BITS);
+
+    if (tctx->codec == TWINVQ_CODEC_METASOUND) {
+        bsize_no_main_cb[1] += 2;
+        bsize_no_main_cb[2] += 2;
+    }
 
     // The remaining bits are all used for the main spectrum coefficients
     for (i = 0; i < 4; i++) {
-        int bit_size;
-        int vect_size;
+        int bit_size, vect_size;
         int rounded_up, rounded_down, num_rounded_down, num_rounded_up;
         if (i == 3) {
             bit_size  = n_ch * mtab->ppc_shape_bit;
             vect_size = n_ch * mtab->ppc_shape_len;
         } else {
-            bit_size = total_fr_bits - bsize_no_main_cb[i];
+            bit_size  = total_fr_bits - bsize_no_main_cb[i];
             vect_size = n_ch * mtab->size;
         }
 
         tctx->n_div[i] = (bit_size + 13) / 14;
 
-        rounded_up   = (bit_size + tctx->n_div[i] - 1)/tctx->n_div[i];
-        rounded_down = (bit_size           )/tctx->n_div[i];
-        num_rounded_down = rounded_up * tctx->n_div[i] - bit_size;
-        num_rounded_up = tctx->n_div[i] - num_rounded_down;
-        tctx->bits_main_spec[0][i][0] = (rounded_up   + 1)/2;
-        tctx->bits_main_spec[1][i][0] = (rounded_up      )/2;
-        tctx->bits_main_spec[0][i][1] = (rounded_down + 1)/2;
-        tctx->bits_main_spec[1][i][1] = (rounded_down    )/2;
+        rounded_up                     = (bit_size + tctx->n_div[i] - 1) /
+                                         tctx->n_div[i];
+        rounded_down                   = (bit_size) / tctx->n_div[i];
+        num_rounded_down               = rounded_up * tctx->n_div[i] - bit_size;
+        num_rounded_up                 = tctx->n_div[i] - num_rounded_down;
+        tctx->bits_main_spec[0][i][0]  = (rounded_up + 1)   / 2;
+        tctx->bits_main_spec[1][i][0]  =  rounded_up        / 2;
+        tctx->bits_main_spec[0][i][1]  = (rounded_down + 1) / 2;
+        tctx->bits_main_spec[1][i][1]  =  rounded_down      / 2;
         tctx->bits_main_spec_change[i] = num_rounded_up;
 
-        rounded_up   = (vect_size + tctx->n_div[i] - 1)/tctx->n_div[i];
-        rounded_down = (vect_size                     )/tctx->n_div[i];
-        num_rounded_down = rounded_up * tctx->n_div[i] - vect_size;
-        num_rounded_up = tctx->n_div[i] - num_rounded_down;
-        tctx->length[i][0] = rounded_up;
-        tctx->length[i][1] = rounded_down;
+        rounded_up             = (vect_size + tctx->n_div[i] - 1) /
+                                 tctx->n_div[i];
+        rounded_down           = (vect_size) / tctx->n_div[i];
+        num_rounded_down       = rounded_up * tctx->n_div[i] - vect_size;
+        num_rounded_up         = tctx->n_div[i] - num_rounded_down;
+        tctx->length[i][0]     = rounded_up;
+        tctx->length[i][1]     = rounded_down;
         tctx->length_change[i] = num_rounded_up;
     }
 
-    for (frametype = FT_SHORT; frametype <= FT_PPC; frametype++)
+    for (frametype = TWINVQ_FT_SHORT; frametype <= TWINVQ_FT_PPC; frametype++)
         construct_perm_table(tctx, frametype);
 }
 
-static av_cold int twin_decode_close(AVCodecContext *avctx)
+av_cold int ff_twinvq_decode_close(AVCodecContext *avctx)
 {
-    TwinContext *tctx = avctx->priv_data;
+    TwinVQContext *tctx = avctx->priv_data;
     int i;
 
     for (i = 0; i < 3; i++) {
@@ -1090,7 +740,6 @@
         av_free(tctx->cos_tabs[i]);
     }
 
-
     av_free(tctx->curr_frame);
     av_free(tctx->spectrum);
     av_free(tctx->prev_frame);
@@ -1099,87 +748,24 @@
     return 0;
 }
 
-static av_cold int twin_decode_init(AVCodecContext *avctx)
+av_cold int ff_twinvq_decode_init(AVCodecContext *avctx)
 {
     int ret;
-    TwinContext *tctx = avctx->priv_data;
-    int isampf, ibps;
+    TwinVQContext *tctx = avctx->priv_data;
 
     tctx->avctx       = avctx;
     avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
 
-    if (!avctx->extradata || avctx->extradata_size < 12) {
-        av_log(avctx, AV_LOG_ERROR, "Missing or incomplete extradata\n");
-        return AVERROR_INVALIDDATA;
-    }
-    avctx->channels = AV_RB32(avctx->extradata    ) + 1;
-    avctx->bit_rate = AV_RB32(avctx->extradata + 4) * 1000;
-    isampf          = AV_RB32(avctx->extradata + 8);
-
-    if (isampf < 8 || isampf > 44) {
-        av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate\n");
-        return AVERROR_INVALIDDATA;
-    }
-    switch (isampf) {
-    case 44: avctx->sample_rate = 44100;         break;
-    case 22: avctx->sample_rate = 22050;         break;
-    case 11: avctx->sample_rate = 11025;         break;
-    default: avctx->sample_rate = isampf * 1000; break;
-    }
-
-    if (avctx->channels <= 0 || avctx->channels > CHANNELS_MAX) {
-        av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %i\n",
-               avctx->channels);
-        return -1;
-    }
-    avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO :
-                                                   AV_CH_LAYOUT_STEREO;
-
-    ibps = avctx->bit_rate / (1000 * avctx->channels);
-
-    if (ibps > 255U) {
-        av_log(avctx, AV_LOG_ERROR, "unsupported per channel bitrate %dkbps\n", ibps);
-        return AVERROR_INVALIDDATA;
-    }
-
-    switch ((isampf << 8) +  ibps) {
-    case (8 <<8) +  8: tctx->mtab = &mode_08_08; break;
-    case (11<<8) +  8: tctx->mtab = &mode_11_08; break;
-    case (11<<8) + 10: tctx->mtab = &mode_11_10; break;
-    case (16<<8) + 16: tctx->mtab = &mode_16_16; break;
-    case (22<<8) + 20: tctx->mtab = &mode_22_20; break;
-    case (22<<8) + 24: tctx->mtab = &mode_22_24; break;
-    case (22<<8) + 32: tctx->mtab = &mode_22_32; break;
-    case (44<<8) + 40: tctx->mtab = &mode_44_40; break;
-    case (44<<8) + 48: tctx->mtab = &mode_44_48; break;
-    default:
-        av_log(avctx, AV_LOG_ERROR, "This version does not support %d kHz - %d kbit/s/ch mode.\n", isampf, isampf);
-        return -1;
-    }
-
     avpriv_float_dsp_init(&tctx->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
     if ((ret = init_mdct_win(tctx))) {
         av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n");
-        twin_decode_close(avctx);
+        ff_twinvq_decode_close(avctx);
         return ret;
     }
     init_bitstream_params(tctx);
 
-    memset_float(tctx->bark_hist[0][0], 0.1, FF_ARRAY_ELEMS(tctx->bark_hist));
+    twinvq_memset_float(tctx->bark_hist[0][0], 0.1,
+                        FF_ARRAY_ELEMS(tctx->bark_hist));
 
     return 0;
 }
-
-AVCodec ff_twinvq_decoder = {
-    .name           = "twinvq",
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_TWINVQ,
-    .priv_data_size = sizeof(TwinContext),
-    .init           = twin_decode_init,
-    .close          = twin_decode_close,
-    .decode         = twin_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("VQF TwinVQ"),
-    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
-                                                      AV_SAMPLE_FMT_NONE },
-};
diff --git a/libavcodec/twinvq.h b/libavcodec/twinvq.h
new file mode 100644
index 0000000..44215db
--- /dev/null
+++ b/libavcodec/twinvq.h
@@ -0,0 +1,198 @@
+/*
+ * TwinVQ decoder
+ * Copyright (c) 2009 Vitor Sessak
+ *
+ * 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
+ */
+
+#ifndef AVCODEC_TWINVQ_H
+#define AVCODEC_TWINVQ_H
+
+#include <math.h>
+#include <stdint.h>
+
+#include "libavutil/common.h"
+#include "libavutil/float_dsp.h"
+#include "avcodec.h"
+#include "fft.h"
+#include "internal.h"
+
+enum TwinVQCodec {
+    TWINVQ_CODEC_VQF,
+    TWINVQ_CODEC_METASOUND,
+};
+
+enum TwinVQFrameType {
+    TWINVQ_FT_SHORT = 0,  ///< Short frame  (divided in n   sub-blocks)
+    TWINVQ_FT_MEDIUM,     ///< Medium frame (divided in m<n sub-blocks)
+    TWINVQ_FT_LONG,       ///< Long frame   (single sub-block + PPC)
+    TWINVQ_FT_PPC,        ///< Periodic Peak Component (part of the long frame)
+};
+
+#define TWINVQ_PPC_SHAPE_CB_SIZE 64
+#define TWINVQ_PPC_SHAPE_LEN_MAX 60
+#define TWINVQ_SUB_AMP_MAX       4500.0
+#define TWINVQ_MULAW_MU          100.0
+#define TWINVQ_GAIN_BITS         8
+#define TWINVQ_AMP_MAX           13000.0
+#define TWINVQ_SUB_GAIN_BITS     5
+#define TWINVQ_WINDOW_TYPE_BITS  4
+#define TWINVQ_PGAIN_MU          200
+#define TWINVQ_LSP_COEFS_MAX     20
+#define TWINVQ_LSP_SPLIT_MAX     4
+#define TWINVQ_CHANNELS_MAX      2
+#define TWINVQ_SUBBLOCKS_MAX     16
+#define TWINVQ_BARK_N_COEF_MAX   4
+
+/**
+ * Parameters and tables that are different for each frame type
+ */
+struct TwinVQFrameMode {
+    uint8_t         sub;      ///< Number subblocks in each frame
+    const uint16_t *bark_tab;
+
+    /** number of distinct bark scale envelope values */
+    uint8_t         bark_env_size;
+
+    const int16_t  *bark_cb;    ///< codebook for the bark scale envelope (BSE)
+    uint8_t         bark_n_coef;///< number of BSE CB coefficients to read
+    uint8_t         bark_n_bit; ///< number of bits of the BSE coefs
+
+    //@{
+    /** main codebooks for spectrum data */
+    const int16_t    *cb0;
+    const int16_t    *cb1;
+    //@}
+
+    uint8_t         cb_len_read; ///< number of spectrum coefficients to read
+};
+
+typedef struct TwinVQFrameData {
+    int     window_type;
+    enum TwinVQFrameType ftype;
+
+    uint8_t main_coeffs[1024];
+    uint8_t ppc_coeffs[TWINVQ_PPC_SHAPE_LEN_MAX];
+
+    uint8_t gain_bits[TWINVQ_CHANNELS_MAX];
+    uint8_t sub_gain_bits[TWINVQ_CHANNELS_MAX * TWINVQ_SUBBLOCKS_MAX];
+
+    uint8_t bark1[TWINVQ_CHANNELS_MAX][TWINVQ_SUBBLOCKS_MAX][TWINVQ_BARK_N_COEF_MAX];
+    uint8_t bark_use_hist[TWINVQ_CHANNELS_MAX][TWINVQ_SUBBLOCKS_MAX];
+
+    uint8_t lpc_idx1[TWINVQ_CHANNELS_MAX];
+    uint8_t lpc_idx2[TWINVQ_CHANNELS_MAX][TWINVQ_LSP_SPLIT_MAX];
+    uint8_t lpc_hist_idx[TWINVQ_CHANNELS_MAX];
+
+    int     p_coef[TWINVQ_CHANNELS_MAX];
+    int     g_coef[TWINVQ_CHANNELS_MAX];
+} TwinVQFrameData;
+
+/**
+ * Parameters and tables that are different for every combination of
+ * bitrate/sample rate
+ */
+typedef struct TwinVQModeTab {
+    struct TwinVQFrameMode fmode[3]; ///< frame type-dependant parameters
+
+    uint16_t     size;        ///< frame size in samples
+    uint8_t      n_lsp;       ///< number of lsp coefficients
+    const float *lspcodebook;
+
+    /* number of bits of the different LSP CB coefficients */
+    uint8_t      lsp_bit0;
+    uint8_t      lsp_bit1;
+    uint8_t      lsp_bit2;
+
+    uint8_t      lsp_split;      ///< number of CB entries for the LSP decoding
+    const int16_t *ppc_shape_cb; ///< PPC shape CB
+
+    /** number of the bits for the PPC period value */
+    uint8_t      ppc_period_bit;
+
+    uint8_t      ppc_shape_bit;  ///< number of bits of the PPC shape CB coeffs
+    uint8_t      ppc_shape_len;  ///< size of PPC shape CB
+    uint8_t      pgain_bit;      ///< bits for PPC gain
+
+    /** constant for peak period to peak width conversion */
+    uint16_t     peak_per2wid;
+} TwinVQModeTab;
+
+typedef struct TwinVQContext {
+    AVCodecContext *avctx;
+    AVFloatDSPContext fdsp;
+    FFTContext mdct_ctx[3];
+
+    const TwinVQModeTab *mtab;
+
+    // history
+    float lsp_hist[2][20];           ///< LSP coefficients of the last frame
+    float bark_hist[3][2][40];       ///< BSE coefficients of last frame
+
+    // bitstream parameters
+    int16_t permut[4][4096];
+    uint8_t length[4][2];            ///< main codebook stride
+    uint8_t length_change[4];
+    uint8_t bits_main_spec[2][4][2]; ///< bits for the main codebook
+    int bits_main_spec_change[4];
+    int n_div[4];
+
+    float *spectrum;
+    float *curr_frame;               ///< non-interleaved output
+    float *prev_frame;               ///< non-interleaved previous frame
+    int last_block_pos[2];
+    int discarded_packets;
+
+    float *cos_tabs[3];
+
+    // scratch buffers
+    float *tmp_buf;
+
+    TwinVQFrameData bits;
+
+    enum TwinVQCodec codec;
+
+    int (*read_bitstream)(AVCodecContext *avctx, struct TwinVQContext *tctx,
+                          const uint8_t *buf, int buf_size);
+    void (*dec_bark_env)(struct TwinVQContext *tctx, const uint8_t *in,
+                         int use_hist, int ch, float *out, float gain,
+                         enum TwinVQFrameType ftype);
+    void (*decode_ppc)(struct TwinVQContext *tctx, int period_coef, int g_coef,
+                       const float *shape, float *speech);
+} TwinVQContext;
+
+extern const enum TwinVQFrameType ff_twinvq_wtype_to_ftype_table[];
+
+/** @note not speed critical, hence not optimized */
+static inline void twinvq_memset_float(float *buf, float val, int size)
+{
+    while (size--)
+        *buf++ = val;
+}
+
+static inline float twinvq_mulawinv(float y, float clip, float mu)
+{
+    y = av_clipf(y / clip, -1, 1);
+    return clip * FFSIGN(y) * (exp(log(1 + mu) * fabs(y)) - 1) / mu;
+}
+
+int ff_twinvq_decode_frame(AVCodecContext *avctx, void *data,
+                           int *got_frame_ptr, AVPacket *avpkt);
+av_cold int ff_twinvq_decode_close(AVCodecContext *avctx);
+av_cold int ff_twinvq_decode_init(AVCodecContext *avctx);
+
+#endif /* AVCODEC_TWINVQ_DATA_H */
diff --git a/libavcodec/twinvq_data.h b/libavcodec/twinvq_data.h
index 63911f8..375acc2 100644
--- a/libavcodec/twinvq_data.h
+++ b/libavcodec/twinvq_data.h
@@ -39,95 +39,94 @@
  * for some slightly nonconventional bark-scale function
  */
 static const uint16_t bark_tab_l08_512[] = {
-    7,     8,     7,     8,     8,     8,     8,     8,     8,     9,
-    9,    10,    10,    11,    11,    12,    12,    14,    15,    16,
-   18,    19,    21,    24,    27,    30,    35,    40,    46,    53
+     7,  8,  7,  8,  8,  8,  8,  8,  8,  9,
+     9, 10, 10, 11, 11, 12, 12, 14, 15, 16,
+    18, 19, 21, 24, 27, 30, 35, 40, 46, 53
 };
 
 static const uint16_t bark_tab_l11_512[] = {
-    6,     6,     6,     6,     6,     6,     7,     6,     7,     7,
-    8,     8,     8,     9,    10,    10,    11,    13,    13,    15,
-   17,    18,    21,    25,    27,    33,    38,    45,    54,    66
+     6,  6,  6,  6,  6,  6,  7,  6,  7,  7,
+     8,  8,  8,  9, 10, 10, 11, 13, 13, 15,
+    17, 18, 21, 25, 27, 33, 38, 45, 54, 66
 };
 
 static const uint16_t bark_tab_l16_1024[] = {
-    9,     9,     8,     9,    10,     9,    10,    10,    10,    12,
-   11,    13,    13,    14,    16,    17,    19,    20,    24,    26,
-   30,    35,    40,    48,    56,    68,    83,   102,   128,   165
+     9,  9,  8,  9, 10, 9,  10,  10,  10,  12,
+    11, 13, 13, 14, 16, 17, 19,  20,  24,  26,
+    30, 35, 40, 48, 56, 68, 83, 102, 128, 165
 };
 
 static const uint16_t bark_tab_l22_1024[] = {
-    6,     7,     6,     6,     7,     7,     7,     7,     7,     8,
-    9,     8,    10,    10,    11,    12,    13,    15,    16,    18,
-   21,    24,    27,    33,    38,    46,    55,    68,    84,   107,
-  140,   191
+      6,   7,  6,  6,  7,  7,  7,  7,  7,   8,
+      9,   8, 10, 10, 11, 12, 13, 15, 16,  18,
+     21,  24, 27, 33, 38, 46, 55, 68, 84, 107,
+    140, 191
 };
 
 static const uint16_t bark_tab_l22_512[] = {
-    3,     3,     3,     4,     3,     3,     4,     3,     4,     4,
-    4,     5,     4,     5,     6,     6,     7,     7,     8,     9,
-   10,    12,    14,    16,    20,    22,    28,    34,    42,    53,
-   71,    95
+     3,  3,  3,  4,  3,  3,  4,  3,  4,  4,
+     4,  5,  4,  5,  6,  6,  7,  7,  8,  9,
+    10, 12, 14, 16, 20, 22, 28, 34, 42, 53,
+    71, 95
 };
 
 static const uint16_t bark_tab_l44_2048[] = {
-    5,     6,     5,     6,     5,     6,     6,     6,     6,     6,
-    7,     7,     7,     8,     8,     9,     9,    10,    11,    11,
-   13,    14,    16,    17,    19,    22,    25,    29,    33,    39,
-   46,    54,    64,    79,    98,   123,   161,   220,   320,   512
+     5,  6,  5,  6,  5,   6,   6,   6,   6,   6,
+     7,  7,  7,  8,  8,   9,   9,  10,  11,  11,
+    13, 14, 16, 17, 19,  22,  25,  29,  33,  39,
+    46, 54, 64, 79, 98, 123, 161, 220, 320, 512
 };
 
 static const uint16_t bark_tab_m08_256[] = {
-    6,     5,     6,     6,     6,     6,     7,     7,     8,     8,
-    9,    10,    11,    13,    15,    18,    20,    25,    31,    39
+    6,  5,  6,  6,  6,  6,  7,  7,  8,  8,
+    9, 10, 11, 13, 15, 18, 20, 25, 31, 39
 };
 
 static const uint16_t bark_tab_m11_256[] = {
-    4,     5,     4,     5,     5,     5,     6,     5,     7,     7,
-    8,     9,    10,    12,    15,    17,    22,    28,    35,    47
+    4, 5,  4,  5,  5,  5,  6,  5,  7,  7,
+    8, 9, 10, 12, 15, 17, 22, 28, 35, 47
 };
 
 static const uint16_t bark_tab_m16_512[] = {
-    7,     6,     7,     7,     7,     8,     9,     9,    10,    11,
-   14,    15,    18,    22,    27,    34,    44,    59,    81,   117
+     7,  6,  7,  7,  7,  8,  9,  9, 10,  11,
+    14, 15, 18, 22, 27, 34, 44, 59, 81, 117
 };
 
 static const uint16_t bark_tab_m22_256[] = {
-    3,     2,     3,     2,     3,     3,     4,     3,     4,     5,
-    5,     7,     8,     9,    13,    16,    22,    30,    44,    70
+    3, 2, 3, 2,  3,  3,  4,  3,  4,  5,
+    5, 7, 8, 9, 13, 16, 22, 30, 44, 70
 };
 
 static const uint16_t bark_tab_m22_512[] = {
-    5,     5,     5,     6,     5,     7,     6,     7,     9,     9,
-   11,    13,    15,    20,    24,    33,    43,    61,    88,   140
+     5,  5,  5,  6,  5,  7,  6,  7,  9,   9,
+    11, 13, 15, 20, 24, 33, 43, 61, 88, 140
 };
 
 static const uint16_t bark_tab_m44_512[] = {
-    3,     2,     3,     3,     3,     4,     3,     5,     4,     6,
-    7,     8,    10,    14,    18,    25,    36,    55,    95,   208
+    3, 2,  3,  3,  3,  4,  3,  5,  4,   6,
+    7, 8, 10, 14, 18, 25, 36, 55, 95, 208
 };
 
 static const uint16_t bark_tab_s08_64[] = {
-    3,     3,     3,     3,     4,     5,     6,     8,    12,    17
+    3, 3, 3, 3, 4, 5, 6, 8, 12, 17
 };
 
 static const uint16_t bark_tab_s11_64[] = {
-    2,     3,     2,     3,     3,     4,     6,     8,    12,    21
+    2, 3, 2, 3, 3, 4, 6, 8, 12, 21
 };
 
 static const uint16_t bark_tab_s16_128[] = {
-    3,     4,     4,     4,     5,     7,    10,    16,    26,    49
+    3, 4, 4, 4, 5, 7, 10, 16, 26, 49
 };
 
 static const uint16_t bark_tab_s22_128[] = {
-    3,     2,     3,     4,     4,     6,     9,    14,    26,    57
+    3, 2, 3, 4, 4, 6, 9, 14, 26, 57
 };
 
 static const uint16_t bark_tab_s44_128[] = {
-    1,     2,     1,     2,     3,     4,     6,    10,    23,    76
+    1, 2, 1, 2, 3, 4, 6, 10, 23, 76
 };
 
-
 /**
  * TwinVQ codebooks. They are coded in a struct so we can use code such as
  *
@@ -10991,147 +10990,155 @@
     },
 };
 
-
 static const uint8_t tab7[][35] = {
-    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0},
-    {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0},
-    {0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
-    {0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
-    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0},
-    {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0},
-    {0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
-    {0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
-    {0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1},
-    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0},
-    {0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0}
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1,
+      0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+      0, 0, 0 },
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0 },
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1,
+      0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+      0, 0, 0 },
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0 },
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0 },
+    { 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0,
+      0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0,
+      1, 0, 1 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0 }
 };
 
 static const uint8_t tab8[][5] = {
-    {0, 0, 0, 1, 1},
-    {0, 1, 0, 0, 1},
-    {1, 1, 0, 0, 0},
-    {1, 0, 0, 1, 0},
-    {0, 0, 0, 1, 1},
-    {0, 1, 0, 0, 1},
-    {1, 1, 0, 0, 0},
-    {1, 0, 0, 1, 0},
-    {0, 0, 0, 1, 1},
-    {0, 1, 0, 0, 1},
-    {1, 1, 0, 0, 0},
-    {0, 0, 0, 0, 0},
-    {0, 1, 0, 1, 0}
+    { 0, 0, 0, 1, 1 },
+    { 0, 1, 0, 0, 1 },
+    { 1, 1, 0, 0, 0 },
+    { 1, 0, 0, 1, 0 },
+    { 0, 0, 0, 1, 1 },
+    { 0, 1, 0, 0, 1 },
+    { 1, 1, 0, 0, 0 },
+    { 1, 0, 0, 1, 0 },
+    { 0, 0, 0, 1, 1 },
+    { 0, 1, 0, 0, 1 },
+    { 1, 1, 0, 0, 0 },
+    { 0, 0, 0, 0, 0 },
+    { 0, 1, 0, 1, 0 }
 };
 
 static const uint8_t tab9[][45] = {
-    {
-     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-     0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0
-    },{
-     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0
-    },{
-     0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },{
-     0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-     0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },{
-     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-     0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0
-    },{
-     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0
-    },{
-     0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },{
-     0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-     0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },{
-     0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1,
-     1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0
-    },{
-     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
-     0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    }
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1,
+      1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+      0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
 };
 
-static const uint8_t tab10[][25] =
-{
-    {1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0},
-    {1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0},
-    {1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0},
-    {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
-    {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
-    {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1},
-    {1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
-    {0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1}
+static const uint8_t tab10[][25] = {
+    { 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0,
+      0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0 },
+    { 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0,
+      0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 },
+    { 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0,
+      0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0 },
+    { 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
+      0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+    { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
+      0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 },
+    { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
+      0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 },
+    { 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+      0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 },
+    { 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0,
+      0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 }
 };
 
 static const uint8_t tab11[][55] = {
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0
-    },{
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-    },{
-        0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    },{
-        0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    }, {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-    },{
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-    },{
-        0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    },{
-        0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    },{
-        0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
-    }
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, },
+    { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+    { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, },
+    { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+    { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+    { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }
 };
 
 static const uint8_t tab12[][15] = {
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0},
-    {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
-    {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0},
-    {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
-    {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0},
-    {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1},
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 },
+    { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 },
+    { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+    { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 },
+    { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 },
+    { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+    { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 },
+    { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1 },
 };
 
 static const struct {
     int size;
     const uint8_t *tab;
 } tabs[] = {
-    {0 , NULL},
-    {5 , &tab8 [0][0]},{5 , &tab8 [0][0]}, {15, &tab12[0][0]},
-    {5 , &tab8 [0][0]},{25, &tab10[0][0]}, {15, &tab12[0][0]},
-    {35, &tab7 [0][0]},{5 , &tab8 [0][0]}, {45, &tab9 [0][0]},
-    {25, &tab10[0][0]},{55, &tab11[0][0]}, {15, &tab12[0][0]}
+    {  0, NULL         },
+    {  5, &tab8[0][0]  }, {  5, &tab8[0][0]  }, { 15, &tab12[0][0] },
+    {  5, &tab8[0][0]  }, { 25, &tab10[0][0] }, { 15, &tab12[0][0] },
+    { 35, &tab7[0][0]  }, {  5, &tab8[0][0]  }, { 45, &tab9[0][0]  },
+    { 25, &tab10[0][0] }, { 55, &tab11[0][0] }, { 15, &tab12[0][0] }
 };
 
 #endif /* AVCODEC_TWINVQ_DATA_H */
diff --git a/libavcodec/twinvqdec.c b/libavcodec/twinvqdec.c
new file mode 100644
index 0000000..05a814b
--- /dev/null
+++ b/libavcodec/twinvqdec.c
@@ -0,0 +1,426 @@
+/*
+ * TwinVQ decoder
+ * Copyright (c) 2009 Vitor Sessak
+ *
+ * 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
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+#include "libavutil/channel_layout.h"
+#include "avcodec.h"
+#include "get_bits.h"
+#include "internal.h"
+#include "twinvq.h"
+#include "twinvq_data.h"
+
+static const TwinVQModeTab mode_08_08 = {
+    {
+        { 8, bark_tab_s08_64,  10, tab.fcb08s, 1, 5, tab.cb0808s0, tab.cb0808s1, 18 },
+        { 2, bark_tab_m08_256, 20, tab.fcb08m, 2, 5, tab.cb0808m0, tab.cb0808m1, 16 },
+        { 1, bark_tab_l08_512, 30, tab.fcb08l, 3, 6, tab.cb0808l0, tab.cb0808l1, 17 }
+    },
+    512, 12, tab.lsp08, 1, 5, 3, 3, tab.shape08, 8, 28, 20, 6, 40
+};
+
+static const TwinVQModeTab mode_11_08 = {
+    {
+        { 8, bark_tab_s11_64,  10, tab.fcb11s, 1, 5, tab.cb1108s0, tab.cb1108s1, 29 },
+        { 2, bark_tab_m11_256, 20, tab.fcb11m, 2, 5, tab.cb1108m0, tab.cb1108m1, 24 },
+        { 1, bark_tab_l11_512, 30, tab.fcb11l, 3, 6, tab.cb1108l0, tab.cb1108l1, 27 }
+    },
+    512, 16, tab.lsp11, 1, 6, 4, 3, tab.shape11, 9, 36, 30, 7, 90
+};
+
+static const TwinVQModeTab mode_11_10 = {
+    {
+        { 8, bark_tab_s11_64,  10, tab.fcb11s, 1, 5, tab.cb1110s0, tab.cb1110s1, 21 },
+        { 2, bark_tab_m11_256, 20, tab.fcb11m, 2, 5, tab.cb1110m0, tab.cb1110m1, 18 },
+        { 1, bark_tab_l11_512, 30, tab.fcb11l, 3, 6, tab.cb1110l0, tab.cb1110l1, 20 }
+    },
+    512, 16, tab.lsp11, 1, 6, 4, 3, tab.shape11, 9, 36, 30, 7, 90
+};
+
+static const TwinVQModeTab mode_16_16 = {
+    {
+        { 8, bark_tab_s16_128,  10, tab.fcb16s, 1, 5, tab.cb1616s0, tab.cb1616s1, 16 },
+        { 2, bark_tab_m16_512,  20, tab.fcb16m, 2, 5, tab.cb1616m0, tab.cb1616m1, 15 },
+        { 1, bark_tab_l16_1024, 30, tab.fcb16l, 3, 6, tab.cb1616l0, tab.cb1616l1, 16 }
+    },
+    1024, 16, tab.lsp16, 1, 6, 4, 3, tab.shape16, 9, 56, 60, 7, 180
+};
+
+static const TwinVQModeTab mode_22_20 = {
+    {
+        { 8, bark_tab_s22_128,  10, tab.fcb22s_1, 1, 6, tab.cb2220s0, tab.cb2220s1, 18 },
+        { 2, bark_tab_m22_512,  20, tab.fcb22m_1, 2, 6, tab.cb2220m0, tab.cb2220m1, 17 },
+        { 1, bark_tab_l22_1024, 32, tab.fcb22l_1, 4, 6, tab.cb2220l0, tab.cb2220l1, 18 }
+    },
+    1024, 16, tab.lsp22_1, 1, 6, 4, 3, tab.shape22_1, 9, 56, 36, 7, 144
+};
+
+static const TwinVQModeTab mode_22_24 = {
+    {
+        { 8, bark_tab_s22_128,  10, tab.fcb22s_1, 1, 6, tab.cb2224s0, tab.cb2224s1, 15 },
+        { 2, bark_tab_m22_512,  20, tab.fcb22m_1, 2, 6, tab.cb2224m0, tab.cb2224m1, 14 },
+        { 1, bark_tab_l22_1024, 32, tab.fcb22l_1, 4, 6, tab.cb2224l0, tab.cb2224l1, 15 }
+    },
+    1024, 16, tab.lsp22_1, 1, 6, 4, 3, tab.shape22_1, 9, 56, 36, 7, 144
+};
+
+static const TwinVQModeTab mode_22_32 = {
+    {
+        { 4, bark_tab_s22_128, 10, tab.fcb22s_2, 1, 6, tab.cb2232s0, tab.cb2232s1, 11 },
+        { 2, bark_tab_m22_256, 20, tab.fcb22m_2, 2, 6, tab.cb2232m0, tab.cb2232m1, 11 },
+        { 1, bark_tab_l22_512, 32, tab.fcb22l_2, 4, 6, tab.cb2232l0, tab.cb2232l1, 12 }
+    },
+    512, 16, tab.lsp22_2, 1, 6, 4, 4, tab.shape22_2, 9, 56, 36, 7, 72
+};
+
+static const TwinVQModeTab mode_44_40 = {
+    {
+        { 16, bark_tab_s44_128,  10, tab.fcb44s, 1, 6, tab.cb4440s0, tab.cb4440s1, 18 },
+        { 4,  bark_tab_m44_512,  20, tab.fcb44m, 2, 6, tab.cb4440m0, tab.cb4440m1, 17 },
+        { 1,  bark_tab_l44_2048, 40, tab.fcb44l, 4, 6, tab.cb4440l0, tab.cb4440l1, 17 }
+    },
+    2048, 20, tab.lsp44, 1, 6, 4, 4, tab.shape44, 9, 84, 54, 7, 432
+};
+
+static const TwinVQModeTab mode_44_48 = {
+    {
+        { 16, bark_tab_s44_128,  10, tab.fcb44s, 1, 6, tab.cb4448s0, tab.cb4448s1, 15 },
+        { 4,  bark_tab_m44_512,  20, tab.fcb44m, 2, 6, tab.cb4448m0, tab.cb4448m1, 14 },
+        { 1,  bark_tab_l44_2048, 40, tab.fcb44l, 4, 6, tab.cb4448l0, tab.cb4448l1, 14 }
+    },
+    2048, 20, tab.lsp44, 1, 6, 4, 4, tab.shape44, 9, 84, 54, 7, 432
+};
+
+/**
+ * Evaluate a * b / 400 rounded to the nearest integer. When, for example,
+ * a * b == 200 and the nearest integer is ill-defined, use a table to emulate
+ * the following broken float-based implementation used by the binary decoder:
+ *
+ * @code
+ * static int very_broken_op(int a, int b)
+ * {
+ *    static float test; // Ugh, force gcc to do the division first...
+ *
+ *    test = a / 400.0;
+ *    return b * test + 0.5;
+ * }
+ * @endcode
+ *
+ * @note if this function is replaced by just ROUNDED_DIV(a * b, 400.0), the
+ * stddev between the original file (before encoding with Yamaha encoder) and
+ * the decoded output increases, which leads one to believe that the encoder
+ * expects exactly this broken calculation.
+ */
+static int very_broken_op(int a, int b)
+{
+    int x = a * b + 200;
+    int size;
+    const uint8_t *rtab;
+
+    if (x % 400 || b % 5)
+        return x / 400;
+
+    x /= 400;
+
+    size = tabs[b / 5].size;
+    rtab = tabs[b / 5].tab;
+    return x - rtab[size * av_log2(2 * (x - 1) / size) + (x - 1) % size];
+}
+
+/**
+ * Sum to data a periodic peak of a given period, width and shape.
+ *
+ * @param period the period of the peak divised by 400.0
+ */
+static void add_peak(int period, int width, const float *shape,
+                     float ppc_gain, float *speech, int len)
+{
+    int i, j;
+
+    const float *shape_end = shape + len;
+    int center;
+
+    // First peak centered around zero
+    for (i = 0; i < width / 2; i++)
+        speech[i] += ppc_gain * *shape++;
+
+    for (i = 1; i < ROUNDED_DIV(len, width); i++) {
+        center = very_broken_op(period, i);
+        for (j = -width / 2; j < (width + 1) / 2; j++)
+            speech[j + center] += ppc_gain * *shape++;
+    }
+
+    // For the last block, be careful not to go beyond the end of the buffer
+    center = very_broken_op(period, i);
+    for (j = -width / 2; j < (width + 1) / 2 && shape < shape_end; j++)
+        speech[j + center] += ppc_gain * *shape++;
+}
+
+static void decode_ppc(TwinVQContext *tctx, int period_coef, int g_coef,
+                       const float *shape, float *speech)
+{
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int isampf = tctx->avctx->sample_rate /  1000;
+    int ibps   = tctx->avctx->bit_rate    / (1000 * tctx->avctx->channels);
+    int min_period   = ROUNDED_DIV(40 * 2 * mtab->size, isampf);
+    int max_period   = ROUNDED_DIV(40 * 2 * mtab->size * 6, isampf);
+    int period_range = max_period - min_period;
+    float pgain_step = 25000.0 / ((1 << mtab->pgain_bit) - 1);
+    float ppc_gain   = 1.0 / 8192 *
+                       twinvq_mulawinv(pgain_step * g_coef +
+                                           pgain_step / 2,
+                                       25000.0, TWINVQ_PGAIN_MU);
+
+    // This is actually the period multiplied by 400. It is just linearly coded
+    // between its maximum and minimum value.
+    int period = min_period +
+                 ROUNDED_DIV(period_coef * period_range,
+                             (1 << mtab->ppc_period_bit) - 1);
+    int width;
+
+    if (isampf == 22 && ibps == 32) {
+        // For some unknown reason, NTT decided to code this case differently...
+        width = ROUNDED_DIV((period + 800) * mtab->peak_per2wid,
+                            400 * mtab->size);
+    } else
+        width = period * mtab->peak_per2wid / (400 * mtab->size);
+
+    add_peak(period, width, shape, ppc_gain, speech, mtab->ppc_shape_len);
+}
+
+static void dec_bark_env(TwinVQContext *tctx, const uint8_t *in, int use_hist,
+                         int ch, float *out, float gain,
+                         enum TwinVQFrameType ftype)
+{
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int i, j;
+    float *hist     = tctx->bark_hist[ftype][ch];
+    float val       = ((const float []) { 0.4, 0.35, 0.28 })[ftype];
+    int bark_n_coef = mtab->fmode[ftype].bark_n_coef;
+    int fw_cb_len   = mtab->fmode[ftype].bark_env_size / bark_n_coef;
+    int idx         = 0;
+
+    for (i = 0; i < fw_cb_len; i++)
+        for (j = 0; j < bark_n_coef; j++, idx++) {
+            float tmp2 = mtab->fmode[ftype].bark_cb[fw_cb_len * in[j] + i] *
+                         (1.0 / 4096);
+            float st   = use_hist ? (1.0 - val) * tmp2 + val * hist[idx] + 1.0
+                                  : tmp2 + 1.0;
+
+            hist[idx] = tmp2;
+            if (st < -1.0)
+                st = 1.0;
+
+            twinvq_memset_float(out, st * gain, mtab->fmode[ftype].bark_tab[idx]);
+            out += mtab->fmode[ftype].bark_tab[idx];
+        }
+}
+
+static void read_cb_data(TwinVQContext *tctx, GetBitContext *gb,
+                         uint8_t *dst, enum TwinVQFrameType ftype)
+{
+    int i;
+
+    for (i = 0; i < tctx->n_div[ftype]; i++) {
+        int bs_second_part = (i >= tctx->bits_main_spec_change[ftype]);
+
+        *dst++ = get_bits(gb, tctx->bits_main_spec[0][ftype][bs_second_part]);
+        *dst++ = get_bits(gb, tctx->bits_main_spec[1][ftype][bs_second_part]);
+    }
+}
+
+static int twinvq_read_bitstream(AVCodecContext *avctx, TwinVQContext *tctx,
+                                 const uint8_t *buf, int buf_size)
+{
+    TwinVQFrameData     *bits = &tctx->bits;
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int channels              = tctx->avctx->channels;
+    int sub;
+    GetBitContext gb;
+    int i, j, k;
+
+    if (buf_size * 8 < avctx->bit_rate * mtab->size / avctx->sample_rate + 8) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Frame too small (%d bytes). Truncated file?\n", buf_size);
+        return AVERROR(EINVAL);
+    }
+
+    init_get_bits(&gb, buf, buf_size * 8);
+    skip_bits(&gb, get_bits(&gb, 8));
+
+    bits->window_type = get_bits(&gb, TWINVQ_WINDOW_TYPE_BITS);
+
+    if (bits->window_type > 8) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid window type, broken sample?\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    bits->ftype = ff_twinvq_wtype_to_ftype_table[tctx->bits.window_type];
+
+    sub = mtab->fmode[bits->ftype].sub;
+
+    read_cb_data(tctx, &gb, bits->main_coeffs, bits->ftype);
+
+    for (i = 0; i < channels; i++)
+        for (j = 0; j < sub; j++)
+            for (k = 0; k < mtab->fmode[bits->ftype].bark_n_coef; k++)
+                bits->bark1[i][j][k] =
+                    get_bits(&gb, mtab->fmode[bits->ftype].bark_n_bit);
+
+    for (i = 0; i < channels; i++)
+        for (j = 0; j < sub; j++)
+            bits->bark_use_hist[i][j] = get_bits1(&gb);
+
+    if (bits->ftype == TWINVQ_FT_LONG) {
+        for (i = 0; i < channels; i++)
+            bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
+    } else {
+        for (i = 0; i < channels; i++) {
+            bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
+            for (j = 0; j < sub; j++)
+                bits->sub_gain_bits[i * sub + j] = get_bits(&gb,
+                                                       TWINVQ_SUB_GAIN_BITS);
+        }
+    }
+
+    for (i = 0; i < channels; i++) {
+        bits->lpc_hist_idx[i] = get_bits(&gb, mtab->lsp_bit0);
+        bits->lpc_idx1[i]     = get_bits(&gb, mtab->lsp_bit1);
+
+        for (j = 0; j < mtab->lsp_split; j++)
+            bits->lpc_idx2[i][j] = get_bits(&gb, mtab->lsp_bit2);
+    }
+
+    if (bits->ftype == TWINVQ_FT_LONG) {
+        read_cb_data(tctx, &gb, bits->ppc_coeffs, 3);
+        for (i = 0; i < channels; i++) {
+            bits->p_coef[i] = get_bits(&gb, mtab->ppc_period_bit);
+            bits->g_coef[i] = get_bits(&gb, mtab->pgain_bit);
+        }
+    }
+
+    return 0;
+}
+
+static av_cold int twinvq_decode_init(AVCodecContext *avctx)
+{
+    int isampf, ibps;
+    TwinVQContext *tctx = avctx->priv_data;
+
+    if (!avctx->extradata || avctx->extradata_size < 12) {
+        av_log(avctx, AV_LOG_ERROR, "Missing or incomplete extradata\n");
+        return AVERROR_INVALIDDATA;
+    }
+    avctx->channels = AV_RB32(avctx->extradata)     + 1;
+    avctx->bit_rate = AV_RB32(avctx->extradata + 4) * 1000;
+    isampf          = AV_RB32(avctx->extradata + 8);
+
+    if (isampf < 8 || isampf > 44) {
+        av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate\n");
+        return AVERROR_INVALIDDATA;
+    }
+    switch (isampf) {
+    case 44:
+        avctx->sample_rate = 44100;
+        break;
+    case 22:
+        avctx->sample_rate = 22050;
+        break;
+    case 11:
+        avctx->sample_rate = 11025;
+        break;
+    default:
+        avctx->sample_rate = isampf * 1000;
+        break;
+    }
+
+    if (avctx->channels <= 0 || avctx->channels > TWINVQ_CHANNELS_MAX) {
+        av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %i\n",
+               avctx->channels);
+        return -1;
+    }
+    avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO
+                                                 : AV_CH_LAYOUT_STEREO;
+
+    ibps = avctx->bit_rate / (1000 * avctx->channels);
+
+    if (ibps > 255U) {
+        av_log(avctx, AV_LOG_ERROR, "unsupported per channel bitrate %dkbps\n", ibps);
+        return AVERROR_INVALIDDATA;
+    }
+
+    switch ((isampf << 8) + ibps) {
+    case (8 << 8) + 8:
+        tctx->mtab = &mode_08_08;
+        break;
+    case (11 << 8) + 8:
+        tctx->mtab = &mode_11_08;
+        break;
+    case (11 << 8) + 10:
+        tctx->mtab = &mode_11_10;
+        break;
+    case (16 << 8) + 16:
+        tctx->mtab = &mode_16_16;
+        break;
+    case (22 << 8) + 20:
+        tctx->mtab = &mode_22_20;
+        break;
+    case (22 << 8) + 24:
+        tctx->mtab = &mode_22_24;
+        break;
+    case (22 << 8) + 32:
+        tctx->mtab = &mode_22_32;
+        break;
+    case (44 << 8) + 40:
+        tctx->mtab = &mode_44_40;
+        break;
+    case (44 << 8) + 48:
+        tctx->mtab = &mode_44_48;
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR,
+               "This version does not support %d kHz - %d kbit/s/ch mode.\n",
+               isampf, isampf);
+        return -1;
+    }
+
+    tctx->codec          = TWINVQ_CODEC_VQF;
+    tctx->read_bitstream = twinvq_read_bitstream;
+    tctx->dec_bark_env   = dec_bark_env;
+    tctx->decode_ppc     = decode_ppc;
+
+    return ff_twinvq_decode_init(avctx);
+}
+
+AVCodec ff_twinvq_decoder = {
+    .name           = "twinvq",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_TWINVQ,
+    .priv_data_size = sizeof(TwinVQContext),
+    .init           = twinvq_decode_init,
+    .close          = ff_twinvq_decode_close,
+    .decode         = ff_twinvq_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name      = NULL_IF_CONFIG_SMALL("VQF TwinVQ"),
+    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
+                                                      AV_SAMPLE_FMT_NONE },
+};
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 1aac0a4..036357a 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -26,12 +26,15 @@
  */
 
 #include "config.h"
+#include "libavutil/atomic.h"
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/bprint.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/crc.h"
 #include "libavutil/frame.h"
+#include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/imgutils.h"
@@ -56,7 +59,7 @@
 
 volatile int ff_avcodec_locked;
 static int volatile entangled_thread_counter = 0;
-static int (*ff_lockmgr_cb)(void **mutex, enum AVLockOp op);
+static int (*lockmgr_cb)(void **mutex, enum AVLockOp op);
 static void *codec_mutex;
 static void *avformat_mutex;
 
@@ -133,7 +136,7 @@
         return first_avcodec;
 }
 
-static void avcodec_init(void)
+static av_cold void avcodec_init(void)
 {
     static int initialized = 0;
 
@@ -155,15 +158,14 @@
     return codec && codec->decode;
 }
 
-void avcodec_register(AVCodec *codec)
+av_cold void avcodec_register(AVCodec *codec)
 {
     AVCodec **p;
     avcodec_init();
     p = &first_avcodec;
-    while (*p != NULL)
-        p = &(*p)->next;
-    *p          = codec;
     codec->next = NULL;
+    while(avpriv_atomic_ptr_cas((void * volatile *)p, NULL, codec))
+        p = &(*p)->next;
 
     if (codec->init_static_data)
         codec->init_static_data(codec);
@@ -178,11 +180,11 @@
 {
     s->coded_width  = width;
     s->coded_height = height;
-    s->width        = -((-width ) >> s->lowres);
-    s->height       = -((-height) >> s->lowres);
+    s->width        = FF_CEIL_RSHIFT(width,  s->lowres);
+    s->height       = FF_CEIL_RSHIFT(height, s->lowres);
 }
 
-#if (ARCH_ARM && HAVE_NEON) || ARCH_PPC || HAVE_MMX
+#if HAVE_NEON || ARCH_PPC || HAVE_MMX
 #   define STRIDE_ALIGN 16
 #else
 #   define STRIDE_ALIGN 8
@@ -202,6 +204,7 @@
     case AV_PIX_FMT_YUV422P:
     case AV_PIX_FMT_YUV440P:
     case AV_PIX_FMT_YUV444P:
+    case AV_PIX_FMT_GBRAP:
     case AV_PIX_FMT_GBRP:
     case AV_PIX_FMT_GRAY8:
     case AV_PIX_FMT_GRAY16BE:
@@ -237,6 +240,18 @@
     case AV_PIX_FMT_YUV444P12BE:
     case AV_PIX_FMT_YUV444P14LE:
     case AV_PIX_FMT_YUV444P14BE:
+    case AV_PIX_FMT_YUVA420P9LE:
+    case AV_PIX_FMT_YUVA420P9BE:
+    case AV_PIX_FMT_YUVA420P10LE:
+    case AV_PIX_FMT_YUVA420P10BE:
+    case AV_PIX_FMT_YUVA422P9LE:
+    case AV_PIX_FMT_YUVA422P9BE:
+    case AV_PIX_FMT_YUVA422P10LE:
+    case AV_PIX_FMT_YUVA422P10BE:
+    case AV_PIX_FMT_YUVA444P9LE:
+    case AV_PIX_FMT_YUVA444P9BE:
+    case AV_PIX_FMT_YUVA444P10LE:
+    case AV_PIX_FMT_YUVA444P10BE:
     case AV_PIX_FMT_GBRP9LE:
     case AV_PIX_FMT_GBRP9BE:
     case AV_PIX_FMT_GBRP10LE:
@@ -249,6 +264,7 @@
         h_align = 16 * 2; // interlaced needs 2 macroblocks height
         break;
     case AV_PIX_FMT_YUV411P:
+    case AV_PIX_FMT_YUVJ411P:
     case AV_PIX_FMT_UYYVYY411:
         w_align = 32;
         h_align = 8;
@@ -323,6 +339,29 @@
     *width              = FFALIGN(*width, align);
 }
 
+int avcodec_enum_to_chroma_pos(int *xpos, int *ypos, enum AVChromaLocation pos)
+{
+    if (pos <= AVCHROMA_LOC_UNSPECIFIED || pos >= AVCHROMA_LOC_NB)
+        return AVERROR(EINVAL);
+    pos--;
+
+    *xpos = (pos&1) * 128;
+    *ypos = ((pos>>1)^(pos<4)) * 128;
+
+    return 0;
+}
+
+enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos)
+{
+    int pos, xout, yout;
+
+    for (pos = AVCHROMA_LOC_UNSPECIFIED + 1; pos < AVCHROMA_LOC_NB; pos++) {
+        if (avcodec_enum_to_chroma_pos(&xout, &yout, pos) == 0 && xout == xpos && yout == ypos)
+            return pos;
+    }
+    return AVCHROMA_LOC_UNSPECIFIED;
+}
+
 int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels,
                              enum AVSampleFormat sample_fmt, const uint8_t *buf,
                              int buf_size, int align)
@@ -408,7 +447,7 @@
             av_buffer_pool_uninit(&pool->pools[i]);
             pool->linesize[i] = picture.linesize[i];
             if (size[i]) {
-                pool->pools[i] = av_buffer_pool_init(size[i] + 16,
+                pool->pools[i] = av_buffer_pool_init(size[i] + 16 + STRIDE_ALIGN - 1,
                                                      CONFIG_MEMORY_POISONING ?
                                                         NULL :
                                                         av_buffer_allocz);
@@ -566,13 +605,14 @@
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
     int p, y, x;
 
-    av_assert0(desc->flags & PIX_FMT_PLANAR);
+    av_assert0(desc->flags & AV_PIX_FMT_FLAG_PLANAR);
 
     for (p = 0; p<desc->nb_components; p++) {
         uint8_t *dst = frame->data[p];
         int is_chroma = p == 1 || p == 2;
-        int bytes = -((-frame->width) >> (is_chroma ? desc->log2_chroma_w : 0));
-        for (y = 0; y<-((-frame->height) >> (is_chroma ? desc->log2_chroma_h : 0)); y++){
+        int bytes  = is_chroma ? FF_CEIL_RSHIFT(frame->width,  desc->log2_chroma_w) : frame->width;
+        int height = is_chroma ? FF_CEIL_RSHIFT(frame->height, desc->log2_chroma_h) : frame->height;
+        for (y = 0; y < height; y++) {
             if (desc->comp[0].depth_minus1 >= 8) {
                 for (x = 0; x<bytes; x++)
                     ((uint16_t*)dst)[x] = c[p];
@@ -591,7 +631,9 @@
         return ret;
 
 #if FF_API_GET_BUFFER
+FF_DISABLE_DEPRECATION_WARNINGS
     frame->type = FF_BUFFER_TYPE_INTERNAL;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
     switch (avctx->codec_type) {
@@ -621,12 +663,16 @@
 
     switch (avctx->codec->type) {
     case AVMEDIA_TYPE_VIDEO:
-        frame->width  = FFMAX(avctx->width , -((-avctx->coded_width )>>avctx->lowres));
-        frame->height = FFMAX(avctx->height, -((-avctx->coded_height)>>avctx->lowres));
+        frame->width  = FFMAX(avctx->width,  FF_CEIL_RSHIFT(avctx->coded_width,  avctx->lowres));
+        frame->height = FFMAX(avctx->height, FF_CEIL_RSHIFT(avctx->coded_height, avctx->lowres));
         if (frame->format < 0)
             frame->format              = avctx->pix_fmt;
         if (!frame->sample_aspect_ratio.num)
             frame->sample_aspect_ratio = avctx->sample_aspect_ratio;
+        if (av_frame_get_colorspace(frame) == AVCOL_SPC_UNSPECIFIED)
+            av_frame_set_colorspace(frame, avctx->colorspace);
+        if (av_frame_get_color_range(frame) == AVCOL_RANGE_UNSPECIFIED)
+            av_frame_set_color_range(frame, avctx->color_range);
         break;
     case AVMEDIA_TYPE_AUDIO:
         if (!frame->sample_rate)
@@ -658,6 +704,7 @@
 }
 
 #if FF_API_GET_BUFFER
+FF_DISABLE_DEPRECATION_WARNINGS
 int avcodec_default_get_buffer(AVCodecContext *avctx, AVFrame *frame)
 {
     return avcodec_default_get_buffer2(avctx, frame, 0);
@@ -681,6 +728,7 @@
     AVBufferRef *buf = opaque;
     av_buffer_unref(&buf);
 }
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
 static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags)
@@ -697,8 +745,9 @@
         return ret;
 
 #if FF_API_GET_BUFFER
+FF_DISABLE_DEPRECATION_WARNINGS
     /*
-     * Wrap an old get_buffer()-allocated buffer in an bunch of AVBuffers.
+     * Wrap an old get_buffer()-allocated buffer in a bunch of AVBuffers.
      * We wrap each plane in its own AVBuffer. Each of those has a reference to
      * a dummy AVBuffer as its private data, unreffing it on free.
      * When all the planes are freed, the dummy buffer's free callback calls
@@ -721,7 +770,7 @@
          * avcodec_default_get_buffer
          */
         if (frame->buf[0])
-            return 0;
+            goto end;
 
         priv = av_mallocz(sizeof(*priv));
         if (!priv) {
@@ -759,7 +808,7 @@
             planes = av_pix_fmt_count_planes(frame->format);
             /* workaround for AVHWAccel plane count of 0, buf[0] is used as
                check for allocated buffers: make libavcodec happy */
-            if (desc && desc->flags & PIX_FMT_HWACCEL)
+            if (desc && desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
                 planes = 1;
             if (!desc || planes <= 0) {
                 ret = AVERROR(EINVAL);
@@ -797,6 +846,7 @@
 
         av_buffer_unref(&dummy_buf);
 
+end:
         frame->width  = avctx->width;
         frame->height = avctx->height;
 
@@ -808,6 +858,7 @@
         av_buffer_unref(&dummy_buf);
         return ret;
     }
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
     ret = avctx->get_buffer2(avctx, frame, flags);
@@ -915,7 +966,7 @@
 static int is_hwaccel_pix_fmt(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
-    return desc->flags & PIX_FMT_HWACCEL;
+    return desc->flags & AV_PIX_FMT_FLAG_HWACCEL;
 }
 
 enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat *fmt)
@@ -947,6 +998,7 @@
     frame->sample_aspect_ratio = (AVRational) {0, 1 };
     frame->format              = -1; /* unknown */
     frame->extended_data       = frame->data;
+    av_frame_set_colorspace(frame, AVCOL_SPC_UNSPECIFIED);
 }
 
 AVFrame *avcodec_alloc_frame(void)
@@ -977,12 +1029,9 @@
     av_freep(frame);
 }
 
-#define MAKE_ACCESSORS(str, name, type, field) \
-    type av_##name##_get_##field(const str *s) { return s->field; } \
-    void av_##name##_set_##field(str *s, type v) { s->field = v; }
-
 MAKE_ACCESSORS(AVCodecContext, codec, AVRational, pkt_timebase)
 MAKE_ACCESSORS(AVCodecContext, codec, const AVCodecDescriptor *, codec_descriptor)
+MAKE_ACCESSORS(AVCodecContext, codec, int, lowres)
 
 static void avcodec_get_subtitle_defaults(AVSubtitle *sub)
 {
@@ -1168,7 +1217,7 @@
             goto free_and_end;
     }
 
-    if (HAVE_THREADS && !avctx->thread_opaque
+    if (HAVE_THREADS
         && !(avctx->internal->frame_thread_encoder && (avctx->active_thread_type&FF_THREAD_FRAME))) {
         ret = ff_thread_init(avctx);
         if (ret < 0) {
@@ -1377,8 +1426,13 @@
 
 int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int size)
 {
-    if (size < 0 || avpkt->size < 0 || size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE) {
-        av_log(avctx, AV_LOG_ERROR, "Size %d invalid\n", size);
+    if (avpkt->size < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid negative user packet size %d\n", avpkt->size);
+        return AVERROR(EINVAL);
+    }
+    if (size < 0 || size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid minimum required packet size %d (max allowed is %d)\n",
+               size, INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE);
         return AVERROR(EINVAL);
     }
 
@@ -1395,7 +1449,9 @@
     if (avpkt->data) {
         AVBufferRef *buf = avpkt->buf;
 #if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
         void *destruct = avpkt->destruct;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
         if (avpkt->size < size) {
@@ -1405,7 +1461,9 @@
 
         av_init_packet(avpkt);
 #if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
         avpkt->destruct = destruct;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
         avpkt->buf      = buf;
         avpkt->size     = size;
@@ -1429,26 +1487,23 @@
 static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src)
 {
     AVFrame *frame = NULL;
-    uint8_t *buf   = NULL;
     int ret;
 
     if (!(frame = avcodec_alloc_frame()))
         return AVERROR(ENOMEM);
-    *frame = *src;
 
-    if ((ret = av_samples_get_buffer_size(&frame->linesize[0], s->channels,
-                                          s->frame_size, s->sample_fmt, 0)) < 0)
+    frame->format         = src->format;
+    frame->channel_layout = src->channel_layout;
+    av_frame_set_channels(frame, av_frame_get_channels(src));
+    frame->nb_samples     = s->frame_size;
+    ret = av_frame_get_buffer(frame, 32);
+    if (ret < 0)
         goto fail;
 
-    if (!(buf = av_malloc(ret))) {
-        ret = AVERROR(ENOMEM);
+    ret = av_frame_copy_props(frame, src);
+    if (ret < 0)
         goto fail;
-    }
 
-    frame->nb_samples = s->frame_size;
-    if ((ret = avcodec_fill_audio_frame(frame, s->channels, s->sample_fmt,
-                                        buf, ret, 0)) < 0)
-        goto fail;
     if ((ret = av_samples_copy(frame->extended_data, src->extended_data, 0, 0,
                                src->nb_samples, s->channels, s->sample_fmt)) < 0)
         goto fail;
@@ -1462,10 +1517,7 @@
     return 0;
 
 fail:
-    if (frame->extended_data != frame->data)
-        av_freep(&frame->extended_data);
-    av_freep(&buf);
-    av_freep(&frame);
+    av_frame_free(&frame);
     return ret;
 }
 
@@ -1587,12 +1639,7 @@
     avpkt->flags |= AV_PKT_FLAG_KEY;
 
 end:
-    if (padded_frame) {
-        av_freep(&padded_frame->data[0]);
-        if (padded_frame->extended_data != padded_frame->data)
-            av_freep(&padded_frame->extended_data);
-        av_freep(&padded_frame);
-    }
+    av_frame_free(&padded_frame);
 
     return ret;
 }
@@ -1665,7 +1712,7 @@
         avctx->coded_frame->key_frame = !!(pkt.flags & AV_PKT_FLAG_KEY);
     }
     /* free any side data since we cannot return it */
-    ff_packet_free_side_data(&pkt);
+    av_packet_free_side_data(&pkt);
 
     if (frame && frame->extended_data != frame->data)
         av_freep(&frame->extended_data);
@@ -1908,6 +1955,8 @@
     // copy to ensure we do not change avpkt
     AVPacket tmp = *avpkt;
 
+    if (!avctx->codec)
+        return AVERROR(EINVAL);
     if (avctx->codec->type != AVMEDIA_TYPE_VIDEO) {
         av_log(avctx, AV_LOG_ERROR, "Invalid media type for video\n");
         return AVERROR(EINVAL);
@@ -1952,7 +2001,7 @@
 
         avctx->pkt = NULL;
         if (did_split) {
-            ff_packet_free_side_data(&tmp);
+            av_packet_free_side_data(&tmp);
             if(ret == tmp.size)
                 ret = avpkt->size;
         }
@@ -1964,6 +2013,7 @@
             if (!avctx->refcounted_frames) {
                 avci->to_free = *picture;
                 avci->to_free.extended_data = avci->to_free.data;
+                memset(picture->buf, 0, sizeof(picture->buf));
             }
 
             avctx->frame_number++;
@@ -2046,6 +2096,8 @@
         av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n");
         return AVERROR(EINVAL);
     }
+    if (!avctx->codec)
+        return AVERROR(EINVAL);
     if (avctx->codec->type != AVMEDIA_TYPE_AUDIO) {
         av_log(avctx, AV_LOG_ERROR, "Invalid media type for audio\n");
         return AVERROR(EINVAL);
@@ -2056,7 +2108,7 @@
     if (!avctx->refcounted_frames)
         av_frame_unref(&avci->to_free);
 
-    if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) {
+    if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) {
         uint8_t *side;
         int side_size;
         // copy to ensure we do not change avpkt
@@ -2065,11 +2117,15 @@
         apply_param_change(avctx, &tmp);
 
         avctx->pkt = &tmp;
-        ret = avctx->codec->decode(avctx, frame, got_frame_ptr, &tmp);
+        if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
+            ret = ff_thread_decode_frame(avctx, frame, got_frame_ptr, &tmp);
+        else {
+            ret = avctx->codec->decode(avctx, frame, got_frame_ptr, &tmp);
+            frame->pkt_dts = avpkt->dts;
+        }
         if (ret >= 0 && *got_frame_ptr) {
             add_metadata_from_side_data(avctx, frame);
             avctx->frame_number++;
-            frame->pkt_dts = avpkt->dts;
             av_frame_set_best_effort_timestamp(frame,
                                                guess_correct_pts(avctx,
                                                                  frame->pkt_pts,
@@ -2082,10 +2138,6 @@
                 av_frame_set_channels(frame, avctx->channels);
             if (!frame->sample_rate)
                 frame->sample_rate = avctx->sample_rate;
-            if (!avctx->refcounted_frames) {
-                avci->to_free = *frame;
-                avci->to_free.extended_data = avci->to_free.data;
-            }
         }
 
         side= av_packet_get_side_data(avctx->pkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size);
@@ -2127,12 +2179,20 @@
 
         avctx->pkt = NULL;
         if (did_split) {
-            ff_packet_free_side_data(&tmp);
+            av_packet_free_side_data(&tmp);
             if(ret == tmp.size)
                 ret = avpkt->size;
         }
 
-        if (ret < 0 && frame->data[0])
+        if (ret >= 0 && *got_frame_ptr) {
+            if (!avctx->refcounted_frames) {
+                avci->to_free = *frame;
+                avci->to_free.extended_data = avci->to_free.data;
+                memset(frame->buf, 0, sizeof(frame->buf));
+                frame->extended_buf    = NULL;
+                frame->nb_extended_buf = 0;
+            }
+        } else if (frame->data[0])
             av_frame_unref(frame);
     }
 
@@ -2211,11 +2271,30 @@
 #endif
 }
 
+static int utf8_check(const uint8_t *str)
+{
+    const uint8_t *byte;
+    uint32_t codepoint, min;
+
+    while (*str) {
+        byte = str;
+        GET_UTF8(codepoint, *(byte++), return 0;);
+        min = byte - str == 1 ? 0 : byte - str == 2 ? 0x80 :
+              1 << (5 * (byte - str) - 4);
+        if (codepoint < min || codepoint >= 0x110000 ||
+            codepoint == 0xFFFE /* BOM */ ||
+            codepoint >= 0xD800 && codepoint <= 0xDFFF /* surrogates */)
+            return 0;
+        str = byte;
+    }
+    return 1;
+}
+
 int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
                              int *got_sub_ptr,
                              AVPacket *avpkt)
 {
-    int ret = 0;
+    int i, ret = 0;
 
     if (avctx->codec->type != AVMEDIA_TYPE_SUBTITLE) {
         av_log(avctx, AV_LOG_ERROR, "Invalid media type for subtitles\n");
@@ -2252,6 +2331,16 @@
                                                      avctx->pkt_timebase, ms);
             }
 
+            for (i = 0; i < sub->num_rects; i++) {
+                if (sub->rects[i]->ass && !utf8_check(sub->rects[i]->ass)) {
+                    av_log(avctx, AV_LOG_ERROR,
+                           "Invalid UTF-8 in decoded subtitles text; "
+                           "maybe missing -sub_charenc option\n");
+                    avsubtitle_free(sub);
+                    return AVERROR_INVALIDDATA;
+                }
+            }
+
             if (tmp.data != pkt_recoded.data) { // did we recode?
                 /* prevent from destroying side data from original packet */
                 pkt_recoded.side_data = NULL;
@@ -2259,12 +2348,15 @@
 
                 av_free_packet(&pkt_recoded);
             }
-            sub->format = !(avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB);
+            if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB)
+                sub->format = 0;
+            else if (avctx->codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB)
+                sub->format = 1;
             avctx->pkt = NULL;
         }
 
         if (did_split) {
-            ff_packet_free_side_data(&tmp);
+            av_packet_free_side_data(&tmp);
             if(ret == tmp.size)
                 ret = avpkt->size;
         }
@@ -2358,6 +2450,8 @@
 //         case AV_CODEC_ID_UTVIDEO_DEPRECATED: return AV_CODEC_ID_UTVIDEO;
         case AV_CODEC_ID_OPUS_DEPRECATED: return AV_CODEC_ID_OPUS;
         case AV_CODEC_ID_TAK_DEPRECATED : return AV_CODEC_ID_TAK;
+        case AV_CODEC_ID_ESCAPE130_DEPRECATED : return AV_CODEC_ID_ESCAPE130;
+        case AV_CODEC_ID_G2M_DEPRECATED : return AV_CODEC_ID_G2M;
         default                         : return id;
     }
 }
@@ -2481,9 +2575,13 @@
             profile = av_get_profile_name(p, enc->profile);
     }
 
-    snprintf(buf, buf_size, "%s: %s%s", codec_type ? codec_type : "unknown",
-             codec_name, enc->mb_decision ? " (hq)" : "");
+    snprintf(buf, buf_size, "%s: %s", codec_type ? codec_type : "unknown",
+             codec_name);
     buf[0] ^= 'a' ^ 'A'; /* first letter in uppercase */
+
+    if (enc->codec && strcmp(enc->codec->name, codec_name))
+        snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s)", enc->codec->name);
+
     if (profile)
         snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s)", profile);
     if (enc->codec_tag) {
@@ -2566,6 +2664,9 @@
     if (bitrate != 0) {
         snprintf(buf + strlen(buf), buf_size - strlen(buf),
                  ", %d kb/s", bitrate / 1000);
+    } else if (enc->rc_max_rate > 0) {
+        snprintf(buf + strlen(buf), buf_size - strlen(buf),
+                 ", max. %d kb/s", enc->rc_max_rate / 1000);
     }
 }
 
@@ -2619,6 +2720,9 @@
 
     avctx->pts_correction_last_pts =
     avctx->pts_correction_last_dts = INT64_MIN;
+
+    if (!avctx->refcounted_frames)
+        av_frame_unref(&avctx->internal->to_free);
 }
 
 int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
@@ -2797,6 +2901,8 @@
             switch (id) {
             case AV_CODEC_ID_ADPCM_AFC:
                 return frame_bytes / (9 * ch) * 16;
+            case AV_CODEC_ID_ADPCM_DTK:
+                return frame_bytes / (16 * ch) * 28;
             case AV_CODEC_ID_ADPCM_4XM:
             case AV_CODEC_ID_ADPCM_IMA_ISS:
                 return (frame_bytes - 4 * ch) * 2 / ch;
@@ -2838,11 +2944,15 @@
                 int blocks = frame_bytes / ba;
                 switch (avctx->codec_id) {
                 case AV_CODEC_ID_ADPCM_IMA_WAV:
-                    return blocks * (1 + (ba - 4 * ch) / (4 * ch) * 8);
+                    if (bps < 2 || bps > 5)
+                        return 0;
+                    return blocks * (1 + (ba - 4 * ch) / (bps * ch) * 8);
                 case AV_CODEC_ID_ADPCM_IMA_DK3:
                     return blocks * (((ba - 16) * 2 / 3 * 4) / ch);
                 case AV_CODEC_ID_ADPCM_IMA_DK4:
                     return blocks * (1 + (ba - 4 * ch) * 2 / ch);
+                case AV_CODEC_ID_ADPCM_IMA_RAD:
+                    return blocks * ((ba - 4 * ch) * 2 / ch);
                 case AV_CODEC_ID_ADPCM_MS:
                     return blocks * (2 + (ba - 7 * ch) * 2 / ch);
                 }
@@ -2899,6 +3009,7 @@
 }
 
 #if FF_API_MISSING_SAMPLE
+FF_DISABLE_DEPRECATION_WARNINGS
 void av_log_missing_feature(void *avc, const char *feature, int want_sample)
 {
     av_log(avc, AV_LOG_WARNING, "%s is not implemented. Update your FFmpeg "
@@ -2923,6 +3034,7 @@
 
     va_end(argument_list);
 }
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif /* FF_API_MISSING_SAMPLE */
 
 static AVHWAccel *first_hwaccel = NULL;
@@ -2930,10 +3042,9 @@
 void av_register_hwaccel(AVHWAccel *hwaccel)
 {
     AVHWAccel **p = &first_hwaccel;
-    while (*p)
-        p = &(*p)->next;
-    *p = hwaccel;
     hwaccel->next = NULL;
+    while(avpriv_atomic_ptr_cas((void * volatile *)p, NULL, hwaccel))
+        p = &(*p)->next;
 }
 
 AVHWAccel *av_hwaccel_next(AVHWAccel *hwaccel)
@@ -2954,19 +3065,19 @@
 
 int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op))
 {
-    if (ff_lockmgr_cb) {
-        if (ff_lockmgr_cb(&codec_mutex, AV_LOCK_DESTROY))
+    if (lockmgr_cb) {
+        if (lockmgr_cb(&codec_mutex, AV_LOCK_DESTROY))
             return -1;
-        if (ff_lockmgr_cb(&avformat_mutex, AV_LOCK_DESTROY))
+        if (lockmgr_cb(&avformat_mutex, AV_LOCK_DESTROY))
             return -1;
     }
 
-    ff_lockmgr_cb = cb;
+    lockmgr_cb = cb;
 
-    if (ff_lockmgr_cb) {
-        if (ff_lockmgr_cb(&codec_mutex, AV_LOCK_CREATE))
+    if (lockmgr_cb) {
+        if (lockmgr_cb(&codec_mutex, AV_LOCK_CREATE))
             return -1;
-        if (ff_lockmgr_cb(&avformat_mutex, AV_LOCK_CREATE))
+        if (lockmgr_cb(&avformat_mutex, AV_LOCK_CREATE))
             return -1;
     }
     return 0;
@@ -2974,13 +3085,15 @@
 
 int ff_lock_avcodec(AVCodecContext *log_ctx)
 {
-    if (ff_lockmgr_cb) {
-        if ((*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN))
+    if (lockmgr_cb) {
+        if ((*lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN))
             return -1;
     }
     entangled_thread_counter++;
     if (entangled_thread_counter != 1) {
         av_log(log_ctx, AV_LOG_ERROR, "Insufficient thread locking around avcodec_open/close()\n");
+        if (!lockmgr_cb)
+            av_log(log_ctx, AV_LOG_ERROR, "No lock manager is set, please see av_lockmgr_register()\n");
         ff_avcodec_locked = 1;
         ff_unlock_avcodec();
         return AVERROR(EINVAL);
@@ -2995,8 +3108,8 @@
     av_assert0(ff_avcodec_locked);
     ff_avcodec_locked = 0;
     entangled_thread_counter--;
-    if (ff_lockmgr_cb) {
-        if ((*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE))
+    if (lockmgr_cb) {
+        if ((*lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE))
             return -1;
     }
     return 0;
@@ -3004,8 +3117,8 @@
 
 int avpriv_lock_avformat(void)
 {
-    if (ff_lockmgr_cb) {
-        if ((*ff_lockmgr_cb)(&avformat_mutex, AV_LOCK_OBTAIN))
+    if (lockmgr_cb) {
+        if ((*lockmgr_cb)(&avformat_mutex, AV_LOCK_OBTAIN))
             return -1;
     }
     return 0;
@@ -3013,8 +3126,8 @@
 
 int avpriv_unlock_avformat(void)
 {
-    if (ff_lockmgr_cb) {
-        if ((*ff_lockmgr_cb)(&avformat_mutex, AV_LOCK_RELEASE))
+    if (lockmgr_cb) {
+        if ((*lockmgr_cb)(&avformat_mutex, AV_LOCK_RELEASE))
             return -1;
     }
     return 0;
@@ -3133,7 +3246,7 @@
 {
     int i;
 
-    assert(p <= end);
+    av_assert0(p <= end);
     if (p >= end)
         return end;
 
diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c
index 4efad1e..241431c 100644
--- a/libavcodec/utvideodec.c
+++ b/libavcodec/utvideodec.c
@@ -70,7 +70,7 @@
         code += 0x80000000u >> (he[i].len - 1);
     }
 
-    return ff_init_vlc_sparse(vlc, FFMIN(he[last].len, 9), last + 1,
+    return ff_init_vlc_sparse(vlc, FFMIN(he[last].len, 10), last + 1,
                               bits,  sizeof(*bits),  sizeof(*bits),
                               codes, sizeof(*codes), sizeof(*codes),
                               syms,  sizeof(*syms),  sizeof(*syms), 0);
@@ -507,10 +507,22 @@
     case MKTAG('U', 'L', 'Y', '0'):
         c->planes      = 3;
         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+        avctx->colorspace = AVCOL_SPC_BT470BG;
         break;
     case MKTAG('U', 'L', 'Y', '2'):
         c->planes      = 3;
         avctx->pix_fmt = AV_PIX_FMT_YUV422P;
+        avctx->colorspace = AVCOL_SPC_BT470BG;
+        break;
+    case MKTAG('U', 'L', 'H', '0'):
+        c->planes      = 3;
+        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+        avctx->colorspace = AVCOL_SPC_BT709;
+        break;
+    case MKTAG('U', 'L', 'H', '2'):
+        c->planes      = 3;
+        avctx->pix_fmt = AV_PIX_FMT_YUV422P;
+        avctx->colorspace = AVCOL_SPC_BT709;
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "Unknown Ut Video FOURCC provided (%08X)\n",
diff --git a/libavcodec/utvideoenc.c b/libavcodec/utvideoenc.c
index acb25c3..3e4c714 100644
--- a/libavcodec/utvideoenc.c
+++ b/libavcodec/utvideoenc.c
@@ -24,6 +24,7 @@
  * Ut Video encoder
  */
 
+#include "libavutil/imgutils.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "internal.h"
@@ -230,20 +231,6 @@
     }
 }
 
-/* Write data to a plane, no prediction applied */
-static void write_plane(uint8_t *src, uint8_t *dst, int stride,
-                        int width, int height)
-{
-    int i, j;
-
-    for (j = 0; j < height; j++) {
-        for (i = 0; i < width; i++)
-            *dst++ = src[i];
-
-        src += stride;
-    }
-}
-
 /* Write data to a plane with left prediction */
 static void left_predict(uint8_t *src, uint8_t *dst, int stride,
                          int width, int height)
@@ -383,8 +370,9 @@
         for (i = 0; i < c->slices; i++) {
             sstart = send;
             send   = height * (i + 1) / c->slices;
-            write_plane(src + sstart * stride, dst + sstart * width,
-                        stride, width, send - sstart);
+            av_image_copy_plane(dst + sstart * width, width,
+                                src + sstart * stride, stride,
+                                width, send - sstart);
         }
         break;
     case PRED_LEFT:
diff --git a/libavcodec/v210dec.c b/libavcodec/v210dec.c
index 42e25cc..c6dba23 100644
--- a/libavcodec/v210dec.c
+++ b/libavcodec/v210dec.c
@@ -146,6 +146,13 @@
         v += pic->linesize[2] / 2 - avctx->width / 2;
     }
 
+    if (avctx->field_order > AV_FIELD_PROGRESSIVE) {
+        /* we have interlaced material flagged in container */
+        pic->interlaced_frame = 1;
+        if (avctx->field_order == AV_FIELD_TT || avctx->field_order == AV_FIELD_TB)
+            pic->top_field_first = 1;
+    }
+
     *got_frame      = 1;
 
     return avpkt->size;
diff --git a/libavcodec/vaapi.c b/libavcodec/vaapi.c
index a220a9d..db4d29d 100644
--- a/libavcodec/vaapi.c
+++ b/libavcodec/vaapi.c
@@ -46,6 +46,9 @@
     VABufferID va_buffers[3];
     unsigned int n_va_buffers = 0;
 
+    if (!vactx->pic_param_buf_id)
+        return 0;
+
     vaUnmapBuffer(vactx->display, vactx->pic_param_buf_id);
     va_buffers[n_va_buffers++] = vactx->pic_param_buf_id;
 
@@ -194,26 +197,4 @@
     vactx->slice_params_alloc  = 0;
 }
 
-int ff_vaapi_mpeg_end_frame(AVCodecContext *avctx)
-{
-    struct vaapi_context * const vactx = avctx->hwaccel_context;
-    MpegEncContext *s = avctx->priv_data;
-    int ret;
-
-    ret = ff_vaapi_commit_slices(vactx);
-    if (ret < 0)
-        goto finish;
-
-    ret = ff_vaapi_render_picture(vactx,
-                                  ff_vaapi_get_surface_id(s->current_picture_ptr));
-    if (ret < 0)
-        goto finish;
-
-    ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
-
-finish:
-    ff_vaapi_common_end_frame(avctx);
-    return ret;
-}
-
 /* @} */
diff --git a/libavcodec/vaapi_mpeg.c b/libavcodec/vaapi_mpeg.c
new file mode 100644
index 0000000..5afa406
--- /dev/null
+++ b/libavcodec/vaapi_mpeg.c
@@ -0,0 +1,48 @@
+/*
+ * Video Acceleration API (video decoding)
+ * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1
+ *
+ * Copyright (C) 2013 Anton Khirnov
+ *
+ * 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
+ */
+
+#include "avcodec.h"
+#include "vaapi_internal.h"
+
+int ff_vaapi_mpeg_end_frame(AVCodecContext *avctx)
+{
+    struct vaapi_context * const vactx = avctx->hwaccel_context;
+    MpegEncContext *s = avctx->priv_data;
+    int ret;
+
+    ret = ff_vaapi_commit_slices(vactx);
+    if (ret < 0)
+        goto finish;
+
+    ret = ff_vaapi_render_picture(vactx,
+                                  ff_vaapi_get_surface_id(s->current_picture_ptr));
+    if (ret < 0)
+        goto finish;
+
+    ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
+
+finish:
+    ff_vaapi_common_end_frame(avctx);
+    return ret;
+}
+
diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c
index 208fef3..f755811 100644
--- a/libavcodec/vc1.c
+++ b/libavcodec/vc1.c
@@ -27,6 +27,7 @@
  *
  */
 
+#include "libavutil/attributes.h"
 #include "internal.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
@@ -576,49 +577,52 @@
     return 0;
 }
 
+/* fill lookup tables for intensity compensation */
+#define INIT_LUT(lumscale, lumshift, luty, lutuv, chain) do {                 \
+        int scale, shift, i;                                                  \
+        if (!lumscale) {                                                      \
+            scale = -64;                                                      \
+            shift = (255 - lumshift * 2) << 6;                                \
+            if (lumshift > 31)                                                \
+                shift += 128 << 6;                                            \
+        } else {                                                              \
+            scale = lumscale + 32;                                            \
+            if (lumshift > 31)                                                \
+                shift = (lumshift - 64) << 6;                                 \
+            else                                                              \
+                shift = lumshift << 6;                                        \
+        }                                                                     \
+        for (i = 0; i < 256; i++) {                                           \
+            int iy = chain ? luty[i]  : i;                                    \
+            int iu = chain ? lutuv[i] : i;                                    \
+            luty[i]  = av_clip_uint8((scale * iy + shift + 32) >> 6);         \
+            lutuv[i] = av_clip_uint8((scale * (iu - 128) + 128*64 + 32) >> 6);\
+        }                                                                     \
+    } while(0)
+
 static void rotate_luts(VC1Context *v)
 {
-#define ROTATE(DEF, L, N, C, A) do {\
-        if (v->s.pict_type == AV_PICTURE_TYPE_BI || v->s.pict_type == AV_PICTURE_TYPE_B) {\
-            C = A;\
-        } else {\
-            DEF;\
-            memcpy(&tmp, &L  , sizeof(tmp));\
-            memcpy(&L  , &N  , sizeof(tmp));\
-            memcpy(&N  , &tmp, sizeof(tmp));\
-            C = N;\
-        }\
-    }while(0)
+#define ROTATE(DEF, L, N, C, A) do {                          \
+        if (v->s.pict_type == AV_PICTURE_TYPE_BI || v->s.pict_type == AV_PICTURE_TYPE_B) { \
+            C = A;                                            \
+        } else {                                              \
+            DEF;                                              \
+            memcpy(&tmp, &L  , sizeof(tmp));                  \
+            memcpy(&L  , &N  , sizeof(tmp));                  \
+            memcpy(&N  , &tmp, sizeof(tmp));                  \
+            C = N;                                            \
+        }                                                     \
+    } while(0)
 
-        ROTATE(int tmp            , v->last_use_ic, v->next_use_ic, v->curr_use_ic, v->aux_use_ic);
-        ROTATE(uint8_t tmp[2][256], v->last_luty , v->next_luty , v->curr_luty , v->aux_luty);
-        ROTATE(uint8_t tmp[2][256], v->last_lutuv, v->next_lutuv, v->curr_lutuv, v->aux_lutuv);
+    ROTATE(int tmp,             v->last_use_ic, v->next_use_ic, v->curr_use_ic, v->aux_use_ic);
+    ROTATE(uint8_t tmp[2][256], v->last_luty,   v->next_luty,   v->curr_luty,   v->aux_luty);
+    ROTATE(uint8_t tmp[2][256], v->last_lutuv,  v->next_lutuv,  v->curr_lutuv,  v->aux_lutuv);
+
+    INIT_LUT(32, 0, v->curr_luty[0], v->curr_lutuv[0], 0);
+    INIT_LUT(32, 0, v->curr_luty[1], v->curr_lutuv[1], 0);
+    v->curr_use_ic = 0;
 }
 
-/* fill lookup tables for intensity compensation */
-#define INIT_LUT(lumscale, lumshift, luty, lutuv, chain)   do {\
-    int scale, shift, i;                            \
-    if (!lumscale) {                                \
-        scale = -64;                                \
-        shift = (255 - lumshift * 2) << 6;          \
-        if (lumshift > 31)                          \
-            shift += 128 << 6;                      \
-    } else {                                        \
-        scale = lumscale + 32;                      \
-        if (lumshift > 31)                          \
-            shift = (lumshift - 64) << 6;           \
-        else                                        \
-            shift = lumshift << 6;                  \
-    }                                               \
-    for (i = 0; i < 256; i++) {                     \
-        int iy = chain ? luty[i] : i;               \
-        int iu = chain ? lutuv[i] : i;              \
-        luty[i]  = av_clip_uint8((scale * iy + shift + 32) >> 6);           \
-        lutuv[i] = av_clip_uint8((scale * (iu - 128) + 128*64 + 32) >> 6);  \
-    } \
-    }while(0)
-
-
 int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
 {
     int pqindex, lowquant, status;
@@ -707,12 +711,8 @@
             (v->s.pict_type == AV_PICTURE_TYPE_P) ? 'P' : ((v->s.pict_type == AV_PICTURE_TYPE_I) ? 'I' : 'B'),
             pqindex, v->pq, v->halfpq, v->rangeredfrm);
 
-    if(v->first_pic_header_flag) {
+    if (v->first_pic_header_flag)
         rotate_luts(v);
-        INIT_LUT(32, 0 , v->curr_luty[0] , v->curr_lutuv[0] , 0);
-        INIT_LUT(32, 0 , v->curr_luty[1] , v->curr_lutuv[1] , 0);
-        v->curr_use_ic = 0;
-    }
 
     switch (v->s.pict_type) {
     case AV_PICTURE_TYPE_P:
@@ -726,10 +726,10 @@
             v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][get_unary(gb, 1, 3)];
             v->lumscale = get_bits(gb, 6);
             v->lumshift = get_bits(gb, 6);
-            v->last_use_ic   = 1;
+            v->last_use_ic = 1;
             /* fill lookup tables for intensity compensation */
-            INIT_LUT(v->lumscale, v->lumshift , v->last_luty[0] , v->last_lutuv[0] , 1);
-            INIT_LUT(v->lumscale, v->lumshift , v->last_luty[1] , v->last_lutuv[1] , 1);
+            INIT_LUT(v->lumscale, v->lumshift, v->last_luty[0], v->last_lutuv[0], 1);
+            INIT_LUT(v->lumscale, v->lumshift, v->last_luty[1], v->last_lutuv[1], 1);
         }
         v->qs_last = v->s.quarter_sample;
         if (v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)
@@ -866,15 +866,12 @@
         if (fcm) {
             if (fcm == ILACE_FIELD)
                 field_mode = 1;
-            if (!v->warn_interlaced++)
-                av_log(v->s.avctx, AV_LOG_ERROR,
-                       "Interlaced frames/fields support is incomplete\n");
         }
     } else {
         fcm = PROGRESSIVE;
     }
     if (!v->first_pic_header_flag && v->field_mode != field_mode)
-        return -1;
+        return AVERROR_INVALIDDATA;
     v->field_mode = field_mode;
     v->fcm = fcm;
 
@@ -987,12 +984,8 @@
     if (v->parse_only)
         return 0;
 
-    if(v->first_pic_header_flag) {
+    if (v->first_pic_header_flag)
         rotate_luts(v);
-        INIT_LUT(32, 0 , v->curr_luty[0] , v->curr_lutuv[0] , 0);
-        INIT_LUT(32, 0 , v->curr_luty[1] , v->curr_lutuv[1] , 0);
-        v->curr_use_ic = 0;
-    }
 
     switch (v->s.pict_type) {
     case AV_PICTURE_TYPE_I:
@@ -1090,7 +1083,7 @@
                 mvmode2 = get_unary(gb, 1, 3);
                 v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][mvmode2];
                 if (v->field_mode) {
-                    v->intcompfield = decode210(gb)^3;
+                    v->intcompfield = decode210(gb) ^ 3;
                 } else
                     v->intcompfield = 3;
 
@@ -1115,7 +1108,7 @@
                         INIT_LUT(v->lumscale2, v->lumshift2, v->curr_luty[v->cur_field_type^1], v->curr_lutuv[v->cur_field_type^1], 0);
                         INIT_LUT(v->lumscale , v->lumshift , v->last_luty[v->cur_field_type  ], v->last_lutuv[v->cur_field_type  ], 1);
                     }
-                    v->curr_use_ic = 1;
+                    v->next_use_ic = v->curr_use_ic = 1;
                 } else {
                     INIT_LUT(v->lumscale , v->lumshift , v->last_luty[0], v->last_lutuv[0], 1);
                     INIT_LUT(v->lumscale2, v->lumshift2, v->last_luty[1], v->last_lutuv[1], 1);
@@ -1253,7 +1246,8 @@
         } else if (v->fcm == ILACE_FRAME) {
             if (v->extended_dmv)
                 v->dmvrange = get_unary(gb, 0, 3);
-            get_bits1(gb); /* intcomp - present but shall always be 0 */
+            if (get_bits1(gb)) /* intcomp - present but shall always be 0 */
+                av_log(v->s.avctx, AV_LOG_WARNING, "Intensity compensation set for B picture\n");
             v->intcomp          = 0;
             v->mv_mode          = MV_PMODE_1MV;
             v->fourmvswitch     = 0;
@@ -1580,7 +1574,7 @@
  * @param v The VC1Context to initialize
  * @return Status
  */
-int ff_vc1_init_common(VC1Context *v)
+av_cold int ff_vc1_init_common(VC1Context *v)
 {
     static int done = 0;
     int i = 0;
diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h
index 9e2ec68..c77ab7c 100644
--- a/libavcodec/vc1.h
+++ b/libavcodec/vc1.h
@@ -354,7 +354,6 @@
     uint8_t zzi_8x8[64];
     uint8_t *blk_mv_type_base, *blk_mv_type;    ///< 0: frame MV, 1: field MV (interlaced frame)
     uint8_t *mv_f_base, *mv_f[2];               ///< 0: MV obtained from same field, 1: opposite field
-    uint8_t *mv_f_last_base, *mv_f_last[2];
     uint8_t *mv_f_next_base, *mv_f_next[2];
     int field_mode;         ///< 1 for interlaced field pictures
     int fptype;
@@ -400,8 +399,6 @@
     int end_mb_x;                ///< Horizontal macroblock limit (used only by mss2)
 
     int parse_only;              ///< Context is used within parser
-
-    int warn_interlaced;
 } VC1Context;
 
 /** Find VC-1 marker in buffer
diff --git a/libavcodec/vc1_parser.c b/libavcodec/vc1_parser.c
index 53af61c..1321320 100644
--- a/libavcodec/vc1_parser.c
+++ b/libavcodec/vc1_parser.c
@@ -25,6 +25,7 @@
  * VC-1 and WMV3 parser
  */
 
+#include "libavutil/attributes.h"
 #include "parser.h"
 #include "vc1.h"
 #include "get_bits.h"
@@ -44,6 +45,7 @@
 
     vpc->v.s.avctx = avctx;
     vpc->v.parse_only = 1;
+    vpc->v.first_pic_header_flag = 1;
     next = buf;
     s->repeat_pict = 0;
 
@@ -88,6 +90,11 @@
                 }
             }
 
+            if (vpc->v.broadcast && vpc->v.interlace && !vpc->v.psf)
+                s->field_order = vpc->v.tff ? AV_FIELD_TT : AV_FIELD_BB;
+            else
+                s->field_order = AV_FIELD_PROGRESSIVE;
+
             break;
         }
     }
@@ -184,7 +191,7 @@
     return 0;
 }
 
-static int vc1_parse_init(AVCodecParserContext *s)
+static av_cold int vc1_parse_init(AVCodecParserContext *s)
 {
     VC1ParseContext *vpc = s->priv_data;
     vpc->v.s.slice_context_count = 1;
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 442a69b..9bd5f69 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -85,7 +85,6 @@
     }
 }
 
-
 /** @} */ //Bitplane group
 
 static void vc1_put_signed_blocks_clamped(VC1Context *v)
@@ -348,10 +347,9 @@
     H264ChromaContext *h264chroma = &v->h264chroma;
     uint8_t *srcY, *srcU, *srcV;
     int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
-    int off, off_uv;
     int v_edge_pos = s->v_edge_pos >> v->field_mode;
     int i;
-    const uint8_t *luty, *lutuv;
+    uint8_t (*luty)[256], (*lutuv)[256];
     int use_ic;
 
     if ((!v->field_mode ||
@@ -391,28 +389,30 @@
             srcY = s->current_picture.f.data[0];
             srcU = s->current_picture.f.data[1];
             srcV = s->current_picture.f.data[2];
-            luty = v->curr_luty [v->ref_field_type[dir]];
-            lutuv= v->curr_lutuv[v->ref_field_type[dir]];
-            use_ic=v->curr_use_ic;
+            luty  = v->curr_luty;
+            lutuv = v->curr_lutuv;
+            use_ic = v->curr_use_ic;
         } else {
             srcY = s->last_picture.f.data[0];
             srcU = s->last_picture.f.data[1];
             srcV = s->last_picture.f.data[2];
-            luty = v->last_luty [v->ref_field_type[dir]];
-            lutuv= v->last_lutuv[v->ref_field_type[dir]];
-            use_ic=v->last_use_ic;
+            luty  = v->last_luty;
+            lutuv = v->last_lutuv;
+            use_ic = v->last_use_ic;
         }
     } else {
         srcY = s->next_picture.f.data[0];
         srcU = s->next_picture.f.data[1];
         srcV = s->next_picture.f.data[2];
-        luty = v->next_luty [v->ref_field_type[dir]];
-        lutuv= v->next_lutuv[v->ref_field_type[dir]];
-        use_ic=v->next_use_ic;
+        luty  = v->next_luty;
+        lutuv = v->next_lutuv;
+        use_ic = v->next_use_ic;
     }
 
-    if(!srcY)
+    if (!srcY || !srcU) {
+        av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
         return;
+    }
 
     src_x   = s->mb_x * 16 + (mx   >> 2);
     src_y   = s->mb_y * 16 + (my   >> 2);
@@ -494,16 +494,18 @@
 
             src = srcY;
             for (j = 0; j < 17 + s->mspel * 2; j++) {
+                int f = v->field_mode ? v->ref_field_type[dir] : ((j + src_y - s->mspel) & 1) ;
                 for (i = 0; i < 17 + s->mspel * 2; i++)
-                    src[i] = luty[src[i]];
+                    src[i] = luty[f][src[i]];
                 src += s->linesize;
             }
             src  = srcU;
             src2 = srcV;
             for (j = 0; j < 9; j++) {
+                int f = v->field_mode ? v->ref_field_type[dir] : ((j + uvsrc_y) & 1);
                 for (i = 0; i < 9; i++) {
-                    src[i]  = lutuv[src[i]];
-                    src2[i] = lutuv[src2[i]];
+                    src[i]  = lutuv[f][src[i]];
+                    src2[i] = lutuv[f][src2[i]];
                 }
                 src  += s->uvlinesize;
                 src2 += s->uvlinesize;
@@ -512,21 +514,19 @@
         srcY += s->mspel * (1 + s->linesize);
     }
 
-        off    = 0;
-        off_uv = 0;
     if (s->mspel) {
         dxy = ((my & 3) << 2) | (mx & 3);
-        v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off    , srcY    , s->linesize, v->rnd);
-        v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8, srcY + 8, s->linesize, v->rnd);
+        v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0]    , srcY    , s->linesize, v->rnd);
+        v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8, srcY + 8, s->linesize, v->rnd);
         srcY += s->linesize * 8;
-        v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize    , srcY    , s->linesize, v->rnd);
-        v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd);
+        v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize    , srcY    , s->linesize, v->rnd);
+        v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd);
     } else { // hpel mc - always used for luma
         dxy = (my & 2) | ((mx & 2) >> 1);
         if (!v->rnd)
-            s->hdsp.put_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
+            s->hdsp.put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
         else
-            s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
+            s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
     }
 
     if (s->flags & CODEC_FLAG_GRAY) return;
@@ -534,11 +534,11 @@
     uvmx = (uvmx & 3) << 1;
     uvmy = (uvmy & 3) << 1;
     if (!v->rnd) {
-        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
-        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
+        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
+        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
     } else {
-        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
-        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
+        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
+        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
     }
 }
 
@@ -563,7 +563,7 @@
     int off;
     int fieldmv = (v->fcm == ILACE_FRAME) ? v->blk_mv_type[s->block_index[n]] : 0;
     int v_edge_pos = s->v_edge_pos >> v->field_mode;
-    const uint8_t *luty;
+    uint8_t (*luty)[256];
     int use_ic;
 
     if ((!v->field_mode ||
@@ -577,21 +577,23 @@
     if (!dir) {
         if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
             srcY = s->current_picture.f.data[0];
-            luty = v->curr_luty[v->ref_field_type[dir]];
-            use_ic=v->curr_use_ic;
+            luty = v->curr_luty;
+            use_ic = v->curr_use_ic;
         } else {
             srcY = s->last_picture.f.data[0];
-            luty = v->last_luty[v->ref_field_type[dir]];
-            use_ic=v->last_use_ic;
+            luty = v->last_luty;
+            use_ic = v->last_use_ic;
         }
     } else {
         srcY = s->next_picture.f.data[0];
-        luty = v->next_luty[v->ref_field_type[dir]];
-        use_ic=v->next_use_ic;
+        luty = v->next_luty;
+        use_ic = v->next_use_ic;
     }
 
-    if(!srcY)
+    if (!srcY) {
+        av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
         return;
+    }
 
     if (v->field_mode) {
         if (v->cur_field_type != v->ref_field_type[dir])
@@ -626,7 +628,7 @@
             ty = (chosen_mv[f][0][1] + chosen_mv[f][1][1]) / 2;
             break;
         default:
-            av_assert2(0);
+            av_assert0(0);
         }
         s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
         s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
@@ -719,8 +721,9 @@
 
             src = srcY;
             for (j = 0; j < 9 + s->mspel * 2; j++) {
+                int f = v->field_mode ? v->ref_field_type[dir] : (((j<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1);
                 for (i = 0; i < 9 + s->mspel * 2; i++)
-                    src[i] = luty[src[i]];
+                    src[i] = luty[f][src[i]];
                 src += s->linesize << fieldmv;
             }
         }
@@ -806,9 +809,9 @@
     int k, tx = 0, ty = 0;
     int mvx[4], mvy[4], intra[4], mv_f[4];
     int valid_count;
-    int chroma_ref_type = v->cur_field_type, off = 0;
+    int chroma_ref_type = v->cur_field_type;
     int v_edge_pos = s->v_edge_pos >> v->field_mode;
-    const uint8_t *lutuv;
+    uint8_t (*lutuv)[256];
     int use_ic;
 
     if (!v->field_mode && !v->s.last_picture.f.data[0])
@@ -875,23 +878,25 @@
         if (v->field_mode && (v->cur_field_type != chroma_ref_type) && v->second_field) {
             srcU = s->current_picture.f.data[1];
             srcV = s->current_picture.f.data[2];
-            lutuv= v->curr_lutuv[chroma_ref_type];
-            use_ic=v->curr_use_ic;
+            lutuv = v->curr_lutuv;
+            use_ic = v->curr_use_ic;
         } else {
             srcU = s->last_picture.f.data[1];
             srcV = s->last_picture.f.data[2];
-            lutuv= v->last_lutuv[chroma_ref_type];
-            use_ic=v->last_use_ic;
+            lutuv = v->last_lutuv;
+            use_ic = v->last_use_ic;
         }
     } else {
         srcU = s->next_picture.f.data[1];
         srcV = s->next_picture.f.data[2];
-        lutuv= v->next_lutuv[chroma_ref_type];
-        use_ic=v->next_use_ic;
+        lutuv = v->next_lutuv;
+        use_ic = v->next_use_ic;
     }
 
-    if(!srcU)
+    if (!srcU) {
+        av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
         return;
+    }
 
     srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
     srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
@@ -901,7 +906,6 @@
             srcU += s->current_picture_ptr->f.linesize[1];
             srcV += s->current_picture_ptr->f.linesize[2];
         }
-        off = 0;
     }
 
     if (v->rangeredfrm || use_ic
@@ -941,9 +945,10 @@
             src  = srcU;
             src2 = srcV;
             for (j = 0; j < 9; j++) {
+                int f = v->field_mode ? chroma_ref_type : ((j + uvsrc_y) & 1);
                 for (i = 0; i < 9; i++) {
-                    src[i]  = lutuv[src[i]];
-                    src2[i] = lutuv[src2[i]];
+                    src[i]  = lutuv[f][src[i]];
+                    src2[i] = lutuv[f][src2[i]];
                 }
                 src  += s->uvlinesize;
                 src2 += s->uvlinesize;
@@ -955,17 +960,17 @@
     uvmx = (uvmx & 3) << 1;
     uvmy = (uvmy & 3) << 1;
     if (!v->rnd) {
-        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1] + off, srcU, s->uvlinesize, 8, uvmx, uvmy);
-        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2] + off, srcV, s->uvlinesize, 8, uvmx, uvmy);
+        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
+        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
     } else {
-        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off, srcU, s->uvlinesize, 8, uvmx, uvmy);
-        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off, srcV, s->uvlinesize, 8, uvmx, uvmy);
+        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
+        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
     }
 }
 
-/** Do motion compensation for 4-MV field chroma macroblock (both U and V)
+/** Do motion compensation for 4-MV interlaced frame chroma macroblock (both U and V)
  */
-static void vc1_mc_4mv_chroma4(VC1Context *v)
+static void vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg)
 {
     MpegEncContext *s = &v->s;
     H264ChromaContext *h264chroma = &v->h264chroma;
@@ -977,17 +982,17 @@
     static const int s_rndtblfield[16] = { 0, 0, 1, 2, 4, 4, 5, 6, 2, 2, 3, 8, 6, 6, 7, 12 };
     int v_dist = fieldmv ? 1 : 4; // vertical offset for lower sub-blocks
     int v_edge_pos = s->v_edge_pos >> 1;
-    int use_ic = v->last_use_ic;
+    int use_ic;
+    uint8_t (*lutuv)[256];
 
-    if (!v->s.last_picture.f.data[0])
-        return;
     if (s->flags & CODEC_FLAG_GRAY)
         return;
 
     for (i = 0; i < 4; i++) {
-        tx = s->mv[0][i][0];
+        int d = i < 2 ? dir: dir2;
+        tx = s->mv[d][i][0];
         uvmx_field[i] = (tx + ((tx & 3) == 3)) >> 1;
-        ty = s->mv[0][i][1];
+        ty = s->mv[d][i][1];
         if (fieldmv)
             uvmy_field[i] = (ty >> 4) * 8 + s_rndtblfield[ty & 0xF];
         else
@@ -1001,8 +1006,21 @@
         // FIXME: implement proper pull-back (see vc1cropmv.c, vc1CROPMV_ChromaPullBack())
         uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width  >> 1);
         uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
-        srcU = s->last_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
-        srcV = s->last_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
+        if (i < 2 ? dir : dir2) {
+            srcU = s->next_picture.f.data[1];
+            srcV = s->next_picture.f.data[2];
+            lutuv  = v->next_lutuv;
+            use_ic = v->next_use_ic;
+        } else {
+            srcU = s->last_picture.f.data[1];
+            srcV = s->last_picture.f.data[2];
+            lutuv  = v->last_lutuv;
+            use_ic = v->last_use_ic;
+        }
+        if (!srcU)
+            return;
+        srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
+        srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
         uvmx_field[i] = (uvmx_field[i] & 3) << 1;
         uvmy_field[i] = (uvmy_field[i] & 3) << 1;
 
@@ -1011,7 +1029,7 @@
 
         if (fieldmv && (uvsrc_y & 1) && uvsrc_y < 2)
             uvsrc_y--;
-        if ((use_ic)
+        if (use_ic
             || s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv)
             || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5
             || (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) {
@@ -1028,26 +1046,36 @@
             if (use_ic) {
                 int i, j;
                 uint8_t *src, *src2;
-                const uint8_t *lutuv = v->last_lutuv[v->ref_field_type[0]];
 
                 src  = srcU;
                 src2 = srcV;
                 for (j = 0; j < 5; j++) {
+                    int f = (uvsrc_y + (j << fieldmv)) & 1;
                     for (i = 0; i < 5; i++) {
-                        src[i]  = lutuv[src[i]];
-                        src2[i] = lutuv[src2[i]];
+                        src[i]  = lutuv[f][src[i]];
+                        src2[i] = lutuv[f][src2[i]];
                     }
-                    src  += s->uvlinesize << 1;
-                    src2 += s->uvlinesize << 1;
+                    src  += s->uvlinesize << fieldmv;
+                    src2 += s->uvlinesize << fieldmv;
                 }
             }
         }
-        if (!v->rnd) {
-            h264chroma->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
-            h264chroma->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+        if (avg) {
+            if (!v->rnd) {
+                h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+                h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+            } else {
+                v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+                v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+            }
         } else {
-            v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
-            v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+            if (!v->rnd) {
+                h264chroma->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+                h264chroma->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+            } else {
+                v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+                v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+            }
         }
     }
 }
@@ -1648,7 +1676,7 @@
     MpegEncContext *s = &v->s;
     int xy, wrap, off = 0;
     int A[2], B[2], C[2];
-    int px, py;
+    int px = 0, py = 0;
     int a_valid = 0, b_valid = 0, c_valid = 0;
     int field_a, field_b, field_c; // 0: same, 1: opposit
     int total_valid, num_samefield, num_oppfield;
@@ -1786,8 +1814,7 @@
                 else if (b_valid) { px = B[0]; py = B[1]; }
                 else if (c_valid) { px = C[0]; py = C[1]; }
                 else av_assert2(0);
-            } else
-                px = py = 0;
+            }
         }
     } else {
         if (a_valid)
@@ -1826,27 +1853,28 @@
                 } else if (!field_b && b_valid) {
                     px = B[0];
                     py = B[1];
-                } else if (c_valid) {
+                } else /*if (c_valid)*/ {
+                    av_assert1(c_valid);
                     px = C[0];
                     py = C[1];
-                } else px = py = 0;
+                } /*else px = py = 0;*/
             } else {
                 if (field_a && a_valid) {
                     px = A[0];
                     py = A[1];
-                } else if (field_b && b_valid) {
+                } else /*if (field_b && b_valid)*/ {
+                    av_assert1(field_b && b_valid);
                     px = B[0];
                     py = B[1];
-                } else if (c_valid) {
+                } /*else if (c_valid) {
                     px = C[0];
                     py = C[1];
-                } else px = py = 0;
+                }*/
             }
         } else if (total_valid == 1) {
             px = (a_valid) ? A[0] : ((b_valid) ? B[0] : C[0]);
             py = (a_valid) ? A[1] : ((b_valid) ? B[1] : C[1]);
-        } else
-            px = py = 0;
+        }
     }
 
     /* store MV using signed modulus of MV range defined in 4.11 */
@@ -1973,23 +2001,25 @@
         }
 
         if (use_ic) {
-            const uint8_t *luty = v->next_luty [v->ref_field_type[1]];
-            const uint8_t *lutuv= v->next_lutuv[v->ref_field_type[1]];
+            uint8_t (*luty )[256] = v->next_luty;
+            uint8_t (*lutuv)[256] = v->next_lutuv;
             int i, j;
             uint8_t *src, *src2;
 
             src = srcY;
             for (j = 0; j < 17 + s->mspel * 2; j++) {
+                int f = v->field_mode ? v->ref_field_type[1] : ((j+src_y - s->mspel) & 1);
                 for (i = 0; i < 17 + s->mspel * 2; i++)
-                    src[i] = luty[src[i]];
+                    src[i] = luty[f][src[i]];
                 src += s->linesize;
             }
             src  = srcU;
             src2 = srcV;
             for (j = 0; j < 9; j++) {
+                int f = v->field_mode ? v->ref_field_type[1] : ((j+uvsrc_y) & 1);
                 for (i = 0; i < 9; i++) {
-                    src[i]  = lutuv[src[i]];
-                    src2[i] = lutuv[src2[i]];
+                    src[i]  = lutuv[f][src[i]];
+                    src2[i] = lutuv[f][src2[i]];
                 }
                 src  += s->uvlinesize;
                 src2 += s->uvlinesize;
@@ -1998,8 +2028,8 @@
         srcY += s->mspel * (1 + s->linesize);
     }
 
-        off    = 0;
-        off_uv = 0;
+    off    = 0;
+    off_uv = 0;
 
     if (s->mspel) {
         dxy = ((my & 3) << 2) | (mx & 3);
@@ -2054,31 +2084,18 @@
 static inline void vc1_b_mc(VC1Context *v, int dmv_x[2], int dmv_y[2],
                             int direct, int mode)
 {
-    int use_ic = v->next_use_ic || v->curr_use_ic || v->last_use_ic;
-    if (use_ic) {
-        v->mv_mode2 = v->mv_mode;
-        v->mv_mode  = MV_PMODE_INTENSITY_COMP;
-    }
     if (direct) {
         vc1_mc_1mv(v, 0);
         vc1_interp_mc(v);
-        if (use_ic)
-            v->mv_mode = v->mv_mode2;
         return;
     }
     if (mode == BMV_TYPE_INTERPOLATED) {
         vc1_mc_1mv(v, 0);
         vc1_interp_mc(v);
-        if (use_ic)
-            v->mv_mode = v->mv_mode2;
         return;
     }
 
-    if (use_ic && (mode == BMV_TYPE_BACKWARD))
-        v->mv_mode = v->mv_mode2;
     vc1_mc_1mv(v, (mode == BMV_TYPE_BACKWARD));
-    if (use_ic)
-        v->mv_mode = v->mv_mode2;
 }
 
 static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2],
@@ -3878,7 +3895,7 @@
                         vc1_pred_mv_intfr(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], 0);
                         vc1_mc_4mv_luma(v, i, 0, 0);
                     } else if (i == 4) {
-                        vc1_mc_4mv_chroma4(v);
+                        vc1_mc_4mv_chroma4(v, 0, 0, 0);
                     }
                 }
             } else if (twomv) {
@@ -3897,7 +3914,7 @@
                 vc1_pred_mv_intfr(v, 2, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], 0);
                 vc1_mc_4mv_luma(v, 2, 0, 0);
                 vc1_mc_4mv_luma(v, 3, 0, 0);
-                vc1_mc_4mv_chroma4(v);
+                vc1_mc_4mv_chroma4(v, 0, 0, 0);
             } else {
                 mvbp = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][2];
                 dmv_x = dmv_y = 0;
@@ -4239,7 +4256,7 @@
     int fwd;
     int dmv_x[2], dmv_y[2], pred_flag[2];
     int bmvtype = BMV_TYPE_BACKWARD;
-    int idx_mbmode, interpmvp;
+    int idx_mbmode;
 
     mquant      = v->pq; /* Lossy initialization */
     s->mb_intra = 0;
@@ -4292,6 +4309,7 @@
         else
             fwd = v->forward_mb_plane[mb_pos];
         if (idx_mbmode <= 5) { // 1-MV
+            int interpmvp = 0;
             dmv_x[0]     = dmv_x[1] = dmv_y[0] = dmv_y[1] = 0;
             pred_flag[0] = pred_flag[1] = 0;
             if (fwd)
@@ -4314,7 +4332,7 @@
             if (bmvtype != BMV_TYPE_DIRECT && idx_mbmode & 1) {
                 get_mvdata_interlaced(v, &dmv_x[bmvtype == BMV_TYPE_BACKWARD], &dmv_y[bmvtype == BMV_TYPE_BACKWARD], &pred_flag[bmvtype == BMV_TYPE_BACKWARD]);
             }
-            if (bmvtype == BMV_TYPE_INTERPOLATED && interpmvp) {
+            if (interpmvp) {
                 get_mvdata_interlaced(v, &dmv_x[1], &dmv_y[1], &pred_flag[1]);
             }
             if (bmvtype == BMV_TYPE_DIRECT) {
@@ -4407,8 +4425,7 @@
 
     if (!skipped) {
         idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 2);
-        if (ff_vc1_mbmode_intfrp[0][idx_mbmode][0] == MV_PMODE_INTFR_2MV_FIELD)
-        {
+        if (ff_vc1_mbmode_intfrp[0][idx_mbmode][0] == MV_PMODE_INTFR_2MV_FIELD) {
             twomv = 1;
             v->blk_mv_type[s->block_index[0]] = 1;
             v->blk_mv_type[s->block_index[1]] = 1;
@@ -4439,7 +4456,7 @@
             s->mv[1][2][0] = s->current_picture.motion_val[1][s->block_index[2]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][0], v->bfraction, 1, s->quarter_sample);
             s->mv[1][2][1] = s->current_picture.motion_val[1][s->block_index[2]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][1], v->bfraction, 1, s->quarter_sample);
 
-            for (i = 1; i < 4; i+=2) {
+            for (i = 1; i < 4; i += 2) {
                 s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = s->mv[0][i-1][0];
                 s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = s->mv[0][i-1][1];
                 s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = s->mv[1][i-1][0];
@@ -4462,7 +4479,7 @@
             s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = 0;
             s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = 0;
         }
-        s->current_picture.mb_type[mb_pos]                     = MB_TYPE_INTRA;
+        s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA;
         s->mb_intra = v->is_intra[s->mb_x] = 1;
         for (i = 0; i < 6; i++)
             v->mb_type[0][s->block_index[i]] = 1;
@@ -4490,7 +4507,8 @@
 
             vc1_decode_intra_block(v, s->block[i], i, val, mquant,
                                    (i & 4) ? v->codingset2 : v->codingset);
-            if ((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue;
+            if (i > 3 && (s->flags & CODEC_FLAG_GRAY))
+                continue;
             v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
             if (i < 4) {
                 stride_y = s->linesize << fieldtx;
@@ -4529,8 +4547,7 @@
             if (!direct) {
                 if (bmvtype == BMV_TYPE_INTERPOLATED & twomv) {
                     v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
-                }
-                else if (bmvtype == BMV_TYPE_INTERPOLATED | twomv) {
+                } else if (bmvtype == BMV_TYPE_INTERPOLATED | twomv) {
                     v->twomvbp = get_vlc2(gb, v->twomvbp_vlc->table, VC1_2MV_BLOCK_PATTERN_VLC_BITS, 1);
                 }
             }
@@ -4546,7 +4563,8 @@
                         vc1_mc_4mv_luma(v, i, 0, 0);
                         vc1_mc_4mv_luma(v, i, 1, 1);
                     }
-                    vc1_mc_4mv_chroma4(v);
+                    vc1_mc_4mv_chroma4(v, 0, 0, 0);
+                    vc1_mc_4mv_chroma4(v, 1, 1, 1);
                 } else {
                     vc1_mc_1mv(v, 0);
                     vc1_interp_mc(v);
@@ -4557,30 +4575,28 @@
                     dir = i==1 || i==3;
                     dmv_x = dmv_y = 0;
                     val = ((mvbp >> (3 - i)) & 1);
-                    if (val) {
+                    if (val)
                         get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
-                    }
                     j = i > 1 ? 2 : 0;
                     vc1_pred_mv_intfr(v, j, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir);
                     vc1_mc_4mv_luma(v, j, dir, dir);
                     vc1_mc_4mv_luma(v, j+1, dir, dir);
                 }
 
-                vc1_mc_4mv_chroma4(v);
+                vc1_mc_4mv_chroma4(v, 0, 0, 0);
+                vc1_mc_4mv_chroma4(v, 1, 1, 1);
             } else if (bmvtype == BMV_TYPE_INTERPOLATED) {
                 mvbp = v->twomvbp;
                 dmv_x = dmv_y = 0;
-                if (mvbp & 2) {
+                if (mvbp & 2)
                     get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
-                }
 
                 vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0);
                 vc1_mc_1mv(v, 0);
 
                 dmv_x = dmv_y = 0;
-                if (mvbp & 1) {
+                if (mvbp & 1)
                     get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
-                }
 
                 vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 1);
                 vc1_interp_mc(v);
@@ -4591,19 +4607,17 @@
                     dir2 = !dir;
                 mvbp = v->twomvbp;
                 dmv_x = dmv_y = 0;
-                if (mvbp & 2) {
+                if (mvbp & 2)
                     get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
-                }
                 vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir);
 
                 dmv_x = dmv_y = 0;
-                if (mvbp & 1) {
+                if (mvbp & 1)
                     get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
-                }
                 vc1_pred_mv_intfr(v, 2, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir2);
 
                 if (mvsw) {
-                    for (i = 0; i<2; i++) {
+                    for (i = 0; i < 2; i++) {
                         s->mv[dir][i+2][0] = s->mv[dir][i][0] = s->current_picture.motion_val[dir][s->block_index[i+2]][0] = s->current_picture.motion_val[dir][s->block_index[i]][0];
                         s->mv[dir][i+2][1] = s->mv[dir][i][1] = s->current_picture.motion_val[dir][s->block_index[i+2]][1] = s->current_picture.motion_val[dir][s->block_index[i]][1];
                         s->mv[dir2][i+2][0] = s->mv[dir2][i][0] = s->current_picture.motion_val[dir2][s->block_index[i]][0] = s->current_picture.motion_val[dir2][s->block_index[i+2]][0];
@@ -4618,15 +4632,14 @@
                 vc1_mc_4mv_luma(v, 1, dir, 0);
                 vc1_mc_4mv_luma(v, 2, dir2, 0);
                 vc1_mc_4mv_luma(v, 3, dir2, 0);
-                vc1_mc_4mv_chroma4(v);
+                vc1_mc_4mv_chroma4(v, dir, dir2, 0);
             } else {
                 dir = bmvtype == BMV_TYPE_BACKWARD;
 
                 mvbp = ff_vc1_mbmode_intfrp[0][idx_mbmode][2];
                 dmv_x = dmv_y = 0;
-                if (mvbp) {
+                if (mvbp)
                     get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
-                }
 
                 vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], dir);
                 v->blk_mv_type[s->block_index[0]] = 1;
@@ -4634,7 +4647,7 @@
                 v->blk_mv_type[s->block_index[2]] = 1;
                 v->blk_mv_type[s->block_index[3]] = 1;
                 vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, 0, !dir);
-                for (i = 0; i<2; i++) {
+                for (i = 0; i < 2; i++) {
                     s->mv[!dir][i+2][0] = s->mv[!dir][i][0] = s->current_picture.motion_val[!dir][s->block_index[i+2]][0] = s->current_picture.motion_val[!dir][s->block_index[i]][0];
                     s->mv[!dir][i+2][1] = s->mv[!dir][i][1] = s->current_picture.motion_val[!dir][s->block_index[i+2]][1] = s->current_picture.motion_val[!dir][s->block_index[i]][1];
                 }
@@ -4690,7 +4703,7 @@
                         int dir2 = dir;
                         if (mvsw)
                             dir2 = !dir;
-                        for (i = 0; i<2; i++) {
+                        for (i = 0; i < 2; i++) {
                             s->mv[dir][i+2][0] = s->mv[dir][i][0] = s->current_picture.motion_val[dir][s->block_index[i+2]][0] = s->current_picture.motion_val[dir][s->block_index[i]][0];
                             s->mv[dir][i+2][1] = s->mv[dir][i][1] = s->current_picture.motion_val[dir][s->block_index[i+2]][1] = s->current_picture.motion_val[dir][s->block_index[i]][1];
                             s->mv[dir2][i+2][0] = s->mv[dir2][i][0] = s->current_picture.motion_val[dir2][s->block_index[i]][0] = s->current_picture.motion_val[dir2][s->block_index[i+2]][0];
@@ -4702,7 +4715,7 @@
                         v->blk_mv_type[s->block_index[2]] = 1;
                         v->blk_mv_type[s->block_index[3]] = 1;
                         vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, 0, !dir);
-                        for (i = 0; i<2; i++) {
+                        for (i = 0; i < 2; i++) {
                             s->mv[!dir][i+2][0] = s->mv[!dir][i][0] = s->current_picture.motion_val[!dir][s->block_index[i+2]][0] = s->current_picture.motion_val[!dir][s->block_index[i]][0];
                             s->mv[!dir][i+2][1] = s->mv[!dir][i][1] = s->current_picture.motion_val[!dir][s->block_index[i+2]][1] = s->current_picture.motion_val[!dir][s->block_index[i]][1];
                         }
@@ -4717,7 +4730,7 @@
         }
     }
     if (s->mb_x == s->mb_width - 1)
-        memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0])*s->mb_stride);
+        memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride);
     v->cbp[s->mb_x]      = block_cbp;
     v->ttblk[s->mb_x]    = block_tt;
     return 0;
@@ -5029,7 +5042,8 @@
         break;
     }
 
-    apply_loop_filter   = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY);
+    apply_loop_filter   = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY) &&
+                          v->fcm == PROGRESSIVE;
     s->first_slice_line = 1;
     memset(v->cbp_base, 0, sizeof(v->cbp_base[0])*2*s->mb_stride);
     for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
@@ -5043,7 +5057,7 @@
             else if (v->fcm == ILACE_FRAME)
                 vc1_decode_p_mb_intfr(v);
             else vc1_decode_p_mb(v);
-            if (s->mb_y != s->start_mb_y && apply_loop_filter && v->fcm == PROGRESSIVE)
+            if (s->mb_y != s->start_mb_y && apply_loop_filter)
                 vc1_apply_p_loop_filter(v);
             if (get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
                 // TODO: may need modification to handle slice coding
@@ -5060,7 +5074,7 @@
         if (s->mb_y != s->start_mb_y) ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
         s->first_slice_line = 0;
     }
-    if (apply_loop_filter && v->fcm == PROGRESSIVE) {
+    if (apply_loop_filter) {
         s->mb_x = 0;
         init_block_index(v);
         for (; s->mb_x < s->mb_width; s->mb_x++) {
@@ -5503,9 +5517,6 @@
     v->mv_f_base        = av_mallocz(2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2));
     v->mv_f[0]          = v->mv_f_base + s->b8_stride + 1;
     v->mv_f[1]          = v->mv_f[0] + (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2);
-    v->mv_f_last_base   = av_mallocz(2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2));
-    v->mv_f_last[0]     = v->mv_f_last_base + s->b8_stride + 1;
-    v->mv_f_last[1]     = v->mv_f_last[0] + (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2);
     v->mv_f_next_base   = av_mallocz(2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2));
     v->mv_f_next[0]     = v->mv_f_next_base + s->b8_stride + 1;
     v->mv_f_next[1]     = v->mv_f_next[0] + (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2);
@@ -5718,7 +5729,6 @@
     av_freep(&v->mb_type_base);
     av_freep(&v->blk_mv_type_base);
     av_freep(&v->mv_f_base);
-    av_freep(&v->mv_f_last_base);
     av_freep(&v->mv_f_next_base);
     av_freep(&v->block);
     av_freep(&v->cbp_base);
@@ -5780,6 +5790,8 @@
     if (avctx->codec_id == AV_CODEC_ID_VC1 || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {
         int buf_size2 = 0;
         buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
+        if (!buf2)
+            return AVERROR(ENOMEM);
 
         if (IS_MARKER(AV_RB32(buf))) { /* frame starts with marker and needs to be parsed */
             const uint8_t *start, *end, *next;
@@ -5997,9 +6009,14 @@
     s->me.qpel_avg = s->dsp.avg_qpel_pixels_tab;
 
     if ((CONFIG_VC1_VDPAU_DECODER)
-        &&s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
-        ff_vdpau_vc1_decode_picture(s, buf_start, (buf + buf_size) - buf_start);
-    else if (avctx->hwaccel) {
+        &&s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) {
+        if (v->field_mode && buf_start_second_field) {
+            ff_vdpau_vc1_decode_picture(s, buf_start, buf_start_second_field - buf_start);
+            ff_vdpau_vc1_decode_picture(s, buf_start_second_field, (buf + buf_size) - buf_start_second_field);
+        } else {
+            ff_vdpau_vc1_decode_picture(s, buf_start, (buf + buf_size) - buf_start);
+        }
+    } else if (avctx->hwaccel) {
         if (v->field_mode && buf_start_second_field) {
             // decode first field
             s->picture_structure = PICT_BOTTOM_FIELD - v->tff;
@@ -6052,6 +6069,9 @@
             s->uvlinesize                    <<= 1;
         }
         mb_height = s->mb_height >> v->field_mode;
+
+        av_assert0 (mb_height > 0);
+
         for (i = 0; i <= n_slices; i++) {
             if (i > 0 &&  slices[i - 1].mby_start >= mb_height) {
                 if (v->field_mode <= 0) {
@@ -6115,15 +6135,8 @@
             s->linesize                      >>= 1;
             s->uvlinesize                    >>= 1;
             if (v->s.pict_type != AV_PICTURE_TYPE_BI && v->s.pict_type != AV_PICTURE_TYPE_B) {
-                uint8_t *tmp[2];
-                tmp[0]          = v->mv_f_last[0];
-                tmp[1]          = v->mv_f_last[1];
-                v->mv_f_last[0] = v->mv_f_next[0];
-                v->mv_f_last[1] = v->mv_f_next[1];
-                v->mv_f_next[0] = v->mv_f[0];
-                v->mv_f_next[1] = v->mv_f[1];
-                v->mv_f[0] = tmp[0];
-                v->mv_f[1] = tmp[1];
+                FFSWAP(uint8_t *, v->mv_f_next[0], v->mv_f[0]);
+                FFSWAP(uint8_t *, v->mv_f_next[1], v->mv_f[1]);
             }
         }
         av_dlog(s->avctx, "Consumed %i/%i bits\n",
@@ -6132,7 +6145,7 @@
 //      return -1;
         if(s->er.error_occurred && s->pict_type == AV_PICTURE_TYPE_B)
             goto err;
-        if(!v->field_mode)
+        if (!v->field_mode)
             ff_er_frame_end(&s->er);
     }
 
diff --git a/libavcodec/vc1dsp.c b/libavcodec/vc1dsp.c
index f66921a..39e9441 100644
--- a/libavcodec/vc1dsp.c
+++ b/libavcodec/vc1dsp.c
@@ -741,6 +741,26 @@
     }
 }
 
+static void avg_no_rnd_vc1_chroma_mc4_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){
+    const int A=(8-x)*(8-y);
+    const int B=(  x)*(8-y);
+    const int C=(8-x)*(  y);
+    const int D=(  x)*(  y);
+    int i;
+
+    av_assert2(x<8 && y<8 && x>=0 && y>=0);
+
+    for(i=0; i<h; i++)
+    {
+        dst[0] = avg2(dst[0], ((A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1] + 32 - 4) >> 6));
+        dst[1] = avg2(dst[1], ((A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + 32 - 4) >> 6));
+        dst[2] = avg2(dst[2], ((A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + 32 - 4) >> 6));
+        dst[3] = avg2(dst[3], ((A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + 32 - 4) >> 6));
+        dst+= stride;
+        src+= stride;
+    }
+}
+
 #if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
 
 static void sprite_h_c(uint8_t *dst, const uint8_t *src, int offset, int advance, int count)
@@ -858,6 +878,7 @@
     dsp->put_no_rnd_vc1_chroma_pixels_tab[0]= put_no_rnd_vc1_chroma_mc8_c;
     dsp->avg_no_rnd_vc1_chroma_pixels_tab[0]= avg_no_rnd_vc1_chroma_mc8_c;
     dsp->put_no_rnd_vc1_chroma_pixels_tab[1] = put_no_rnd_vc1_chroma_mc4_c;
+    dsp->avg_no_rnd_vc1_chroma_pixels_tab[1] = avg_no_rnd_vc1_chroma_mc4_c;
 
 #if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
     dsp->sprite_h = sprite_h_c;
@@ -867,8 +888,8 @@
     dsp->sprite_v_double_twoscale = sprite_v_double_twoscale_c;
 #endif
 
-    if (HAVE_ALTIVEC)
-        ff_vc1dsp_init_altivec(dsp);
     if (ARCH_X86)
         ff_vc1dsp_init_x86(dsp);
+    if (ARCH_PPC)
+        ff_vc1dsp_init_ppc(dsp);
 }
diff --git a/libavcodec/vc1dsp.h b/libavcodec/vc1dsp.h
index 5e332a0..a0d6048 100644
--- a/libavcodec/vc1dsp.h
+++ b/libavcodec/vc1dsp.h
@@ -77,7 +77,7 @@
 } VC1DSPContext;
 
 void ff_vc1dsp_init(VC1DSPContext* c);
-void ff_vc1dsp_init_altivec(VC1DSPContext* c);
+void ff_vc1dsp_init_ppc(VC1DSPContext *c);
 void ff_vc1dsp_init_x86(VC1DSPContext* dsp);
 
 #endif /* AVCODEC_VC1DSP_H */
diff --git a/libavcodec/vda.h b/libavcodec/vda.h
index 281785f..b3d6399 100644
--- a/libavcodec/vda.h
+++ b/libavcodec/vda.h
@@ -134,6 +134,17 @@
      * - decoding: Set/Unset by libavcodec.
      */
     int                 priv_allocated_size;
+
+    /**
+     * Use av_buffer to manage buffer.
+     * When the flag is set, the CVPixelBuffers returned by the decoder will
+     * be released automatically, so you have to retain them if necessary.
+     * Not setting this flag may cause memory leak.
+     *
+     * encoding: unused
+     * decoding: Set by user.
+     */
+    int                 use_ref_buffer;
 };
 
 /** Create the video decoder. */
diff --git a/libavcodec/vda_h264.c b/libavcodec/vda_h264.c
index d0237c2..c01a21a 100644
--- a/libavcodec/vda_h264.c
+++ b/libavcodec/vda_h264.c
@@ -28,6 +28,9 @@
 #include "libavutil/avutil.h"
 #include "h264.h"
 
+struct vda_buffer {
+    CVPixelBufferRef cv_buffer;
+};
 
 /* Decoder callback that adds the vda frame to the queue in display order. */
 static void vda_decoder_callback (void *vda_hw_ctx,
@@ -108,11 +111,20 @@
     return 0;
 }
 
+static void vda_h264_release_buffer(void *opaque, uint8_t *data)
+{
+    struct vda_buffer *context = opaque;
+    CVPixelBufferRelease(context->cv_buffer);
+    av_free(context);
+}
+
 static int vda_h264_end_frame(AVCodecContext *avctx)
 {
     H264Context *h                      = avctx->priv_data;
     struct vda_context *vda_ctx         = avctx->hwaccel_context;
     AVFrame *frame                      = &h->cur_pic_ptr->f;
+    struct vda_buffer *context;
+    AVBufferRef *buffer;
     int status;
 
     if (!vda_ctx->decoder || !vda_ctx->priv_bitstream)
@@ -124,6 +136,20 @@
     if (status)
         av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status);
 
+    if (!vda_ctx->use_ref_buffer || status)
+        return status;
+
+    context = av_mallocz(sizeof(*context));
+    buffer = av_buffer_create(NULL, 0, vda_h264_release_buffer, context, 0);
+    if (!context || !buffer) {
+        CVPixelBufferRelease(vda_ctx->cv_buffer);
+        av_free(context);
+        return -1;
+    }
+
+    context->cv_buffer = vda_ctx->cv_buffer;
+    frame->buf[3] = buffer;
+
     return status;
 }
 
diff --git a/libavcodec/vda_h264_dec.c b/libavcodec/vda_h264_dec.c
index 4e60de0..9463f6a 100644
--- a/libavcodec/vda_h264_dec.c
+++ b/libavcodec/vda_h264_dec.c
@@ -102,6 +102,8 @@
         AVBufferRef *buffer = pic->buf[0];
         VDABufferContext *context = av_buffer_get_opaque(buffer);
         CVPixelBufferRef cv_buffer = (CVPixelBufferRef)pic->data[3];
+
+        CVPixelBufferRetain(cv_buffer);
         CVPixelBufferLockBaseAddress(cv_buffer, 0);
         context->cv_buffer = cv_buffer;
         pic->format = ctx->pix_fmt;
@@ -133,48 +135,6 @@
     return 0;
 }
 
-static av_cold int check_format(AVCodecContext *avctx)
-{
-    AVCodecParserContext *parser;
-    uint8_t *pout;
-    int psize;
-    int index;
-    H264Context *h;
-    int ret = -1;
-
-    /* init parser & parse file */
-    parser = av_parser_init(avctx->codec->id);
-    if (!parser) {
-        av_log(avctx, AV_LOG_ERROR, "Failed to open H.264 parser.\n");
-        goto final;
-    }
-    parser->flags = PARSER_FLAG_COMPLETE_FRAMES;
-    index = av_parser_parse2(parser, avctx, &pout, &psize, NULL, 0, 0, 0, 0);
-    if (index < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Failed to parse this file.\n");
-        goto release_parser;
-    }
-
-    /* check if support */
-    h = parser->priv_data;
-    switch (h->sps.bit_depth_luma) {
-    case 8:
-        if (!CHROMA444(h) && !CHROMA422(h)) {
-            // only this will H.264 decoder switch to hwaccel
-            ret = 0;
-            break;
-        }
-    default:
-        av_log(avctx, AV_LOG_ERROR, "Unsupported file.\n");
-    }
-
-release_parser:
-    av_parser_close(parser);
-
-final:
-    return ret;
-}
-
 static av_cold int vdadec_init(AVCodecContext *avctx)
 {
     VDADecoderContext *ctx = avctx->priv_data;
@@ -192,16 +152,13 @@
             ff_h264_vda_decoder.pix_fmts = vda_pixfmts;
     }
 
-    /* check if VDA supports this file */
-    if (check_format(avctx) < 0)
-        goto failed;
-
     /* init vda */
     memset(vda_ctx, 0, sizeof(struct vda_context));
     vda_ctx->width = avctx->width;
     vda_ctx->height = avctx->height;
     vda_ctx->format = 'avc1';
     vda_ctx->use_sync_decoding = 1;
+    vda_ctx->use_ref_buffer = 1;
     ctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts);
     switch (ctx->pix_fmt) {
     case AV_PIX_FMT_UYVY422:
diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c
index b9a07cd..7a4d145 100644
--- a/libavcodec/vdpau.c
+++ b/libavcodec/vdpau.c
@@ -38,13 +38,22 @@
  * @{
  */
 
-int ff_vdpau_common_start_frame(AVCodecContext *avctx,
+AVVDPAUContext *av_alloc_vdpaucontext(void)
+{
+    return av_mallocz(sizeof(AVVDPAUContext));
+}
+
+MAKE_ACCESSORS(AVVDPAUContext, vdpau_hwaccel, AVVDPAU_Render2, render2)
+
+int ff_vdpau_common_start_frame(Picture *pic,
                                 av_unused const uint8_t *buffer,
                                 av_unused uint32_t size)
 {
-    AVVDPAUContext *hwctx = avctx->hwaccel_context;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
 
-    hwctx->bitstream_buffers_used = 0;
+    pic_ctx->bitstream_buffers_allocated = 0;
+    pic_ctx->bitstream_buffers_used      = 0;
+    pic_ctx->bitstream_buffers           = NULL;
     return 0;
 }
 
@@ -53,33 +62,39 @@
     CONFIG_VC1_VDPAU_HWACCEL   || CONFIG_WMV3_VDPAU_HWACCEL
 int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx)
 {
+    int res = 0;
     AVVDPAUContext *hwctx = avctx->hwaccel_context;
     MpegEncContext *s = avctx->priv_data;
-    VdpVideoSurface surf = ff_vdpau_get_surface_id(s->current_picture_ptr);
+    Picture *pic = s->current_picture_ptr;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
+    VdpVideoSurface surf = ff_vdpau_get_surface_id(pic);
 
-    hwctx->render(hwctx->decoder, surf, (void *)&hwctx->info,
-                  hwctx->bitstream_buffers_used, hwctx->bitstream_buffers);
+    if (!hwctx->render) {
+        res = hwctx->render2(avctx, &pic->f, (void *)&pic_ctx->info,
+                             pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers);
+    } else
+    hwctx->render(hwctx->decoder, surf, (void *)&pic_ctx->info,
+                  pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers);
 
     ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
-    hwctx->bitstream_buffers_used = 0;
+    av_freep(&pic_ctx->bitstream_buffers);
 
-    return 0;
+    return res;
 }
 #endif
 
-int ff_vdpau_add_buffer(AVCodecContext *avctx,
-                        const uint8_t *buf, uint32_t size)
+int ff_vdpau_add_buffer(Picture *pic, const uint8_t *buf, uint32_t size)
 {
-    AVVDPAUContext *hwctx = avctx->hwaccel_context;
-    VdpBitstreamBuffer *buffers = hwctx->bitstream_buffers;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
+    VdpBitstreamBuffer *buffers = pic_ctx->bitstream_buffers;
 
-    buffers = av_fast_realloc(buffers, &hwctx->bitstream_buffers_allocated,
-                              (hwctx->bitstream_buffers_used + 1) * sizeof(*buffers));
+    buffers = av_fast_realloc(buffers, &pic_ctx->bitstream_buffers_allocated,
+                              (pic_ctx->bitstream_buffers_used + 1) * sizeof(*buffers));
     if (!buffers)
         return AVERROR(ENOMEM);
 
-    hwctx->bitstream_buffers = buffers;
-    buffers += hwctx->bitstream_buffers_used++;
+    pic_ctx->bitstream_buffers = buffers;
+    buffers += pic_ctx->bitstream_buffers_used++;
 
     buffers->struct_version  = VDP_BITSTREAM_BUFFER_VERSION;
     buffers->bitstream       = buf;
@@ -307,7 +322,7 @@
     assert(render);
 
     /*  fill LvPictureInfoVC1 struct */
-    render->info.vc1.frame_coding_mode  = v->fcm;
+    render->info.vc1.frame_coding_mode  = v->fcm ? v->fcm + 1 : 0;
     render->info.vc1.postprocflag       = v->postprocflag;
     render->info.vc1.pulldown           = v->broadcast;
     render->info.vc1.interlace          = v->interlace;
diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h
index f5b2317..b1c836c 100644
--- a/libavcodec/vdpau.h
+++ b/libavcodec/vdpau.h
@@ -52,18 +52,36 @@
 #include <vdpau/vdpau.h>
 #include <vdpau/vdpau_x11.h>
 #include "libavutil/avconfig.h"
+#include "libavutil/attributes.h"
 
-union FFVdpPictureInfo {
+#ifndef FF_API_CAP_VDPAU
+#define FF_API_CAP_VDPAU 1
+#endif
+#ifndef FF_API_BUFS_VDPAU
+#define FF_API_BUFS_VDPAU 1
+#endif
+
+#if FF_API_BUFS_VDPAU
+union AVVDPAUPictureInfo {
     VdpPictureInfoH264        h264;
     VdpPictureInfoMPEG1Or2    mpeg;
     VdpPictureInfoVC1          vc1;
     VdpPictureInfoMPEG4Part2 mpeg4;
 };
+#endif
+
+struct AVCodecContext;
+struct AVFrame;
+
+typedef int (*AVVDPAU_Render2)(struct AVCodecContext *, struct AVFrame *,
+                               const VdpPictureInfo *, uint32_t,
+                               const VdpBitstreamBuffer *);
 
 /**
  * This structure is used to share data between the libavcodec library and
  * the client video application.
- * The user shall zero-allocate the structure and make it available as
+ * The user shall allocate the structure via the av_alloc_vdpau_hwaccel
+ * function and make it available as
  * AVCodecContext.hwaccel_context. Members can be set by the user once
  * during initialization or through each AVCodecContext.get_buffer()
  * function call. In any case, they must be valid prior to calling
@@ -84,18 +102,21 @@
      */
     VdpDecoderRender *render;
 
+#if FF_API_BUFS_VDPAU
     /**
      * VDPAU picture information
      *
      * Set by libavcodec.
      */
-    union FFVdpPictureInfo info;
+    attribute_deprecated
+    union AVVDPAUPictureInfo info;
 
     /**
      * Allocated size of the bitstream_buffers table.
      *
      * Set by libavcodec.
      */
+    attribute_deprecated
     int bitstream_buffers_allocated;
 
     /**
@@ -103,6 +124,7 @@
      *
      * Set by libavcodec.
      */
+    attribute_deprecated
     int bitstream_buffers_used;
 
    /**
@@ -111,10 +133,23 @@
      *
      * Set by libavcodec.
      */
+    attribute_deprecated
     VdpBitstreamBuffer *bitstream_buffers;
+#endif
+    AVVDPAU_Render2 render2;
 } AVVDPAUContext;
 
+/**
+ * @brief allocation function for AVVDPAUContext
+ *
+ * Allows extending the struct without breaking API/ABI
+ */
+AVVDPAUContext *av_alloc_vdpaucontext(void);
 
+AVVDPAU_Render2 av_vdpau_hwaccel_get_render2(const AVVDPAUContext *);
+void av_vdpau_hwaccel_set_render2(AVVDPAUContext *, AVVDPAU_Render2);
+
+#if FF_API_CAP_VDPAU
 /** @brief The videoSurface is used for rendering. */
 #define FF_VDPAU_STATE_USED_FOR_RENDER 1
 
@@ -136,9 +171,9 @@
 
     int state; ///< Holds FF_VDPAU_STATE_* values.
 
-#if AV_HAVE_INCOMPATIBLE_FORK_ABI
+#if AV_HAVE_INCOMPATIBLE_LIBAV_ABI
     /** picture parameter information for all supported codecs */
-    union FFVdpPictureInfo info;
+    union AVVDPAUPictureInfo info;
 #endif
 
     /** Describe size/location of the compressed video data.
@@ -148,11 +183,12 @@
     /** The user is responsible for freeing this buffer using av_freep(). */
     VdpBitstreamBuffer *bitstream_buffers;
 
-#if !AV_HAVE_INCOMPATIBLE_FORK_ABI
+#if !AV_HAVE_INCOMPATIBLE_LIBAV_ABI
     /** picture parameter information for all supported codecs */
-    union FFVdpPictureInfo info;
+    union AVVDPAUPictureInfo info;
 #endif
 };
+#endif
 
 /* @}*/
 
diff --git a/libavcodec/vdpau_h264.c b/libavcodec/vdpau_h264.c
index ad1aff0..3f6415d 100644
--- a/libavcodec/vdpau_h264.c
+++ b/libavcodec/vdpau_h264.c
@@ -66,8 +66,8 @@
 static void vdpau_h264_set_reference_frames(AVCodecContext *avctx)
 {
     H264Context * const h = avctx->priv_data;
-    AVVDPAUContext *hwctx = avctx->hwaccel_context;
-    VdpPictureInfoH264 *info = &hwctx->info.h264;
+    struct vdpau_picture_context *pic_ctx = h->cur_pic_ptr->hwaccel_picture_private;
+    VdpPictureInfoH264 *info = &pic_ctx->info.h264;
     int list;
 
     VdpReferenceFrameH264 *rf = &info->referenceFrames[0];
@@ -118,9 +118,9 @@
                                   const uint8_t *buffer, uint32_t size)
 {
     H264Context * const h = avctx->priv_data;
-    AVVDPAUContext *hwctx = avctx->hwaccel_context;
-    VdpPictureInfoH264 *info = &hwctx->info.h264;
     Picture *pic = h->cur_pic_ptr;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
+    VdpPictureInfoH264 *info = &pic_ctx->info.h264;
 
     /* init VdpPictureInfoH264 */
     info->slice_count                            = 0;
@@ -161,7 +161,7 @@
 
     vdpau_h264_set_reference_frames(avctx);
 
-    return ff_vdpau_common_start_frame(avctx, buffer, size);
+    return ff_vdpau_common_start_frame(pic, buffer, size);
 }
 
 static const uint8_t start_code_prefix[3] = { 0x00, 0x00, 0x01 };
@@ -169,34 +169,43 @@
 static int vdpau_h264_decode_slice(AVCodecContext *avctx,
                                    const uint8_t *buffer, uint32_t size)
 {
-    AVVDPAUContext *hwctx = avctx->hwaccel_context;
+    H264Context *h = avctx->priv_data;
+    Picture *pic   = h->cur_pic_ptr;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
     int val;
 
-    val = ff_vdpau_add_buffer(avctx, start_code_prefix, 3);
+    val = ff_vdpau_add_buffer(pic, start_code_prefix, 3);
     if (val)
         return val;
 
-    val = ff_vdpau_add_buffer(avctx, buffer, size);
+    val = ff_vdpau_add_buffer(pic, buffer, size);
     if (val)
         return val;
 
-    hwctx->info.h264.slice_count++;
+    pic_ctx->info.h264.slice_count++;
     return 0;
 }
 
 static int vdpau_h264_end_frame(AVCodecContext *avctx)
 {
+    int res = 0;
     AVVDPAUContext *hwctx = avctx->hwaccel_context;
     H264Context *h = avctx->priv_data;
-    VdpVideoSurface surf = ff_vdpau_get_surface_id(h->cur_pic_ptr);
+    Picture *pic   = h->cur_pic_ptr;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
+    VdpVideoSurface surf = ff_vdpau_get_surface_id(pic);
 
-    hwctx->render(hwctx->decoder, surf, (void *)&hwctx->info,
-                  hwctx->bitstream_buffers_used, hwctx->bitstream_buffers);
+    if (!hwctx->render) {
+        res = hwctx->render2(avctx, &pic->f, (void *)&pic_ctx->info,
+                             pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers);
+    } else
+    hwctx->render(hwctx->decoder, surf, (void *)&pic_ctx->info,
+                  pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers);
 
     ff_h264_draw_horiz_band(h, 0, h->avctx->height);
-    hwctx->bitstream_buffers_used = 0;
+    av_freep(&pic_ctx->bitstream_buffers);
 
-    return 0;
+    return res;
 }
 
 AVHWAccel ff_h264_vdpau_hwaccel = {
@@ -207,4 +216,5 @@
     .start_frame    = vdpau_h264_start_frame,
     .end_frame      = vdpau_h264_end_frame,
     .decode_slice   = vdpau_h264_decode_slice,
+    .priv_data_size = sizeof(struct vdpau_picture_context),
 };
diff --git a/libavcodec/vdpau_internal.h b/libavcodec/vdpau_internal.h
index 790b3ef..7fdfda0 100644
--- a/libavcodec/vdpau_internal.h
+++ b/libavcodec/vdpau_internal.h
@@ -25,6 +25,10 @@
 #define AVCODEC_VDPAU_INTERNAL_H
 
 #include <stdint.h>
+#if CONFIG_VDPAU
+#include <vdpau/vdpau.h>
+#include "vdpau.h"
+#endif
 #include "h264.h"
 #include "mpegvideo.h"
 
@@ -34,11 +38,43 @@
     return (uintptr_t)pic->f.data[3];
 }
 
-int ff_vdpau_common_start_frame(AVCodecContext *avctx,
+#if CONFIG_VDPAU
+#if !FF_API_BUFS_VDPAU
+union AVVDPAUPictureInfo {
+    VdpPictureInfoH264        h264;
+    VdpPictureInfoMPEG1Or2    mpeg;
+    VdpPictureInfoVC1          vc1;
+    VdpPictureInfoMPEG4Part2 mpeg4;
+};
+#endif
+
+struct vdpau_picture_context {
+    /**
+     * VDPAU picture information.
+     */
+    union AVVDPAUPictureInfo info;
+
+    /**
+     * Allocated size of the bitstream_buffers table.
+     */
+    int bitstream_buffers_allocated;
+
+    /**
+     * Useful bitstream buffers in the bitstream buffers table.
+     */
+    int bitstream_buffers_used;
+
+   /**
+     * Table of bitstream buffers.
+     */
+    VdpBitstreamBuffer *bitstream_buffers;
+};
+#endif
+
+int ff_vdpau_common_start_frame(Picture *pic,
                                 const uint8_t *buffer, uint32_t size);
 int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx);
-int ff_vdpau_add_buffer(AVCodecContext *avctx,
-                        const uint8_t *buf, uint32_t buf_size);
+int ff_vdpau_add_buffer(Picture *pic, const uint8_t *buf, uint32_t buf_size);
 
 
 void ff_vdpau_add_data_chunk(uint8_t *data, const uint8_t *buf,
diff --git a/libavcodec/vdpau_mpeg12.c b/libavcodec/vdpau_mpeg12.c
index 74e3f16..f21b341 100644
--- a/libavcodec/vdpau_mpeg12.c
+++ b/libavcodec/vdpau_mpeg12.c
@@ -31,8 +31,9 @@
                                   const uint8_t *buffer, uint32_t size)
 {
     MpegEncContext * const s = avctx->priv_data;
-    AVVDPAUContext *hwctx    = avctx->hwaccel_context;
-    VdpPictureInfoMPEG1Or2 *info = &hwctx->info.mpeg;
+    Picture *pic             = s->current_picture_ptr;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
+    VdpPictureInfoMPEG1Or2 *info = &pic_ctx->info.mpeg;
     VdpVideoSurface ref;
     int i;
 
@@ -44,11 +45,11 @@
     case AV_PICTURE_TYPE_B:
         ref = ff_vdpau_get_surface_id(&s->next_picture);
         assert(ref != VDP_INVALID_HANDLE);
-        hwctx->info.mpeg.backward_reference = ref;
+        info->backward_reference = ref;
         /* fall through to forward prediction */
     case AV_PICTURE_TYPE_P:
         ref = ff_vdpau_get_surface_id(&s->last_picture);
-        hwctx->info.mpeg.forward_reference  = ref;
+        info->forward_reference  = ref;
     }
 
     info->slice_count                = 0;
@@ -74,20 +75,22 @@
         info->non_intra_quantizer_matrix[i] = s->inter_matrix[i];
     }
 
-    return ff_vdpau_common_start_frame(avctx, buffer, size);
+    return ff_vdpau_common_start_frame(pic, buffer, size);
 }
 
 static int vdpau_mpeg_decode_slice(AVCodecContext *avctx,
                                    const uint8_t *buffer, uint32_t size)
 {
-    AVVDPAUContext *hwctx = avctx->hwaccel_context;
+    MpegEncContext * const s = avctx->priv_data;
+    Picture *pic             = s->current_picture_ptr;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
     int val;
 
-    val = ff_vdpau_add_buffer(avctx, buffer, size);
+    val = ff_vdpau_add_buffer(pic, buffer, size);
     if (val < 0)
         return val;
 
-    hwctx->info.mpeg.slice_count++;
+    pic_ctx->info.mpeg.slice_count++;
     return 0;
 }
 
@@ -100,6 +103,7 @@
     .start_frame    = vdpau_mpeg_start_frame,
     .end_frame      = ff_vdpau_mpeg_end_frame,
     .decode_slice   = vdpau_mpeg_decode_slice,
+    .priv_data_size = sizeof(struct vdpau_picture_context),
 };
 #endif
 
@@ -112,5 +116,6 @@
     .start_frame    = vdpau_mpeg_start_frame,
     .end_frame      = ff_vdpau_mpeg_end_frame,
     .decode_slice   = vdpau_mpeg_decode_slice,
+    .priv_data_size = sizeof(struct vdpau_picture_context),
 };
 #endif
diff --git a/libavcodec/vdpau_mpeg4.c b/libavcodec/vdpau_mpeg4.c
index cb8ee0a..84683a4 100644
--- a/libavcodec/vdpau_mpeg4.c
+++ b/libavcodec/vdpau_mpeg4.c
@@ -31,8 +31,9 @@
                                    const uint8_t *buffer, uint32_t size)
 {
     MpegEncContext * const s = avctx->priv_data;
-    AVVDPAUContext *hwctx    = avctx->hwaccel_context;
-    VdpPictureInfoMPEG4Part2 *info = &hwctx->info.mpeg4;
+    Picture *pic             = s->current_picture_ptr;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
+    VdpPictureInfoMPEG4Part2 *info = &pic_ctx->info.mpeg4;
     VdpVideoSurface ref;
     int i;
 
@@ -74,8 +75,8 @@
         info->non_intra_quantizer_matrix[i] = s->inter_matrix[i];
     }
 
-    ff_vdpau_common_start_frame(avctx, buffer, size);
-    return ff_vdpau_add_buffer(avctx, buffer, size);
+    ff_vdpau_common_start_frame(pic, buffer, size);
+    return ff_vdpau_add_buffer(pic, buffer, size);
 }
 
 static int vdpau_mpeg4_decode_slice(av_unused AVCodecContext *avctx,
@@ -94,6 +95,7 @@
     .start_frame    = vdpau_mpeg4_start_frame,
     .end_frame      = ff_vdpau_mpeg_end_frame,
     .decode_slice   = vdpau_mpeg4_decode_slice,
+    .priv_data_size = sizeof(struct vdpau_picture_context),
 };
 #endif
 
@@ -106,5 +108,6 @@
     .start_frame    = vdpau_mpeg4_start_frame,
     .end_frame      = ff_vdpau_mpeg_end_frame,
     .decode_slice   = vdpau_mpeg4_decode_slice,
+    .priv_data_size = sizeof(struct vdpau_picture_context),
 };
 #endif
diff --git a/libavcodec/vdpau_vc1.c b/libavcodec/vdpau_vc1.c
index f5da9bb..272b2d9 100644
--- a/libavcodec/vdpau_vc1.c
+++ b/libavcodec/vdpau_vc1.c
@@ -32,9 +32,10 @@
                                  const uint8_t *buffer, uint32_t size)
 {
     VC1Context * const v  = avctx->priv_data;
-    AVVDPAUContext *hwctx = avctx->hwaccel_context;
     MpegEncContext * const s = &v->s;
-    VdpPictureInfoVC1 *info = &hwctx->info.vc1;
+    Picture *pic          = s->current_picture_ptr;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
+    VdpPictureInfoVC1 *info = &pic_ctx->info.vc1;
     VdpVideoSurface ref;
 
     /*  fill LvPictureInfoVC1 struct */
@@ -59,7 +60,7 @@
     else
         info->picture_type  = s->pict_type - 1 + s->pict_type / 3;
 
-    info->frame_coding_mode = v->fcm;
+    info->frame_coding_mode = v->fcm ? (v->fcm + 1) : 0;
     info->postprocflag      = v->postprocflag;
     info->pulldown          = v->broadcast;
     info->interlace         = v->interlace;
@@ -88,20 +89,23 @@
     info->deblockEnable     = v->postprocflag & 1;
     info->pquant            = v->pq;
 
-    return ff_vdpau_common_start_frame(avctx, buffer, size);
+    return ff_vdpau_common_start_frame(pic, buffer, size);
 }
 
 static int vdpau_vc1_decode_slice(AVCodecContext *avctx,
                                   const uint8_t *buffer, uint32_t size)
 {
-    AVVDPAUContext *hwctx = avctx->hwaccel_context;
+    VC1Context * const v  = avctx->priv_data;
+    MpegEncContext * const s = &v->s;
+    Picture *pic          = s->current_picture_ptr;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
     int val;
 
-    val = ff_vdpau_add_buffer(avctx, buffer, size);
+    val = ff_vdpau_add_buffer(pic, buffer, size);
     if (val < 0)
         return val;
 
-    hwctx->info.vc1.slice_count++;
+    pic_ctx->info.vc1.slice_count++;
     return 0;
 }
 
@@ -114,6 +118,7 @@
     .start_frame    = vdpau_vc1_start_frame,
     .end_frame      = ff_vdpau_mpeg_end_frame,
     .decode_slice   = vdpau_vc1_decode_slice,
+    .priv_data_size = sizeof(struct vdpau_picture_context),
 };
 #endif
 
@@ -125,4 +130,5 @@
     .start_frame    = vdpau_vc1_start_frame,
     .end_frame      = ff_vdpau_mpeg_end_frame,
     .decode_slice   = vdpau_vc1_decode_slice,
+    .priv_data_size = sizeof(struct vdpau_picture_context),
 };
diff --git a/libavcodec/version.h b/libavcodec/version.h
index d6f7b8e..7d01933 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@
 #include "libavutil/avutil.h"
 
 #define LIBAVCODEC_VERSION_MAJOR 55
-#define LIBAVCODEC_VERSION_MINOR  6
+#define LIBAVCODEC_VERSION_MINOR  29
 #define LIBAVCODEC_VERSION_MICRO 100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
@@ -88,5 +88,17 @@
 #ifndef FF_API_MISSING_SAMPLE
 #define FF_API_MISSING_SAMPLE    (LIBAVCODEC_VERSION_MAJOR < 56)
 #endif
+#ifndef FF_API_LOWRES
+#define FF_API_LOWRES            (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_CAP_VDPAU
+#define FF_API_CAP_VDPAU         (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_BUFS_VDPAU
+#define FF_API_BUFS_VDPAU        (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_VOXWARE
+#define FF_API_VOXWARE           (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
 
 #endif /* AVCODEC_VERSION_H */
diff --git a/libavcodec/videodsp.c b/libavcodec/videodsp.c
index f91bac3..13e4a7b 100644
--- a/libavcodec/videodsp.c
+++ b/libavcodec/videodsp.c
@@ -18,6 +18,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "libavutil/common.h"
 #include "videodsp.h"
@@ -34,7 +35,7 @@
 {
 }
 
-void ff_videodsp_init(VideoDSPContext *ctx, int bpc)
+av_cold void ff_videodsp_init(VideoDSPContext *ctx, int bpc)
 {
     ctx->prefetch = just_return;
     if (bpc <= 8) {
diff --git a/libavcodec/vima.c b/libavcodec/vima.c
index 705839e..0513ee2 100644
--- a/libavcodec/vima.c
+++ b/libavcodec/vima.c
@@ -19,15 +19,20 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+/**
+ * @file
+ * LucasArts VIMA audio decoder
+ * @author Paul B Mahol
+ */
+
 #include "libavutil/channel_layout.h"
 #include "avcodec.h"
 #include "get_bits.h"
 #include "internal.h"
 #include "adpcm_data.h"
 
-typedef struct {
-    uint16_t    predict_table[5786 * 2];
-} VimaContext;
+static int predict_table_init = 0;
+static uint16_t predict_table[5786 * 2];
 
 static const uint8_t size_table[] =
 {
@@ -103,8 +108,12 @@
 
 static av_cold int decode_init(AVCodecContext *avctx)
 {
-    VimaContext *vima = avctx->priv_data;
-    int         start_pos;
+    int start_pos;
+
+    avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+    if (predict_table_init)
+        return 0;
 
     for (start_pos = 0; start_pos < 64; start_pos++) {
         unsigned int dest_pos, table_pos;
@@ -120,11 +129,10 @@
                     put += table_value;
                 table_value >>= 1;
             }
-            vima->predict_table[dest_pos] = put;
+            predict_table[dest_pos] = put;
         }
     }
-
-    avctx->sample_fmt  = AV_SAMPLE_FMT_S16;
+    predict_table_init = 1;
 
     return 0;
 }
@@ -133,7 +141,6 @@
                         int *got_frame_ptr, AVPacket *pkt)
 {
     GetBitContext  gb;
-    VimaContext    *vima = avctx->priv_data;
     AVFrame        *frame = data;
     int16_t        pcm_data[2];
     uint32_t       samples;
@@ -200,7 +207,7 @@
 
                 predict_index = (lookup << (7 - lookup_size)) | (step_index << 6);
                 predict_index = av_clip(predict_index, 0, 5785);
-                diff          = vima->predict_table[predict_index];
+                diff          = predict_table[predict_index];
                 if (lookup)
                     diff += ff_adpcm_step_table[step_index] >> (lookup_size - 1);
                 if (highbit)
@@ -225,7 +232,6 @@
     .name           = "vima",
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_VIMA,
-    .priv_data_size = sizeof(VimaContext),
     .init           = decode_init,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c
index 867d8c76..fcb8a9b 100644
--- a/libavcodec/vmdav.c
+++ b/libavcodec/vmdav.c
@@ -43,6 +43,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "libavutil/avassert.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
@@ -151,9 +152,10 @@
                       int src_count, int src_size, int dest_len)
 {
     unsigned char *pd;
-    int i, l;
+    int i, l, used = 0;
     unsigned char *dest_end = dest + dest_len;
     GetByteContext gb;
+    uint16_t run_val;
 
     bytestream2_init(&gb, src, src_size);
     pd = dest;
@@ -161,10 +163,9 @@
         if (bytestream2_get_bytes_left(&gb) < 1)
             return 0;
         *pd++ = bytestream2_get_byteu(&gb);
+        used++;
     }
 
-    src_count >>= 1;
-    i = 0;
     do {
         if (bytestream2_get_bytes_left(&gb) < 1)
             break;
@@ -176,21 +177,22 @@
             bytestream2_get_bufferu(&gb, pd, l);
             pd += l;
         } else {
-            if (dest_end - pd < i || bytestream2_get_bytes_left(&gb) < 2)
+            if (dest_end - pd < 2*l || bytestream2_get_bytes_left(&gb) < 2)
                 return bytestream2_tell(&gb);
+            run_val = bytestream2_get_ne16(&gb);
             for (i = 0; i < l; i++) {
-                *pd++ = bytestream2_get_byteu(&gb);
-                *pd++ = bytestream2_get_byteu(&gb);
+                AV_WN16(pd, run_val);
+                pd += 2;
             }
-            bytestream2_skip(&gb, 2);
+            l *= 2;
         }
-        i += l;
-    } while (i < src_count);
+        used += l;
+    } while (used < src_count);
 
     return bytestream2_tell(&gb);
 }
 
-static void vmd_decode(VmdVideoContext *s, AVFrame *frame)
+static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
 {
     int i;
     unsigned int *palette32;
@@ -211,16 +213,6 @@
     frame_y = AV_RL16(&s->buf[8]);
     frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
     frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
-    if (frame_x < 0 || frame_width < 0 ||
-        frame_x >= s->avctx->width ||
-        frame_width > s->avctx->width ||
-        frame_x + frame_width > s->avctx->width)
-        return;
-    if (frame_y < 0 || frame_height < 0 ||
-        frame_y >= s->avctx->height ||
-        frame_height > s->avctx->height ||
-        frame_y + frame_height > s->avctx->height)
-        return;
 
     if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
         (frame_x || frame_y)) {
@@ -231,6 +223,25 @@
     frame_x -= s->x_off;
     frame_y -= s->y_off;
 
+    if (frame_x < 0 || frame_width < 0 ||
+        frame_x >= s->avctx->width ||
+        frame_width > s->avctx->width ||
+        frame_x + frame_width > s->avctx->width) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "Invalid horizontal range %d-%d\n",
+               frame_x, frame_width);
+        return AVERROR_INVALIDDATA;
+    }
+    if (frame_y < 0 || frame_height < 0 ||
+        frame_y >= s->avctx->height ||
+        frame_height > s->avctx->height ||
+        frame_y + frame_height > s->avctx->height) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "Invalid vertical range %d-%d\n",
+               frame_x, frame_width);
+        return AVERROR_INVALIDDATA;
+    }
+
     /* if only a certain region will be updated, copy the entire previous
      * frame before the decode */
     if (s->prev_frame.data[0] &&
@@ -254,93 +265,112 @@
                 palette32[i] = 0xFFU << 24 | (r << 16) | (g << 8) | (b);
                 palette32[i] |= palette32[i] >> 6 & 0x30303;
             }
+        } else {
+            av_log(s->avctx, AV_LOG_ERROR, "Incomplete palette\n");
+            return AVERROR_INVALIDDATA;
         }
     }
-    if (s->size > 0) {
-        /* originally UnpackFrame in VAG's code */
-        bytestream2_init(&gb, gb.buffer, s->buf + s->size - gb.buffer);
-        if (bytestream2_get_bytes_left(&gb) < 1)
-            return;
-        meth = bytestream2_get_byteu(&gb);
-        if (meth & 0x80) {
-            lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb),
-                      s->unpack_buffer, s->unpack_buffer_size);
-            meth &= 0x7F;
-            bytestream2_init(&gb, s->unpack_buffer, s->unpack_buffer_size);
+
+    if (!s->size)
+        return 0;
+
+    /* originally UnpackFrame in VAG's code */
+    if (bytestream2_get_bytes_left(&gb) < 1)
+        return AVERROR_INVALIDDATA;
+    meth = bytestream2_get_byteu(&gb);
+    if (meth & 0x80) {
+        if (!s->unpack_buffer_size) {
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "Trying to unpack LZ-compressed frame with no LZ buffer\n");
+            return AVERROR_INVALIDDATA;
         }
+        lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb),
+                  s->unpack_buffer, s->unpack_buffer_size);
+        meth &= 0x7F;
+        bytestream2_init(&gb, s->unpack_buffer, s->unpack_buffer_size);
+    }
 
-        dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x];
-        pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
-        switch (meth) {
-        case 1:
-            for (i = 0; i < frame_height; i++) {
-                ofs = 0;
-                do {
-                    len = bytestream2_get_byte(&gb);
-                    if (len & 0x80) {
-                        len = (len & 0x7F) + 1;
-                        if (ofs + len > frame_width || bytestream2_get_bytes_left(&gb) < len)
-                            return;
-                        bytestream2_get_bufferu(&gb, &dp[ofs], len);
-                        ofs += len;
-                    } else {
-                        /* interframe pixel copy */
-                        if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
-                            return;
-                        memcpy(&dp[ofs], &pp[ofs], len + 1);
-                        ofs += len + 1;
-                    }
-                } while (ofs < frame_width);
-                if (ofs > frame_width) {
-                    av_log(s->avctx, AV_LOG_ERROR, "offset > width (%d > %d)\n",
-                        ofs, frame_width);
-                    break;
+    dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x];
+    pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
+    switch (meth) {
+    case 1:
+        for (i = 0; i < frame_height; i++) {
+            ofs = 0;
+            do {
+                len = bytestream2_get_byte(&gb);
+                if (len & 0x80) {
+                    len = (len & 0x7F) + 1;
+                    if (ofs + len > frame_width ||
+                        bytestream2_get_bytes_left(&gb) < len)
+                        return AVERROR_INVALIDDATA;
+                    bytestream2_get_bufferu(&gb, &dp[ofs], len);
+                    ofs += len;
+                } else {
+                    /* interframe pixel copy */
+                    if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
+                        return AVERROR_INVALIDDATA;
+                    memcpy(&dp[ofs], &pp[ofs], len + 1);
+                    ofs += len + 1;
                 }
-                dp += frame->linesize[0];
-                pp += s->prev_frame.linesize[0];
+            } while (ofs < frame_width);
+            if (ofs > frame_width) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "offset > width (%d > %d)\n",
+                       ofs, frame_width);
+                return AVERROR_INVALIDDATA;
             }
-            break;
+            dp += frame->linesize[0];
+            pp += s->prev_frame.linesize[0];
+        }
+        break;
 
-        case 2:
-            for (i = 0; i < frame_height; i++) {
-                bytestream2_get_buffer(&gb, dp, frame_width);
-                dp += frame->linesize[0];
-                pp += s->prev_frame.linesize[0];
-            }
-            break;
+    case 2:
+        for (i = 0; i < frame_height; i++) {
+            bytestream2_get_buffer(&gb, dp, frame_width);
+            dp += frame->linesize[0];
+            pp += s->prev_frame.linesize[0];
+        }
+        break;
 
-        case 3:
-            for (i = 0; i < frame_height; i++) {
-                ofs = 0;
-                do {
-                    len = bytestream2_get_byte(&gb);
-                    if (len & 0x80) {
-                        len = (len & 0x7F) + 1;
-                        if (bytestream2_get_byte(&gb) == 0xFF)
-                            len = rle_unpack(gb.buffer, &dp[ofs],
-                                             len, bytestream2_get_bytes_left(&gb),
-                                             frame_width - ofs);
-                        else
-                            bytestream2_get_buffer(&gb, &dp[ofs], len);
+    case 3:
+        for (i = 0; i < frame_height; i++) {
+            ofs = 0;
+            do {
+                len = bytestream2_get_byte(&gb);
+                if (len & 0x80) {
+                    len = (len & 0x7F) + 1;
+                    if (bytestream2_peek_byte(&gb) == 0xFF) {
+                        int slen = len;
+                        bytestream2_get_byte(&gb);
+                        len = rle_unpack(gb.buffer, &dp[ofs],
+                                         len, bytestream2_get_bytes_left(&gb),
+                                         frame_width - ofs);
+                        ofs += slen;
                         bytestream2_skip(&gb, len);
                     } else {
-                        /* interframe pixel copy */
-                        if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
-                            return;
-                        memcpy(&dp[ofs], &pp[ofs], len + 1);
-                        ofs += len + 1;
+                        bytestream2_get_buffer(&gb, &dp[ofs], len);
+                        ofs += len;
                     }
-                } while (ofs < frame_width);
-                if (ofs > frame_width) {
-                    av_log(s->avctx, AV_LOG_ERROR, "offset > width (%d > %d)\n",
-                        ofs, frame_width);
+                } else {
+                    /* interframe pixel copy */
+                    if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
+                        return AVERROR_INVALIDDATA;
+                    memcpy(&dp[ofs], &pp[ofs], len + 1);
+                    ofs += len + 1;
                 }
-                dp += frame->linesize[0];
-                pp += s->prev_frame.linesize[0];
+            } while (ofs < frame_width);
+            if (ofs > frame_width) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "offset > width (%d > %d)\n",
+                       ofs, frame_width);
+                return AVERROR_INVALIDDATA;
             }
-            break;
+            dp += frame->linesize[0];
+            pp += s->prev_frame.linesize[0];
         }
+        break;
     }
+    return 0;
 }
 
 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
@@ -360,14 +390,16 @@
     if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
         av_log(s->avctx, AV_LOG_ERROR, "expected extradata size of %d\n",
             VMD_HEADER_SIZE);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     vmd_header = (unsigned char *)avctx->extradata;
 
     s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
-    s->unpack_buffer = av_malloc(s->unpack_buffer_size);
-    if (!s->unpack_buffer)
-        return -1;
+    if (s->unpack_buffer_size) {
+        s->unpack_buffer = av_malloc(s->unpack_buffer_size);
+        if (!s->unpack_buffer)
+            return AVERROR(ENOMEM);
+    }
 
     /* load up the initial palette */
     raw_palette = &vmd_header[28];
@@ -376,7 +408,8 @@
         r = raw_palette[palette_index++] * 4;
         g = raw_palette[palette_index++] * 4;
         b = raw_palette[palette_index++] * 4;
-        palette32[i] = (r << 16) | (g << 8) | (b);
+        palette32[i] = 0xFFU << 24 | (r << 16) | (g << 8) | (b);
+        palette32[i] |= palette32[i] >> 6 & 0x30303;
     }
 
     avcodec_get_frame_defaults(&s->prev_frame);
@@ -398,12 +431,13 @@
     s->size = buf_size;
 
     if (buf_size < 16)
-        return buf_size;
+        return AVERROR_INVALIDDATA;
 
     if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
         return ret;
 
-    vmd_decode(s, frame);
+    if ((ret = vmd_decode(s, frame)) < 0)
+        return ret;
 
     /* make the palette available on the way out */
     memcpy(frame->data[1], s->palette, PALETTE_COUNT * 4);
@@ -567,6 +601,9 @@
     /* ensure output buffer is large enough */
     audio_chunks = buf_size / s->chunk_size;
 
+    /* drop incomplete chunks */
+    buf_size     = audio_chunks * s->chunk_size;
+
     /* get output buffer */
     frame->nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) /
                         avctx->channels;
@@ -578,6 +615,8 @@
     /* decode silent chunks */
     if (silent_chunks > 0) {
         int silent_size = avctx->block_align * silent_chunks;
+        av_assert0(avctx->block_align * silent_chunks <= frame->nb_samples * avctx->channels);
+
         if (s->out_bps == 2) {
             memset(output_samples_s16, 0x00, silent_size * 2);
             output_samples_s16 += silent_size;
@@ -590,6 +629,7 @@
     /* decode audio chunks */
     if (audio_chunks > 0) {
         buf_end = buf + buf_size;
+        av_assert0((buf_size & (avctx->channels > 1)) == 0);
         while (buf_end - buf >= s->chunk_size) {
             if (s->out_bps == 2) {
                 decode_audio_s16(output_samples_s16, buf, s->chunk_size,
diff --git a/libavcodec/vmnc.c b/libavcodec/vmnc.c
index 99571a1..9fe9940 100644
--- a/libavcodec/vmnc.c
+++ b/libavcodec/vmnc.c
@@ -56,7 +56,7 @@
  */
 typedef struct VmncContext {
     AVCodecContext *avctx;
-    AVFrame pic;
+    AVFrame *frame;
 
     int bpp;
     int bpp2;
@@ -295,12 +295,13 @@
     uint8_t *outptr;
     const uint8_t *src = buf;
     int dx, dy, w, h, depth, enc, chunks, res, size_left, ret;
+    AVFrame *frame = c->frame;
 
-    if ((ret = ff_reget_buffer(avctx, &c->pic)) < 0)
+    if ((ret = ff_reget_buffer(avctx, frame)) < 0)
         return ret;
 
-    c->pic.key_frame = 0;
-    c->pic.pict_type = AV_PICTURE_TYPE_P;
+    frame->key_frame = 0;
+    frame->pict_type = AV_PICTURE_TYPE_P;
 
     //restore screen after cursor
     if(c->screendta) {
@@ -320,10 +321,10 @@
             dy = 0;
         }
         if((w > 0) && (h > 0)) {
-            outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0];
+            outptr = frame->data[0] + dx * c->bpp2 + dy * frame->linesize[0];
             for(i = 0; i < h; i++) {
                 memcpy(outptr, c->screendta + i * c->cur_w * c->bpp2, w * c->bpp2);
-                outptr += c->pic.linesize[0];
+                outptr += frame->linesize[0];
             }
         }
     }
@@ -339,7 +340,7 @@
         w  = AV_RB16(src); src += 2;
         h  = AV_RB16(src); src += 2;
         enc = AV_RB32(src); src += 4;
-        outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0];
+        outptr = frame->data[0] + dx * c->bpp2 + dy * frame->linesize[0];
         size_left = buf_size - (src - buf);
         switch(enc) {
         case MAGIC_WMVd: // cursor
@@ -360,9 +361,11 @@
                 av_log(avctx, AV_LOG_ERROR, "Cursor hot spot is not in image: %ix%i of %ix%i cursor size\n", c->cur_hx, c->cur_hy, c->cur_w, c->cur_h);
                 c->cur_hx = c->cur_hy = 0;
             }
-            c->curbits = av_realloc(c->curbits, c->cur_w * c->cur_h * c->bpp2);
-            c->curmask = av_realloc(c->curmask, c->cur_w * c->cur_h * c->bpp2);
-            c->screendta = av_realloc(c->screendta, c->cur_w * c->cur_h * c->bpp2);
+            c->curbits = av_realloc_f(c->curbits, c->cur_w * c->cur_h, c->bpp2);
+            c->curmask = av_realloc_f(c->curmask, c->cur_w * c->cur_h, c->bpp2);
+            c->screendta = av_realloc_f(c->screendta, c->cur_w * c->cur_h, c->bpp2);
+            if (!c->curbits || !c->curmask || !c->screendta)
+                return AVERROR(ENOMEM);
             load_cursor(c, src);
             src += w * h * c->bpp2 * 2;
             break;
@@ -380,8 +383,8 @@
             src += 4;
             break;
         case MAGIC_WMVi: // ServerInitialization struct
-            c->pic.key_frame = 1;
-            c->pic.pict_type = AV_PICTURE_TYPE_I;
+            frame->key_frame = 1;
+            frame->pict_type = AV_PICTURE_TYPE_I;
             depth = *src++;
             if(depth != c->bpp) {
                 av_log(avctx, AV_LOG_INFO, "Depth mismatch. Container %i bpp, Frame data: %i bpp\n", c->bpp, depth);
@@ -407,7 +410,7 @@
                 av_log(avctx, AV_LOG_ERROR, "Premature end of data! (need %i got %i)\n", w * h * c->bpp2, size_left);
                 return -1;
             }
-            paint_raw(outptr, w, h, src, c->bpp2, c->bigendian, c->pic.linesize[0]);
+            paint_raw(outptr, w, h, src, c->bpp2, c->bigendian, frame->linesize[0]);
             src += w * h * c->bpp2;
             break;
         case 0x00000005: // HexTile encoded rectangle
@@ -415,7 +418,7 @@
                 av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height);
                 return -1;
             }
-            res = decode_hextile(c, outptr, src, size_left, w, h, c->pic.linesize[0]);
+            res = decode_hextile(c, outptr, src, size_left, w, h, frame->linesize[0]);
             if(res < 0)
                 return -1;
             src += res;
@@ -443,17 +446,17 @@
             dy = 0;
         }
         if((w > 0) && (h > 0)) {
-            outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0];
+            outptr = frame->data[0] + dx * c->bpp2 + dy * frame->linesize[0];
             for(i = 0; i < h; i++) {
                 memcpy(c->screendta + i * c->cur_w * c->bpp2, outptr, w * c->bpp2);
-                outptr += c->pic.linesize[0];
+                outptr += frame->linesize[0];
             }
-            outptr = c->pic.data[0];
-            put_cursor(outptr, c->pic.linesize[0], c, c->cur_x, c->cur_y);
+            outptr = frame->data[0];
+            put_cursor(outptr, frame->linesize[0], c, c->cur_x, c->cur_y);
         }
     }
     *got_frame      = 1;
-    if ((ret = av_frame_ref(data, &c->pic)) < 0)
+    if ((ret = av_frame_ref(data, frame)) < 0)
         return ret;
 
     /* always report that the buffer was completely consumed */
@@ -478,7 +481,6 @@
 
     c->bpp = avctx->bits_per_coded_sample;
     c->bpp2 = c->bpp/8;
-    avcodec_get_frame_defaults(&c->pic);
 
     switch(c->bpp){
     case 8:
@@ -495,7 +497,9 @@
         return AVERROR_INVALIDDATA;
     }
 
-    avcodec_get_frame_defaults(&c->pic);
+    c->frame = av_frame_alloc();
+    if (!c->frame)
+        return AVERROR(ENOMEM);
 
     return 0;
 }
@@ -511,7 +515,7 @@
 {
     VmncContext * const c = avctx->priv_data;
 
-    av_frame_unref(&c->pic);
+    av_frame_free(&c->frame);
 
     av_free(c->curbits);
     av_free(c->curmask);
diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c
index f30745d..c5950e6 100644
--- a/libavcodec/vorbisdec.c
+++ b/libavcodec/vorbisdec.c
@@ -1230,8 +1230,11 @@
 
             cval = cval >> cbits;
             if (book > -1) {
-                floor1_Y[offset+j] = get_vlc2(gb, vc->codebooks[book].vlc.table,
-                vc->codebooks[book].nb_bits, 3);
+                int v = get_vlc2(gb, vc->codebooks[book].vlc.table,
+                                 vc->codebooks[book].nb_bits, 3);
+                if (v < 0)
+                    return AVERROR_INVALIDDATA;
+                floor1_Y[offset+j] = v;
             } else {
                 floor1_Y[offset+j] = 0;
             }
@@ -1308,6 +1311,50 @@
     return 0;
 }
 
+static av_always_inline int setup_classifs(vorbis_context *vc,
+                                           vorbis_residue *vr,
+                                           uint8_t *do_not_decode,
+                                           unsigned ch_used,
+                                           int partition_count)
+{
+    int p, j, i;
+    unsigned c_p_c         = vc->codebooks[vr->classbook].dimensions;
+    unsigned inverse_class = ff_inverse[vr->classifications];
+    unsigned temp, temp2;
+    for (p = 0, j = 0; j < ch_used; ++j) {
+        if (!do_not_decode[j]) {
+            temp = get_vlc2(&vc->gb, vc->codebooks[vr->classbook].vlc.table,
+                                     vc->codebooks[vr->classbook].nb_bits, 3);
+
+            av_dlog(NULL, "Classword: %u\n", temp);
+
+            if ((int)temp < 0)
+                return temp;
+
+            av_assert0(vr->classifications > 1); //needed for inverse[]
+
+            if (temp <= 65536) {
+                for (i = partition_count + c_p_c - 1; i >= partition_count; i--) {
+                    temp2 = (((uint64_t)temp) * inverse_class) >> 32;
+
+                    if (i < vr->ptns_to_read)
+                        vr->classifs[p + i] = temp - temp2 * vr->classifications;
+                    temp = temp2;
+                }
+            } else {
+                for (i = partition_count + c_p_c - 1; i >= partition_count; i--) {
+                    temp2 = temp / vr->classifications;
+
+                    if (i < vr->ptns_to_read)
+                        vr->classifs[p + i] = temp - temp2 * vr->classifications;
+                    temp = temp2;
+                }
+            }
+        }
+        p += vr->ptns_to_read;
+    }
+    return 0;
+}
 // Read and decode residue
 
 static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc,
@@ -1321,10 +1368,10 @@
 {
     GetBitContext *gb = &vc->gb;
     unsigned c_p_c        = vc->codebooks[vr->classbook].dimensions;
-    unsigned ptns_to_read = vr->ptns_to_read;
     uint8_t *classifs = vr->classifs;
     unsigned pass, ch_used, i, j, k, l;
     unsigned max_output = (ch - 1) * vlen;
+    int ptns_to_read = vr->ptns_to_read;
 
     if (vr_type == 2) {
         for (j = 1; j < ch; ++j)
@@ -1340,37 +1387,20 @@
 
     if (max_output > ch_left * vlen) {
         av_log(vc->avctx, AV_LOG_ERROR, "Insufficient output buffer\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     av_dlog(NULL, " residue type 0/1/2 decode begin, ch: %d  cpc %d  \n", ch, c_p_c);
 
     for (pass = 0; pass <= vr->maxpass; ++pass) { // FIXME OPTIMIZE?
-        uint16_t voffset, partition_count, j_times_ptns_to_read;
+        int voffset, partition_count, j_times_ptns_to_read;
 
         voffset = vr->begin;
         for (partition_count = 0; partition_count < ptns_to_read;) {  // SPEC        error
             if (!pass) {
-                unsigned inverse_class = ff_inverse[vr->classifications];
-                for (j_times_ptns_to_read = 0, j = 0; j < ch_used; ++j) {
-                    if (!do_not_decode[j]) {
-                        unsigned temp = get_vlc2(gb, vc->codebooks[vr->classbook].vlc.table,
-                                                 vc->codebooks[vr->classbook].nb_bits, 3);
-
-                        av_dlog(NULL, "Classword: %u\n", temp);
-
-                        av_assert0(vr->classifications > 1 && temp <= 65536); //needed for inverse[]
-                        for (i = 0; i < c_p_c; ++i) {
-                            unsigned temp2;
-
-                            temp2 = (((uint64_t)temp) * inverse_class) >> 32;
-                            if (partition_count + c_p_c - 1 - i < ptns_to_read)
-                                classifs[j_times_ptns_to_read + partition_count + c_p_c - 1 - i] = temp - temp2 * vr->classifications;
-                            temp = temp2;
-                        }
-                    }
-                    j_times_ptns_to_read += ptns_to_read;
-                }
+                int ret;
+                if ((ret = setup_classifs(vc, vr, do_not_decode, ch_used, partition_count)) < 0)
+                    return ret;
             }
             for (i = 0; (i < c_p_c) && (partition_count < ptns_to_read); ++i) {
                 for (j_times_ptns_to_read = 0, j = 0; j < ch_used; ++j) {
@@ -1610,7 +1640,7 @@
         residue = &vc->residues[mapping->submap_residue[i]];
         if (ch_left < ch) {
             av_log(vc->avctx, AV_LOG_ERROR, "Too many channels in vorbis_floor_decode.\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         if (ch) {
             ret = vorbis_residue_decode(vc, residue, ch, do_not_decode, ch_res_ptr, vlen, ch_left);
diff --git a/libavcodec/vorbisdsp.c b/libavcodec/vorbisdsp.c
index fd8dcd7..5842cfd 100644
--- a/libavcodec/vorbisdsp.c
+++ b/libavcodec/vorbisdsp.c
@@ -17,10 +17,11 @@
  */
 
 #include "config.h"
+#include "libavutil/attributes.h"
 #include "vorbisdsp.h"
 #include "vorbis.h"
 
-void ff_vorbisdsp_init(VorbisDSPContext *dsp)
+av_cold void ff_vorbisdsp_init(VorbisDSPContext *dsp)
 {
     dsp->vorbis_inverse_coupling = ff_vorbis_inverse_coupling;
 
diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c
index d685996..1af76d4 100644
--- a/libavcodec/vorbisenc.c
+++ b/libavcodec/vorbisenc.c
@@ -140,9 +140,9 @@
 static inline int put_codeword(PutBitContext *pb, vorbis_enc_codebook *cb,
                                int entry)
 {
-    assert(entry >= 0);
-    assert(entry < cb->nentries);
-    assert(cb->lens[entry]);
+    av_assert2(entry >= 0);
+    av_assert2(entry < cb->nentries);
+    av_assert2(cb->lens[entry]);
     if (pb->size_in_bits - put_bits_count(pb) < cb->lens[entry])
         return AVERROR(EINVAL);
     put_bits(pb, cb->lens[entry], cb->codewords[entry]);
@@ -189,7 +189,7 @@
                 cb->pow2[i] += cb->dimensions[i * cb->ndimensions + j] * cb->dimensions[i * cb->ndimensions + j];
                 div *= vals;
             }
-            cb->pow2[i] /= 2.;
+            cb->pow2[i] /= 2.0;
         }
     }
     return 0;
@@ -198,7 +198,7 @@
 static int ready_residue(vorbis_enc_residue *rc, vorbis_enc_context *venc)
 {
     int i;
-    assert(rc->type == 2);
+    av_assert0(rc->type == 2);
     rc->maxes = av_mallocz(sizeof(float[2]) * rc->classifications);
     if (!rc->maxes)
         return AVERROR(ENOMEM);
@@ -728,7 +728,7 @@
 {
     int range = 255 / fc->multiplier + 1;
     int i;
-    float tot_average = 0.;
+    float tot_average = 0.0;
     float averages[MAX_FLOOR_VALUES];
     for (i = 0; i < fc->values; i++) {
         averages[i] = get_floor_average(fc, coeffs, i);
@@ -878,10 +878,10 @@
     int classes[MAX_CHANNELS][NUM_RESIDUE_PARTITIONS];
     int classwords = venc->codebooks[rc->classbook].ndimensions;
 
-    assert(rc->type == 2);
-    assert(real_ch == 2);
+    av_assert0(rc->type == 2);
+    av_assert0(real_ch == 2);
     for (p = 0; p < partitions; p++) {
-        float max1 = 0., max2 = 0.;
+        float max1 = 0.0, max2 = 0.0;
         int s = rc->begin + p * psize;
         for (k = s; k < s + psize; k += 2) {
             max1 = FFMAX(max1, fabs(coeffs[          k / real_ch]));
@@ -968,7 +968,7 @@
     int i, channel;
     const float * win = venc->win[0];
     int window_len = 1 << (venc->log2_blocksize[0] - 1);
-    float n = (float)(1 << venc->log2_blocksize[0]) / 4.;
+    float n = (float)(1 << venc->log2_blocksize[0]) / 4.0;
     // FIXME use dsp
 
     if (!venc->have_saved && !samples)
diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
index ddfb49f..fe4e48b 100644
--- a/libavcodec/vp3.c
+++ b/libavcodec/vp3.c
@@ -1632,16 +1632,16 @@
     y_fragment_count = s->fragment_width[0] * s->fragment_height[0];
     c_fragment_count = s->fragment_width[1] * s->fragment_height[1];
 
-    s->superblock_coding = av_malloc(s->superblock_count);
-    s->all_fragments = av_malloc(s->fragment_count * sizeof(Vp3Fragment));
-    s->coded_fragment_list[0] = av_malloc(s->fragment_count * sizeof(int));
+    s->superblock_coding = av_mallocz(s->superblock_count);
+    s->all_fragments = av_mallocz(s->fragment_count * sizeof(Vp3Fragment));
+    s->coded_fragment_list[0] = av_mallocz(s->fragment_count * sizeof(int));
     s->dct_tokens_base = av_mallocz(64*s->fragment_count * sizeof(*s->dct_tokens_base));
-    s->motion_val[0] = av_malloc(y_fragment_count * sizeof(*s->motion_val[0]));
-    s->motion_val[1] = av_malloc(c_fragment_count * sizeof(*s->motion_val[1]));
+    s->motion_val[0] = av_mallocz(y_fragment_count * sizeof(*s->motion_val[0]));
+    s->motion_val[1] = av_mallocz(c_fragment_count * sizeof(*s->motion_val[1]));
 
     /* work out the block mapping tables */
-    s->superblock_fragments = av_malloc(s->superblock_count * 16 * sizeof(int));
-    s->macroblock_coding = av_malloc(s->macroblock_count + 1);
+    s->superblock_fragments = av_mallocz(s->superblock_count * 16 * sizeof(int));
+    s->macroblock_coding = av_mallocz(s->macroblock_count + 1);
 
     if (!s->superblock_coding || !s->all_fragments || !s->dct_tokens_base ||
         !s->coded_fragment_list[0] || !s->superblock_fragments || !s->macroblock_coding ||
diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c
index c707295..38f0e08 100644
--- a/libavcodec/vp56.c
+++ b/libavcodec/vp56.c
@@ -34,8 +34,8 @@
 void ff_vp56_init_dequant(VP56Context *s, int quantizer)
 {
     s->quantizer = quantizer;
-    s->dequant_dc = vp56_dc_dequant[quantizer] << 2;
-    s->dequant_ac = vp56_ac_dequant[quantizer] << 2;
+    s->dequant_dc = ff_vp56_dc_dequant[quantizer] << 2;
+    s->dequant_ac = ff_vp56_ac_dequant[quantizer] << 2;
 }
 
 static int vp56_get_vectors_predictors(VP56Context *s, int row, int col,
@@ -47,14 +47,14 @@
     VP56mv mvp;
 
     for (pos=0; pos<12; pos++) {
-        mvp.x = col + vp56_candidate_predictor_pos[pos][0];
-        mvp.y = row + vp56_candidate_predictor_pos[pos][1];
+        mvp.x = col + ff_vp56_candidate_predictor_pos[pos][0];
+        mvp.y = row + ff_vp56_candidate_predictor_pos[pos][1];
         if (mvp.x < 0 || mvp.x >= s->mb_width ||
             mvp.y < 0 || mvp.y >= s->mb_height)
             continue;
         offset = mvp.x + s->mb_width*mvp.y;
 
-        if (vp56_reference_frame[s->macroblocks[offset].type] != ref_frame)
+        if (ff_vp56_reference_frame[s->macroblocks[offset].type] != ref_frame)
             continue;
         if ((s->macroblocks[offset].mv.x == vect[0].x &&
              s->macroblocks[offset].mv.y == vect[0].y) ||
@@ -86,7 +86,7 @@
         if (vp56_rac_get_prob(c, 174)) {
             int idx = vp56_rac_gets(c, 4);
             memcpy(model->mb_types_stats[ctx],
-                   vp56_pre_def_mb_type_stats[idx][ctx],
+                   ff_vp56_pre_def_mb_type_stats[idx][ctx],
                    sizeof(model->mb_types_stats[ctx]));
         }
         if (vp56_rac_get_prob(c, 254)) {
@@ -95,8 +95,8 @@
                     if (vp56_rac_get_prob(c, 205)) {
                         int delta, sign = vp56_rac_get(c);
 
-                        delta = vp56_rac_get_tree(c, vp56_pmbtm_tree,
-                                                  vp56_mb_type_model_model);
+                        delta = vp56_rac_get_tree(c, ff_vp56_pmbtm_tree,
+                                                  ff_vp56_mb_type_model_model);
                         if (!delta)
                             delta = 4 * vp56_rac_gets(c, 7);
                         model->mb_types_stats[ctx][type][i] += (delta ^ -sign) + sign;
@@ -156,7 +156,7 @@
     if (vp56_rac_get_prob(c, mb_type_model[0]))
         return prev_type;
     else
-        return vp56_rac_get_tree(c, vp56_pmbt_tree, mb_type_model);
+        return vp56_rac_get_tree(c, ff_vp56_pmbt_tree, mb_type_model);
 }
 
 static void vp56_decode_4mv(VP56Context *s, int row, int col)
@@ -305,7 +305,7 @@
 static void vp56_deblock_filter(VP56Context *s, uint8_t *yuv,
                                 int stride, int dx, int dy)
 {
-    int t = vp56_filter_threshold[s->quantizer];
+    int t = ff_vp56_filter_threshold[s->quantizer];
     if (dx)  s->vp56dsp.edge_filter_hor(yuv +         10-dx , stride, t);
     if (dy)  s->vp56dsp.edge_filter_ver(yuv + stride*(10-dy), stride, t);
 }
@@ -391,7 +391,7 @@
         mb_type = VP56_MB_INTRA;
     else
         mb_type = vp56_decode_mv(s, row, col);
-    ref_frame = vp56_reference_frame[mb_type];
+    ref_frame = ff_vp56_reference_frame[mb_type];
 
     s->parse_coeff(s);
 
diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h
index 4b0f5e1..9a95296 100644
--- a/libavcodec/vp56.h
+++ b/libavcodec/vp56.h
@@ -26,7 +26,6 @@
 #ifndef AVCODEC_VP56_H
 #define AVCODEC_VP56_H
 
-#include "vp56data.h"
 #include "dsputil.h"
 #include "get_bits.h"
 #include "hpeldsp.h"
@@ -38,6 +37,32 @@
 
 typedef struct vp56_context VP56Context;
 
+typedef enum {
+    VP56_FRAME_NONE     =-1,
+    VP56_FRAME_CURRENT  = 0,
+    VP56_FRAME_PREVIOUS = 1,
+    VP56_FRAME_GOLDEN   = 2,
+    VP56_FRAME_GOLDEN2  = 3,
+} VP56Frame;
+
+typedef enum {
+    VP56_MB_INTER_NOVEC_PF = 0,  /**< Inter MB, no vector, from previous frame */
+    VP56_MB_INTRA          = 1,  /**< Intra MB */
+    VP56_MB_INTER_DELTA_PF = 2,  /**< Inter MB, above/left vector + delta, from previous frame */
+    VP56_MB_INTER_V1_PF    = 3,  /**< Inter MB, first vector, from previous frame */
+    VP56_MB_INTER_V2_PF    = 4,  /**< Inter MB, second vector, from previous frame */
+    VP56_MB_INTER_NOVEC_GF = 5,  /**< Inter MB, no vector, from golden frame */
+    VP56_MB_INTER_DELTA_GF = 6,  /**< Inter MB, above/left vector + delta, from golden frame */
+    VP56_MB_INTER_4V       = 7,  /**< Inter MB, 4 vectors, from previous frame */
+    VP56_MB_INTER_V1_GF    = 8,  /**< Inter MB, first vector, from golden frame */
+    VP56_MB_INTER_V2_GF    = 9,  /**< Inter MB, second vector, from golden frame */
+} VP56mb;
+
+typedef struct VP56Tree {
+  int8_t val;
+  int8_t prob_idx;
+} VP56Tree;
+
 typedef struct VP56mv {
     DECLARE_ALIGNED(4, int16_t, x);
     int16_t y;
diff --git a/libavcodec/vp56data.c b/libavcodec/vp56data.c
index 5500fe0..0080370 100644
--- a/libavcodec/vp56data.c
+++ b/libavcodec/vp56data.c
@@ -66,3 +66,189 @@
 
 const uint8_t ff_vp56_coeff_bias[] = { 0, 1, 2, 3, 4, 5, 7, 11, 19, 35, 67 };
 const uint8_t ff_vp56_coeff_bit_length[] = { 0, 1, 2, 3, 4, 10 };
+
+const VP56Frame ff_vp56_reference_frame[] = {
+    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_NOVEC_PF */
+    VP56_FRAME_CURRENT,   /* VP56_MB_INTRA */
+    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_DELTA_PF */
+    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_V1_PF */
+    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_V2_PF */
+    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_NOVEC_GF */
+    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_DELTA_GF */
+    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_4V */
+    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_V1_GF */
+    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_V2_GF */
+};
+
+const uint8_t ff_vp56_ac_dequant[64] = {
+    94, 92, 90, 88, 86, 82, 78, 74,
+    70, 66, 62, 58, 54, 53, 52, 51,
+    50, 49, 48, 47, 46, 45, 44, 43,
+    42, 40, 39, 37, 36, 35, 34, 33,
+    32, 31, 30, 29, 28, 27, 26, 25,
+    24, 23, 22, 21, 20, 19, 18, 17,
+    16, 15, 14, 13, 12, 11, 10,  9,
+     8,  7,  6,  5,  4,  3,  2,  1,
+};
+
+const uint8_t ff_vp56_dc_dequant[64] = {
+    47, 47, 47, 47, 45, 43, 43, 43,
+    43, 43, 42, 41, 41, 40, 40, 40,
+    40, 35, 35, 35, 35, 33, 33, 33,
+    33, 32, 32, 32, 27, 27, 26, 26,
+    25, 25, 24, 24, 23, 23, 19, 19,
+    19, 19, 18, 18, 17, 16, 16, 16,
+    16, 16, 15, 11, 11, 11, 10, 10,
+     9,  8,  7,  5,  3,  3,  2,  2,
+};
+
+const uint8_t ff_vp56_pre_def_mb_type_stats[16][3][10][2] = {
+  { { {   9, 15 }, {  32, 25 }, {  7,  19 }, {   9, 21 }, {  1, 12 },
+      {  14, 12 }, {   3, 18 }, { 14,  23 }, {   3, 10 }, {  0,  4 }, },
+    { {  41, 22 }, {   1,  0 }, {  1,  31 }, {   0,  0 }, {  0,  0 },
+      {   0,  1 }, {   1,  7 }, {  0,   1 }, {  98, 25 }, {  4, 10 }, },
+    { {   2,  3 }, {   2,  3 }, {  0,   2 }, {   0,  2 }, {  0,  0 },
+      {  11,  4 }, {   1,  4 }, {  0,   2 }, {   3,  2 }, {  0,  4 }, }, },
+  { { {  48, 39 }, {   1,  2 }, { 11,  27 }, {  29, 44 }, {  7, 27 },
+      {   1,  4 }, {   0,  3 }, {  1,   6 }, {   1,  2 }, {  0,  0 }, },
+    { { 123, 37 }, {   6,  4 }, {  1,  27 }, {   0,  0 }, {  0,  0 },
+      {   5,  8 }, {   1,  7 }, {  0,   1 }, {  12, 10 }, {  0,  2 }, },
+    { {  49, 46 }, {   3,  4 }, {  7,  31 }, {  42, 41 }, {  0,  0 },
+      {   2,  6 }, {   1,  7 }, {  1,   4 }, {   2,  4 }, {  0,  1 }, }, },
+  { { {  21, 32 }, {   1,  2 }, {  4,  10 }, {  32, 43 }, {  6, 23 },
+      {   2,  3 }, {   1, 19 }, {  1,   6 }, {  12, 21 }, {  0,  7 }, },
+    { {  26, 14 }, {  14, 12 }, {  0,  24 }, {   0,  0 }, {  0,  0 },
+      {  55, 17 }, {   1,  9 }, {  0,  36 }, {   5,  7 }, {  1,  3 }, },
+    { {  26, 25 }, {   1,  1 }, {  2,  10 }, {  67, 39 }, {  0,  0 },
+      {   1,  1 }, {   0, 14 }, {  0,   2 }, {  31, 26 }, {  1,  6 }, }, },
+  { { {  69, 83 }, {   0,  0 }, {  0,   2 }, {  10, 29 }, {  3, 12 },
+      {   0,  1 }, {   0,  3 }, {  0,   3 }, {   2,  2 }, {  0,  0 }, },
+    { { 209,  5 }, {   0,  0 }, {  0,  27 }, {   0,  0 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, },
+    { { 103, 46 }, {   1,  2 }, {  2,  10 }, {  33, 42 }, {  0,  0 },
+      {   1,  4 }, {   0,  3 }, {  0,   1 }, {   1,  3 }, {  0,  0 }, }, },
+  { { {  11, 20 }, {   1,  4 }, { 18,  36 }, {  43, 48 }, { 13, 35 },
+      {   0,  2 }, {   0,  5 }, {  3,  12 }, {   1,  2 }, {  0,  0 }, },
+    { {   2,  5 }, {   4,  5 }, {  0, 121 }, {   0,  0 }, {  0,  0 },
+      {   0,  3 }, {   2,  4 }, {  1,   4 }, {   2,  2 }, {  0,  1 }, },
+    { {  14, 31 }, {   9, 13 }, { 14,  54 }, {  22, 29 }, {  0,  0 },
+      {   2,  6 }, {   4, 18 }, {  6,  13 }, {   1,  5 }, {  0,  1 }, }, },
+  { { {  70, 44 }, {   0,  1 }, {  2,  10 }, {  37, 46 }, {  8, 26 },
+      {   0,  2 }, {   0,  2 }, {  0,   2 }, {   0,  1 }, {  0,  0 }, },
+    { { 175,  5 }, {   0,  1 }, {  0,  48 }, {   0,  0 }, {  0,  0 },
+      {   0,  2 }, {   0,  1 }, {  0,   2 }, {   0,  1 }, {  0,  0 }, },
+    { {  85, 39 }, {   0,  0 }, {  1,   9 }, {  69, 40 }, {  0,  0 },
+      {   0,  1 }, {   0,  3 }, {  0,   1 }, {   2,  3 }, {  0,  0 }, }, },
+  { { {   8, 15 }, {   0,  1 }, {  8,  21 }, {  74, 53 }, { 22, 42 },
+      {   0,  1 }, {   0,  2 }, {  0,   3 }, {   1,  2 }, {  0,  0 }, },
+    { {  83,  5 }, {   2,  3 }, {  0, 102 }, {   0,  0 }, {  0,  0 },
+      {   1,  3 }, {   0,  2 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, },
+    { {  31, 28 }, {   0,  0 }, {  3,  14 }, { 130, 34 }, {  0,  0 },
+      {   0,  1 }, {   0,  3 }, {  0,   1 }, {   3,  3 }, {  0,  1 }, }, },
+  { { { 141, 42 }, {   0,  0 }, {  1,   4 }, {  11, 24 }, {  1, 11 },
+      {   0,  1 }, {   0,  1 }, {  0,   2 }, {   0,  0 }, {  0,  0 }, },
+    { { 233,  6 }, {   0,  0 }, {  0,   8 }, {   0,  0 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   0 }, {   0,  1 }, {  0,  0 }, },
+    { { 171, 25 }, {   0,  0 }, {  1,   5 }, {  25, 21 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   0 }, {   0,  0 }, {  0,  0 }, }, },
+  { { {   8, 19 }, {   4, 10 }, { 24,  45 }, {  21, 37 }, {  9, 29 },
+      {   0,  3 }, {   1,  7 }, { 11,  25 }, {   0,  2 }, {  0,  1 }, },
+    { {  34, 16 }, { 112, 21 }, {  1,  28 }, {   0,  0 }, {  0,  0 },
+      {   6,  8 }, {   1,  7 }, {  0,   3 }, {   2,  5 }, {  0,  2 }, },
+    { {  17, 21 }, {  68, 29 }, {  6,  15 }, {  13, 22 }, {  0,  0 },
+      {   6, 12 }, {   3, 14 }, {  4,  10 }, {   1,  7 }, {  0,  3 }, }, },
+  { { {  46, 42 }, {   0,  1 }, {  2,  10 }, {  54, 51 }, { 10, 30 },
+      {   0,  2 }, {   0,  2 }, {  0,   1 }, {   0,  1 }, {  0,  0 }, },
+    { { 159, 35 }, {   2,  2 }, {  0,  25 }, {   0,  0 }, {  0,  0 },
+      {   3,  6 }, {   0,  5 }, {  0,   1 }, {   4,  4 }, {  0,  1 }, },
+    { {  51, 39 }, {   0,  1 }, {  2,  12 }, {  91, 44 }, {  0,  0 },
+      {   0,  2 }, {   0,  3 }, {  0,   1 }, {   2,  3 }, {  0,  1 }, }, },
+  { { {  28, 32 }, {   0,  0 }, {  3,  10 }, {  75, 51 }, { 14, 33 },
+      {   0,  1 }, {   0,  2 }, {  0,   1 }, {   1,  2 }, {  0,  0 }, },
+    { {  75, 39 }, {   5,  7 }, {  2,  48 }, {   0,  0 }, {  0,  0 },
+      {   3, 11 }, {   2, 16 }, {  1,   4 }, {   7, 10 }, {  0,  2 }, },
+    { {  81, 25 }, {   0,  0 }, {  2,   9 }, { 106, 26 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   1,  1 }, {  0,  0 }, }, },
+  { { { 100, 46 }, {   0,  1 }, {  3,   9 }, {  21, 37 }, {  5, 20 },
+      {   0,  1 }, {   0,  2 }, {  1,   2 }, {   0,  1 }, {  0,  0 }, },
+    { { 212, 21 }, {   0,  1 }, {  0,   9 }, {   0,  0 }, {  0,  0 },
+      {   1,  2 }, {   0,  2 }, {  0,   0 }, {   2,  2 }, {  0,  0 }, },
+    { { 140, 37 }, {   0,  1 }, {  1,   8 }, {  24, 33 }, {  0,  0 },
+      {   1,  2 }, {   0,  2 }, {  0,   1 }, {   1,  2 }, {  0,  0 }, }, },
+  { { {  27, 29 }, {   0,  1 }, {  9,  25 }, {  53, 51 }, { 12, 34 },
+      {   0,  1 }, {   0,  3 }, {  1,   5 }, {   0,  2 }, {  0,  0 }, },
+    { {   4,  2 }, {   0,  0 }, {  0, 172 }, {   0,  0 }, {  0,  0 },
+      {   0,  1 }, {   0,  2 }, {  0,   0 }, {   2,  0 }, {  0,  0 }, },
+    { {  14, 23 }, {   1,  3 }, { 11,  53 }, {  90, 31 }, {  0,  0 },
+      {   0,  3 }, {   1,  5 }, {  2,   6 }, {   1,  2 }, {  0,  0 }, }, },
+  { { {  80, 38 }, {   0,  0 }, {  1,   4 }, {  69, 33 }, {  5, 16 },
+      {   0,  1 }, {   0,  1 }, {  0,   0 }, {   0,  1 }, {  0,  0 }, },
+    { { 187, 22 }, {   1,  1 }, {  0,  17 }, {   0,  0 }, {  0,  0 },
+      {   3,  6 }, {   0,  4 }, {  0,   1 }, {   4,  4 }, {  0,  1 }, },
+    { { 123, 29 }, {   0,  0 }, {  1,   7 }, {  57, 30 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   0,  1 }, {  0,  0 }, }, },
+  { { {  16, 20 }, {   0,  0 }, {  2,   8 }, { 104, 49 }, { 15, 33 },
+      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   1,  1 }, {  0,  0 }, },
+    { { 133,  6 }, {   1,  2 }, {  1,  70 }, {   0,  0 }, {  0,  0 },
+      {   0,  2 }, {   0,  4 }, {  0,   3 }, {   1,  1 }, {  0,  0 }, },
+    { {  13, 14 }, {   0,  0 }, {  4,  20 }, { 175, 20 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   1,  1 }, {  0,  0 }, }, },
+  { { { 194, 16 }, {   0,  0 }, {  1,   1 }, {   1,  9 }, {  1,  3 },
+      {   0,  0 }, {   0,  1 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, },
+    { { 251,  1 }, {   0,  0 }, {  0,   2 }, {   0,  0 }, {  0,  0 },
+      {   0,  0 }, {   0,  0 }, {  0,   0 }, {   0,  0 }, {  0,  0 }, },
+    { { 202, 23 }, {   0,  0 }, {  1,   3 }, {   2,  9 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, }, },
+};
+
+const uint8_t ff_vp56_filter_threshold[] = {
+    14, 14, 13, 13, 12, 12, 10, 10,
+    10, 10,  8,  8,  8,  8,  8,  8,
+     8,  8,  8,  8,  8,  8,  8,  8,
+     8,  8,  8,  8,  8,  8,  8,  8,
+     8,  8,  8,  8,  7,  7,  7,  7,
+     7,  7,  6,  6,  6,  6,  6,  6,
+     5,  5,  5,  5,  4,  4,  4,  4,
+     4,  4,  4,  3,  3,  3,  3,  2,
+};
+
+const uint8_t ff_vp56_mb_type_model_model[] = {
+    171, 83, 199, 140, 125, 104,
+};
+
+const VP56Tree ff_vp56_pmbtm_tree[] = {
+    { 4, 0},
+    { 2, 1}, {-8}, {-4},
+    { 8, 2},
+    { 6, 3},
+    { 4, 4},
+    { 2, 5}, {-24}, {-20}, {-16}, {-12}, {-0},
+};
+
+const VP56Tree ff_vp56_pmbt_tree[] = {
+    { 8, 1},
+    { 4, 2},
+    { 2, 4}, {-VP56_MB_INTER_NOVEC_PF}, {-VP56_MB_INTER_DELTA_PF},
+    { 2, 5}, {-VP56_MB_INTER_V1_PF},    {-VP56_MB_INTER_V2_PF},
+    { 4, 3},
+    { 2, 6}, {-VP56_MB_INTRA},          {-VP56_MB_INTER_4V},
+    { 4, 7},
+    { 2, 8}, {-VP56_MB_INTER_NOVEC_GF}, {-VP56_MB_INTER_DELTA_GF},
+    { 2, 9}, {-VP56_MB_INTER_V1_GF},    {-VP56_MB_INTER_V2_GF},
+};
+
+/* relative pos of surrounding blocks, from closest to farthest */
+const int8_t ff_vp56_candidate_predictor_pos[12][2] = {
+    {  0, -1 },
+    { -1,  0 },
+    { -1, -1 },
+    {  1, -1 },
+    {  0, -2 },
+    { -2,  0 },
+    { -2, -1 },
+    { -1, -2 },
+    {  1, -2 },
+    {  2, -1 },
+    { -2, -2 },
+    {  2, -2 },
+};
diff --git a/libavcodec/vp56data.h b/libavcodec/vp56data.h
index 3cafaaf..3be268c 100644
--- a/libavcodec/vp56data.h
+++ b/libavcodec/vp56data.h
@@ -27,32 +27,7 @@
 #define AVCODEC_VP56DATA_H
 
 #include "libavutil/common.h"
-
-typedef enum {
-    VP56_FRAME_NONE     =-1,
-    VP56_FRAME_CURRENT  = 0,
-    VP56_FRAME_PREVIOUS = 1,
-    VP56_FRAME_GOLDEN   = 2,
-    VP56_FRAME_GOLDEN2  = 3,
-} VP56Frame;
-
-typedef enum {
-    VP56_MB_INTER_NOVEC_PF = 0,  /**< Inter MB, no vector, from previous frame */
-    VP56_MB_INTRA          = 1,  /**< Intra MB */
-    VP56_MB_INTER_DELTA_PF = 2,  /**< Inter MB, above/left vector + delta, from previous frame */
-    VP56_MB_INTER_V1_PF    = 3,  /**< Inter MB, first vector, from previous frame */
-    VP56_MB_INTER_V2_PF    = 4,  /**< Inter MB, second vector, from previous frame */
-    VP56_MB_INTER_NOVEC_GF = 5,  /**< Inter MB, no vector, from golden frame */
-    VP56_MB_INTER_DELTA_GF = 6,  /**< Inter MB, above/left vector + delta, from golden frame */
-    VP56_MB_INTER_4V       = 7,  /**< Inter MB, 4 vectors, from previous frame */
-    VP56_MB_INTER_V1_GF    = 8,  /**< Inter MB, first vector, from golden frame */
-    VP56_MB_INTER_V2_GF    = 9,  /**< Inter MB, second vector, from golden frame */
-} VP56mb;
-
-typedef struct VP56Tree {
-  int8_t val;
-  int8_t prob_idx;
-} VP56Tree;
+#include "vp56.h"
 
 extern const uint8_t ff_vp56_b2p[];
 extern const uint8_t ff_vp56_b6to4[];
@@ -63,190 +38,14 @@
 extern const uint8_t ff_vp56_coeff_bias[];
 extern const uint8_t ff_vp56_coeff_bit_length[];
 
-static const VP56Frame vp56_reference_frame[] = {
-    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_NOVEC_PF */
-    VP56_FRAME_CURRENT,   /* VP56_MB_INTRA */
-    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_DELTA_PF */
-    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_V1_PF */
-    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_V2_PF */
-    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_NOVEC_GF */
-    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_DELTA_GF */
-    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_4V */
-    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_V1_GF */
-    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_V2_GF */
-};
-
-static const uint8_t vp56_ac_dequant[64] = {
-    94, 92, 90, 88, 86, 82, 78, 74,
-    70, 66, 62, 58, 54, 53, 52, 51,
-    50, 49, 48, 47, 46, 45, 44, 43,
-    42, 40, 39, 37, 36, 35, 34, 33,
-    32, 31, 30, 29, 28, 27, 26, 25,
-    24, 23, 22, 21, 20, 19, 18, 17,
-    16, 15, 14, 13, 12, 11, 10,  9,
-     8,  7,  6,  5,  4,  3,  2,  1,
-};
-
-static const uint8_t vp56_dc_dequant[64] = {
-    47, 47, 47, 47, 45, 43, 43, 43,
-    43, 43, 42, 41, 41, 40, 40, 40,
-    40, 35, 35, 35, 35, 33, 33, 33,
-    33, 32, 32, 32, 27, 27, 26, 26,
-    25, 25, 24, 24, 23, 23, 19, 19,
-    19, 19, 18, 18, 17, 16, 16, 16,
-    16, 16, 15, 11, 11, 11, 10, 10,
-     9,  8,  7,  5,  3,  3,  2,  2,
-};
-
-static const uint8_t vp56_pre_def_mb_type_stats[16][3][10][2] = {
-  { { {   9, 15 }, {  32, 25 }, {  7,  19 }, {   9, 21 }, {  1, 12 },
-      {  14, 12 }, {   3, 18 }, { 14,  23 }, {   3, 10 }, {  0,  4 }, },
-    { {  41, 22 }, {   1,  0 }, {  1,  31 }, {   0,  0 }, {  0,  0 },
-      {   0,  1 }, {   1,  7 }, {  0,   1 }, {  98, 25 }, {  4, 10 }, },
-    { {   2,  3 }, {   2,  3 }, {  0,   2 }, {   0,  2 }, {  0,  0 },
-      {  11,  4 }, {   1,  4 }, {  0,   2 }, {   3,  2 }, {  0,  4 }, }, },
-  { { {  48, 39 }, {   1,  2 }, { 11,  27 }, {  29, 44 }, {  7, 27 },
-      {   1,  4 }, {   0,  3 }, {  1,   6 }, {   1,  2 }, {  0,  0 }, },
-    { { 123, 37 }, {   6,  4 }, {  1,  27 }, {   0,  0 }, {  0,  0 },
-      {   5,  8 }, {   1,  7 }, {  0,   1 }, {  12, 10 }, {  0,  2 }, },
-    { {  49, 46 }, {   3,  4 }, {  7,  31 }, {  42, 41 }, {  0,  0 },
-      {   2,  6 }, {   1,  7 }, {  1,   4 }, {   2,  4 }, {  0,  1 }, }, },
-  { { {  21, 32 }, {   1,  2 }, {  4,  10 }, {  32, 43 }, {  6, 23 },
-      {   2,  3 }, {   1, 19 }, {  1,   6 }, {  12, 21 }, {  0,  7 }, },
-    { {  26, 14 }, {  14, 12 }, {  0,  24 }, {   0,  0 }, {  0,  0 },
-      {  55, 17 }, {   1,  9 }, {  0,  36 }, {   5,  7 }, {  1,  3 }, },
-    { {  26, 25 }, {   1,  1 }, {  2,  10 }, {  67, 39 }, {  0,  0 },
-      {   1,  1 }, {   0, 14 }, {  0,   2 }, {  31, 26 }, {  1,  6 }, }, },
-  { { {  69, 83 }, {   0,  0 }, {  0,   2 }, {  10, 29 }, {  3, 12 },
-      {   0,  1 }, {   0,  3 }, {  0,   3 }, {   2,  2 }, {  0,  0 }, },
-    { { 209,  5 }, {   0,  0 }, {  0,  27 }, {   0,  0 }, {  0,  0 },
-      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, },
-    { { 103, 46 }, {   1,  2 }, {  2,  10 }, {  33, 42 }, {  0,  0 },
-      {   1,  4 }, {   0,  3 }, {  0,   1 }, {   1,  3 }, {  0,  0 }, }, },
-  { { {  11, 20 }, {   1,  4 }, { 18,  36 }, {  43, 48 }, { 13, 35 },
-      {   0,  2 }, {   0,  5 }, {  3,  12 }, {   1,  2 }, {  0,  0 }, },
-    { {   2,  5 }, {   4,  5 }, {  0, 121 }, {   0,  0 }, {  0,  0 },
-      {   0,  3 }, {   2,  4 }, {  1,   4 }, {   2,  2 }, {  0,  1 }, },
-    { {  14, 31 }, {   9, 13 }, { 14,  54 }, {  22, 29 }, {  0,  0 },
-      {   2,  6 }, {   4, 18 }, {  6,  13 }, {   1,  5 }, {  0,  1 }, }, },
-  { { {  70, 44 }, {   0,  1 }, {  2,  10 }, {  37, 46 }, {  8, 26 },
-      {   0,  2 }, {   0,  2 }, {  0,   2 }, {   0,  1 }, {  0,  0 }, },
-    { { 175,  5 }, {   0,  1 }, {  0,  48 }, {   0,  0 }, {  0,  0 },
-      {   0,  2 }, {   0,  1 }, {  0,   2 }, {   0,  1 }, {  0,  0 }, },
-    { {  85, 39 }, {   0,  0 }, {  1,   9 }, {  69, 40 }, {  0,  0 },
-      {   0,  1 }, {   0,  3 }, {  0,   1 }, {   2,  3 }, {  0,  0 }, }, },
-  { { {   8, 15 }, {   0,  1 }, {  8,  21 }, {  74, 53 }, { 22, 42 },
-      {   0,  1 }, {   0,  2 }, {  0,   3 }, {   1,  2 }, {  0,  0 }, },
-    { {  83,  5 }, {   2,  3 }, {  0, 102 }, {   0,  0 }, {  0,  0 },
-      {   1,  3 }, {   0,  2 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, },
-    { {  31, 28 }, {   0,  0 }, {  3,  14 }, { 130, 34 }, {  0,  0 },
-      {   0,  1 }, {   0,  3 }, {  0,   1 }, {   3,  3 }, {  0,  1 }, }, },
-  { { { 141, 42 }, {   0,  0 }, {  1,   4 }, {  11, 24 }, {  1, 11 },
-      {   0,  1 }, {   0,  1 }, {  0,   2 }, {   0,  0 }, {  0,  0 }, },
-    { { 233,  6 }, {   0,  0 }, {  0,   8 }, {   0,  0 }, {  0,  0 },
-      {   0,  1 }, {   0,  1 }, {  0,   0 }, {   0,  1 }, {  0,  0 }, },
-    { { 171, 25 }, {   0,  0 }, {  1,   5 }, {  25, 21 }, {  0,  0 },
-      {   0,  1 }, {   0,  1 }, {  0,   0 }, {   0,  0 }, {  0,  0 }, }, },
-  { { {   8, 19 }, {   4, 10 }, { 24,  45 }, {  21, 37 }, {  9, 29 },
-      {   0,  3 }, {   1,  7 }, { 11,  25 }, {   0,  2 }, {  0,  1 }, },
-    { {  34, 16 }, { 112, 21 }, {  1,  28 }, {   0,  0 }, {  0,  0 },
-      {   6,  8 }, {   1,  7 }, {  0,   3 }, {   2,  5 }, {  0,  2 }, },
-    { {  17, 21 }, {  68, 29 }, {  6,  15 }, {  13, 22 }, {  0,  0 },
-      {   6, 12 }, {   3, 14 }, {  4,  10 }, {   1,  7 }, {  0,  3 }, }, },
-  { { {  46, 42 }, {   0,  1 }, {  2,  10 }, {  54, 51 }, { 10, 30 },
-      {   0,  2 }, {   0,  2 }, {  0,   1 }, {   0,  1 }, {  0,  0 }, },
-    { { 159, 35 }, {   2,  2 }, {  0,  25 }, {   0,  0 }, {  0,  0 },
-      {   3,  6 }, {   0,  5 }, {  0,   1 }, {   4,  4 }, {  0,  1 }, },
-    { {  51, 39 }, {   0,  1 }, {  2,  12 }, {  91, 44 }, {  0,  0 },
-      {   0,  2 }, {   0,  3 }, {  0,   1 }, {   2,  3 }, {  0,  1 }, }, },
-  { { {  28, 32 }, {   0,  0 }, {  3,  10 }, {  75, 51 }, { 14, 33 },
-      {   0,  1 }, {   0,  2 }, {  0,   1 }, {   1,  2 }, {  0,  0 }, },
-    { {  75, 39 }, {   5,  7 }, {  2,  48 }, {   0,  0 }, {  0,  0 },
-      {   3, 11 }, {   2, 16 }, {  1,   4 }, {   7, 10 }, {  0,  2 }, },
-    { {  81, 25 }, {   0,  0 }, {  2,   9 }, { 106, 26 }, {  0,  0 },
-      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   1,  1 }, {  0,  0 }, }, },
-  { { { 100, 46 }, {   0,  1 }, {  3,   9 }, {  21, 37 }, {  5, 20 },
-      {   0,  1 }, {   0,  2 }, {  1,   2 }, {   0,  1 }, {  0,  0 }, },
-    { { 212, 21 }, {   0,  1 }, {  0,   9 }, {   0,  0 }, {  0,  0 },
-      {   1,  2 }, {   0,  2 }, {  0,   0 }, {   2,  2 }, {  0,  0 }, },
-    { { 140, 37 }, {   0,  1 }, {  1,   8 }, {  24, 33 }, {  0,  0 },
-      {   1,  2 }, {   0,  2 }, {  0,   1 }, {   1,  2 }, {  0,  0 }, }, },
-  { { {  27, 29 }, {   0,  1 }, {  9,  25 }, {  53, 51 }, { 12, 34 },
-      {   0,  1 }, {   0,  3 }, {  1,   5 }, {   0,  2 }, {  0,  0 }, },
-    { {   4,  2 }, {   0,  0 }, {  0, 172 }, {   0,  0 }, {  0,  0 },
-      {   0,  1 }, {   0,  2 }, {  0,   0 }, {   2,  0 }, {  0,  0 }, },
-    { {  14, 23 }, {   1,  3 }, { 11,  53 }, {  90, 31 }, {  0,  0 },
-      {   0,  3 }, {   1,  5 }, {  2,   6 }, {   1,  2 }, {  0,  0 }, }, },
-  { { {  80, 38 }, {   0,  0 }, {  1,   4 }, {  69, 33 }, {  5, 16 },
-      {   0,  1 }, {   0,  1 }, {  0,   0 }, {   0,  1 }, {  0,  0 }, },
-    { { 187, 22 }, {   1,  1 }, {  0,  17 }, {   0,  0 }, {  0,  0 },
-      {   3,  6 }, {   0,  4 }, {  0,   1 }, {   4,  4 }, {  0,  1 }, },
-    { { 123, 29 }, {   0,  0 }, {  1,   7 }, {  57, 30 }, {  0,  0 },
-      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   0,  1 }, {  0,  0 }, }, },
-  { { {  16, 20 }, {   0,  0 }, {  2,   8 }, { 104, 49 }, { 15, 33 },
-      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   1,  1 }, {  0,  0 }, },
-    { { 133,  6 }, {   1,  2 }, {  1,  70 }, {   0,  0 }, {  0,  0 },
-      {   0,  2 }, {   0,  4 }, {  0,   3 }, {   1,  1 }, {  0,  0 }, },
-    { {  13, 14 }, {   0,  0 }, {  4,  20 }, { 175, 20 }, {  0,  0 },
-      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   1,  1 }, {  0,  0 }, }, },
-  { { { 194, 16 }, {   0,  0 }, {  1,   1 }, {   1,  9 }, {  1,  3 },
-      {   0,  0 }, {   0,  1 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, },
-    { { 251,  1 }, {   0,  0 }, {  0,   2 }, {   0,  0 }, {  0,  0 },
-      {   0,  0 }, {   0,  0 }, {  0,   0 }, {   0,  0 }, {  0,  0 }, },
-    { { 202, 23 }, {   0,  0 }, {  1,   3 }, {   2,  9 }, {  0,  0 },
-      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, }, },
-};
-
-static const uint8_t vp56_filter_threshold[] = {
-    14, 14, 13, 13, 12, 12, 10, 10,
-    10, 10,  8,  8,  8,  8,  8,  8,
-     8,  8,  8,  8,  8,  8,  8,  8,
-     8,  8,  8,  8,  8,  8,  8,  8,
-     8,  8,  8,  8,  7,  7,  7,  7,
-     7,  7,  6,  6,  6,  6,  6,  6,
-     5,  5,  5,  5,  4,  4,  4,  4,
-     4,  4,  4,  3,  3,  3,  3,  2,
-};
-
-static const uint8_t vp56_mb_type_model_model[] = {
-    171, 83, 199, 140, 125, 104,
-};
-
-static const VP56Tree vp56_pmbtm_tree[] = {
-    { 4, 0},
-    { 2, 1}, {-8}, {-4},
-    { 8, 2},
-    { 6, 3},
-    { 4, 4},
-    { 2, 5}, {-24}, {-20}, {-16}, {-12}, {-0},
-};
-
-static const VP56Tree vp56_pmbt_tree[] = {
-    { 8, 1},
-    { 4, 2},
-    { 2, 4}, {-VP56_MB_INTER_NOVEC_PF}, {-VP56_MB_INTER_DELTA_PF},
-    { 2, 5}, {-VP56_MB_INTER_V1_PF},    {-VP56_MB_INTER_V2_PF},
-    { 4, 3},
-    { 2, 6}, {-VP56_MB_INTRA},          {-VP56_MB_INTER_4V},
-    { 4, 7},
-    { 2, 8}, {-VP56_MB_INTER_NOVEC_GF}, {-VP56_MB_INTER_DELTA_GF},
-    { 2, 9}, {-VP56_MB_INTER_V1_GF},    {-VP56_MB_INTER_V2_GF},
-};
-
-/* relative pos of surrounding blocks, from closest to farthest */
-static const int8_t vp56_candidate_predictor_pos[12][2] = {
-    {  0, -1 },
-    { -1,  0 },
-    { -1, -1 },
-    {  1, -1 },
-    {  0, -2 },
-    { -2,  0 },
-    { -2, -1 },
-    { -1, -2 },
-    {  1, -2 },
-    {  2, -1 },
-    { -2, -2 },
-    {  2, -2 },
-};
+extern const VP56Frame ff_vp56_reference_frame[];
+extern const uint8_t ff_vp56_ac_dequant[64];
+extern const uint8_t ff_vp56_dc_dequant[64];
+extern const uint8_t ff_vp56_pre_def_mb_type_stats[16][3][10][2];
+extern const uint8_t ff_vp56_filter_threshold[];
+extern const uint8_t ff_vp56_mb_type_model_model[];
+extern const VP56Tree ff_vp56_pmbtm_tree[];
+extern const VP56Tree ff_vp56_pmbt_tree[];
+extern const int8_t ff_vp56_candidate_predictor_pos[12][2];
 
 #endif /* AVCODEC_VP56DATA_H */
diff --git a/libavcodec/vp56dsp.c b/libavcodec/vp56dsp.c
index a72c48e..8c17fd9 100644
--- a/libavcodec/vp56dsp.c
+++ b/libavcodec/vp56dsp.c
@@ -20,6 +20,8 @@
  */
 
 #include <stdint.h>
+
+#include "libavutil/attributes.h"
 #include "avcodec.h"
 #include "vp56dsp.h"
 #include "libavutil/common.h"
@@ -75,7 +77,7 @@
 VP56_EDGE_FILTER(vp6, hor, 1, stride)
 VP56_EDGE_FILTER(vp6, ver, stride, 1)
 
-void ff_vp56dsp_init(VP56DSPContext *s, enum AVCodecID codec)
+av_cold void ff_vp56dsp_init(VP56DSPContext *s, enum AVCodecID codec)
 {
     if (codec == AV_CODEC_ID_VP5) {
         s->edge_filter_hor = vp5_edge_filter_hor;
diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c
index 6e385ce..cc0ac6c 100644
--- a/libavcodec/vp6.c
+++ b/libavcodec/vp6.c
@@ -388,11 +388,11 @@
             } else {
                 if (get_bits_left(&s->gb) <= 0)
                     return;
-                coeff = get_vlc2(&s->gb, vlc_coeff->table, 9, 3);
+                coeff = get_vlc2(&s->gb, vlc_coeff->table, FF_HUFFMAN_BITS, 3);
                 if (coeff == 0) {
                     if (coeff_idx) {
                         int pt = (coeff_idx >= 6);
-                        run += get_vlc2(&s->gb, s->runv_vlc[pt].table, 9, 3);
+                        run += get_vlc2(&s->gb, s->runv_vlc[pt].table, FF_HUFFMAN_BITS, 3);
                         if (run >= 9)
                             run += get_bits(&s->gb, 6);
                     } else
diff --git a/libavcodec/vp6data.h b/libavcodec/vp6data.h
index 3ebfd0e..539e19a 100644
--- a/libavcodec/vp6data.h
+++ b/libavcodec/vp6data.h
@@ -26,7 +26,9 @@
 #ifndef AVCODEC_VP6DATA_H
 #define AVCODEC_VP6DATA_H
 
-#include "vp56data.h"
+#include <stdint.h>
+
+#include "vp56.h"
 
 static const uint8_t vp6_def_fdv_vector_model[2][8] = {
     { 247, 210, 135, 68, 138, 220, 239, 246 },
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index 553e5c8..9848802 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -1680,6 +1680,11 @@
     if (s->mb_layout == 1)
         mb = s->macroblocks_base + ((s->mb_width+1)*(mb_y + 1) + 1);
     else {
+        // Make sure the previous frame has read its segmentation map,
+        // if we re-use the same map.
+        if (prev_frame && s->segmentation.enabled &&
+            !s->segmentation.update_map)
+            ff_thread_await_progress(&prev_frame->tf, mb_y, 0);
         mb = s->macroblocks + (s->mb_height - mb_y - 1)*2;
         memset(mb - 1, 0, sizeof(*mb)); // zero left macroblock
         AV_WN32A(s->intra4x4_pred_mode_left, DC_PRED*0x01010101);
@@ -1959,13 +1964,14 @@
     memset(s->ref_count, 0, sizeof(s->ref_count));
 
 
-    // Make sure the previous frame has read its segmentation map,
-    // if we re-use the same map.
-    if (prev_frame && s->segmentation.enabled && !s->segmentation.update_map)
-        ff_thread_await_progress(&prev_frame->tf, 1, 0);
-
-    if (s->mb_layout == 1)
+    if (s->mb_layout == 1) {
+        // Make sure the previous frame has read its segmentation map,
+        // if we re-use the same map.
+        if (prev_frame && s->segmentation.enabled &&
+            !s->segmentation.update_map)
+            ff_thread_await_progress(&prev_frame->tf, 1, 0);
         vp8_decode_mv_mb_modes(avctx, curframe, prev_frame);
+    }
 
     if (avctx->active_thread_type == FF_THREAD_FRAME)
         num_jobs = 1;
diff --git a/libavcodec/vp8.h b/libavcodec/vp8.h
index 90109ad..f66954d 100644
--- a/libavcodec/vp8.h
+++ b/libavcodec/vp8.h
@@ -29,16 +29,15 @@
 #include "libavutil/buffer.h"
 
 #include "vp56.h"
-#include "vp56data.h"
 #include "vp8dsp.h"
 #include "h264pred.h"
 #include "thread.h"
 #if HAVE_PTHREADS
 #include <pthread.h>
-#elif HAVE_W32THREADS
-#include "w32pthreads.h"
 #elif HAVE_OS2THREADS
-#include "os2threads.h"
+#include "compat/os2threads.h"
+#elif HAVE_W32THREADS
+#include "compat/w32pthreads.h"
 #endif
 
 #define VP8_MAX_QUANT 127
diff --git a/libavcodec/vp8dsp.c b/libavcodec/vp8dsp.c
index a61a59e..39d8038 100644
--- a/libavcodec/vp8dsp.c
+++ b/libavcodec/vp8dsp.c
@@ -523,8 +523,8 @@
 
     if (ARCH_X86)
         ff_vp8dsp_init_x86(dsp);
-    if (HAVE_ALTIVEC)
-        ff_vp8dsp_init_altivec(dsp);
     if (ARCH_ARM)
         ff_vp8dsp_init_arm(dsp);
+    if (ARCH_PPC)
+        ff_vp8dsp_init_ppc(dsp);
 }
diff --git a/libavcodec/vp8dsp.h b/libavcodec/vp8dsp.h
index 6308ff4..58ec65a 100644
--- a/libavcodec/vp8dsp.h
+++ b/libavcodec/vp8dsp.h
@@ -90,7 +90,7 @@
 
 void ff_vp8dsp_init(VP8DSPContext *c);
 void ff_vp8dsp_init_x86(VP8DSPContext *c);
-void ff_vp8dsp_init_altivec(VP8DSPContext *c);
 void ff_vp8dsp_init_arm(VP8DSPContext *c);
+void ff_vp8dsp_init_ppc(VP8DSPContext *c);
 
 #endif /* AVCODEC_VP8DSP_H */
diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c
index a47e2db..0a2b668 100644
--- a/libavcodec/vqavideo.c
+++ b/libavcodec/vqavideo.c
@@ -134,8 +134,15 @@
 
     /* load up the VQA parameters from the header */
     s->vqa_version = s->avctx->extradata[0];
-    if (s->vqa_version < 1 || s->vqa_version > 3) {
-        av_log(s->avctx, AV_LOG_ERROR, "unsupported version %d\n", s->vqa_version);
+    switch (s->vqa_version) {
+    case 1:
+    case 2:
+        break;
+    case 3:
+        avpriv_report_missing_feature(avctx, "VQA Version %d", s->vqa_version);
+        return AVERROR_PATCHWELCOME;
+    default:
+        avpriv_request_sample(avctx, "VQA Version %i", s->vqa_version);
         return AVERROR_PATCHWELCOME;
     }
     s->width = AV_RL16(&s->avctx->extradata[6]);
diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 481d323..ac03c16 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -25,54 +25,16 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "internal.h"
+#include "thread.h"
 #include "unary.h"
+#include "bytestream.h"
+#include "wavpack.h"
 
 /**
  * @file
  * WavPack lossless audio decoder
  */
 
-#define WV_MONO           0x00000004
-#define WV_JOINT_STEREO   0x00000010
-#define WV_FALSE_STEREO   0x40000000
-
-#define WV_HYBRID_MODE    0x00000008
-#define WV_HYBRID_SHAPE   0x00000008
-#define WV_HYBRID_BITRATE 0x00000200
-#define WV_HYBRID_BALANCE 0x00000400
-
-#define WV_FLT_SHIFT_ONES 0x01
-#define WV_FLT_SHIFT_SAME 0x02
-#define WV_FLT_SHIFT_SENT 0x04
-#define WV_FLT_ZERO_SENT  0x08
-#define WV_FLT_ZERO_SIGN  0x10
-
-#define WV_MAX_SAMPLES    131072
-
-enum WP_ID_Flags {
-    WP_IDF_MASK   = 0x1F,
-    WP_IDF_IGNORE = 0x20,
-    WP_IDF_ODD    = 0x40,
-    WP_IDF_LONG   = 0x80
-};
-
-enum WP_ID {
-    WP_ID_DUMMY = 0,
-    WP_ID_ENCINFO,
-    WP_ID_DECTERMS,
-    WP_ID_DECWEIGHTS,
-    WP_ID_DECSAMPLES,
-    WP_ID_ENTROPY,
-    WP_ID_HYBRID,
-    WP_ID_SHAPING,
-    WP_ID_FLOATINFO,
-    WP_ID_INT32INFO,
-    WP_ID_DATA,
-    WP_ID_CORR,
-    WP_ID_EXTRABITS,
-    WP_ID_CHANINFO
-};
-
 typedef struct SavedContext {
     int offset;
     int size;
@@ -80,23 +42,6 @@
     uint32_t crc;
 } SavedContext;
 
-#define MAX_TERMS 16
-
-typedef struct Decorr {
-    int delta;
-    int value;
-    int weightA;
-    int weightB;
-    int samplesA[8];
-    int samplesB[8];
-} Decorr;
-
-typedef struct WvChannel {
-    int median[3];
-    int slow_level, error_limit;
-    int bitrate_acc, bitrate_delta;
-} WvChannel;
-
 typedef struct WavpackFrameContext {
     AVCodecContext *avctx;
     int frame_flags;
@@ -133,113 +78,21 @@
     WavpackFrameContext *fdec[WV_MAX_FRAME_DECODERS];
     int fdec_num;
 
-    int multichannel;
-    int mkv_mode;
     int block;
     int samples;
     int ch_offset;
 } WavpackContext;
 
-// exponent table copied from WavPack source
-static const uint8_t wp_exp2_table [256] = {
-    0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b,
-    0x0b, 0x0c, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x13, 0x14, 0x15, 0x16, 0x16,
-    0x17, 0x18, 0x19, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1f, 0x20, 0x20, 0x21, 0x22, 0x23,
-    0x24, 0x24, 0x25, 0x26, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
-    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3a, 0x3b, 0x3c, 0x3d,
-    0x3e, 0x3f, 0x40, 0x41, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x48, 0x49, 0x4a, 0x4b,
-    0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
-    0x5b, 0x5c, 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
-    0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
-    0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a,
-    0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
-    0x9c, 0x9d, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad,
-    0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
-    0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc8, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf, 0xd0, 0xd2, 0xd3, 0xd4,
-    0xd6, 0xd7, 0xd8, 0xd9, 0xdb, 0xdc, 0xdd, 0xde, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe8, 0xe9,
-    0xea, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf2, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xff
-};
-
-static const uint8_t wp_log2_table [] = {
-    0x00, 0x01, 0x03, 0x04, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x10, 0x11, 0x12, 0x14, 0x15,
-    0x16, 0x18, 0x19, 0x1a, 0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a,
-    0x2c, 0x2d, 0x2e, 0x2f, 0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3d, 0x3e,
-    0x3f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
-    0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
-    0x64, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x74, 0x75,
-    0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85,
-    0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95,
-    0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4,
-    0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb2,
-    0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc0,
-    0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xce,
-    0xcf, 0xd0, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd8, 0xd9, 0xda, 0xdb,
-    0xdc, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe4, 0xe5, 0xe6, 0xe7, 0xe7,
-    0xe8, 0xe9, 0xea, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xee, 0xef, 0xf0, 0xf1, 0xf1, 0xf2, 0xf3, 0xf4,
-    0xf4, 0xf5, 0xf6, 0xf7, 0xf7, 0xf8, 0xf9, 0xf9, 0xfa, 0xfb, 0xfc, 0xfc, 0xfd, 0xfe, 0xff, 0xff
-};
-
-static av_always_inline int wp_exp2(int16_t val)
-{
-    int res, neg = 0;
-
-    if (val < 0) {
-        val = -val;
-        neg = 1;
-    }
-
-    res = wp_exp2_table[val & 0xFF] | 0x100;
-    val >>= 8;
-    res = (val > 9) ? (res << (val - 9)) : (res >> (9 - val));
-    return neg ? -res : res;
-}
-
-static av_always_inline int wp_log2(int32_t val)
-{
-    int bits;
-
-    if (!val)
-        return 0;
-    if (val == 1)
-        return 256;
-    val += val >> 9;
-    bits = av_log2(val) + 1;
-    if (bits < 9)
-        return (bits << 8) + wp_log2_table[(val << (9 - bits)) & 0xFF];
-    else
-        return (bits << 8) + wp_log2_table[(val >> (bits - 9)) & 0xFF];
-}
-
 #define LEVEL_DECAY(a)  ((a + 0x80) >> 8)
 
-// macros for manipulating median values
-#define GET_MED(n) ((c->median[n] >> 4) + 1)
-#define DEC_MED(n) c->median[n] -= ((c->median[n] + (128 >> n) - 2) / (128 >> n)) * 2
-#define INC_MED(n) c->median[n] += ((c->median[n] + (128 >> n)    ) / (128 >> n)) * 5
-
-// macros for applying weight
-#define UPDATE_WEIGHT_CLIP(weight, delta, samples, in) \
-    if (samples && in) { \
-        if ((samples ^ in) < 0) { \
-            weight -= delta; \
-            if (weight < -1024) \
-                weight = -1024; \
-        } else { \
-            weight += delta; \
-            if (weight > 1024) \
-                weight = 1024; \
-        } \
-    }
-
-
 static av_always_inline int get_tail(GetBitContext *gb, int k)
 {
     int p, e, res;
 
     if (k < 1)
         return 0;
-    p = av_log2(k);
-    e = (1 << (p + 1)) - k - 1;
+    p   = av_log2(k);
+    e   = (1 << (p + 1)) - k - 1;
     res = p ? get_bits(gb, p) : 0;
     if (res >= e)
         res = (res << 1) - e + get_bits1(gb);
@@ -252,8 +105,8 @@
 
     for (i = 0; i <= ctx->stereo_in; i++) {
         ctx->ch[i].bitrate_acc += ctx->ch[i].bitrate_delta;
-        br[i] = ctx->ch[i].bitrate_acc >> 16;
-        sl[i] = LEVEL_DECAY(ctx->ch[i].slow_level);
+        br[i]                   = ctx->ch[i].bitrate_acc >> 16;
+        sl[i]                   = LEVEL_DECAY(ctx->ch[i].slow_level);
     }
     if (ctx->stereo_in && ctx->hybrid_bitrate) {
         int balance = (sl[1] - sl[0] + br[1] + 1) >> 1;
@@ -262,7 +115,7 @@
             br[0] = 0;
         } else if (-balance > br[0]) {
             br[0] <<= 1;
-            br[1] = 0;
+            br[1]   = 0;
         } else {
             br[1] = br[0] + balance;
             br[0] = br[0] - balance;
@@ -302,7 +155,7 @@
             if (t >= 2) {
                 if (get_bits_left(gb) < t - 1)
                     goto error;
-                t = get_bits(gb, t - 1) | (1 << (t-1));
+                t = get_bits(gb, t - 1) | (1 << (t - 1));
             } else {
                 if (get_bits_left(gb) < 0)
                     goto error;
@@ -318,7 +171,7 @@
     }
 
     if (ctx->zero) {
-        t = 0;
+        t         = 0;
         ctx->zero = 0;
     } else {
         t = get_unary_0_33(gb);
@@ -339,10 +192,10 @@
 
         if (ctx->one) {
             ctx->one = t & 1;
-            t = (t >> 1) + 1;
+            t        = (t >> 1) + 1;
         } else {
             ctx->one = t & 1;
-            t >>= 1;
+            t      >>= 1;
         }
         ctx->zero = !ctx->one;
     }
@@ -409,11 +262,12 @@
 {
     int bit;
 
-    if (s->extra_bits){
+    if (s->extra_bits) {
         S <<= s->extra_bits;
 
-        if (s->got_extra_bits && get_bits_left(&s->gb_extra_bits) >= s->extra_bits) {
-            S |= get_bits(&s->gb_extra_bits, s->extra_bits);
+        if (s->got_extra_bits &&
+            get_bits_left(&s->gb_extra_bits) >= s->extra_bits) {
+            S   |= get_bits(&s->gb_extra_bits, s->extra_bits);
             *crc = *crc * 9 + (S & 0xffff) * 3 + ((unsigned)S >> 16);
         }
     }
@@ -446,7 +300,7 @@
     }
 
     if (S) {
-        S <<= s->float_shift;
+        S  <<= s->float_shift;
         sign = S < 0;
         if (sign)
             S = -S;
@@ -466,7 +320,8 @@
             if (shift) {
                 S <<= shift;
                 if ((s->float_flag & WV_FLT_SHIFT_ONES) ||
-                    (s->got_extra_bits && (s->float_flag & WV_FLT_SHIFT_SAME) &&
+                    (s->got_extra_bits &&
+                     (s->float_flag & WV_FLT_SHIFT_SAME) &&
                      get_bits1(&s->gb_extra_bits))) {
                     S |= (1 << shift) - 1;
                 } else if (s->got_extra_bits &&
@@ -480,7 +335,7 @@
         S &= 0x7fffff;
     } else {
         sign = 0;
-        exp = 0;
+        exp  = 0;
         if (s->got_extra_bits && (s->float_flag & WV_FLT_ZERO_SENT)) {
             if (get_bits1(&s->gb_extra_bits)) {
                 S = get_bits(&s->gb_extra_bits, 23);
@@ -502,7 +357,7 @@
 
 static void wv_reset_saved_context(WavpackFrameContext *s)
 {
-    s->pos = 0;
+    s->pos    = 0;
     s->sc.crc = s->extra_sc.crc = 0xFFFFFFFF;
 }
 
@@ -522,18 +377,20 @@
 }
 
 static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb,
-                                   void *dst, const int type)
+                                   void *dst_l, void *dst_r, const int type)
 {
     int i, j, count = 0;
     int last, t;
     int A, B, L, L2, R, R2;
-    int pos = s->pos;
-    uint32_t crc = s->sc.crc;
+    int pos                 = s->pos;
+    uint32_t crc            = s->sc.crc;
     uint32_t crc_extra_bits = s->extra_sc.crc;
-    int16_t *dst16 = dst;
-    int32_t *dst32 = dst;
-    float   *dstfl = dst;
-    const int channel_pad = s->avctx->channels - 2;
+    int16_t *dst16_l        = dst_l;
+    int16_t *dst16_r        = dst_r;
+    int32_t *dst32_l        = dst_l;
+    int32_t *dst32_r        = dst_r;
+    float *dstfl_l          = dst_l;
+    float *dstfl_r          = dst_r;
 
     s->one = s->zero = s->zeroes = 0;
     do {
@@ -556,39 +413,41 @@
                     }
                     s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0];
                     s->decorr[i].samplesB[1] = s->decorr[i].samplesB[0];
-                    j = 0;
+                    j                        = 0;
                 } else {
                     A = s->decorr[i].samplesA[pos];
                     B = s->decorr[i].samplesB[pos];
                     j = (pos + t) & 7;
                 }
-                if (type != AV_SAMPLE_FMT_S16) {
+                if (type != AV_SAMPLE_FMT_S16P) {
                     L2 = L + ((s->decorr[i].weightA * (int64_t)A + 512) >> 10);
                     R2 = R + ((s->decorr[i].weightB * (int64_t)B + 512) >> 10);
                 } else {
                     L2 = L + ((s->decorr[i].weightA * A + 512) >> 10);
                     R2 = R + ((s->decorr[i].weightB * B + 512) >> 10);
                 }
-                if (A && L) s->decorr[i].weightA -= ((((L ^ A) >> 30) & 2) - 1) * s->decorr[i].delta;
-                if (B && R) s->decorr[i].weightB -= ((((R ^ B) >> 30) & 2) - 1) * s->decorr[i].delta;
+                if (A && L)
+                    s->decorr[i].weightA -= ((((L ^ A) >> 30) & 2) - 1) * s->decorr[i].delta;
+                if (B && R)
+                    s->decorr[i].weightB -= ((((R ^ B) >> 30) & 2) - 1) * s->decorr[i].delta;
                 s->decorr[i].samplesA[j] = L = L2;
                 s->decorr[i].samplesB[j] = R = R2;
             } else if (t == -1) {
-                if (type != AV_SAMPLE_FMT_S16)
+                if (type != AV_SAMPLE_FMT_S16P)
                     L2 = L + ((s->decorr[i].weightA * (int64_t)s->decorr[i].samplesA[0] + 512) >> 10);
                 else
                     L2 = L + ((s->decorr[i].weightA * s->decorr[i].samplesA[0] + 512) >> 10);
                 UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, s->decorr[i].samplesA[0], L);
                 L = L2;
-                if (type != AV_SAMPLE_FMT_S16)
+                if (type != AV_SAMPLE_FMT_S16P)
                     R2 = R + ((s->decorr[i].weightB * (int64_t)L2 + 512) >> 10);
                 else
                     R2 = R + ((s->decorr[i].weightB * L2 + 512) >> 10);
                 UPDATE_WEIGHT_CLIP(s->decorr[i].weightB, s->decorr[i].delta, L2, R);
-                R = R2;
+                R                        = R2;
                 s->decorr[i].samplesA[0] = R;
             } else {
-                if (type != AV_SAMPLE_FMT_S16)
+                if (type != AV_SAMPLE_FMT_S16P)
                     R2 = R + ((s->decorr[i].weightB * (int64_t)s->decorr[i].samplesB[0] + 512) >> 10);
                 else
                     R2 = R + ((s->decorr[i].weightB * s->decorr[i].samplesB[0] + 512) >> 10);
@@ -596,16 +455,16 @@
                 R = R2;
 
                 if (t == -3) {
-                    R2 = s->decorr[i].samplesA[0];
+                    R2                       = s->decorr[i].samplesA[0];
                     s->decorr[i].samplesA[0] = R;
                 }
 
-                if (type != AV_SAMPLE_FMT_S16)
+                if (type != AV_SAMPLE_FMT_S16P)
                     L2 = L + ((s->decorr[i].weightA * (int64_t)R2 + 512) >> 10);
                 else
                     L2 = L + ((s->decorr[i].weightA * R2 + 512) >> 10);
                 UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, R2, L);
-                L = L2;
+                L                        = L2;
                 s->decorr[i].samplesB[0] = L;
             }
         }
@@ -614,18 +473,15 @@
             L += (R -= (L >> 1));
         crc = (crc * 3 + L) * 3 + R;
 
-        if (type == AV_SAMPLE_FMT_FLT) {
-            *dstfl++ = wv_get_value_float(s, &crc_extra_bits, L);
-            *dstfl++ = wv_get_value_float(s, &crc_extra_bits, R);
-            dstfl += channel_pad;
-        } else if (type == AV_SAMPLE_FMT_S32) {
-            *dst32++ = wv_get_value_integer(s, &crc_extra_bits, L);
-            *dst32++ = wv_get_value_integer(s, &crc_extra_bits, R);
-            dst32 += channel_pad;
+        if (type == AV_SAMPLE_FMT_FLTP) {
+            *dstfl_l++ = wv_get_value_float(s, &crc_extra_bits, L);
+            *dstfl_r++ = wv_get_value_float(s, &crc_extra_bits, R);
+        } else if (type == AV_SAMPLE_FMT_S32P) {
+            *dst32_l++ = wv_get_value_integer(s, &crc_extra_bits, L);
+            *dst32_r++ = wv_get_value_integer(s, &crc_extra_bits, R);
         } else {
-            *dst16++ = wv_get_value_integer(s, &crc_extra_bits, L);
-            *dst16++ = wv_get_value_integer(s, &crc_extra_bits, R);
-            dst16 += channel_pad;
+            *dst16_l++ = wv_get_value_integer(s, &crc_extra_bits, L);
+            *dst16_r++ = wv_get_value_integer(s, &crc_extra_bits, R);
         }
         count++;
     } while (!last && count < s->samples);
@@ -635,7 +491,7 @@
         wv_check_crc(s, crc, crc_extra_bits))
         return AVERROR_INVALIDDATA;
 
-    return count * 2;
+    return 0;
 }
 
 static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb,
@@ -644,13 +500,12 @@
     int i, j, count = 0;
     int last, t;
     int A, S, T;
-    int pos = s->pos;
-    uint32_t crc = s->sc.crc;
-    uint32_t crc_extra_bits = s->extra_sc.crc;
-    int16_t *dst16 = dst;
-    int32_t *dst32 = dst;
-    float   *dstfl = dst;
-    const int channel_stride = s->avctx->channels;
+    int pos                  = s->pos;
+    uint32_t crc             = s->sc.crc;
+    uint32_t crc_extra_bits  = s->extra_sc.crc;
+    int16_t *dst16           = dst;
+    int32_t *dst32           = dst;
+    float *dstfl             = dst;
 
     s->one = s->zero = s->zeroes = 0;
     do {
@@ -666,12 +521,12 @@
                 else
                     A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1;
                 s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0];
-                j = 0;
+                j                        = 0;
             } else {
                 A = s->decorr[i].samplesA[pos];
                 j = (pos + t) & 7;
             }
-            if (type != AV_SAMPLE_FMT_S16)
+            if (type != AV_SAMPLE_FMT_S16P)
                 S = T + ((s->decorr[i].weightA * (int64_t)A + 512) >> 10);
             else
                 S = T + ((s->decorr[i].weightA * A + 512) >> 10);
@@ -682,15 +537,12 @@
         pos = (pos + 1) & 7;
         crc = crc * 3 + S;
 
-        if (type == AV_SAMPLE_FMT_FLT) {
-            *dstfl = wv_get_value_float(s, &crc_extra_bits, S);
-            dstfl += channel_stride;
-        } else if (type == AV_SAMPLE_FMT_S32) {
-            *dst32 = wv_get_value_integer(s, &crc_extra_bits, S);
-            dst32 += channel_stride;
+        if (type == AV_SAMPLE_FMT_FLTP) {
+            *dstfl++ = wv_get_value_float(s, &crc_extra_bits, S);
+        } else if (type == AV_SAMPLE_FMT_S32P) {
+            *dst32++ = wv_get_value_integer(s, &crc_extra_bits, S);
         } else {
-            *dst16 = wv_get_value_integer(s, &crc_extra_bits, S);
-            dst16 += channel_stride;
+            *dst16++ = wv_get_value_integer(s, &crc_extra_bits, S);
         }
         count++;
     } while (!last && count < s->samples);
@@ -700,12 +552,11 @@
         wv_check_crc(s, crc, crc_extra_bits))
         return AVERROR_INVALIDDATA;
 
-    return count;
+    return 0;
 }
 
 static av_cold int wv_alloc_frame_context(WavpackContext *c)
 {
-
     if (c->fdec_num == WV_MAX_FRAME_DECODERS)
         return -1;
 
@@ -719,28 +570,18 @@
     return 0;
 }
 
+static int init_thread_copy(AVCodecContext *avctx)
+{
+    WavpackContext *s = avctx->priv_data;
+    s->avctx = avctx;
+    return 0;
+}
+
 static av_cold int wavpack_decode_init(AVCodecContext *avctx)
 {
     WavpackContext *s = avctx->priv_data;
 
     s->avctx = avctx;
-    if (avctx->bits_per_coded_sample <= 16)
-        avctx->sample_fmt = AV_SAMPLE_FMT_S16;
-    else
-        avctx->sample_fmt = AV_SAMPLE_FMT_S32;
-    if (avctx->channels <= 2 && !avctx->channel_layout)
-        avctx->channel_layout = (avctx->channels == 2) ? AV_CH_LAYOUT_STEREO :
-                                                         AV_CH_LAYOUT_MONO;
-
-    s->multichannel = avctx->channels > 2;
-    /* lavf demuxer does not provide extradata, Matroska stores 0x403
-       there, use this to detect decoding mode for multichannel */
-    s->mkv_mode = 0;
-    if (s->multichannel && avctx->extradata && avctx->extradata_size == 2) {
-        int ver = AV_RL16(avctx->extradata);
-        if (ver >= 0x402 && ver <= 0x410)
-            s->mkv_mode = 1;
-    }
 
     s->fdec_num = 0;
 
@@ -760,64 +601,50 @@
 }
 
 static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
-                                void *data, int *got_frame_ptr,
-                                const uint8_t *buf, int buf_size)
+                                AVFrame *frame, const uint8_t *buf, int buf_size)
 {
     WavpackContext *wc = avctx->priv_data;
+    ThreadFrame tframe = { .f = frame };
     WavpackFrameContext *s;
-    void *samples = data;
-    int samplecount;
+    GetByteContext gb;
+    void *samples_l, *samples_r;
+    int ret;
     int got_terms   = 0, got_weights = 0, got_samples = 0,
         got_entropy = 0, got_bs      = 0, got_float   = 0, got_hybrid = 0;
-    const uint8_t *orig_buf = buf;
-    const uint8_t *buf_end  = buf + buf_size;
     int i, j, id, size, ssize, weights, t;
-    int bpp, chan, chmask, orig_bpp;
-
-    if (buf_size == 0) {
-        *got_frame_ptr = 0;
-        return 0;
-    }
+    int bpp, chan = 0, chmask = 0, orig_bpp, sample_rate = 0;
+    int multiblock;
 
     if (block_no >= wc->fdec_num && wv_alloc_frame_context(wc) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Error creating frame decode context\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     s = wc->fdec[block_no];
     if (!s) {
-        av_log(avctx, AV_LOG_ERROR, "Context for block %d is not present\n", block_no);
-        return -1;
-    }
-
-    if (wc->ch_offset >= avctx->channels) {
-        av_log(avctx, AV_LOG_ERROR, "too many channels\n");
-        return -1;
+        av_log(avctx, AV_LOG_ERROR, "Context for block %d is not present\n",
+               block_no);
+        return AVERROR_INVALIDDATA;
     }
 
     memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr));
     memset(s->ch, 0, sizeof(s->ch));
-    s->extra_bits = 0;
-    s->and = s->or = s->shift = 0;
+    s->extra_bits     = 0;
+    s->and            = s->or = s->shift = 0;
     s->got_extra_bits = 0;
 
-    if (!wc->mkv_mode) {
-        s->samples = AV_RL32(buf); buf += 4;
-        if (!s->samples) {
-            *got_frame_ptr = 0;
-            return 0;
-        }
-        if (s->samples > wc->samples) {
-            av_log(avctx, AV_LOG_ERROR, "too many samples in block");
-            return -1;
-        }
-    } else {
-        s->samples = wc->samples;
+    bytestream2_init(&gb, buf, buf_size);
+
+    s->samples = bytestream2_get_le32(&gb);
+    if (s->samples != wc->samples) {
+        av_log(avctx, AV_LOG_ERROR, "Mismatching number of samples in "
+               "a sequence: %d and %d\n", wc->samples, s->samples);
+        return AVERROR_INVALIDDATA;
     }
-    s->frame_flags = AV_RL32(buf); buf += 4;
-    bpp = av_get_bytes_per_sample(avctx->sample_fmt);
-    samples = (uint8_t*)samples + bpp * wc->ch_offset;
-    orig_bpp = ((s->frame_flags & 0x03) + 1) << 3;
+    s->frame_flags = bytestream2_get_le32(&gb);
+    bpp            = av_get_bytes_per_sample(avctx->sample_fmt);
+    orig_bpp       = ((s->frame_flags & 0x03) + 1) << 3;
+    multiblock     = (s->frame_flags & WV_SINGLE_BLOCK) != WV_SINGLE_BLOCK;
 
     s->stereo         = !(s->frame_flags & WV_MONO);
     s->stereo_in      =  (s->frame_flags & WV_FALSE_STEREO) ? 0 : s->stereo;
@@ -825,51 +652,45 @@
     s->hybrid         =   s->frame_flags & WV_HYBRID_MODE;
     s->hybrid_bitrate =   s->frame_flags & WV_HYBRID_BITRATE;
     s->post_shift     = bpp * 8 - orig_bpp + ((s->frame_flags >> 13) & 0x1f);
-    s->hybrid_maxclip = (( 1LL << (orig_bpp - 1)) - 1);
+    s->hybrid_maxclip =  ((1LL << (orig_bpp - 1)) - 1);
     s->hybrid_minclip = ((-1LL << (orig_bpp - 1)));
-    s->CRC            = AV_RL32(buf); buf += 4;
-    if (wc->mkv_mode)
-        buf += 4; //skip block size;
-
-    wc->ch_offset += 1 + s->stereo;
+    s->CRC            = bytestream2_get_le32(&gb);
 
     // parse metadata blocks
-    while (buf < buf_end) {
-        id   = *buf++;
-        size = *buf++;
+    while (bytestream2_get_bytes_left(&gb)) {
+        id   = bytestream2_get_byte(&gb);
+        size = bytestream2_get_byte(&gb);
         if (id & WP_IDF_LONG) {
-            size |= (*buf++) << 8;
-            size |= (*buf++) << 16;
+            size |= (bytestream2_get_byte(&gb)) << 8;
+            size |= (bytestream2_get_byte(&gb)) << 16;
         }
         size <<= 1; // size is specified in words
-        ssize = size;
+        ssize  = size;
         if (id & WP_IDF_ODD)
             size--;
         if (size < 0) {
-            av_log(avctx, AV_LOG_ERROR, "Got incorrect block %02X with size %i\n", id, size);
+            av_log(avctx, AV_LOG_ERROR,
+                   "Got incorrect block %02X with size %i\n", id, size);
             break;
         }
-        if (buf + ssize > buf_end) {
-            av_log(avctx, AV_LOG_ERROR, "Block size %i is out of bounds\n", size);
+        if (bytestream2_get_bytes_left(&gb) < ssize) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "Block size %i is out of bounds\n", size);
             break;
         }
-        if (id & WP_IDF_IGNORE) {
-            buf += ssize;
-            continue;
-        }
         switch (id & WP_IDF_MASK) {
         case WP_ID_DECTERMS:
             if (size > MAX_TERMS) {
                 av_log(avctx, AV_LOG_ERROR, "Too many decorrelation terms\n");
                 s->terms = 0;
-                buf += ssize;
+                bytestream2_skip(&gb, ssize);
                 continue;
             }
             s->terms = size;
             for (i = 0; i < s->terms; i++) {
-                s->decorr[s->terms - i - 1].value = (*buf & 0x1F) - 5;
-                s->decorr[s->terms - i - 1].delta = *buf >> 5;
-                buf++;
+                uint8_t val = bytestream2_get_byte(&gb);
+                s->decorr[s->terms - i - 1].value = (val & 0x1F) - 5;
+                s->decorr[s->terms - i - 1].delta =  val >> 5;
             }
             got_terms = 1;
             break;
@@ -881,21 +702,21 @@
             weights = size >> s->stereo_in;
             if (weights > MAX_TERMS || weights > s->terms) {
                 av_log(avctx, AV_LOG_ERROR, "Too many decorrelation weights\n");
-                buf += ssize;
+                bytestream2_skip(&gb, ssize);
                 continue;
             }
             for (i = 0; i < weights; i++) {
-                t = (int8_t)(*buf++);
+                t = (int8_t)bytestream2_get_byte(&gb);
                 s->decorr[s->terms - i - 1].weightA = t << 3;
                 if (s->decorr[s->terms - i - 1].weightA > 0)
                     s->decorr[s->terms - i - 1].weightA +=
-                            (s->decorr[s->terms - i - 1].weightA + 64) >> 7;
+                        (s->decorr[s->terms - i - 1].weightA + 64) >> 7;
                 if (s->stereo_in) {
-                    t = (int8_t)(*buf++);
+                    t = (int8_t)bytestream2_get_byte(&gb);
                     s->decorr[s->terms - i - 1].weightB = t << 3;
                     if (s->decorr[s->terms - i - 1].weightB > 0)
                         s->decorr[s->terms - i - 1].weightB +=
-                                (s->decorr[s->terms - i - 1].weightB + 64) >> 7;
+                            (s->decorr[s->terms - i - 1].weightB + 64) >> 7;
                 }
             }
             got_weights = 1;
@@ -906,25 +727,34 @@
                 continue;
             }
             t = 0;
-            for (i = s->terms - 1; (i >= 0) && (t < size) && buf <= buf_end; i--) {
+            for (i = s->terms - 1; (i >= 0) && (t < size); i--) {
                 if (s->decorr[i].value > 8) {
-                    s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2;
-                    s->decorr[i].samplesA[1] = wp_exp2(AV_RL16(buf)); buf += 2;
+                    s->decorr[i].samplesA[0] =
+                        wp_exp2(bytestream2_get_le16(&gb));
+                    s->decorr[i].samplesA[1] =
+                        wp_exp2(bytestream2_get_le16(&gb));
+
                     if (s->stereo_in) {
-                        s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2;
-                        s->decorr[i].samplesB[1] = wp_exp2(AV_RL16(buf)); buf += 2;
-                        t += 4;
+                        s->decorr[i].samplesB[0] =
+                            wp_exp2(bytestream2_get_le16(&gb));
+                        s->decorr[i].samplesB[1] =
+                            wp_exp2(bytestream2_get_le16(&gb));
+                        t                       += 4;
                     }
                     t += 4;
                 } else if (s->decorr[i].value < 0) {
-                    s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2;
-                    s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2;
-                    t += 4;
+                    s->decorr[i].samplesA[0] =
+                        wp_exp2(bytestream2_get_le16(&gb));
+                    s->decorr[i].samplesB[0] =
+                        wp_exp2(bytestream2_get_le16(&gb));
+                    t                       += 4;
                 } else {
-                    for (j = 0; j < s->decorr[i].value && buf+1<buf_end; j++) {
-                        s->decorr[i].samplesA[j] = wp_exp2(AV_RL16(buf)); buf += 2;
+                    for (j = 0; j < s->decorr[i].value; j++) {
+                        s->decorr[i].samplesA[j] =
+                            wp_exp2(bytestream2_get_le16(&gb));
                         if (s->stereo_in) {
-                            s->decorr[i].samplesB[j] = wp_exp2(AV_RL16(buf)); buf += 2;
+                            s->decorr[i].samplesB[j] =
+                                wp_exp2(bytestream2_get_le16(&gb));
                         }
                     }
                     t += s->decorr[i].value * 2 * (s->stereo_in + 1);
@@ -934,36 +764,33 @@
             break;
         case WP_ID_ENTROPY:
             if (size != 6 * (s->stereo_in + 1)) {
-                av_log(avctx, AV_LOG_ERROR, "Entropy vars size should be %i, "
-                       "got %i", 6 * (s->stereo_in + 1), size);
-                buf += ssize;
+                av_log(avctx, AV_LOG_ERROR,
+                       "Entropy vars size should be %i, got %i.\n",
+                       6 * (s->stereo_in + 1), size);
+                bytestream2_skip(&gb, ssize);
                 continue;
             }
-            for (j = 0; j <= s->stereo_in; j++) {
+            for (j = 0; j <= s->stereo_in; j++)
                 for (i = 0; i < 3; i++) {
-                    s->ch[j].median[i] = wp_exp2(AV_RL16(buf));
-                    buf += 2;
+                    s->ch[j].median[i] = wp_exp2(bytestream2_get_le16(&gb));
                 }
-            }
             got_entropy = 1;
             break;
         case WP_ID_HYBRID:
             if (s->hybrid_bitrate) {
                 for (i = 0; i <= s->stereo_in; i++) {
-                    s->ch[i].slow_level = wp_exp2(AV_RL16(buf));
-                    buf += 2;
-                    size -= 2;
+                    s->ch[i].slow_level = wp_exp2(bytestream2_get_le16(&gb));
+                    size               -= 2;
                 }
             }
             for (i = 0; i < (s->stereo_in + 1); i++) {
-                s->ch[i].bitrate_acc = AV_RL16(buf) << 16;
-                buf += 2;
-                size -= 2;
+                s->ch[i].bitrate_acc = bytestream2_get_le16(&gb) << 16;
+                size                -= 2;
             }
             if (size > 0) {
                 for (i = 0; i < (s->stereo_in + 1); i++) {
-                    s->ch[i].bitrate_delta = wp_exp2((int16_t)AV_RL16(buf));
-                    buf += 2;
+                    s->ch[i].bitrate_delta =
+                        wp_exp2((int16_t)bytestream2_get_le16(&gb));
                 }
             } else {
                 for (i = 0; i < (s->stereo_in + 1); i++)
@@ -971,82 +798,96 @@
             }
             got_hybrid = 1;
             break;
-        case WP_ID_INT32INFO:
+        case WP_ID_INT32INFO: {
+            uint8_t val[4];
             if (size != 4) {
-                av_log(avctx, AV_LOG_ERROR, "Invalid INT32INFO, size = %i, sent_bits = %i\n", size, *buf);
-                buf += ssize;
+                av_log(avctx, AV_LOG_ERROR,
+                       "Invalid INT32INFO, size = %i\n",
+                       size);
+                bytestream2_skip(&gb, ssize - 4);
                 continue;
             }
-            if (buf[0])
-                s->extra_bits = buf[0];
-            else if (buf[1])
-                s->shift = buf[1];
-            else if (buf[2]){
-                s->and = s->or = 1;
-                s->shift = buf[2];
-            } else if(buf[3]) {
+            bytestream2_get_buffer(&gb, val, 4);
+            if (val[0]) {
+                s->extra_bits = val[0];
+            } else if (val[1]) {
+                s->shift = val[1];
+            } else if (val[2]) {
+                s->and   = s->or = 1;
+                s->shift = val[2];
+            } else if (val[3]) {
                 s->and   = 1;
-                s->shift = buf[3];
+                s->shift = val[3];
             }
             /* original WavPack decoder forces 32-bit lossy sound to be treated
-             * as 24-bit one in order to have proper clipping
-             */
+             * as 24-bit one in order to have proper clipping */
             if (s->hybrid && bpp == 4 && s->post_shift < 8 && s->shift > 8) {
-                s->post_shift += 8;
-                s->shift      -= 8;
+                s->post_shift      += 8;
+                s->shift           -= 8;
                 s->hybrid_maxclip >>= 8;
                 s->hybrid_minclip >>= 8;
             }
-            buf += 4;
             break;
+        }
         case WP_ID_FLOATINFO:
             if (size != 4) {
-                av_log(avctx, AV_LOG_ERROR, "Invalid FLOATINFO, size = %i\n", size);
-                buf += ssize;
+                av_log(avctx, AV_LOG_ERROR,
+                       "Invalid FLOATINFO, size = %i\n", size);
+                bytestream2_skip(&gb, ssize);
                 continue;
             }
-            s->float_flag    = buf[0];
-            s->float_shift   = buf[1];
-            s->float_max_exp = buf[2];
-            buf += 4;
-            got_float = 1;
+            s->float_flag    = bytestream2_get_byte(&gb);
+            s->float_shift   = bytestream2_get_byte(&gb);
+            s->float_max_exp = bytestream2_get_byte(&gb);
+            got_float        = 1;
+            bytestream2_skip(&gb, 1);
             break;
         case WP_ID_DATA:
-            s->sc.offset = buf - orig_buf;
+            s->sc.offset = bytestream2_tell(&gb);
             s->sc.size   = size * 8;
-            init_get_bits(&s->gb, buf, size * 8);
+            init_get_bits(&s->gb, gb.buffer, size * 8);
             s->data_size = size * 8;
-            buf += size;
-            got_bs = 1;
+            bytestream2_skip(&gb, size);
+            got_bs       = 1;
             break;
         case WP_ID_EXTRABITS:
             if (size <= 4) {
                 av_log(avctx, AV_LOG_ERROR, "Invalid EXTRABITS, size = %i\n",
                        size);
-                buf += size;
+                bytestream2_skip(&gb, size);
                 continue;
             }
-            s->extra_sc.offset = buf - orig_buf;
+            s->extra_sc.offset = bytestream2_tell(&gb);
             s->extra_sc.size   = size * 8;
-            init_get_bits(&s->gb_extra_bits, buf, size * 8);
-            s->crc_extra_bits = get_bits_long(&s->gb_extra_bits, 32);
-            buf += size;
-            s->got_extra_bits = 1;
+            init_get_bits(&s->gb_extra_bits, gb.buffer, size * 8);
+            s->crc_extra_bits  = get_bits_long(&s->gb_extra_bits, 32);
+            bytestream2_skip(&gb, size);
+            s->got_extra_bits  = 1;
             break;
         case WP_ID_CHANINFO:
             if (size <= 1) {
-                av_log(avctx, AV_LOG_ERROR, "Insufficient channel information\n");
-                return -1;
+                av_log(avctx, AV_LOG_ERROR,
+                       "Insufficient channel information\n");
+                return AVERROR_INVALIDDATA;
             }
-            chan = *buf++;
+            chan = bytestream2_get_byte(&gb);
             switch (size - 2) {
-            case 0: chmask = *buf;         break;
-            case 1: chmask = AV_RL16(buf); break;
-            case 2: chmask = AV_RL24(buf); break;
-            case 3: chmask = AV_RL32(buf); break;
+            case 0:
+                chmask = bytestream2_get_byte(&gb);
+                break;
+            case 1:
+                chmask = bytestream2_get_le16(&gb);
+                break;
+            case 2:
+                chmask = bytestream2_get_le24(&gb);
+                break;
+            case 3:
+                chmask = bytestream2_get_le32(&gb);
+                break;
             case 5:
-                chan |= (buf[1] & 0xF) << 8;
-                chmask = AV_RL24(buf + 2);
+                bytestream2_skip(&gb, 1);
+                chan  |= (bytestream2_get_byte(&gb) & 0xF) << 8;
+                chmask = bytestream2_get_le16(&gb);
                 break;
             default:
                 av_log(avctx, AV_LOG_ERROR, "Invalid channel info size %d\n",
@@ -1054,52 +895,50 @@
                 chan   = avctx->channels;
                 chmask = avctx->channel_layout;
             }
-            if (chan != avctx->channels) {
-                av_log(avctx, AV_LOG_ERROR, "Block reports total %d channels, "
-                       "decoder believes it's %d channels\n", chan,
-                       avctx->channels);
-                return -1;
+            break;
+        case WP_ID_SAMPLE_RATE:
+            if (size != 3) {
+                av_log(avctx, AV_LOG_ERROR, "Invalid custom sample rate.\n");
+                return AVERROR_INVALIDDATA;
             }
-            if (!avctx->channel_layout)
-                avctx->channel_layout = chmask;
-            buf += size - 1;
+            sample_rate = bytestream2_get_le24(&gb);
             break;
         default:
-            buf += size;
+            bytestream2_skip(&gb, size);
         }
         if (id & WP_IDF_ODD)
-            buf++;
+            bytestream2_skip(&gb, 1);
     }
 
     if (!got_terms) {
         av_log(avctx, AV_LOG_ERROR, "No block with decorrelation terms\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (!got_weights) {
         av_log(avctx, AV_LOG_ERROR, "No block with decorrelation weights\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (!got_samples) {
         av_log(avctx, AV_LOG_ERROR, "No block with decorrelation samples\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (!got_entropy) {
         av_log(avctx, AV_LOG_ERROR, "No block with entropy info\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (s->hybrid && !got_hybrid) {
         av_log(avctx, AV_LOG_ERROR, "Hybrid config not found\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (!got_bs) {
         av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
-    if (!got_float && avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {
+    if (!got_float && avctx->sample_fmt == AV_SAMPLE_FMT_FLTP) {
         av_log(avctx, AV_LOG_ERROR, "Float information not found\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
-    if (s->got_extra_bits && avctx->sample_fmt != AV_SAMPLE_FMT_FLT) {
+    if (s->got_extra_bits && avctx->sample_fmt != AV_SAMPLE_FMT_FLTP) {
         const int size   = get_bits_left(&s->gb_extra_bits);
         const int wanted = s->samples * s->extra_bits << s->stereo_in;
         if (size < wanted) {
@@ -1108,64 +947,60 @@
         }
     }
 
-    if (s->stereo_in) {
-        if (avctx->sample_fmt == AV_SAMPLE_FMT_S16)
-            samplecount = wv_unpack_stereo(s, &s->gb, samples, AV_SAMPLE_FMT_S16);
-        else if (avctx->sample_fmt == AV_SAMPLE_FMT_S32)
-            samplecount = wv_unpack_stereo(s, &s->gb, samples, AV_SAMPLE_FMT_S32);
-        else
-            samplecount = wv_unpack_stereo(s, &s->gb, samples, AV_SAMPLE_FMT_FLT);
-
-        if (samplecount < 0)
-            return -1;
-
-        samplecount >>= 1;
-    } else {
-        const int channel_stride = avctx->channels;
-
-        if (avctx->sample_fmt == AV_SAMPLE_FMT_S16)
-            samplecount = wv_unpack_mono(s, &s->gb, samples, AV_SAMPLE_FMT_S16);
-        else if (avctx->sample_fmt == AV_SAMPLE_FMT_S32)
-            samplecount = wv_unpack_mono(s, &s->gb, samples, AV_SAMPLE_FMT_S32);
-        else
-            samplecount = wv_unpack_mono(s, &s->gb, samples, AV_SAMPLE_FMT_FLT);
-
-        if (samplecount < 0)
-            return -1;
-
-        if (s->stereo && avctx->sample_fmt == AV_SAMPLE_FMT_S16) {
-            int16_t *dst = (int16_t*)samples + 1;
-            int16_t *src = (int16_t*)samples;
-            int cnt = samplecount;
-            while (cnt--) {
-                *dst = *src;
-                src += channel_stride;
-                dst += channel_stride;
+    if (!wc->ch_offset) {
+        int sr = (s->frame_flags >> 23) & 0xf;
+        if (sr == 0xf) {
+            if (!sample_rate) {
+                av_log(avctx, AV_LOG_ERROR, "Custom sample rate missing.\n");
+                return AVERROR_INVALIDDATA;
             }
-        } else if (s->stereo && avctx->sample_fmt == AV_SAMPLE_FMT_S32) {
-            int32_t *dst = (int32_t*)samples + 1;
-            int32_t *src = (int32_t*)samples;
-            int cnt = samplecount;
-            while (cnt--) {
-                *dst = *src;
-                src += channel_stride;
-                dst += channel_stride;
-            }
-        } else if (s->stereo) {
-            float *dst = (float*)samples + 1;
-            float *src = (float*)samples;
-            int cnt = samplecount;
-            while (cnt--) {
-                *dst = *src;
-                src += channel_stride;
-                dst += channel_stride;
-            }
+            avctx->sample_rate = sample_rate;
+        } else
+            avctx->sample_rate = wv_rates[sr];
+
+        if (multiblock) {
+            if (chan)
+                avctx->channels = chan;
+            if (chmask)
+                avctx->channel_layout = chmask;
+        } else {
+            avctx->channels       = s->stereo ? 2 : 1;
+            avctx->channel_layout = s->stereo ? AV_CH_LAYOUT_STEREO :
+                                                AV_CH_LAYOUT_MONO;
         }
+
+        /* get output buffer */
+        frame->nb_samples = s->samples + 1;
+        if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
+            return ret;
+        frame->nb_samples = s->samples;
     }
 
-    *got_frame_ptr = 1;
+    if (wc->ch_offset + s->stereo >= avctx->channels) {
+        av_log(avctx, AV_LOG_WARNING, "Too many channels coded in a packet.\n");
+        return (avctx->err_recognition & AV_EF_EXPLODE) ? AVERROR_INVALIDDATA : 0;
+    }
 
-    return samplecount * bpp;
+    samples_l = frame->extended_data[wc->ch_offset];
+    if (s->stereo)
+        samples_r = frame->extended_data[wc->ch_offset + 1];
+
+    wc->ch_offset += 1 + s->stereo;
+
+    if (s->stereo_in) {
+        ret = wv_unpack_stereo(s, &s->gb, samples_l, samples_r, avctx->sample_fmt);
+        if (ret < 0)
+            return ret;
+    } else {
+        ret = wv_unpack_mono(s, &s->gb, samples_l, avctx->sample_fmt);
+        if (ret < 0)
+            return ret;
+
+        if (s->stereo)
+            memcpy(samples_r, samples_l, bpp * s->samples);
+    }
+
+    return 0;
 }
 
 static void wavpack_decode_flush(AVCodecContext *avctx)
@@ -1185,73 +1020,61 @@
     int buf_size       = avpkt->size;
     AVFrame *frame     = data;
     int frame_size, ret, frame_flags;
-    int samplecount = 0;
+
+    if (avpkt->size <= WV_HEADER_SIZE)
+        return AVERROR_INVALIDDATA;
 
     s->block     = 0;
     s->ch_offset = 0;
 
     /* determine number of samples */
-    if (s->mkv_mode) {
-        s->samples  = AV_RL32(buf); buf += 4;
-        frame_flags = AV_RL32(buf);
-    } else {
-        if (s->multichannel) {
-            s->samples  = AV_RL32(buf + 4);
-            frame_flags = AV_RL32(buf + 8);
-        } else {
-            s->samples  = AV_RL32(buf);
-            frame_flags = AV_RL32(buf + 4);
-        }
-    }
+    s->samples  = AV_RL32(buf + 20);
+    frame_flags = AV_RL32(buf + 24);
     if (s->samples <= 0 || s->samples > WV_MAX_SAMPLES) {
         av_log(avctx, AV_LOG_ERROR, "Invalid number of samples: %d\n",
                s->samples);
-        return AVERROR(EINVAL);
+        return AVERROR_INVALIDDATA;
     }
 
     if (frame_flags & 0x80) {
-        avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+        avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
     } else if ((frame_flags & 0x03) <= 1) {
-        avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+        avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
     } else {
-        avctx->sample_fmt = AV_SAMPLE_FMT_S32;
+        avctx->sample_fmt          = AV_SAMPLE_FMT_S32P;
         avctx->bits_per_raw_sample = ((frame_flags & 0x03) + 1) << 3;
     }
 
-    /* get output buffer */
-    frame->nb_samples = s->samples + 1;
-    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
-        return ret;
-    frame->nb_samples = s->samples;
-
     while (buf_size > 0) {
-        if (!s->multichannel) {
-            frame_size = buf_size;
-        } else {
-            if (!s->mkv_mode) {
-                frame_size = AV_RL32(buf) - 12; buf += 4; buf_size -= 4;
-            } else {
-                if (buf_size < 12) //MKV files can have zero flags after last block
-                    break;
-                frame_size = AV_RL32(buf + 8) + 12;
-            }
-        }
-        if (frame_size < 0 || frame_size > buf_size) {
-            av_log(avctx, AV_LOG_ERROR, "Block %d has invalid size (size %d "
-                   "vs. %d bytes left)\n", s->block, frame_size, buf_size);
+        if (buf_size <= WV_HEADER_SIZE)
+            break;
+        frame_size = AV_RL32(buf + 4) - 12;
+        buf       += 20;
+        buf_size  -= 20;
+        if (frame_size <= 0 || frame_size > buf_size) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "Block %d has invalid size (size %d vs. %d bytes left)\n",
+                   s->block, frame_size, buf_size);
             wavpack_decode_flush(avctx);
             return AVERROR_INVALIDDATA;
         }
-        if ((samplecount = wavpack_decode_block(avctx, s->block,
-                                                frame->data[0], got_frame_ptr,
-                                                buf, frame_size)) < 0) {
+        if ((ret = wavpack_decode_block(avctx, s->block,
+                                        frame, buf, frame_size)) < 0) {
             wavpack_decode_flush(avctx);
-            return AVERROR_INVALIDDATA;
+            return ret;
         }
         s->block++;
-        buf += frame_size; buf_size -= frame_size;
+        buf      += frame_size;
+        buf_size -= frame_size;
     }
 
+    if (s->ch_offset != avctx->channels) {
+        av_log(avctx, AV_LOG_ERROR, "Not enough channels coded in a packet.\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    *got_frame_ptr = 1;
+
     return avpkt->size;
 }
 
@@ -1264,6 +1087,7 @@
     .close          = wavpack_decode_end,
     .decode         = wavpack_decode_frame,
     .flush          = wavpack_decode_flush,
-    .capabilities   = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
+    .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
     .long_name      = NULL_IF_CONFIG_SMALL("WavPack"),
 };
diff --git a/libavcodec/wavpack.h b/libavcodec/wavpack.h
new file mode 100644
index 0000000..bca6c45
--- /dev/null
+++ b/libavcodec/wavpack.h
@@ -0,0 +1,192 @@
+/*
+ * WavPack decoder/encoder common code
+ * Copyright (c) 2006,2011 Konstantin Shishkov
+ *
+ * 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
+ */
+
+#ifndef AVCODEC_WAVPACK_H
+#define AVCODEC_WAVPACK_H
+
+#define MAX_TERMS      16
+#define MAX_TERM        8
+
+#define WV_HEADER_SIZE    32
+
+#define WV_MONO           0x00000004
+#define WV_JOINT_STEREO   0x00000010
+#define WV_CROSS_DECORR   0x00000020
+#define WV_FLOAT_DATA     0x00000080
+#define WV_INT32_DATA     0x00000100
+#define WV_FALSE_STEREO   0x40000000
+
+#define WV_HYBRID_MODE    0x00000008
+#define WV_HYBRID_SHAPE   0x00000008
+#define WV_HYBRID_BITRATE 0x00000200
+#define WV_HYBRID_BALANCE 0x00000400
+#define WV_INITIAL_BLOCK  0x00000800
+#define WV_FINAL_BLOCK    0x00001000
+
+#define WV_MONO_DATA    (WV_MONO | WV_FALSE_STEREO)
+
+#define WV_SINGLE_BLOCK (WV_INITIAL_BLOCK | WV_FINAL_BLOCK)
+
+#define WV_FLT_SHIFT_ONES 0x01
+#define WV_FLT_SHIFT_SAME 0x02
+#define WV_FLT_SHIFT_SENT 0x04
+#define WV_FLT_ZERO_SENT  0x08
+#define WV_FLT_ZERO_SIGN  0x10
+
+#define WV_MAX_SAMPLES    131072
+
+enum WP_ID_Flags {
+    WP_IDF_MASK   = 0x3F,
+    WP_IDF_IGNORE = 0x20,
+    WP_IDF_ODD    = 0x40,
+    WP_IDF_LONG   = 0x80
+};
+
+enum WP_ID {
+    WP_ID_DUMMY = 0,
+    WP_ID_ENCINFO,
+    WP_ID_DECTERMS,
+    WP_ID_DECWEIGHTS,
+    WP_ID_DECSAMPLES,
+    WP_ID_ENTROPY,
+    WP_ID_HYBRID,
+    WP_ID_SHAPING,
+    WP_ID_FLOATINFO,
+    WP_ID_INT32INFO,
+    WP_ID_DATA,
+    WP_ID_CORR,
+    WP_ID_EXTRABITS,
+    WP_ID_CHANINFO,
+    WP_ID_SAMPLE_RATE = 0x27,
+};
+
+typedef struct Decorr {
+    int delta;
+    int value;
+    int weightA;
+    int weightB;
+    int samplesA[MAX_TERM];
+    int samplesB[MAX_TERM];
+    int sumA;
+    int sumB;
+} Decorr;
+
+typedef struct WvChannel {
+    int median[3];
+    int slow_level, error_limit;
+    int bitrate_acc, bitrate_delta;
+} WvChannel;
+
+// macros for manipulating median values
+#define GET_MED(n) ((c->median[n] >> 4) + 1)
+#define DEC_MED(n) c->median[n] -= ((c->median[n] + (128 >> n) - 2) / (128 >> n)) * 2
+#define INC_MED(n) c->median[n] += ((c->median[n] + (128 >> n)    ) / (128 >> n)) * 5
+
+// macros for applying weight
+#define UPDATE_WEIGHT_CLIP(weight, delta, samples, in) \
+    if (samples && in) { \
+        if ((samples ^ in) < 0) { \
+            weight -= delta; \
+            if (weight < -1024) \
+                weight = -1024; \
+        } else { \
+            weight += delta; \
+            if (weight > 1024) \
+                weight = 1024; \
+        } \
+    }
+
+static const int wv_rates[16] = {
+     6000,  8000,  9600, 11025, 12000, 16000,  22050, 24000,
+    32000, 44100, 48000, 64000, 88200, 96000, 192000,     0
+};
+
+// exponent table copied from WavPack source
+static const uint8_t wp_exp2_table[256] = {
+    0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b,
+    0x0b, 0x0c, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x13, 0x14, 0x15, 0x16, 0x16,
+    0x17, 0x18, 0x19, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1f, 0x20, 0x20, 0x21, 0x22, 0x23,
+    0x24, 0x24, 0x25, 0x26, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3a, 0x3b, 0x3c, 0x3d,
+    0x3e, 0x3f, 0x40, 0x41, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x48, 0x49, 0x4a, 0x4b,
+    0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
+    0x5b, 0x5c, 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+    0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+    0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a,
+    0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
+    0x9c, 0x9d, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad,
+    0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
+    0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc8, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf, 0xd0, 0xd2, 0xd3, 0xd4,
+    0xd6, 0xd7, 0xd8, 0xd9, 0xdb, 0xdc, 0xdd, 0xde, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe8, 0xe9,
+    0xea, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf2, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xff
+};
+
+static const uint8_t wp_log2_table [] = {
+    0x00, 0x01, 0x03, 0x04, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x10, 0x11, 0x12, 0x14, 0x15,
+    0x16, 0x18, 0x19, 0x1a, 0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a,
+    0x2c, 0x2d, 0x2e, 0x2f, 0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3d, 0x3e,
+    0x3f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
+    0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
+    0x64, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x74, 0x75,
+    0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85,
+    0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95,
+    0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4,
+    0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb2,
+    0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc0,
+    0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xce,
+    0xcf, 0xd0, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd8, 0xd9, 0xda, 0xdb,
+    0xdc, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe4, 0xe5, 0xe6, 0xe7, 0xe7,
+    0xe8, 0xe9, 0xea, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xee, 0xef, 0xf0, 0xf1, 0xf1, 0xf2, 0xf3, 0xf4,
+    0xf4, 0xf5, 0xf6, 0xf7, 0xf7, 0xf8, 0xf9, 0xf9, 0xfa, 0xfb, 0xfc, 0xfc, 0xfd, 0xfe, 0xff, 0xff
+};
+
+static av_always_inline int wp_exp2(int16_t val)
+{
+    int res, neg = 0;
+
+    if (val < 0) {
+        val = -val;
+        neg = 1;
+    }
+
+    res   = wp_exp2_table[val & 0xFF] | 0x100;
+    val >>= 8;
+    res   = (val > 9) ? (res << (val - 9)) : (res >> (9 - val));
+    return neg ? -res : res;
+}
+
+static av_always_inline int wp_log2(int32_t val)
+{
+    int bits;
+
+    if (!val)
+        return 0;
+    if (val == 1)
+        return 256;
+    val += val >> 9;
+    bits = av_log2(val) + 1;
+    if (bits < 9)
+        return (bits << 8) + wp_log2_table[(val << (9 - bits)) & 0xFF];
+    else
+        return (bits << 8) + wp_log2_table[(val >> (bits - 9)) & 0xFF];
+}
+
+#endif /* AVCODEC_WAVPACK_H */
diff --git a/libavcodec/wavpackenc.c b/libavcodec/wavpackenc.c
new file mode 100644
index 0000000..10e6e14
--- /dev/null
+++ b/libavcodec/wavpackenc.c
@@ -0,0 +1,2989 @@
+/*
+ * WavPack lossless audio encoder
+ *
+ * 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 BITSTREAM_WRITER_LE
+
+#include "libavutil/intreadwrite.h"
+#include "libavutil/opt.h"
+#include "avcodec.h"
+#include "internal.h"
+#include "put_bits.h"
+#include "bytestream.h"
+#include "wavpackenc.h"
+#include "wavpack.h"
+
+#define UPDATE_WEIGHT(weight, delta, source, result) \
+    if (source && result) { \
+        int32_t s = (int32_t) (source ^ result) >> 31; \
+        weight = (delta ^ s) + (weight - s); \
+    }
+
+#define APPLY_WEIGHT_F(weight, sample) (((((sample & 0xffff) * weight) >> 9) + \
+    (((sample & ~0xffff) >> 9) * weight) + 1) >> 1)
+
+#define APPLY_WEIGHT_I(weight, sample) ((weight * sample + 512) >> 10)
+
+#define APPLY_WEIGHT(weight, sample) (sample != (short) sample ? \
+    APPLY_WEIGHT_F(weight, sample) : APPLY_WEIGHT_I (weight, sample))
+
+#define CLEAR(destin) memset(&destin, 0, sizeof(destin));
+
+#define SHIFT_LSB       13
+#define SHIFT_MASK      (0x1FU << SHIFT_LSB)
+
+#define MAG_LSB         18
+#define MAG_MASK        (0x1FU << MAG_LSB)
+
+#define SRATE_LSB       23
+#define SRATE_MASK      (0xFU << SRATE_LSB)
+
+#define EXTRA_TRY_DELTAS     1
+#define EXTRA_ADJUST_DELTAS  2
+#define EXTRA_SORT_FIRST     4
+#define EXTRA_BRANCHES       8
+#define EXTRA_SORT_LAST     16
+
+typedef struct WavPackExtraInfo {
+    struct Decorr dps[MAX_TERMS];
+    int nterms, log_limit, gt16bit;
+    uint32_t best_bits;
+} WavPackExtraInfo;
+
+typedef struct WavPackWords {
+    int pend_data, holding_one, zeros_acc;
+    int holding_zero, pend_count;
+    WvChannel c[2];
+} WavPackWords;
+
+typedef struct WavPackEncodeContext {
+    AVClass *class;
+    AVCodecContext *avctx;
+    PutBitContext pb;
+    int block_samples;
+    int buffer_size;
+    int sample_index;
+    int stereo, stereo_in;
+    int ch_offset;
+
+    int32_t *samples[2];
+    int samples_size[2];
+
+    int32_t *sampleptrs[MAX_TERMS+2][2];
+    int sampleptrs_size[MAX_TERMS+2][2];
+
+    int32_t *temp_buffer[2][2];
+    int temp_buffer_size[2][2];
+
+    int32_t *best_buffer[2];
+    int best_buffer_size[2];
+
+    int32_t *js_left, *js_right;
+    int js_left_size, js_right_size;
+
+    int32_t *orig_l, *orig_r;
+    int orig_l_size, orig_r_size;
+
+    unsigned extra_flags;
+    int optimize_mono;
+    int decorr_filter;
+    int joint;
+    int num_branches;
+
+    uint32_t flags;
+    uint32_t crc_x;
+    WavPackWords w;
+
+    uint8_t int32_sent_bits, int32_zeros, int32_ones, int32_dups;
+    uint8_t float_flags, float_shift, float_max_exp, max_exp;
+    int32_t shifted_ones, shifted_zeros, shifted_both;
+    int32_t false_zeros, neg_zeros, ordata;
+
+    int num_terms, shift, joint_stereo, false_stereo;
+    int num_decorrs, num_passes, best_decorr, mask_decorr;
+    struct Decorr decorr_passes[MAX_TERMS];
+    const WavPackDecorrSpec *decorr_specs;
+    float delta_decay;
+} WavPackEncodeContext;
+
+static av_cold int wavpack_encode_init(AVCodecContext *avctx)
+{
+    WavPackEncodeContext *s = avctx->priv_data;
+
+    s->avctx = avctx;
+
+    if (!avctx->frame_size) {
+        int block_samples;
+        if (!(avctx->sample_rate & 1))
+            block_samples = avctx->sample_rate / 2;
+        else
+            block_samples = avctx->sample_rate;
+
+        while (block_samples * avctx->channels > 150000)
+            block_samples /= 2;
+
+        while (block_samples * avctx->channels < 40000)
+            block_samples *= 2;
+        avctx->frame_size = block_samples;
+    } else if (avctx->frame_size && (avctx->frame_size < 128 ||
+                              avctx->frame_size > WV_MAX_SAMPLES)) {
+        av_log(avctx, AV_LOG_ERROR, "invalid block size: %d\n", avctx->frame_size);
+        return AVERROR(EINVAL);
+    }
+
+    if (avctx->compression_level != FF_COMPRESSION_DEFAULT) {
+        if (avctx->compression_level >= 3) {
+            s->decorr_filter = 3;
+            s->num_passes = 9;
+            if      (avctx->compression_level >= 8) {
+                s->num_branches = 4;
+                s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_SORT_FIRST|EXTRA_SORT_LAST|EXTRA_BRANCHES;
+            } else if (avctx->compression_level >= 7) {
+                s->num_branches = 3;
+                s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_SORT_FIRST|EXTRA_BRANCHES;
+            } else if (avctx->compression_level >= 6) {
+                s->num_branches = 2;
+                s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_SORT_FIRST|EXTRA_BRANCHES;
+            } else if (avctx->compression_level >= 5) {
+                s->num_branches = 1;
+                s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_SORT_FIRST|EXTRA_BRANCHES;
+            } else if (avctx->compression_level >= 4) {
+                s->num_branches = 1;
+                s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_BRANCHES;
+            }
+        } else if (avctx->compression_level == 2) {
+            s->decorr_filter = 2;
+            s->num_passes = 4;
+        } else if (avctx->compression_level == 1) {
+            s->decorr_filter = 1;
+            s->num_passes = 2;
+        } else if (avctx->compression_level < 1) {
+            s->decorr_filter = 0;
+            s->num_passes = 0;
+        }
+    }
+
+    s->num_decorrs = decorr_filter_sizes[s->decorr_filter];
+    s->decorr_specs = decorr_filters[s->decorr_filter];
+
+    s->delta_decay = 2.0;
+
+    return 0;
+}
+
+static void shift_mono(int32_t *samples, int nb_samples, int shift)
+{
+    int i;
+    for (i = 0; i < nb_samples; i++)
+        samples[i] >>= shift;
+}
+
+static void shift_stereo(int32_t *left, int32_t *right,
+                         int nb_samples, int shift)
+{
+    int i;
+    for (i = 0; i < nb_samples; i++) {
+        left [i] >>= shift;
+        right[i] >>= shift;
+    }
+}
+
+#define FLOAT_SHIFT_ONES 1
+#define FLOAT_SHIFT_SAME 2
+#define FLOAT_SHIFT_SENT 4
+#define FLOAT_ZEROS_SENT 8
+#define FLOAT_NEG_ZEROS  0x10
+#define FLOAT_EXCEPTIONS 0x20
+
+#define get_mantissa(f)     ((f) & 0x7fffff)
+#define get_exponent(f)     (((f) >> 23) & 0xff)
+#define get_sign(f)         (((f) >> 31) & 0x1)
+
+static void process_float(WavPackEncodeContext *s, int32_t *sample)
+{
+    int32_t shift_count, value, f = *sample;
+
+    if (get_exponent(f) == 255) {
+        s->float_flags |= FLOAT_EXCEPTIONS;
+        value = 0x1000000;
+        shift_count = 0;
+    } else if (get_exponent(f)) {
+        shift_count = s->max_exp - get_exponent(f);
+        value = 0x800000 + get_mantissa(f);
+    } else {
+        shift_count = s->max_exp ? s->max_exp - 1 : 0;
+        value = get_mantissa(f);
+    }
+
+    if (shift_count < 25)
+        value >>= shift_count;
+    else
+        value = 0;
+
+    if (!value) {
+        if (get_exponent(f) || get_mantissa(f))
+            s->false_zeros++;
+        else if (get_sign(f))
+            s->neg_zeros++;
+    } else if (shift_count) {
+        int32_t mask = (1 << shift_count) - 1;
+
+        if (!(get_mantissa(f) & mask))
+            s->shifted_zeros++;
+        else if ((get_mantissa(f) & mask) == mask)
+            s->shifted_ones++;
+        else
+            s->shifted_both++;
+    }
+
+    s->ordata |= value;
+    *sample = get_sign(f) ? -value : value;
+}
+
+static int scan_float(WavPackEncodeContext *s,
+                      int32_t *samples_l, int32_t *samples_r,
+                      int nb_samples)
+{
+    uint32_t crc = 0xffffffffu;
+    int i;
+
+    s->shifted_ones = s->shifted_zeros = s->shifted_both = s->ordata = 0;
+    s->float_shift = s->float_flags = 0;
+    s->false_zeros = s->neg_zeros = 0;
+    s->max_exp = 0;
+
+    if (s->flags & WV_MONO_DATA) {
+        for (i = 0; i < nb_samples; i++) {
+            int32_t f = samples_l[i];
+            crc = crc * 27 + get_mantissa(f) * 9 + get_exponent(f) * 3 + get_sign(f);
+
+            if (get_exponent(f) > s->max_exp && get_exponent(f) < 255)
+                s->max_exp = get_exponent(f);
+        }
+    } else {
+        for (i = 0; i < nb_samples; i++) {
+            int32_t f;
+
+            f = samples_l[i];
+            crc = crc * 27 + get_mantissa(f) * 9 + get_exponent(f) * 3 + get_sign(f);
+            if (get_exponent(f) > s->max_exp && get_exponent(f) < 255)
+                s->max_exp = get_exponent(f);
+
+            f = samples_r[i];
+            crc = crc * 27 + get_mantissa(f) * 9 + get_exponent(f) * 3 + get_sign(f);
+
+            if (get_exponent(f) > s->max_exp && get_exponent(f) < 255)
+                s->max_exp = get_exponent(f);
+        }
+    }
+
+    s->crc_x = crc;
+
+    if (s->flags & WV_MONO_DATA) {
+        for (i = 0; i < nb_samples; i++)
+            process_float(s, &samples_l[i]);
+    } else {
+        for (i = 0; i < nb_samples; i++) {
+            process_float(s, &samples_l[i]);
+            process_float(s, &samples_r[i]);
+        }
+    }
+
+    s->float_max_exp = s->max_exp;
+
+    if (s->shifted_both)
+        s->float_flags |= FLOAT_SHIFT_SENT;
+    else if (s->shifted_ones && !s->shifted_zeros)
+        s->float_flags |= FLOAT_SHIFT_ONES;
+    else if (s->shifted_ones && s->shifted_zeros)
+        s->float_flags |= FLOAT_SHIFT_SAME;
+    else if (s->ordata && !(s->ordata & 1)) {
+        do {
+            s->float_shift++;
+            s->ordata >>= 1;
+        } while (!(s->ordata & 1));
+
+        if (s->flags & WV_MONO_DATA)
+            shift_mono(samples_l, nb_samples, s->float_shift);
+        else
+            shift_stereo(samples_l, samples_r, nb_samples, s->float_shift);
+    }
+
+    s->flags &= ~MAG_MASK;
+
+    while (s->ordata) {
+        s->flags += 1 << MAG_LSB;
+        s->ordata >>= 1;
+    }
+
+    if (s->false_zeros || s->neg_zeros)
+        s->float_flags |= FLOAT_ZEROS_SENT;
+
+    if (s->neg_zeros)
+        s->float_flags |= FLOAT_NEG_ZEROS;
+
+    return s->float_flags & (FLOAT_EXCEPTIONS | FLOAT_ZEROS_SENT |
+                             FLOAT_SHIFT_SENT | FLOAT_SHIFT_SAME);
+}
+
+static void scan_int23(WavPackEncodeContext *s,
+                       int32_t *samples_l, int32_t *samples_r,
+                       int nb_samples)
+{
+    uint32_t magdata = 0, ordata = 0, xordata = 0, anddata = ~0;
+    int i, total_shift = 0;
+
+    s->int32_sent_bits = s->int32_zeros = s->int32_ones = s->int32_dups = 0;
+
+    if (s->flags & WV_MONO_DATA) {
+        for (i = 0; i < nb_samples; i++) {
+            int32_t M = samples_l[i];
+
+            magdata |= (M < 0) ? ~M : M;
+            xordata |= M ^ -(M & 1);
+            anddata &= M;
+            ordata  |= M;
+
+            if ((ordata & 1) && !(anddata & 1) && (xordata & 2))
+                return;
+        }
+    } else {
+        for (i = 0; i < nb_samples; i++) {
+            int32_t L = samples_l[i];
+            int32_t R = samples_r[i];
+
+            magdata |= (L < 0) ? ~L : L;
+            magdata |= (R < 0) ? ~R : R;
+            xordata |= L ^ -(L & 1);
+            xordata |= R ^ -(R & 1);
+            anddata &= L & R;
+            ordata  |= L | R;
+
+            if ((ordata & 1) && !(anddata & 1) && (xordata & 2))
+                return;
+        }
+    }
+
+    s->flags &= ~MAG_MASK;
+
+    while (magdata) {
+        s->flags += 1 << MAG_LSB;
+        magdata >>= 1;
+    }
+
+    if (!(s->flags & MAG_MASK))
+        return;
+
+    if (!(ordata & 1)) {
+        do {
+            s->flags -= 1 << MAG_LSB;
+            s->int32_zeros++;
+            total_shift++;
+            ordata >>= 1;
+        } while (!(ordata & 1));
+    } else if (anddata & 1) {
+        do {
+            s->flags -= 1 << MAG_LSB;
+            s->int32_ones++;
+            total_shift++;
+            anddata >>= 1;
+        } while (anddata & 1);
+    } else if (!(xordata & 2)) {
+        do {
+            s->flags -= 1 << MAG_LSB;
+            s->int32_dups++;
+            total_shift++;
+            xordata >>= 1;
+        } while (!(xordata & 2));
+    }
+
+    if (total_shift) {
+        s->flags |= WV_INT32_DATA;
+
+        if (s->flags & WV_MONO_DATA)
+            shift_mono(samples_l, nb_samples, total_shift);
+        else
+            shift_stereo(samples_l, samples_r, nb_samples, total_shift);
+    }
+}
+
+static int scan_int32(WavPackEncodeContext *s,
+                      int32_t *samples_l, int32_t *samples_r,
+                      int nb_samples)
+{
+    uint32_t magdata = 0, ordata = 0, xordata = 0, anddata = ~0;
+    uint32_t crc = 0xffffffffu;
+    int i, total_shift = 0;
+
+    s->int32_sent_bits = s->int32_zeros = s->int32_ones = s->int32_dups = 0;
+
+    if (s->flags & WV_MONO_DATA) {
+        for (i = 0; i < nb_samples; i++) {
+            int32_t M = samples_l[i];
+
+            crc = crc * 9 + (M & 0xffff) * 3 + ((M >> 16) & 0xffff);
+            magdata |= (M < 0) ? ~M : M;
+            xordata |= M ^ -(M & 1);
+            anddata &= M;
+            ordata  |= M;
+        }
+    } else {
+        for (i = 0; i < nb_samples; i++) {
+            int32_t L = samples_l[i];
+            int32_t R = samples_r[i];
+
+            crc = crc * 9 + (L & 0xffff) * 3 + ((L >> 16) & 0xffff);
+            crc = crc * 9 + (R & 0xffff) * 3 + ((R >> 16) & 0xffff);
+            magdata |= (L < 0) ? ~L : L;
+            magdata |= (R < 0) ? ~R : R;
+            xordata |= L ^ -(L & 1);
+            xordata |= R ^ -(R & 1);
+            anddata &= L & R;
+            ordata  |= L | R;
+        }
+    }
+
+    s->crc_x = crc;
+    s->flags &= ~MAG_MASK;
+
+    while (magdata) {
+        s->flags += 1 << MAG_LSB;
+        magdata >>= 1;
+    }
+
+    if (!((s->flags & MAG_MASK) >> MAG_LSB)) {
+        s->flags &= ~WV_INT32_DATA;
+        return 0;
+    }
+
+    if (!(ordata & 1))
+        do {
+            s->flags -= 1 << MAG_LSB;
+            s->int32_zeros++;
+            total_shift++;
+            ordata >>= 1;
+        } while (!(ordata & 1));
+    else if (anddata & 1)
+        do {
+            s->flags -= 1 << MAG_LSB;
+            s->int32_ones++;
+            total_shift++;
+            anddata >>= 1;
+        } while (anddata & 1);
+    else if (!(xordata & 2))
+        do {
+            s->flags -= 1 << MAG_LSB;
+            s->int32_dups++;
+            total_shift++;
+            xordata >>= 1;
+        } while (!(xordata & 2));
+
+    if (((s->flags & MAG_MASK) >> MAG_LSB) > 23) {
+        s->int32_sent_bits = (uint8_t)(((s->flags & MAG_MASK) >> MAG_LSB) - 23);
+        total_shift += s->int32_sent_bits;
+        s->flags &= ~MAG_MASK;
+        s->flags += 23 << MAG_LSB;
+    }
+
+    if (total_shift) {
+        s->flags |= WV_INT32_DATA;
+
+        if (s->flags & WV_MONO_DATA)
+            shift_mono(samples_l, nb_samples, total_shift);
+        else
+            shift_stereo(samples_l, samples_r, nb_samples, total_shift);
+    }
+
+    return s->int32_sent_bits;
+}
+
+static int8_t store_weight(int weight)
+{
+    weight = av_clip(weight, -1024, 1024);
+    if (weight > 0)
+        weight -= (weight + 64) >> 7;
+
+    return (weight + 4) >> 3;
+}
+
+static int restore_weight(int8_t weight)
+{
+    int result;
+
+    if ((result = (int) weight << 3) > 0)
+        result += (result + 64) >> 7;
+
+    return result;
+}
+
+static int log2s(int32_t value)
+{
+    return (value < 0) ? -wp_log2(-value) : wp_log2(value);
+}
+
+static void decorr_mono(int32_t *in_samples, int32_t *out_samples,
+                        int nb_samples, struct Decorr *dpp, int dir)
+{
+    int m = 0, i;
+
+    dpp->sumA = 0;
+
+    if (dir < 0) {
+        out_samples += (nb_samples - 1);
+        in_samples  += (nb_samples - 1);
+    }
+
+    dpp->weightA = restore_weight(store_weight(dpp->weightA));
+
+    for (i = 0; i < MAX_TERM; i++)
+        dpp->samplesA[i] = wp_exp2(log2s(dpp->samplesA[i]));
+
+    if (dpp->value > MAX_TERM) {
+        while (nb_samples--) {
+            int32_t left, sam_A;
+
+            sam_A = ((3 - (dpp->value & 1)) * dpp->samplesA[0] - dpp->samplesA[1]) >> !(dpp->value & 1);
+
+            dpp->samplesA[1] = dpp->samplesA[0];
+            dpp->samplesA[0] = left = in_samples[0];
+
+            left -= APPLY_WEIGHT(dpp->weightA, sam_A);
+            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam_A, left);
+            dpp->sumA += dpp->weightA;
+            out_samples[0] = left;
+            in_samples += dir;
+            out_samples += dir;
+        }
+    } else if (dpp->value > 0) {
+        while (nb_samples--) {
+            int k = (m + dpp->value) & (MAX_TERM - 1);
+            int32_t left, sam_A;
+
+            sam_A = dpp->samplesA[m];
+            dpp->samplesA[k] = left = in_samples[0];
+            m = (m + 1) & (MAX_TERM - 1);
+
+            left -= APPLY_WEIGHT(dpp->weightA, sam_A);
+            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam_A, left);
+            dpp->sumA += dpp->weightA;
+            out_samples[0] = left;
+            in_samples += dir;
+            out_samples += dir;
+        }
+    }
+
+    if (m && dpp->value > 0 && dpp->value <= MAX_TERM) {
+        int32_t temp_A[MAX_TERM];
+
+        memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA));
+
+        for (i = 0; i < MAX_TERM; i++) {
+            dpp->samplesA[i] = temp_A[m];
+            m = (m + 1) & (MAX_TERM - 1);
+        }
+    }
+}
+
+static void reverse_mono_decorr(struct Decorr *dpp)
+{
+    if (dpp->value > MAX_TERM) {
+        int32_t sam_A;
+
+        if (dpp->value & 1)
+            sam_A = 2 * dpp->samplesA[0] - dpp->samplesA[1];
+        else
+            sam_A = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1;
+
+        dpp->samplesA[1] = dpp->samplesA[0];
+        dpp->samplesA[0] = sam_A;
+
+        if (dpp->value & 1)
+            sam_A = 2 * dpp->samplesA[0] - dpp->samplesA[1];
+        else
+            sam_A = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1;
+
+        dpp->samplesA[1] = sam_A;
+    } else if (dpp->value > 1) {
+        int i, j, k;
+
+        for (i = 0, j = dpp->value - 1, k = 0; k < dpp->value / 2; i++, j--, k++) {
+            i &= (MAX_TERM - 1);
+            j &= (MAX_TERM - 1);
+            dpp->samplesA[i] ^= dpp->samplesA[j];
+            dpp->samplesA[j] ^= dpp->samplesA[i];
+            dpp->samplesA[i] ^= dpp->samplesA[j];
+        }
+    }
+}
+
+static uint32_t log2sample(uint32_t v, int limit, uint32_t *result)
+{
+    uint32_t dbits;
+
+    if ((v += v >> 9) < (1 << 8)) {
+        dbits = nbits_table[v];
+        result += (dbits << 8) + wp_log2_table[(v << (9 - dbits)) & 0xff];
+    } else {
+        if (v < (1L << 16))
+            dbits = nbits_table[v >> 8] + 8;
+        else if (v < (1L << 24))
+            dbits = nbits_table[v >> 16] + 16;
+        else
+            dbits = nbits_table[v >> 24] + 24;
+
+        result += dbits = (dbits << 8) + wp_log2_table[(v >> (dbits - 9)) & 0xff];
+
+        if (limit && dbits >= limit)
+            return 1;
+    }
+
+    return 0;
+}
+
+static uint32_t log2mono(int32_t *samples, int nb_samples, int limit)
+{
+    uint32_t result = 0;
+    while (nb_samples--) {
+        if (log2sample(abs(*samples++), limit, &result))
+            return UINT32_MAX;
+    }
+    return result;
+}
+
+static uint32_t log2stereo(int32_t *samples_l, int32_t *samples_r,
+                           int nb_samples, int limit)
+{
+    uint32_t result = 0;
+    while (nb_samples--) {
+        if (log2sample(abs(*samples_l++), limit, &result) ||
+            log2sample(abs(*samples_r++), limit, &result))
+            return UINT32_MAX;
+    }
+    return result;
+}
+
+static void decorr_mono_buffer(int32_t *samples, int32_t *outsamples,
+                               int nb_samples, struct Decorr *dpp,
+                               int tindex)
+{
+    struct Decorr dp, *dppi = dpp + tindex;
+    int delta = dppi->delta, pre_delta, term = dppi->value;
+
+    if (delta == 7)
+        pre_delta = 7;
+    else if (delta < 2)
+        pre_delta = 3;
+    else
+        pre_delta = delta + 1;
+
+    CLEAR(dp);
+    dp.value = term;
+    dp.delta = pre_delta;
+    decorr_mono(samples, outsamples, FFMIN(2048, nb_samples), &dp, -1);
+    dp.delta = delta;
+
+    if (tindex == 0)
+        reverse_mono_decorr(&dp);
+    else
+        CLEAR(dp.samplesA);
+
+    memcpy(dppi->samplesA, dp.samplesA, sizeof(dp.samplesA));
+    dppi->weightA = dp.weightA;
+
+    if (delta == 0) {
+        dp.delta = 1;
+        decorr_mono(samples, outsamples, nb_samples, &dp, 1);
+        dp.delta = 0;
+        memcpy(dp.samplesA, dppi->samplesA, sizeof(dp.samplesA));
+        dppi->weightA = dp.weightA = dp.sumA / nb_samples;
+    }
+
+    decorr_mono(samples, outsamples, nb_samples, &dp, 1);
+}
+
+static void recurse_mono(WavPackEncodeContext *s, WavPackExtraInfo *info,
+                         int depth, int delta, uint32_t input_bits)
+{
+    int term, branches = s->num_branches - depth;
+    int32_t *samples, *outsamples;
+    uint32_t term_bits[22], bits;
+
+    if (branches < 1 || depth + 1 == info->nterms)
+        branches = 1;
+
+    CLEAR(term_bits);
+    samples = s->sampleptrs[depth][0];
+    outsamples = s->sampleptrs[depth + 1][0];
+
+    for (term = 1; term <= 18; term++) {
+        if (term == 17 && branches == 1 && depth + 1 < info->nterms)
+            continue;
+
+        if (term > 8 && term < 17)
+            continue;
+
+        if (!s->extra_flags && (term > 4 && term < 17))
+            continue;
+
+        info->dps[depth].value = term;
+        info->dps[depth].delta = delta;
+        decorr_mono_buffer(samples, outsamples, s->block_samples, info->dps, depth);
+        bits = log2mono(outsamples, s->block_samples, info->log_limit);
+
+        if (bits < info->best_bits) {
+            info->best_bits = bits;
+            CLEAR(s->decorr_passes);
+            memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * (depth + 1));
+            memcpy(s->sampleptrs[info->nterms + 1][0],
+                   s->sampleptrs[depth + 1][0], s->block_samples * 4);
+        }
+
+        term_bits[term + 3] = bits;
+    }
+
+    while (depth + 1 < info->nterms && branches--) {
+        uint32_t local_best_bits = input_bits;
+        int best_term = 0, i;
+
+        for (i = 0; i < 22; i++)
+            if (term_bits[i] && term_bits[i] < local_best_bits) {
+                local_best_bits = term_bits[i];
+                best_term = i - 3;
+            }
+
+        if (!best_term)
+            break;
+
+        term_bits[best_term + 3] = 0;
+
+        info->dps[depth].value = best_term;
+        info->dps[depth].delta = delta;
+        decorr_mono_buffer(samples, outsamples, s->block_samples, info->dps, depth);
+
+        recurse_mono(s, info, depth + 1, delta, local_best_bits);
+    }
+}
+
+static void sort_mono(WavPackEncodeContext *s, WavPackExtraInfo *info)
+{
+    int reversed = 1;
+    uint32_t bits;
+
+    while (reversed) {
+        int ri, i;
+
+        memcpy(info->dps, s->decorr_passes, sizeof(s->decorr_passes));
+        reversed = 0;
+
+        for (ri = 0; ri < info->nterms && s->decorr_passes[ri].value; ri++) {
+
+            if (ri + 1 >= info->nterms || !s->decorr_passes[ri+1].value)
+                break;
+
+            if (s->decorr_passes[ri].value == s->decorr_passes[ri+1].value) {
+                decorr_mono_buffer(s->sampleptrs[ri][0], s->sampleptrs[ri+1][0],
+                                   s->block_samples, info->dps, ri);
+                continue;
+            }
+
+            info->dps[ri  ] = s->decorr_passes[ri+1];
+            info->dps[ri+1] = s->decorr_passes[ri  ];
+
+            for (i = ri; i < info->nterms && s->decorr_passes[i].value; i++)
+                decorr_mono_buffer(s->sampleptrs[i][0], s->sampleptrs[i+1][0],
+                                   s->block_samples, info->dps, i);
+
+            bits = log2mono(s->sampleptrs[i][0], s->block_samples, info->log_limit);
+            if (bits < info->best_bits) {
+                reversed = 1;
+                info->best_bits = bits;
+                CLEAR(s->decorr_passes);
+                memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i);
+                memcpy(s->sampleptrs[info->nterms + 1][0], s->sampleptrs[i][0],
+                       s->block_samples * 4);
+            } else {
+                info->dps[ri  ] = s->decorr_passes[ri];
+                info->dps[ri+1] = s->decorr_passes[ri+1];
+                decorr_mono_buffer(s->sampleptrs[ri][0], s->sampleptrs[ri+1][0],
+                                   s->block_samples, info->dps, ri);
+            }
+        }
+    }
+}
+
+static void delta_mono(WavPackEncodeContext *s, WavPackExtraInfo *info)
+{
+    int lower = 0, delta, d;
+    uint32_t bits;
+
+    if (!s->decorr_passes[0].value)
+        return;
+    delta = s->decorr_passes[0].delta;
+
+    for (d = delta - 1; d >= 0; d--) {
+        int i;
+
+        for (i = 0; i < info->nterms && s->decorr_passes[i].value; i++) {
+            info->dps[i].value = s->decorr_passes[i].value;
+            info->dps[i].delta = d;
+            decorr_mono_buffer(s->sampleptrs[i][0], s->sampleptrs[i+1][0],
+                               s->block_samples, info->dps, i);
+        }
+
+        bits = log2mono(s->sampleptrs[i][0], s->block_samples, info->log_limit);
+        if (bits >= info->best_bits)
+            break;
+
+        lower = 1;
+        info->best_bits = bits;
+        CLEAR(s->decorr_passes);
+        memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i);
+        memcpy(s->sampleptrs[info->nterms + 1][0],  s->sampleptrs[i][0],
+               s->block_samples * 4);
+    }
+
+    for (d = delta + 1; !lower && d <= 7; d++) {
+        int i;
+
+        for (i = 0; i < info->nterms && s->decorr_passes[i].value; i++) {
+            info->dps[i].value = s->decorr_passes[i].value;
+            info->dps[i].delta = d;
+            decorr_mono_buffer(s->sampleptrs[i][0], s->sampleptrs[i+1][0],
+                               s->block_samples, info->dps, i);
+        }
+
+        bits = log2mono(s->sampleptrs[i][0], s->block_samples, info->log_limit);
+        if (bits >= info->best_bits)
+            break;
+
+        info->best_bits = bits;
+        CLEAR(s->decorr_passes);
+        memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i);
+        memcpy(s->sampleptrs[info->nterms + 1][0], s->sampleptrs[i][0],
+               s->block_samples * 4);
+    }
+}
+
+static int allocate_buffers2(WavPackEncodeContext *s, int nterms)
+{
+    int i;
+
+    for (i = 0; i < nterms + 2; i++) {
+        av_fast_padded_malloc(&s->sampleptrs[i][0], &s->sampleptrs_size[i][0],
+                              s->block_samples * 4);
+        if (!s->sampleptrs[i][0])
+            return AVERROR(ENOMEM);
+        if (!(s->flags & WV_MONO_DATA)) {
+            av_fast_padded_malloc(&s->sampleptrs[i][1], &s->sampleptrs_size[i][1],
+                                  s->block_samples * 4);
+            if (!s->sampleptrs[i][1])
+                return AVERROR(ENOMEM);
+        }
+    }
+
+    return 0;
+}
+
+static int allocate_buffers(WavPackEncodeContext *s)
+{
+    int i;
+
+    for (i = 0; i < 2; i++) {
+        av_fast_padded_malloc(&s->best_buffer[0], &s->best_buffer_size[0],
+                              s->block_samples * 4);
+        if (!s->best_buffer[0])
+            return AVERROR(ENOMEM);
+
+        av_fast_padded_malloc(&s->temp_buffer[i][0], &s->temp_buffer_size[i][0],
+                              s->block_samples * 4);
+        if (!s->temp_buffer[i][0])
+            return AVERROR(ENOMEM);
+        if (!(s->flags & WV_MONO_DATA)) {
+            av_fast_padded_malloc(&s->best_buffer[1], &s->best_buffer_size[1],
+                                  s->block_samples * 4);
+            if (!s->best_buffer[1])
+                return AVERROR(ENOMEM);
+
+            av_fast_padded_malloc(&s->temp_buffer[i][1], &s->temp_buffer_size[i][1],
+                                  s->block_samples * 4);
+            if (!s->temp_buffer[i][1])
+                return AVERROR(ENOMEM);
+        }
+    }
+
+    return 0;
+}
+
+static void analyze_mono(WavPackEncodeContext *s, int32_t *samples, int do_samples)
+{
+    WavPackExtraInfo info;
+    int i;
+
+    info.log_limit = (((s->flags & MAG_MASK) >> MAG_LSB) + 4) * 256;
+    info.log_limit = FFMIN(6912, info.log_limit);
+
+    info.nterms = s->num_terms;
+
+    if (allocate_buffers2(s, s->num_terms))
+        return;
+
+    memcpy(info.dps, s->decorr_passes, sizeof(info.dps));
+    memcpy(s->sampleptrs[0][0], samples, s->block_samples * 4);
+
+    for (i = 0; i < info.nterms && info.dps[i].value; i++)
+        decorr_mono(s->sampleptrs[i][0], s->sampleptrs[i + 1][0],
+                    s->block_samples, info.dps + i, 1);
+
+    info.best_bits = log2mono(s->sampleptrs[info.nterms][0], s->block_samples, 0) * 1;
+    memcpy(s->sampleptrs[info.nterms + 1][0], s->sampleptrs[i][0], s->block_samples * 4);
+
+    if (s->extra_flags & EXTRA_BRANCHES)
+        recurse_mono(s, &info, 0, (int) floor(s->delta_decay + 0.5),
+                     log2mono(s->sampleptrs[0][0], s->block_samples, 0));
+
+    if (s->extra_flags & EXTRA_SORT_FIRST)
+        sort_mono(s, &info);
+
+    if (s->extra_flags & EXTRA_TRY_DELTAS) {
+        delta_mono(s, &info);
+
+        if ((s->extra_flags & EXTRA_ADJUST_DELTAS) && s->decorr_passes[0].value)
+            s->delta_decay = (float)((s->delta_decay * 2.0 + s->decorr_passes[0].delta) / 3.0);
+        else
+            s->delta_decay = 2.0;
+    }
+
+    if (s->extra_flags & EXTRA_SORT_LAST)
+        sort_mono(s, &info);
+
+    if (do_samples)
+        memcpy(samples, s->sampleptrs[info.nterms + 1][0], s->block_samples * 4);
+
+    for (i = 0; i < info.nterms; i++)
+        if (!s->decorr_passes[i].value)
+            break;
+
+    s->num_terms = i;
+}
+
+static void scan_word(WavPackEncodeContext *s, WvChannel *c,
+                      int32_t *samples, int nb_samples, int dir)
+{
+    if (dir < 0)
+        samples += nb_samples - 1;
+
+    while (nb_samples--) {
+        uint32_t low, value = labs(samples[0]);
+
+        if (value < GET_MED(0)) {
+            DEC_MED(0);
+        } else {
+            low = GET_MED(0);
+            INC_MED(0);
+
+            if (value - low < GET_MED(1)) {
+                DEC_MED(1);
+            } else {
+                low += GET_MED(1);
+                INC_MED(1);
+
+                if (value - low < GET_MED(2)) {
+                    DEC_MED(2);
+                } else {
+                    INC_MED(2);
+                }
+            }
+        }
+        samples += dir;
+    }
+}
+
+static int wv_mono(WavPackEncodeContext *s, int32_t *samples,
+                   int no_history, int do_samples)
+{
+    struct Decorr temp_decorr_pass, save_decorr_passes[MAX_TERMS] = {{0}};
+    int nb_samples = s->block_samples;
+    int buf_size = sizeof(int32_t) * nb_samples;
+    uint32_t best_size = UINT32_MAX, size;
+    int log_limit, pi, i, ret;
+
+    for (i = 0; i < nb_samples; i++)
+        if (samples[i])
+            break;
+
+    if (i == nb_samples) {
+        CLEAR(s->decorr_passes);
+        CLEAR(s->w);
+        s->num_terms = 0;
+        return 0;
+    }
+
+    log_limit = (((s->flags & MAG_MASK) >> MAG_LSB) + 4) * 256;
+    log_limit = FFMIN(6912, log_limit);
+
+    if ((ret = allocate_buffers(s)) < 0)
+        return ret;
+
+    if (no_history || s->num_passes >= 7)
+        s->best_decorr = s->mask_decorr = 0;
+
+    for (pi = 0; pi < s->num_passes;) {
+        const WavPackDecorrSpec *wpds;
+        int nterms, c, j;
+
+        if (!pi) {
+            c = s->best_decorr;
+        } else {
+            if (s->mask_decorr == 0)
+                c = 0;
+            else
+                c = (s->best_decorr & (s->mask_decorr - 1)) | s->mask_decorr;
+
+            if (c == s->best_decorr) {
+                s->mask_decorr = s->mask_decorr ? ((s->mask_decorr << 1) & (s->num_decorrs - 1)) : 1;
+                continue;
+            }
+        }
+
+        wpds = &s->decorr_specs[c];
+        nterms = decorr_filter_nterms[s->decorr_filter];
+
+        while (1) {
+        memcpy(s->temp_buffer[0][0], samples, buf_size);
+        CLEAR(save_decorr_passes);
+
+        for (j = 0; j < nterms; j++) {
+            CLEAR(temp_decorr_pass);
+            temp_decorr_pass.delta = wpds->delta;
+            temp_decorr_pass.value = wpds->terms[j];
+
+            if (temp_decorr_pass.value < 0)
+                temp_decorr_pass.value = 1;
+
+            decorr_mono(s->temp_buffer[j&1][0], s->temp_buffer[~j&1][0],
+                        FFMIN(nb_samples, 2048), &temp_decorr_pass, -1);
+
+            if (j) {
+                CLEAR(temp_decorr_pass.samplesA);
+            } else {
+                reverse_mono_decorr(&temp_decorr_pass);
+            }
+
+            memcpy(save_decorr_passes + j, &temp_decorr_pass, sizeof(struct Decorr));
+            decorr_mono(s->temp_buffer[j&1][0], s->temp_buffer[~j&1][0],
+                        nb_samples, &temp_decorr_pass, 1);
+        }
+
+        size = log2mono(s->temp_buffer[j&1][0], nb_samples, log_limit);
+        if (size != UINT32_MAX || !nterms)
+            break;
+        nterms >>= 1;
+        }
+
+        if (size < best_size) {
+            memcpy(s->best_buffer[0], s->temp_buffer[j&1][0], buf_size);
+            memcpy(s->decorr_passes, save_decorr_passes, sizeof(struct Decorr) * MAX_TERMS);
+            s->num_terms = nterms;
+            s->best_decorr = c;
+            best_size = size;
+        }
+
+        if (pi++)
+            s->mask_decorr = s->mask_decorr ? ((s->mask_decorr << 1) & (s->num_decorrs - 1)) : 1;
+    }
+
+    if (s->extra_flags)
+        analyze_mono(s, samples, do_samples);
+    else if (do_samples)
+        memcpy(samples, s->best_buffer[0], buf_size);
+
+    if (no_history || s->extra_flags) {
+        CLEAR(s->w);
+        scan_word(s, &s->w.c[0], s->best_buffer[0], nb_samples, -1);
+    }
+    return 0;
+}
+
+static void decorr_stereo(int32_t *in_left, int32_t *in_right,
+                          int32_t *out_left, int32_t *out_right,
+                          int nb_samples, struct Decorr *dpp, int dir)
+{
+    int m = 0, i;
+
+    dpp->sumA = dpp->sumB = 0;
+
+    if (dir < 0) {
+        out_left  += nb_samples - 1;
+        out_right += nb_samples - 1;
+        in_left   += nb_samples - 1;
+        in_right  += nb_samples - 1;
+    }
+
+    dpp->weightA = restore_weight(store_weight(dpp->weightA));
+    dpp->weightB = restore_weight(store_weight(dpp->weightB));
+
+    for (i = 0; i < MAX_TERM; i++) {
+        dpp->samplesA[i] = wp_exp2(log2s(dpp->samplesA[i]));
+        dpp->samplesB[i] = wp_exp2(log2s(dpp->samplesB[i]));
+    }
+
+    switch (dpp->value) {
+    case 2:
+        while (nb_samples--) {
+            int32_t sam, tmp;
+
+            sam = dpp->samplesA[0];
+            dpp->samplesA[0] = dpp->samplesA[1];
+            out_left[0] = tmp = (dpp->samplesA[1] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam);
+            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
+            dpp->sumA += dpp->weightA;
+
+            sam = dpp->samplesB[0];
+            dpp->samplesB[0] = dpp->samplesB[1];
+            out_right[0] = tmp = (dpp->samplesB[1] = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam);
+            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
+            dpp->sumB += dpp->weightB;
+
+            in_left   += dir;
+            out_left  += dir;
+            in_right  += dir;
+            out_right += dir;
+        }
+        break;
+    case 17:
+        while (nb_samples--) {
+            int32_t sam, tmp;
+
+            sam = 2 * dpp->samplesA[0] - dpp->samplesA[1];
+            dpp->samplesA[1] = dpp->samplesA[0];
+            out_left[0] = tmp = (dpp->samplesA[0] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam);
+            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
+            dpp->sumA += dpp->weightA;
+
+            sam = 2 * dpp->samplesB[0] - dpp->samplesB[1];
+            dpp->samplesB[1] = dpp->samplesB[0];
+            out_right[0] = tmp = (dpp->samplesB[0] = in_right[0]) - APPLY_WEIGHT (dpp->weightB, sam);
+            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
+            dpp->sumB += dpp->weightB;
+
+            in_left   += dir;
+            out_left  += dir;
+            in_right  += dir;
+            out_right += dir;
+        }
+        break;
+    case 18:
+        while (nb_samples--) {
+            int32_t sam, tmp;
+
+            sam = dpp->samplesA[0] + ((dpp->samplesA[0] - dpp->samplesA[1]) >> 1);
+            dpp->samplesA[1] = dpp->samplesA[0];
+            out_left[0] = tmp = (dpp->samplesA[0] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam);
+            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
+            dpp->sumA += dpp->weightA;
+
+            sam = dpp->samplesB[0] + ((dpp->samplesB[0] - dpp->samplesB[1]) >> 1);
+            dpp->samplesB[1] = dpp->samplesB[0];
+            out_right[0] = tmp = (dpp->samplesB[0] = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam);
+            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
+            dpp->sumB += dpp->weightB;
+
+            in_left   += dir;
+            out_left  += dir;
+            in_right  += dir;
+            out_right += dir;
+        }
+        break;
+    default: {
+        int k = dpp->value & (MAX_TERM - 1);
+
+        while (nb_samples--) {
+            int32_t sam, tmp;
+
+            sam = dpp->samplesA[m];
+            out_left[0] = tmp = (dpp->samplesA[k] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam);
+            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
+            dpp->sumA += dpp->weightA;
+
+            sam = dpp->samplesB[m];
+            out_right[0] = tmp = (dpp->samplesB[k] = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam);
+            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
+            dpp->sumB += dpp->weightB;
+
+            in_left   += dir;
+            out_left  += dir;
+            in_right  += dir;
+            out_right += dir;
+            m = (m + 1) & (MAX_TERM - 1);
+            k = (k + 1) & (MAX_TERM - 1);
+        }
+
+        if (m) {
+            int32_t temp_A[MAX_TERM], temp_B[MAX_TERM];
+            int k;
+
+            memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA));
+            memcpy(temp_B, dpp->samplesB, sizeof(dpp->samplesB));
+
+            for (k = 0; k < MAX_TERM; k++) {
+                dpp->samplesA[k] = temp_A[m];
+                dpp->samplesB[k] = temp_B[m];
+                m = (m + 1) & (MAX_TERM - 1);
+            }
+        }
+        break;
+        }
+    case -1:
+        while (nb_samples--) {
+            int32_t sam_A, sam_B, tmp;
+
+            sam_A = dpp->samplesA[0];
+            out_left[0] = tmp = (sam_B = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam_A);
+            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
+            dpp->sumA += dpp->weightA;
+
+            out_right[0] = tmp = (dpp->samplesA[0] = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam_B);
+            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
+            dpp->sumB += dpp->weightB;
+
+            in_left   += dir;
+            out_left  += dir;
+            in_right  += dir;
+            out_right += dir;
+        }
+        break;
+    case -2:
+        while (nb_samples--) {
+            int32_t sam_A, sam_B, tmp;
+
+            sam_B = dpp->samplesB[0];
+            out_right[0] = tmp = (sam_A = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam_B);
+            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
+            dpp->sumB += dpp->weightB;
+
+            out_left[0] = tmp = (dpp->samplesB[0] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam_A);
+            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
+            dpp->sumA += dpp->weightA;
+
+            in_left   += dir;
+            out_left  += dir;
+            in_right  += dir;
+            out_right += dir;
+        }
+        break;
+    case -3:
+        while (nb_samples--) {
+            int32_t sam_A, sam_B, tmp;
+
+            sam_A = dpp->samplesA[0];
+            sam_B = dpp->samplesB[0];
+
+            dpp->samplesA[0] = tmp = in_right[0];
+            out_right[0] = tmp -= APPLY_WEIGHT(dpp->weightB, sam_B);
+            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
+            dpp->sumB += dpp->weightB;
+
+            dpp->samplesB[0] = tmp = in_left[0];
+            out_left[0] = tmp -= APPLY_WEIGHT(dpp->weightA, sam_A);
+            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
+            dpp->sumA += dpp->weightA;
+
+            in_left   += dir;
+            out_left  += dir;
+            in_right  += dir;
+            out_right += dir;
+        }
+        break;
+    }
+}
+
+static void reverse_decorr(struct Decorr *dpp)
+{
+    if (dpp->value > MAX_TERM) {
+        int32_t sam_A, sam_B;
+
+        if (dpp->value & 1) {
+            sam_A = 2 * dpp->samplesA[0] - dpp->samplesA[1];
+            sam_B = 2 * dpp->samplesB[0] - dpp->samplesB[1];
+        } else {
+            sam_A = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1;
+            sam_B = (3 * dpp->samplesB[0] - dpp->samplesB[1]) >> 1;
+        }
+
+        dpp->samplesA[1] = dpp->samplesA[0];
+        dpp->samplesB[1] = dpp->samplesB[0];
+        dpp->samplesA[0] = sam_A;
+        dpp->samplesB[0] = sam_B;
+
+        if (dpp->value & 1) {
+            sam_A = 2 * dpp->samplesA[0] - dpp->samplesA[1];
+            sam_B = 2 * dpp->samplesB[0] - dpp->samplesB[1];
+        } else {
+            sam_A = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1;
+            sam_B = (3 * dpp->samplesB[0] - dpp->samplesB[1]) >> 1;
+        }
+
+        dpp->samplesA[1] = sam_A;
+        dpp->samplesB[1] = sam_B;
+    } else if (dpp->value > 1) {
+        int i, j, k;
+
+        for (i = 0, j = dpp->value - 1, k = 0; k < dpp->value / 2; i++, j--, k++) {
+            i &= (MAX_TERM - 1);
+            j &= (MAX_TERM - 1);
+            dpp->samplesA[i] ^= dpp->samplesA[j];
+            dpp->samplesA[j] ^= dpp->samplesA[i];
+            dpp->samplesA[i] ^= dpp->samplesA[j];
+            dpp->samplesB[i] ^= dpp->samplesB[j];
+            dpp->samplesB[j] ^= dpp->samplesB[i];
+            dpp->samplesB[i] ^= dpp->samplesB[j];
+        }
+    }
+}
+
+static void decorr_stereo_quick(int32_t *in_left,  int32_t *in_right,
+                                int32_t *out_left, int32_t *out_right,
+                                int nb_samples, struct Decorr *dpp)
+{
+    int m = 0, i;
+
+    dpp->weightA = restore_weight(store_weight(dpp->weightA));
+    dpp->weightB = restore_weight(store_weight(dpp->weightB));
+
+    for (i = 0; i < MAX_TERM; i++) {
+        dpp->samplesA[i] = wp_exp2(log2s(dpp->samplesA[i]));
+        dpp->samplesB[i] = wp_exp2(log2s(dpp->samplesB[i]));
+    }
+
+    switch (dpp->value) {
+    case 2:
+        for (i = 0; i < nb_samples; i++) {
+            int32_t sam, tmp;
+
+            sam = dpp->samplesA[0];
+            dpp->samplesA[0] = dpp->samplesA[1];
+            out_left[i] = tmp = (dpp->samplesA[1] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
+            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
+
+            sam = dpp->samplesB[0];
+            dpp->samplesB[0] = dpp->samplesB[1];
+            out_right[i] = tmp = (dpp->samplesB[1] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
+            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
+        }
+        break;
+    case 17:
+        for (i = 0; i < nb_samples; i++) {
+            int32_t sam, tmp;
+
+            sam = 2 * dpp->samplesA[0] - dpp->samplesA[1];
+            dpp->samplesA[1] = dpp->samplesA[0];
+            out_left[i] = tmp = (dpp->samplesA[0] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
+            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
+
+            sam = 2 * dpp->samplesB[0] - dpp->samplesB[1];
+            dpp->samplesB[1] = dpp->samplesB[0];
+            out_right[i] = tmp = (dpp->samplesB[0] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
+            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
+        }
+        break;
+    case 18:
+        for (i = 0; i < nb_samples; i++) {
+            int32_t sam, tmp;
+
+            sam = dpp->samplesA[0] + ((dpp->samplesA[0] - dpp->samplesA[1]) >> 1);
+            dpp->samplesA[1] = dpp->samplesA[0];
+            out_left[i] = tmp = (dpp->samplesA[0] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
+            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
+
+            sam = dpp->samplesB[0] + ((dpp->samplesB[0] - dpp->samplesB[1]) >> 1);
+            dpp->samplesB[1] = dpp->samplesB[0];
+            out_right[i] = tmp = (dpp->samplesB[0] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
+            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
+        }
+        break;
+    default: {
+        int k = dpp->value & (MAX_TERM - 1);
+
+        for (i = 0; i < nb_samples; i++) {
+            int32_t sam, tmp;
+
+            sam = dpp->samplesA[m];
+            out_left[i] = tmp = (dpp->samplesA[k] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
+            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
+
+            sam = dpp->samplesB[m];
+            out_right[i] = tmp = (dpp->samplesB[k] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
+            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
+
+            m = (m + 1) & (MAX_TERM - 1);
+            k = (k + 1) & (MAX_TERM - 1);
+        }
+
+        if (m) {
+            int32_t temp_A[MAX_TERM], temp_B[MAX_TERM];
+            int k;
+
+            memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA));
+            memcpy(temp_B, dpp->samplesB, sizeof(dpp->samplesB));
+
+            for (k = 0; k < MAX_TERM; k++) {
+                dpp->samplesA[k] = temp_A[m];
+                dpp->samplesB[k] = temp_B[m];
+                m = (m + 1) & (MAX_TERM - 1);
+            }
+        }
+        break;
+    }
+    case -1:
+        for (i = 0; i < nb_samples; i++) {
+            int32_t sam_A, sam_B, tmp;
+
+            sam_A = dpp->samplesA[0];
+            out_left[i] = tmp = (sam_B = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam_A);
+            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
+
+            out_right[i] = tmp = (dpp->samplesA[0] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam_B);
+            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
+        }
+        break;
+    case -2:
+        for (i = 0; i < nb_samples; i++) {
+            int32_t sam_A, sam_B, tmp;
+
+            sam_B = dpp->samplesB[0];
+            out_right[i] = tmp = (sam_A = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam_B);
+            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
+
+            out_left[i] = tmp = (dpp->samplesB[0] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam_A);
+            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
+        }
+        break;
+    case -3:
+        for (i = 0; i < nb_samples; i++) {
+            int32_t sam_A, sam_B, tmp;
+
+            sam_A = dpp->samplesA[0];
+            sam_B = dpp->samplesB[0];
+
+            dpp->samplesA[0] = tmp = in_right[i];
+            out_right[i] = tmp -= APPLY_WEIGHT_I(dpp->weightB, sam_B);
+            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
+
+            dpp->samplesB[0] = tmp = in_left[i];
+            out_left[i] = tmp -= APPLY_WEIGHT_I(dpp->weightA, sam_A);
+            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
+        }
+        break;
+    }
+}
+
+static void decorr_stereo_buffer(WavPackExtraInfo *info,
+                                 int32_t *in_left,  int32_t *in_right,
+                                 int32_t *out_left, int32_t *out_right,
+                                 int nb_samples, int tindex)
+{
+    struct Decorr dp = {0}, *dppi = info->dps + tindex;
+    int delta = dppi->delta, pre_delta;
+    int term = dppi->value;
+
+    if (delta == 7)
+        pre_delta = 7;
+    else if (delta < 2)
+        pre_delta = 3;
+    else
+        pre_delta = delta + 1;
+
+    dp.value = term;
+    dp.delta = pre_delta;
+    decorr_stereo(in_left, in_right, out_left, out_right,
+                  FFMIN(2048, nb_samples), &dp, -1);
+    dp.delta = delta;
+
+    if (tindex == 0) {
+        reverse_decorr(&dp);
+    } else {
+        CLEAR(dp.samplesA);
+        CLEAR(dp.samplesB);
+    }
+
+    memcpy(dppi->samplesA, dp.samplesA, sizeof(dp.samplesA));
+    memcpy(dppi->samplesB, dp.samplesB, sizeof(dp.samplesB));
+    dppi->weightA = dp.weightA;
+    dppi->weightB = dp.weightB;
+
+    if (delta == 0) {
+        dp.delta = 1;
+        decorr_stereo(in_left, in_right, out_left, out_right, nb_samples, &dp, 1);
+        dp.delta = 0;
+        memcpy(dp.samplesA, dppi->samplesA, sizeof(dp.samplesA));
+        memcpy(dp.samplesB, dppi->samplesB, sizeof(dp.samplesB));
+        dppi->weightA = dp.weightA = dp.sumA / nb_samples;
+        dppi->weightB = dp.weightB = dp.sumB / nb_samples;
+    }
+
+    if (info->gt16bit)
+        decorr_stereo(in_left, in_right, out_left, out_right,
+                           nb_samples, &dp, 1);
+    else
+        decorr_stereo_quick(in_left, in_right, out_left, out_right,
+                            nb_samples, &dp);
+}
+
+static void sort_stereo(WavPackEncodeContext *s, WavPackExtraInfo *info)
+{
+    int reversed = 1;
+    uint32_t bits;
+
+    while (reversed) {
+        int ri, i;
+
+        memcpy(info->dps, s->decorr_passes, sizeof(s->decorr_passes));
+        reversed = 0;
+
+        for (ri = 0; ri < info->nterms && s->decorr_passes[ri].value; ri++) {
+
+            if (ri + 1 >= info->nterms || !s->decorr_passes[ri+1].value)
+                break;
+
+            if (s->decorr_passes[ri].value == s->decorr_passes[ri+1].value) {
+                decorr_stereo_buffer(info,
+                                     s->sampleptrs[ri  ][0], s->sampleptrs[ri  ][1],
+                                     s->sampleptrs[ri+1][0], s->sampleptrs[ri+1][1],
+                                     s->block_samples, ri);
+                continue;
+            }
+
+            info->dps[ri  ] = s->decorr_passes[ri+1];
+            info->dps[ri+1] = s->decorr_passes[ri  ];
+
+            for (i = ri; i < info->nterms && s->decorr_passes[i].value; i++)
+                decorr_stereo_buffer(info,
+                                     s->sampleptrs[i  ][0], s->sampleptrs[i  ][1],
+                                     s->sampleptrs[i+1][0], s->sampleptrs[i+1][1],
+                                     s->block_samples, i);
+
+            bits = log2stereo(s->sampleptrs[i][0], s->sampleptrs[i][1],
+                              s->block_samples, info->log_limit);
+
+            if (bits < info->best_bits) {
+                reversed = 1;
+                info->best_bits = bits;
+                CLEAR(s->decorr_passes);
+                memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i);
+                memcpy(s->sampleptrs[info->nterms + 1][0],
+                       s->sampleptrs[i][0], s->block_samples * 4);
+                memcpy(s->sampleptrs[info->nterms + 1][1],
+                       s->sampleptrs[i][1], s->block_samples * 4);
+            } else {
+                info->dps[ri  ] = s->decorr_passes[ri  ];
+                info->dps[ri+1] = s->decorr_passes[ri+1];
+                decorr_stereo_buffer(info,
+                                     s->sampleptrs[ri  ][0], s->sampleptrs[ri  ][1],
+                                     s->sampleptrs[ri+1][0], s->sampleptrs[ri+1][1],
+                                     s->block_samples, ri);
+            }
+        }
+    }
+}
+
+static void delta_stereo(WavPackEncodeContext *s, WavPackExtraInfo *info)
+{
+    int lower = 0, delta, d, i;
+    uint32_t bits;
+
+    if (!s->decorr_passes[0].value)
+        return;
+    delta = s->decorr_passes[0].delta;
+
+    for (d = delta - 1; d >= 0; d--) {
+        for (i = 0; i < info->nterms && s->decorr_passes[i].value; i++) {
+            info->dps[i].value = s->decorr_passes[i].value;
+            info->dps[i].delta = d;
+            decorr_stereo_buffer(info,
+                                 s->sampleptrs[i  ][0], s->sampleptrs[i  ][1],
+                                 s->sampleptrs[i+1][0], s->sampleptrs[i+1][1],
+                                 s->block_samples, i);
+        }
+
+        bits = log2stereo(s->sampleptrs[i][0], s->sampleptrs[i][1],
+                          s->block_samples, info->log_limit);
+        if (bits >= info->best_bits)
+            break;
+        lower = 1;
+        info->best_bits = bits;
+        CLEAR(s->decorr_passes);
+        memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i);
+        memcpy(s->sampleptrs[info->nterms + 1][0], s->sampleptrs[i][0],
+               s->block_samples * 4);
+        memcpy(s->sampleptrs[info->nterms + 1][1], s->sampleptrs[i][1],
+               s->block_samples * 4);
+    }
+
+    for (d = delta + 1; !lower && d <= 7; d++) {
+        for (i = 0; i < info->nterms && s->decorr_passes[i].value; i++) {
+            info->dps[i].value = s->decorr_passes[i].value;
+            info->dps[i].delta = d;
+            decorr_stereo_buffer(info,
+                                 s->sampleptrs[i  ][0], s->sampleptrs[i  ][1],
+                                 s->sampleptrs[i+1][0], s->sampleptrs[i+1][1],
+                                 s->block_samples, i);
+        }
+
+        bits = log2stereo(s->sampleptrs[i][0], s->sampleptrs[i][1],
+                          s->block_samples, info->log_limit);
+
+        if (bits < info->best_bits) {
+            info->best_bits = bits;
+            CLEAR(s->decorr_passes);
+            memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i);
+            memcpy(s->sampleptrs[info->nterms + 1][0],
+                   s->sampleptrs[i][0], s->block_samples * 4);
+            memcpy(s->sampleptrs[info->nterms + 1][1],
+                   s->sampleptrs[i][1], s->block_samples * 4);
+        }
+        else
+            break;
+    }
+}
+
+static void recurse_stereo(WavPackEncodeContext *s, WavPackExtraInfo *info,
+                           int depth, int delta, uint32_t input_bits)
+{
+    int term, branches = s->num_branches - depth;
+    int32_t *in_left, *in_right, *out_left, *out_right;
+    uint32_t term_bits[22], bits;
+
+    if (branches < 1 || depth + 1 == info->nterms)
+        branches = 1;
+
+    CLEAR(term_bits);
+    in_left   = s->sampleptrs[depth    ][0];
+    in_right  = s->sampleptrs[depth    ][1];
+    out_left  = s->sampleptrs[depth + 1][0];
+    out_right = s->sampleptrs[depth + 1][1];
+
+    for (term = -3; term <= 18; term++) {
+        if (!term || (term > 8 && term < 17))
+            continue;
+
+        if (term == 17 && branches == 1 && depth + 1 < info->nterms)
+            continue;
+
+        if (term == -1 || term == -2)
+            if (!(s->flags & WV_CROSS_DECORR))
+                continue;
+
+        if (!s->extra_flags && (term > 4 && term < 17))
+            continue;
+
+        info->dps[depth].value = term;
+        info->dps[depth].delta = delta;
+        decorr_stereo_buffer(info, in_left, in_right, out_left, out_right,
+                             s->block_samples, depth);
+        bits = log2stereo(out_left, out_right, s->block_samples, info->log_limit);
+
+        if (bits < info->best_bits) {
+            info->best_bits = bits;
+            CLEAR(s->decorr_passes);
+            memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * (depth + 1));
+            memcpy(s->sampleptrs[info->nterms + 1][0], s->sampleptrs[depth + 1][0],
+                   s->block_samples * 4);
+            memcpy(s->sampleptrs[info->nterms + 1][1], s->sampleptrs[depth + 1][1],
+                   s->block_samples * 4);
+        }
+
+        term_bits[term + 3] = bits;
+    }
+
+    while (depth + 1 < info->nterms && branches--) {
+        uint32_t local_best_bits = input_bits;
+        int best_term = 0, i;
+
+        for (i = 0; i < 22; i++)
+            if (term_bits[i] && term_bits[i] < local_best_bits) {
+                local_best_bits = term_bits[i];
+                best_term = i - 3;
+            }
+
+        if (!best_term)
+            break;
+
+        term_bits[best_term + 3] = 0;
+
+        info->dps[depth].value = best_term;
+        info->dps[depth].delta = delta;
+        decorr_stereo_buffer(info, in_left, in_right, out_left, out_right,
+                             s->block_samples, depth);
+
+        recurse_stereo(s, info, depth + 1, delta, local_best_bits);
+    }
+}
+
+static void analyze_stereo(WavPackEncodeContext *s,
+                           int32_t *in_left, int32_t *in_right,
+                           int do_samples)
+{
+    WavPackExtraInfo info;
+    int i;
+
+    info.gt16bit = ((s->flags & MAG_MASK) >> MAG_LSB) >= 16;
+
+    info.log_limit = (((s->flags & MAG_MASK) >> MAG_LSB) + 4) * 256;
+    info.log_limit = FFMIN(6912, info.log_limit);
+
+    info.nterms = s->num_terms;
+
+    if (allocate_buffers2(s, s->num_terms))
+        return;
+
+    memcpy(info.dps, s->decorr_passes, sizeof(info.dps));
+    memcpy(s->sampleptrs[0][0], in_left,  s->block_samples * 4);
+    memcpy(s->sampleptrs[0][1], in_right, s->block_samples * 4);
+
+    for (i = 0; i < info.nterms && info.dps[i].value; i++)
+        if (info.gt16bit)
+            decorr_stereo(s->sampleptrs[i    ][0], s->sampleptrs[i    ][1],
+                          s->sampleptrs[i + 1][0], s->sampleptrs[i + 1][1],
+                          s->block_samples, info.dps + i, 1);
+        else
+            decorr_stereo_quick(s->sampleptrs[i    ][0], s->sampleptrs[i    ][1],
+                                s->sampleptrs[i + 1][0], s->sampleptrs[i + 1][1],
+                                s->block_samples, info.dps + i);
+
+    info.best_bits = log2stereo(s->sampleptrs[info.nterms][0], s->sampleptrs[info.nterms][1],
+                                s->block_samples, 0);
+
+    memcpy(s->sampleptrs[info.nterms + 1][0], s->sampleptrs[i][0], s->block_samples * 4);
+    memcpy(s->sampleptrs[info.nterms + 1][1], s->sampleptrs[i][1], s->block_samples * 4);
+
+    if (s->extra_flags & EXTRA_BRANCHES)
+        recurse_stereo(s, &info, 0, (int) floor(s->delta_decay + 0.5),
+                       log2stereo(s->sampleptrs[0][0], s->sampleptrs[0][1],
+                                  s->block_samples, 0));
+
+    if (s->extra_flags & EXTRA_SORT_FIRST)
+        sort_stereo(s, &info);
+
+    if (s->extra_flags & EXTRA_TRY_DELTAS) {
+        delta_stereo(s, &info);
+
+        if ((s->extra_flags & EXTRA_ADJUST_DELTAS) && s->decorr_passes[0].value)
+            s->delta_decay = (float)((s->delta_decay * 2.0 + s->decorr_passes[0].delta) / 3.0);
+        else
+            s->delta_decay = 2.0;
+    }
+
+    if (s->extra_flags & EXTRA_SORT_LAST)
+        sort_stereo(s, &info);
+
+    if (do_samples) {
+        memcpy(in_left,  s->sampleptrs[info.nterms + 1][0], s->block_samples * 4);
+        memcpy(in_right, s->sampleptrs[info.nterms + 1][1], s->block_samples * 4);
+    }
+
+    for (i = 0; i < info.nterms; i++)
+        if (!s->decorr_passes[i].value)
+            break;
+
+    s->num_terms = i;
+}
+
+static int wv_stereo(WavPackEncodeContext *s,
+                     int32_t *samples_l, int32_t *samples_r,
+                     int no_history, int do_samples)
+{
+    struct Decorr temp_decorr_pass, save_decorr_passes[MAX_TERMS] = {{0}};
+    int nb_samples = s->block_samples, ret;
+    int buf_size = sizeof(int32_t) * nb_samples;
+    int log_limit, force_js = 0, force_ts = 0, got_js = 0, pi, i;
+    uint32_t best_size = UINT32_MAX, size;
+
+    for (i = 0; i < nb_samples; i++)
+        if (samples_l[i] || samples_r[i])
+            break;
+
+    if (i == nb_samples) {
+        s->flags &= ~((uint32_t) WV_JOINT_STEREO);
+        CLEAR(s->decorr_passes);
+        CLEAR(s->w);
+        s->num_terms = 0;
+        return 0;
+    }
+
+    log_limit = (((s->flags & MAG_MASK) >> MAG_LSB) + 4) * 256;
+    log_limit = FFMIN(6912, log_limit);
+
+    if (s->joint) {
+        force_js = s->joint > 0;
+        force_ts = s->joint < 0;
+    }
+
+    if ((ret = allocate_buffers(s)) < 0)
+        return ret;
+
+    if (no_history || s->num_passes >= 7)
+        s->best_decorr = s->mask_decorr = 0;
+
+    for (pi = 0; pi < s->num_passes;) {
+        const WavPackDecorrSpec *wpds;
+        int nterms, c, j;
+
+        if (!pi)
+            c = s->best_decorr;
+        else {
+            if (s->mask_decorr == 0)
+                c = 0;
+            else
+                c = (s->best_decorr & (s->mask_decorr - 1)) | s->mask_decorr;
+
+            if (c == s->best_decorr) {
+                s->mask_decorr = s->mask_decorr ? ((s->mask_decorr << 1) & (s->num_decorrs - 1)) : 1;
+                continue;
+            }
+        }
+
+        wpds = &s->decorr_specs[c];
+        nterms = decorr_filter_nterms[s->decorr_filter];
+
+        while (1) {
+            if (force_js || (wpds->joint_stereo && !force_ts)) {
+                if (!got_js) {
+                    av_fast_padded_malloc(&s->js_left,  &s->js_left_size,  buf_size);
+                    av_fast_padded_malloc(&s->js_right, &s->js_right_size, buf_size);
+                    memcpy(s->js_left,  samples_l, buf_size);
+                    memcpy(s->js_right, samples_r, buf_size);
+
+                    for (i = 0; i < nb_samples; i++)
+                        s->js_right[i] += ((s->js_left[i] -= s->js_right[i]) >> 1);
+                    got_js = 1;
+                }
+
+                memcpy(s->temp_buffer[0][0], s->js_left,  buf_size);
+                memcpy(s->temp_buffer[0][1], s->js_right, buf_size);
+            } else {
+                memcpy(s->temp_buffer[0][0], samples_l, buf_size);
+                memcpy(s->temp_buffer[0][1], samples_r, buf_size);
+            }
+
+            CLEAR(save_decorr_passes);
+
+            for (j = 0; j < nterms; j++) {
+                CLEAR(temp_decorr_pass);
+                temp_decorr_pass.delta = wpds->delta;
+                temp_decorr_pass.value = wpds->terms[j];
+
+                if (temp_decorr_pass.value < 0 && !(s->flags & WV_CROSS_DECORR))
+                    temp_decorr_pass.value = -3;
+
+                decorr_stereo(s->temp_buffer[ j&1][0], s->temp_buffer[ j&1][1],
+                              s->temp_buffer[~j&1][0], s->temp_buffer[~j&1][1],
+                              FFMIN(2048, nb_samples), &temp_decorr_pass, -1);
+
+                if (j) {
+                    CLEAR(temp_decorr_pass.samplesA);
+                    CLEAR(temp_decorr_pass.samplesB);
+                } else {
+                    reverse_decorr(&temp_decorr_pass);
+                }
+
+                memcpy(save_decorr_passes + j, &temp_decorr_pass, sizeof(struct Decorr));
+
+                if (((s->flags & MAG_MASK) >> MAG_LSB) >= 16)
+                    decorr_stereo(s->temp_buffer[ j&1][0], s->temp_buffer[ j&1][1],
+                                  s->temp_buffer[~j&1][0], s->temp_buffer[~j&1][1],
+                                  nb_samples, &temp_decorr_pass, 1);
+                else
+                    decorr_stereo_quick(s->temp_buffer[ j&1][0], s->temp_buffer[ j&1][1],
+                                        s->temp_buffer[~j&1][0], s->temp_buffer[~j&1][1],
+                                        nb_samples, &temp_decorr_pass);
+            }
+
+            size = log2stereo(s->temp_buffer[j&1][0], s->temp_buffer[j&1][1],
+                              nb_samples, log_limit);
+            if (size != UINT32_MAX || !nterms)
+                break;
+            nterms >>= 1;
+        }
+
+        if (size < best_size) {
+            memcpy(s->best_buffer[0], s->temp_buffer[j&1][0], buf_size);
+            memcpy(s->best_buffer[1], s->temp_buffer[j&1][1], buf_size);
+            memcpy(s->decorr_passes, save_decorr_passes, sizeof(struct Decorr) * MAX_TERMS);
+            s->num_terms = nterms;
+            s->best_decorr = c;
+            best_size = size;
+        }
+
+        if (pi++)
+            s->mask_decorr = s->mask_decorr ? ((s->mask_decorr << 1) & (s->num_decorrs - 1)) : 1;
+    }
+
+    if (force_js || (s->decorr_specs[s->best_decorr].joint_stereo && !force_ts))
+        s->flags |= WV_JOINT_STEREO;
+    else
+        s->flags &= ~((uint32_t) WV_JOINT_STEREO);
+
+    if (s->extra_flags) {
+        if (s->flags & WV_JOINT_STEREO) {
+            analyze_stereo(s, s->js_left, s->js_right, do_samples);
+
+            if (do_samples) {
+                memcpy(samples_l, s->js_left,  buf_size);
+                memcpy(samples_r, s->js_right, buf_size);
+            }
+        } else
+            analyze_stereo(s, samples_l, samples_r, do_samples);
+    } else if (do_samples) {
+        memcpy(samples_l, s->best_buffer[0], buf_size);
+        memcpy(samples_r, s->best_buffer[1], buf_size);
+    }
+
+    if (s->extra_flags || no_history ||
+        s->joint_stereo != s->decorr_specs[s->best_decorr].joint_stereo) {
+        s->joint_stereo = s->decorr_specs[s->best_decorr].joint_stereo;
+        CLEAR(s->w);
+        scan_word(s, &s->w.c[0], s->best_buffer[0], nb_samples, -1);
+        scan_word(s, &s->w.c[1], s->best_buffer[1], nb_samples, -1);
+    }
+    return 0;
+}
+
+#define count_bits(av) ( \
+ (av) < (1 << 8) ? nbits_table[av] : \
+  ( \
+   (av) < (1L << 16) ? nbits_table[(av) >> 8] + 8 : \
+   ((av) < (1L << 24) ? nbits_table[(av) >> 16] + 16 : nbits_table[(av) >> 24] + 24) \
+  ) \
+)
+
+static void encode_flush(WavPackEncodeContext *s)
+{
+    WavPackWords *w = &s->w;
+    PutBitContext *pb = &s->pb;
+
+    if (w->zeros_acc) {
+        int cbits = count_bits(w->zeros_acc);
+
+        do {
+            if (cbits > 31) {
+                put_bits(pb, 31, 0x7FFFFFFF);
+                cbits -= 31;
+            } else {
+                put_bits(pb, cbits, (1 << cbits) - 1);
+                cbits = 0;
+            }
+        } while (cbits);
+
+        put_bits(pb, 1, 0);
+
+        while (w->zeros_acc > 1) {
+            put_bits(pb, 1, w->zeros_acc & 1);
+            w->zeros_acc >>= 1;
+        }
+
+        w->zeros_acc = 0;
+    }
+
+    if (w->holding_one) {
+        if (w->holding_one >= 16) {
+            int cbits;
+
+            put_bits(pb, 16, (1 << 16) - 1);
+            put_bits(pb, 1, 0);
+            w->holding_one -= 16;
+            cbits = count_bits(w->holding_one);
+
+            do {
+                if (cbits > 31) {
+                    put_bits(pb, 31, 0x7FFFFFFF);
+                    cbits -= 31;
+                } else {
+                    put_bits(pb, cbits, (1 << cbits) - 1);
+                    cbits = 0;
+                }
+            } while (cbits);
+
+            put_bits(pb, 1, 0);
+
+            while (w->holding_one > 1) {
+                put_bits(pb, 1, w->holding_one & 1);
+                w->holding_one >>= 1;
+            }
+
+            w->holding_zero = 0;
+        } else {
+            put_bits(pb, w->holding_one, (1 << w->holding_one) - 1);
+        }
+
+        w->holding_one = 0;
+    }
+
+    if (w->holding_zero) {
+        put_bits(pb, 1, 0);
+        w->holding_zero = 0;
+    }
+
+    if (w->pend_count) {
+        put_bits(pb, w->pend_count, w->pend_data);
+        w->pend_data = w->pend_count = 0;
+    }
+}
+
+static void wavpack_encode_sample(WavPackEncodeContext *s, WvChannel *c, int32_t sample)
+{
+    WavPackWords *w = &s->w;
+    uint32_t ones_count, low, high;
+    int sign = sample < 0;
+
+    if (s->w.c[0].median[0] < 2 && !s->w.holding_zero && s->w.c[1].median[0] < 2) {
+        if (w->zeros_acc) {
+            if (sample)
+                encode_flush(s);
+            else {
+                w->zeros_acc++;
+                return;
+            }
+        } else if (sample) {
+            put_bits(&s->pb, 1, 0);
+        } else {
+            CLEAR(s->w.c[0].median);
+            CLEAR(s->w.c[1].median);
+            w->zeros_acc = 1;
+            return;
+        }
+    }
+
+    if (sign)
+        sample = ~sample;
+
+    if (sample < (int32_t) GET_MED(0)) {
+        ones_count = low = 0;
+        high = GET_MED(0) - 1;
+        DEC_MED(0);
+    } else {
+        low = GET_MED(0);
+        INC_MED(0);
+
+        if (sample - low < GET_MED(1)) {
+            ones_count = 1;
+            high = low + GET_MED(1) - 1;
+            DEC_MED(1);
+        } else {
+            low += GET_MED(1);
+            INC_MED(1);
+
+            if (sample - low < GET_MED(2)) {
+                ones_count = 2;
+                high = low + GET_MED(2) - 1;
+                DEC_MED(2);
+            } else {
+                ones_count = 2 + (sample - low) / GET_MED(2);
+                low += (ones_count - 2) * GET_MED(2);
+                high = low + GET_MED(2) - 1;
+                INC_MED(2);
+            }
+        }
+    }
+
+    if (w->holding_zero) {
+        if (ones_count)
+            w->holding_one++;
+
+        encode_flush(s);
+
+        if (ones_count) {
+            w->holding_zero = 1;
+            ones_count--;
+        } else
+            w->holding_zero = 0;
+    } else
+        w->holding_zero = 1;
+
+    w->holding_one = ones_count * 2;
+
+    if (high != low) {
+        uint32_t maxcode = high - low, code = sample - low;
+        int bitcount = count_bits(maxcode);
+        uint32_t extras = (1 << bitcount) - maxcode - 1;
+
+        if (code < extras) {
+            w->pend_data |= code << w->pend_count;
+            w->pend_count += bitcount - 1;
+        } else {
+            w->pend_data |= ((code + extras) >> 1) << w->pend_count;
+            w->pend_count += bitcount - 1;
+            w->pend_data |= ((code + extras) & 1) << w->pend_count++;
+        }
+    }
+
+    w->pend_data |= ((int32_t) sign << w->pend_count++);
+
+    if (!w->holding_zero)
+        encode_flush(s);
+}
+
+static void pack_int32(WavPackEncodeContext *s,
+                       int32_t *samples_l, int32_t *samples_r,
+                       int nb_samples)
+{
+    const int sent_bits = s->int32_sent_bits;
+    int32_t value, mask = (1 << sent_bits) - 1;
+    PutBitContext *pb = &s->pb;
+    int i, pre_shift;
+
+    pre_shift = s->int32_zeros + s->int32_ones + s->int32_dups;
+
+    if (!sent_bits)
+        return;
+
+    if (s->flags & WV_MONO_DATA) {
+        for (i = 0; i < nb_samples; i++) {
+            value = (samples_l[i] >> pre_shift) & mask;
+            put_bits(pb, sent_bits, value);
+        }
+    } else {
+        for (i = 0; i < nb_samples; i++) {
+            value = (samples_l[i] >> pre_shift) & mask;
+            put_bits(pb, sent_bits, value);
+            value = (samples_r[i] >> pre_shift) & mask;
+            put_bits(pb, sent_bits, value);
+        }
+    }
+}
+
+static void pack_float_sample(WavPackEncodeContext *s, int32_t *sample)
+{
+    const int max_exp = s->float_max_exp;
+    PutBitContext *pb = &s->pb;
+    int32_t value, shift_count;
+
+    if (get_exponent(*sample) == 255) {
+        if (get_mantissa(*sample)) {
+            put_bits(pb, 1, 1);
+            put_bits(pb, 23, get_mantissa(*sample));
+        } else {
+            put_bits(pb, 1, 0);
+        }
+
+        value = 0x1000000;
+        shift_count = 0;
+    } else if (get_exponent(*sample)) {
+        shift_count = max_exp - get_exponent(*sample);
+        value = 0x800000 + get_mantissa(*sample);
+    } else {
+        shift_count = max_exp ? max_exp - 1 : 0;
+        value = get_mantissa(*sample);
+    }
+
+    if (shift_count < 25)
+        value >>= shift_count;
+    else
+        value = 0;
+
+    if (!value) {
+        if (s->float_flags & FLOAT_ZEROS_SENT) {
+            if (get_exponent(*sample) || get_mantissa(*sample)) {
+                put_bits(pb, 1, 1);
+                put_bits(pb, 23, get_mantissa(*sample));
+
+                if (max_exp >= 25)
+                    put_bits(pb, 8, get_exponent(*sample));
+
+                put_bits(pb, 1, get_sign(*sample));
+            } else {
+                put_bits(pb, 1, 0);
+
+                if (s->float_flags & FLOAT_NEG_ZEROS)
+                    put_bits(pb, 1, get_sign(*sample));
+            }
+        }
+    } else if (shift_count) {
+        if (s->float_flags & FLOAT_SHIFT_SENT) {
+            int32_t data = get_mantissa(*sample) & ((1 << shift_count) - 1);
+            put_bits(pb, shift_count, data);
+        } else if (s->float_flags & FLOAT_SHIFT_SAME) {
+            put_bits(pb, 1, get_mantissa(*sample) & 1);
+        }
+    }
+}
+
+static void pack_float(WavPackEncodeContext *s,
+                       int32_t *samples_l, int32_t *samples_r,
+                       int nb_samples)
+{
+    int i;
+
+    if (s->flags & WV_MONO_DATA) {
+        for (i = 0; i < nb_samples; i++)
+            pack_float_sample(s, &samples_l[i]);
+    } else {
+        for (i = 0; i < nb_samples; i++) {
+            pack_float_sample(s, &samples_l[i]);
+            pack_float_sample(s, &samples_r[i]);
+        }
+    }
+}
+
+static void decorr_stereo_pass2(struct Decorr *dpp,
+                                int32_t *samples_l, int32_t *samples_r,
+                                int nb_samples)
+{
+    int i, m, k;
+
+    switch (dpp->value) {
+    case 17:
+        for (i = 0; i < nb_samples; i++) {
+            int32_t sam, tmp;
+
+            sam = 2 * dpp->samplesA[0] - dpp->samplesA[1];
+            dpp->samplesA[1] = dpp->samplesA[0];
+            samples_l[i] = tmp = (dpp->samplesA[0] = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam);
+            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
+
+            sam = 2 * dpp->samplesB[0] - dpp->samplesB[1];
+            dpp->samplesB[1] = dpp->samplesB[0];
+            samples_r[i] = tmp = (dpp->samplesB[0] = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam);
+            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
+        }
+        break;
+    case 18:
+        for (i = 0; i < nb_samples; i++) {
+            int32_t sam, tmp;
+
+            sam = dpp->samplesA[0] + ((dpp->samplesA[0] - dpp->samplesA[1]) >> 1);
+            dpp->samplesA[1] = dpp->samplesA[0];
+            samples_l[i] = tmp = (dpp->samplesA[0] = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam);
+            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
+
+            sam = dpp->samplesB[0] + ((dpp->samplesB[0] - dpp->samplesB[1]) >> 1);
+            dpp->samplesB[1] = dpp->samplesB[0];
+            samples_r[i] = tmp = (dpp->samplesB[0] = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam);
+            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
+        }
+        break;
+    default:
+        for (m = 0, k = dpp->value & (MAX_TERM - 1), i = 0; i < nb_samples; i++) {
+            int32_t sam, tmp;
+
+            sam = dpp->samplesA[m];
+            samples_l[i] = tmp = (dpp->samplesA[k] = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam);
+            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
+
+            sam = dpp->samplesB[m];
+            samples_r[i] = tmp = (dpp->samplesB[k] = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam);
+            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
+
+            m = (m + 1) & (MAX_TERM - 1);
+            k = (k + 1) & (MAX_TERM - 1);
+        }
+        if (m) {
+            int32_t temp_A[MAX_TERM], temp_B[MAX_TERM];
+
+            memcpy(temp_A, dpp->samplesA, sizeof (dpp->samplesA));
+            memcpy(temp_B, dpp->samplesB, sizeof (dpp->samplesB));
+
+            for (k = 0; k < MAX_TERM; k++) {
+                dpp->samplesA[k] = temp_A[m];
+                dpp->samplesB[k] = temp_B[m];
+                m = (m + 1) & (MAX_TERM - 1);
+            }
+        }
+        break;
+    case -1:
+        for (i = 0; i < nb_samples; i++) {
+            int32_t sam_A, sam_B, tmp;
+
+            sam_A = dpp->samplesA[0];
+            samples_l[i] = tmp = (sam_B = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam_A);
+            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
+
+            samples_r[i] = tmp = (dpp->samplesA[0] = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam_B);
+            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
+        }
+        break;
+    case -2:
+        for (i = 0; i < nb_samples; i++) {
+            int32_t sam_A, sam_B, tmp;
+
+            sam_B = dpp->samplesB[0];
+            samples_r[i] = tmp = (sam_A = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam_B);
+            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
+
+            samples_l[i] = tmp = (dpp->samplesB[0] = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam_A);
+            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
+        }
+        break;
+    case -3:
+        for (i = 0; i < nb_samples; i++) {
+            int32_t sam_A, sam_B, tmp;
+
+            sam_A = dpp->samplesA[0];
+            sam_B = dpp->samplesB[0];
+
+            dpp->samplesA[0] = tmp = samples_r[i];
+            samples_r[i] = tmp -= APPLY_WEIGHT(dpp->weightB, sam_B);
+            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
+
+            dpp->samplesB[0] = tmp = samples_l[i];
+            samples_l[i] = tmp -= APPLY_WEIGHT(dpp->weightA, sam_A);
+            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
+        }
+        break;
+    }
+}
+
+#define update_weight_d2(weight, delta, source, result) \
+    if (source && result) \
+        weight -= (((source ^ result) >> 29) & 4) - 2;
+
+#define update_weight_clip_d2(weight, delta, source, result) \
+    if (source && result) { \
+        const int32_t s = (source ^ result) >> 31; \
+        if ((weight = (weight ^ s) + (2 - s)) > 1024) weight = 1024; \
+        weight = (weight ^ s) - s; \
+    }
+
+static void decorr_stereo_pass_id2(struct Decorr *dpp,
+                                   int32_t *samples_l, int32_t *samples_r,
+                                   int nb_samples)
+{
+    int i, m, k;
+
+    switch (dpp->value) {
+    case 17:
+        for (i = 0; i < nb_samples; i++) {
+            int32_t sam, tmp;
+
+            sam = 2 * dpp->samplesA[0] - dpp->samplesA[1];
+            dpp->samplesA[1] = dpp->samplesA[0];
+            samples_l[i] = tmp = (dpp->samplesA[0] = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
+            update_weight_d2(dpp->weightA, dpp->delta, sam, tmp);
+
+            sam = 2 * dpp->samplesB[0] - dpp->samplesB[1];
+            dpp->samplesB[1] = dpp->samplesB[0];
+            samples_r[i] = tmp = (dpp->samplesB[0] = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
+            update_weight_d2(dpp->weightB, dpp->delta, sam, tmp);
+        }
+        break;
+    case 18:
+        for (i = 0; i < nb_samples; i++) {
+            int32_t sam, tmp;
+
+            sam = dpp->samplesA[0] + ((dpp->samplesA[0] - dpp->samplesA[1]) >> 1);
+            dpp->samplesA[1] = dpp->samplesA[0];
+            samples_l[i] = tmp = (dpp->samplesA[0] = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
+            update_weight_d2(dpp->weightA, dpp->delta, sam, tmp);
+
+            sam = dpp->samplesB[0] + ((dpp->samplesB[0] - dpp->samplesB[1]) >> 1);
+            dpp->samplesB[1] = dpp->samplesB[0];
+            samples_r[i] = tmp = (dpp->samplesB[0] = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
+            update_weight_d2(dpp->weightB, dpp->delta, sam, tmp);
+        }
+        break;
+    default:
+        for (m = 0, k = dpp->value & (MAX_TERM - 1), i = 0; i < nb_samples; i++) {
+            int32_t sam, tmp;
+
+            sam = dpp->samplesA[m];
+            samples_l[i] = tmp = (dpp->samplesA[k] = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
+            update_weight_d2(dpp->weightA, dpp->delta, sam, tmp);
+
+            sam = dpp->samplesB[m];
+            samples_r[i] = tmp = (dpp->samplesB[k] = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
+            update_weight_d2(dpp->weightB, dpp->delta, sam, tmp);
+
+            m = (m + 1) & (MAX_TERM - 1);
+            k = (k + 1) & (MAX_TERM - 1);
+        }
+
+        if (m) {
+            int32_t temp_A[MAX_TERM], temp_B[MAX_TERM];
+
+            memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA));
+            memcpy(temp_B, dpp->samplesB, sizeof(dpp->samplesB));
+
+            for (k = 0; k < MAX_TERM; k++) {
+                dpp->samplesA[k] = temp_A[m];
+                dpp->samplesB[k] = temp_B[m];
+                m = (m + 1) & (MAX_TERM - 1);
+            }
+        }
+        break;
+    case -1:
+        for (i = 0; i < nb_samples; i++) {
+            int32_t sam_A, sam_B, tmp;
+
+            sam_A = dpp->samplesA[0];
+            samples_l[i] = tmp = (sam_B = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam_A);
+            update_weight_clip_d2(dpp->weightA, dpp->delta, sam_A, tmp);
+
+            samples_r[i] = tmp = (dpp->samplesA[0] = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam_B);
+            update_weight_clip_d2(dpp->weightB, dpp->delta, sam_B, tmp);
+        }
+        break;
+    case -2:
+        for (i = 0; i < nb_samples; i++) {
+            int32_t sam_A, sam_B, tmp;
+
+            sam_B = dpp->samplesB[0];
+            samples_r[i] = tmp = (sam_A = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam_B);
+            update_weight_clip_d2(dpp->weightB, dpp->delta, sam_B, tmp);
+
+            samples_l[i] = tmp = (dpp->samplesB[0] = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam_A);
+            update_weight_clip_d2(dpp->weightA, dpp->delta, sam_A, tmp);
+        }
+        break;
+    case -3:
+        for (i = 0; i < nb_samples; i++) {
+            int32_t sam_A, sam_B, tmp;
+
+            sam_A = dpp->samplesA[0];
+            sam_B = dpp->samplesB[0];
+
+            dpp->samplesA[0] = tmp = samples_r[i];
+            samples_r[i] = tmp -= APPLY_WEIGHT_I(dpp->weightB, sam_B);
+            update_weight_clip_d2(dpp->weightB, dpp->delta, sam_B, tmp);
+
+            dpp->samplesB[0] = tmp = samples_l[i];
+            samples_l[i] = tmp -= APPLY_WEIGHT_I(dpp->weightA, sam_A);
+            update_weight_clip_d2(dpp->weightA, dpp->delta, sam_A, tmp);
+        }
+        break;
+    }
+}
+
+static void put_metadata_block(PutByteContext *pb, int flags, int size)
+{
+    if (size & 1)
+        flags |= WP_IDF_ODD;
+
+    bytestream2_put_byte(pb, flags);
+    bytestream2_put_byte(pb, (size + 1) >> 1);
+}
+
+static int wavpack_encode_block(WavPackEncodeContext *s,
+                                int32_t *samples_l, int32_t *samples_r,
+                                uint8_t *out, int out_size)
+{
+    int block_size, start, end, data_size, tcount, temp, m = 0;
+    int i, j, ret, got_extra = 0, nb_samples = s->block_samples;
+    uint32_t crc = 0xffffffffu;
+    struct Decorr *dpp;
+    PutByteContext pb;
+
+    if (!(s->flags & WV_MONO) && s->optimize_mono) {
+        int32_t lor = 0, diff = 0;
+
+        for (i = 0; i < nb_samples; i++) {
+            lor  |= samples_l[i] | samples_r[i];
+            diff |= samples_l[i] - samples_r[i];
+
+            if (lor && diff)
+                break;
+        }
+
+        if (i == nb_samples && lor && !diff) {
+            s->flags &= ~(WV_JOINT_STEREO | WV_CROSS_DECORR);
+            s->flags |= WV_FALSE_STEREO;
+
+            if (!s->false_stereo) {
+                s->false_stereo = 1;
+                s->num_terms = 0;
+                CLEAR(s->w);
+            }
+        } else if (s->false_stereo) {
+            s->false_stereo = 0;
+            s->num_terms = 0;
+            CLEAR(s->w);
+        }
+    }
+
+    if (s->flags & SHIFT_MASK) {
+        int shift = (s->flags & SHIFT_MASK) >> SHIFT_LSB;
+        int mag = (s->flags & MAG_MASK) >> MAG_LSB;
+
+        if (s->flags & WV_MONO_DATA)
+            shift_mono(samples_l, nb_samples, shift);
+        else
+            shift_stereo(samples_l, samples_r, nb_samples, shift);
+
+        if ((mag -= shift) < 0)
+            s->flags &= ~MAG_MASK;
+        else
+            s->flags -= (1 << MAG_LSB) * shift;
+    }
+
+    if ((s->flags & WV_FLOAT_DATA) || (s->flags & MAG_MASK) >> MAG_LSB >= 24) {
+        av_fast_padded_malloc(&s->orig_l, &s->orig_l_size, sizeof(int32_t) * nb_samples);
+        memcpy(s->orig_l, samples_l, sizeof(int32_t) * nb_samples);
+        if (!(s->flags & WV_MONO_DATA)) {
+            av_fast_padded_malloc(&s->orig_r, &s->orig_r_size, sizeof(int32_t) * nb_samples);
+            memcpy(s->orig_r, samples_r, sizeof(int32_t) * nb_samples);
+        }
+
+        if (s->flags & WV_FLOAT_DATA)
+            got_extra = scan_float(s, samples_l, samples_r, nb_samples);
+        else
+            got_extra = scan_int32(s, samples_l, samples_r, nb_samples);
+        s->num_terms = 0;
+    } else {
+        scan_int23(s, samples_l, samples_r, nb_samples);
+        if (s->shift != s->int32_zeros + s->int32_ones + s->int32_dups) {
+            s->shift = s->int32_zeros + s->int32_ones + s->int32_dups;
+            s->num_terms = 0;
+        }
+    }
+
+    if (!s->num_passes && !s->num_terms) {
+        s->num_passes = 1;
+
+        if (s->flags & WV_MONO_DATA)
+            ret = wv_mono(s, samples_l, 1, 0);
+        else
+            ret = wv_stereo(s, samples_l, samples_r, 1, 0);
+
+        s->num_passes = 0;
+    }
+    if (s->flags & WV_MONO_DATA) {
+        for (i = 0; i < nb_samples; i++)
+            crc += (crc << 1) + samples_l[i];
+
+        if (s->num_passes)
+            ret = wv_mono(s, samples_l, !s->num_terms, 1);
+    } else {
+        for (i = 0; i < nb_samples; i++)
+            crc += (crc << 3) + (samples_l[i] << 1) + samples_l[i] + samples_r[i];
+
+        if (s->num_passes)
+            ret = wv_stereo(s, samples_l, samples_r, !s->num_terms, 1);
+    }
+    if (ret < 0)
+        return ret;
+
+    if (!s->ch_offset)
+        s->flags |= WV_INITIAL_BLOCK;
+
+    s->ch_offset += 1 + !(s->flags & WV_MONO);
+
+    if (s->ch_offset == s->avctx->channels)
+        s->flags |= WV_FINAL_BLOCK;
+
+    bytestream2_init_writer(&pb, out, out_size);
+    bytestream2_put_le32(&pb, MKTAG('w', 'v', 'p', 'k'));
+    bytestream2_put_le32(&pb, 0);
+    bytestream2_put_le16(&pb, 0x410);
+    bytestream2_put_le16(&pb, 0);
+    bytestream2_put_le32(&pb, 0);
+    bytestream2_put_le32(&pb, s->sample_index);
+    bytestream2_put_le32(&pb, nb_samples);
+    bytestream2_put_le32(&pb, s->flags);
+    bytestream2_put_le32(&pb, crc);
+
+    if (s->flags & WV_INITIAL_BLOCK &&
+        s->avctx->channel_layout != AV_CH_LAYOUT_MONO &&
+        s->avctx->channel_layout != AV_CH_LAYOUT_STEREO) {
+        put_metadata_block(&pb, WP_ID_CHANINFO, 5);
+        bytestream2_put_byte(&pb, s->avctx->channels);
+        bytestream2_put_le32(&pb, s->avctx->channel_layout);
+        bytestream2_put_byte(&pb, 0);
+    }
+
+    if ((s->flags & SRATE_MASK) == SRATE_MASK) {
+        put_metadata_block(&pb, WP_ID_SAMPLE_RATE, 3);
+        bytestream2_put_le24(&pb, s->avctx->sample_rate);
+        bytestream2_put_byte(&pb, 0);
+    }
+
+    put_metadata_block(&pb, WP_ID_DECTERMS, s->num_terms);
+    for (i = 0; i < s->num_terms; i++) {
+        struct Decorr *dpp = &s->decorr_passes[i];
+        bytestream2_put_byte(&pb, ((dpp->value + 5) & 0x1f) | ((dpp->delta << 5) & 0xe0));
+    }
+    if (s->num_terms & 1)
+        bytestream2_put_byte(&pb, 0);
+
+#define WRITE_DECWEIGHT(type) do {            \
+        temp = store_weight(type);    \
+        bytestream2_put_byte(&pb, temp);      \
+        type = restore_weight(temp);  \
+    } while (0)
+
+    bytestream2_put_byte(&pb, WP_ID_DECWEIGHTS);
+    bytestream2_put_byte(&pb, 0);
+    start = bytestream2_tell_p(&pb);
+    for (i = s->num_terms - 1; i >= 0; --i) {
+        struct Decorr *dpp = &s->decorr_passes[i];
+
+        if (store_weight(dpp->weightA) ||
+            (!(s->flags & WV_MONO_DATA) && store_weight(dpp->weightB)))
+                break;
+    }
+    tcount = i + 1;
+    for (i = 0; i < s->num_terms; i++) {
+        struct Decorr *dpp = &s->decorr_passes[i];
+        if (i < tcount) {
+            WRITE_DECWEIGHT(dpp->weightA);
+            if (!(s->flags & WV_MONO_DATA))
+                WRITE_DECWEIGHT(dpp->weightB);
+        } else {
+            dpp->weightA = dpp->weightB = 0;
+        }
+    }
+    end = bytestream2_tell_p(&pb);
+    out[start - 2] = WP_ID_DECWEIGHTS | (((end - start) & 1) ? WP_IDF_ODD: 0);
+    out[start - 1] = (end - start + 1) >> 1;
+    if ((end - start) & 1)
+        bytestream2_put_byte(&pb, 0);
+
+#define WRITE_DECSAMPLE(type) do {        \
+        temp = log2s(type);               \
+        type = wp_exp2(temp);             \
+        bytestream2_put_le16(&pb, temp);  \
+    } while (0)
+
+    bytestream2_put_byte(&pb, WP_ID_DECSAMPLES);
+    bytestream2_put_byte(&pb, 0);
+    start = bytestream2_tell_p(&pb);
+    for (i = 0; i < s->num_terms; i++) {
+        struct Decorr *dpp = &s->decorr_passes[i];
+        if (i == 0) {
+            if (dpp->value > MAX_TERM) {
+                WRITE_DECSAMPLE(dpp->samplesA[0]);
+                WRITE_DECSAMPLE(dpp->samplesA[1]);
+                if (!(s->flags & WV_MONO_DATA)) {
+                    WRITE_DECSAMPLE(dpp->samplesB[0]);
+                    WRITE_DECSAMPLE(dpp->samplesB[1]);
+                }
+            } else if (dpp->value < 0) {
+                WRITE_DECSAMPLE(dpp->samplesA[0]);
+                WRITE_DECSAMPLE(dpp->samplesB[0]);
+            } else {
+                for (j = 0; j < dpp->value; j++) {
+                    WRITE_DECSAMPLE(dpp->samplesA[j]);
+                    if (!(s->flags & WV_MONO_DATA))
+                        WRITE_DECSAMPLE(dpp->samplesB[j]);
+                }
+            }
+        } else {
+            CLEAR(dpp->samplesA);
+            CLEAR(dpp->samplesB);
+        }
+    }
+    end = bytestream2_tell_p(&pb);
+    out[start - 1] = (end - start) >> 1;
+
+#define WRITE_CHAN_ENTROPY(chan) do {               \
+        for (i = 0; i < 3; i++) {                   \
+            temp = wp_log2(s->w.c[chan].median[i]); \
+            bytestream2_put_le16(&pb, temp);        \
+            s->w.c[chan].median[i] = wp_exp2(temp); \
+        }                                           \
+    } while (0)
+
+    put_metadata_block(&pb, WP_ID_ENTROPY, 6 * (1 + (!(s->flags & WV_MONO_DATA))));
+    WRITE_CHAN_ENTROPY(0);
+    if (!(s->flags & WV_MONO_DATA))
+        WRITE_CHAN_ENTROPY(1);
+
+    if (s->flags & WV_FLOAT_DATA) {
+        put_metadata_block(&pb, WP_ID_FLOATINFO, 4);
+        bytestream2_put_byte(&pb, s->float_flags);
+        bytestream2_put_byte(&pb, s->float_shift);
+        bytestream2_put_byte(&pb, s->float_max_exp);
+        bytestream2_put_byte(&pb, 127);
+    }
+
+    if (s->flags & WV_INT32_DATA) {
+        put_metadata_block(&pb, WP_ID_INT32INFO, 4);
+        bytestream2_put_byte(&pb, s->int32_sent_bits);
+        bytestream2_put_byte(&pb, s->int32_zeros);
+        bytestream2_put_byte(&pb, s->int32_ones);
+        bytestream2_put_byte(&pb, s->int32_dups);
+    }
+
+    if (s->flags & WV_MONO_DATA && !s->num_passes) {
+        for (i = 0; i < nb_samples; i++) {
+            int32_t code = samples_l[i];
+
+            for (tcount = s->num_terms, dpp = s->decorr_passes; tcount--; dpp++) {
+                int32_t sam;
+
+                if (dpp->value > MAX_TERM) {
+                    if (dpp->value & 1)
+                        sam = 2 * dpp->samplesA[0] - dpp->samplesA[1];
+                    else
+                        sam = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1;
+
+                    dpp->samplesA[1] = dpp->samplesA[0];
+                    dpp->samplesA[0] = code;
+                } else {
+                    sam = dpp->samplesA[m];
+                    dpp->samplesA[(m + dpp->value) & (MAX_TERM - 1)] = code;
+                }
+
+                code -= APPLY_WEIGHT(dpp->weightA, sam);
+                UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, code);
+            }
+
+            m = (m + 1) & (MAX_TERM - 1);
+            samples_l[i] = code;
+        }
+        if (m) {
+            for (tcount = s->num_terms, dpp = s->decorr_passes; tcount--; dpp++)
+                if (dpp->value > 0 && dpp->value <= MAX_TERM) {
+                int32_t temp_A[MAX_TERM], temp_B[MAX_TERM];
+                int k;
+
+                memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA));
+                memcpy(temp_B, dpp->samplesB, sizeof(dpp->samplesB));
+
+                for (k = 0; k < MAX_TERM; k++) {
+                    dpp->samplesA[k] = temp_A[m];
+                    dpp->samplesB[k] = temp_B[m];
+                    m = (m + 1) & (MAX_TERM - 1);
+                }
+            }
+        }
+    } else if (!s->num_passes) {
+        if (s->flags & WV_JOINT_STEREO) {
+            for (i = 0; i < nb_samples; i++)
+                samples_r[i] += ((samples_l[i] -= samples_r[i]) >> 1);
+        }
+
+        for (i = 0; i < s->num_terms; i++) {
+            struct Decorr *dpp = &s->decorr_passes[i];
+            if (((s->flags & MAG_MASK) >> MAG_LSB) >= 16 || dpp->delta != 2)
+                decorr_stereo_pass2(dpp, samples_l, samples_r, nb_samples);
+            else
+                decorr_stereo_pass_id2(dpp, samples_l, samples_r, nb_samples);
+        }
+    }
+
+    bytestream2_put_byte(&pb, WP_ID_DATA | WP_IDF_LONG);
+    init_put_bits(&s->pb, pb.buffer + 3, bytestream2_get_bytes_left_p(&pb));
+    if (s->flags & WV_MONO_DATA) {
+        for (i = 0; i < nb_samples; i++)
+            wavpack_encode_sample(s, &s->w.c[0], s->samples[0][i]);
+    } else {
+        for (i = 0; i < nb_samples; i++) {
+            wavpack_encode_sample(s, &s->w.c[0], s->samples[0][i]);
+            wavpack_encode_sample(s, &s->w.c[1], s->samples[1][i]);
+        }
+    }
+    encode_flush(s);
+    flush_put_bits(&s->pb);
+    data_size = put_bits_count(&s->pb) >> 3;
+    bytestream2_put_le24(&pb, (data_size + 1) >> 1);
+    bytestream2_skip_p(&pb, data_size);
+    if (data_size & 1)
+        bytestream2_put_byte(&pb, 0);
+
+    if (got_extra) {
+        bytestream2_put_byte(&pb, WP_ID_EXTRABITS | WP_IDF_LONG);
+        init_put_bits(&s->pb, pb.buffer + 7, bytestream2_get_bytes_left_p(&pb));
+        if (s->flags & WV_FLOAT_DATA)
+            pack_float(s, s->orig_l, s->orig_r, nb_samples);
+        else
+            pack_int32(s, s->orig_l, s->orig_r, nb_samples);
+        flush_put_bits(&s->pb);
+        data_size = put_bits_count(&s->pb) >> 3;
+        bytestream2_put_le24(&pb, (data_size + 5) >> 1);
+        bytestream2_put_le32(&pb, s->crc_x);
+        bytestream2_skip_p(&pb, data_size);
+        if (data_size & 1)
+            bytestream2_put_byte(&pb, 0);
+    }
+
+    block_size = bytestream2_tell_p(&pb);
+    AV_WL32(out + 4, block_size - 8);
+
+    return block_size;
+}
+
+static void fill_buffer(WavPackEncodeContext *s,
+                        const int8_t *src, int32_t *dst,
+                        int nb_samples)
+{
+    int i;
+
+#define COPY_SAMPLES(type, offset, shift) do {            \
+        const type *sptr = (const type *)src;             \
+        for (i = 0; i < nb_samples; i++)                  \
+            dst[i] = (sptr[i] - offset) >> shift;         \
+    } while (0)
+
+    switch (s->avctx->sample_fmt) {
+    case AV_SAMPLE_FMT_U8P:
+        COPY_SAMPLES(int8_t, 0x80, 0);
+        break;
+    case AV_SAMPLE_FMT_S16P:
+        COPY_SAMPLES(int16_t, 0, 0);
+        break;
+    case AV_SAMPLE_FMT_S32P:
+        if (s->avctx->bits_per_raw_sample <= 24) {
+            COPY_SAMPLES(int32_t, 0, 8);
+            break;
+        }
+    case AV_SAMPLE_FMT_FLTP:
+        memcpy(dst, src, nb_samples * 4);
+    }
+}
+
+static void set_samplerate(WavPackEncodeContext *s)
+{
+    int i;
+
+    for (i = 0; i < 15; i++) {
+        if (wv_rates[i] == s->avctx->sample_rate)
+            break;
+    }
+
+    s->flags = i << SRATE_LSB;
+}
+
+static int wavpack_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
+                                const AVFrame *frame, int *got_packet_ptr)
+{
+    WavPackEncodeContext *s = avctx->priv_data;
+    int buf_size, ret;
+    uint8_t *buf;
+
+    s->block_samples = frame->nb_samples;
+    av_fast_padded_malloc(&s->samples[0], &s->samples_size[0],
+                          sizeof(int32_t) * s->block_samples);
+    if (!s->samples[0])
+        return AVERROR(ENOMEM);
+    if (avctx->channels > 1) {
+        av_fast_padded_malloc(&s->samples[1], &s->samples_size[1],
+                              sizeof(int32_t) * s->block_samples);
+        if (!s->samples[1])
+            return AVERROR(ENOMEM);
+    }
+
+    if ((ret = ff_alloc_packet2(avctx, avpkt, s->block_samples * avctx->channels * 8)) < 0)
+        return ret;
+    buf = avpkt->data;
+    buf_size = avpkt->size;
+
+    for (s->ch_offset = 0; s->ch_offset < avctx->channels;) {
+        set_samplerate(s);
+
+        switch (s->avctx->sample_fmt) {
+        case AV_SAMPLE_FMT_S16P: s->flags |= 1; break;
+        case AV_SAMPLE_FMT_S32P: s->flags |= 3 - (s->avctx->bits_per_raw_sample <= 24); break;
+        case AV_SAMPLE_FMT_FLTP: s->flags |= 3 | WV_FLOAT_DATA;
+        }
+
+        fill_buffer(s, frame->extended_data[s->ch_offset], s->samples[0], s->block_samples);
+        if (avctx->channels - s->ch_offset == 1) {
+            s->flags |= WV_MONO;
+        } else {
+            s->flags |= WV_CROSS_DECORR;
+            fill_buffer(s, frame->extended_data[s->ch_offset + 1], s->samples[1], s->block_samples);
+        }
+
+        s->flags += (1 << MAG_LSB) * ((s->flags & 3) * 8 + 7);
+
+        if ((ret = wavpack_encode_block(s, s->samples[0], s->samples[1],
+                                        buf, buf_size)) < 0)
+            return ret;
+
+        buf      += ret;
+        buf_size -= ret;
+    }
+    s->sample_index += frame->nb_samples;
+
+    avpkt->pts      = frame->pts;
+    avpkt->size     = buf - avpkt->data;
+    avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples);
+    *got_packet_ptr = 1;
+    return 0;
+}
+
+static av_cold int wavpack_encode_close(AVCodecContext *avctx)
+{
+    WavPackEncodeContext *s = avctx->priv_data;
+    int i;
+
+    for (i = 0; i < MAX_TERMS + 2; i++) {
+        av_freep(&s->sampleptrs[i][0]);
+        av_freep(&s->sampleptrs[i][1]);
+        s->sampleptrs_size[i][0] = s->sampleptrs_size[i][1] = 0;
+    }
+
+    for (i = 0; i < 2; i++) {
+        av_freep(&s->samples[i]);
+        s->samples_size[i] = 0;
+
+        av_freep(&s->best_buffer[i]);
+        s->best_buffer_size[i] = 0;
+
+        av_freep(&s->temp_buffer[i][0]);
+        av_freep(&s->temp_buffer[i][1]);
+        s->temp_buffer_size[i][0] = s->temp_buffer_size[i][1] = 0;
+    }
+
+    av_freep(&s->js_left);
+    av_freep(&s->js_right);
+    s->js_left_size = s->js_right_size = 0;
+
+    av_freep(&s->orig_l);
+    av_freep(&s->orig_r);
+    s->orig_l_size = s->orig_r_size = 0;
+
+    return 0;
+}
+
+#define OFFSET(x) offsetof(WavPackEncodeContext, x)
+#define FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
+static const AVOption options[] = {
+    { "joint_stereo",  "", OFFSET(joint), AV_OPT_TYPE_INT, {.i64=0},-1, 1, FLAGS, "joint" },
+    { "on",   "mid/side",   0, AV_OPT_TYPE_CONST, {.i64= 1}, 0, 0, FLAGS, "joint"},
+    { "off",  "left/right", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, FLAGS, "joint"},
+    { "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 0}, 0, 0, FLAGS, "joint"},
+    { "optimize_mono",        "", OFFSET(optimize_mono), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "opt_mono" },
+    { "on",   NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "opt_mono"},
+    { "off",  NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "opt_mono"},
+    { NULL },
+};
+
+static const AVClass wavpack_encoder_class = {
+    .class_name = "WavPack encoder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_wavpack_encoder = {
+    .name           = "wavpack",
+    .long_name      = NULL_IF_CONFIG_SMALL("WavPack"),
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_WAVPACK,
+    .priv_data_size = sizeof(WavPackEncodeContext),
+    .priv_class     = &wavpack_encoder_class,
+    .init           = wavpack_encode_init,
+    .encode2        = wavpack_encode_frame,
+    .close          = wavpack_encode_close,
+    .capabilities   = CODEC_CAP_SMALL_LAST_FRAME,
+    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_U8P,
+                                                     AV_SAMPLE_FMT_S16P,
+                                                     AV_SAMPLE_FMT_S32P,
+                                                     AV_SAMPLE_FMT_FLTP,
+                                                     AV_SAMPLE_FMT_NONE },
+};
diff --git a/libavcodec/wavpackenc.h b/libavcodec/wavpackenc.h
new file mode 100644
index 0000000..1582d68
--- /dev/null
+++ b/libavcodec/wavpackenc.h
@@ -0,0 +1,664 @@
+/*
+ * WavPack lossless audio encoder
+ *
+ * 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
+ */
+
+#ifndef AVCODEC_WAVPACKENC_H
+#define AVCODEC_WAVPACKENC_H
+
+#include "wavpack.h"
+
+typedef struct WavPackDecorrSpec {
+    int8_t joint_stereo, delta, terms[MAX_TERMS+1];
+} WavPackDecorrSpec;
+
+static const WavPackDecorrSpec fast_specs[] = {
+ { 1, 2, { 18,17 } }, { 1, 1, { 17,17 } }, { 0, 2, { 18,17 } },
+ { 0, 1, { 17,17 } }, { 1, 3, {  1,18 } }, { 1, 1, { 17, 1 } },
+ { 0, 1, {  1,17 } }, { 0, 1, { -2,17 } }, { 0, 2, { -1,17 } },
+ { 1, 1, { 17, 2 } }, { 0, 3, { 18,18 } }, { 0, 1, { 17, 1 } },
+ { 1, 6, {  1, 2 } }, { 1, 1, { 17, 3 } }, { 0, 1, { -2, 3 } },
+ { 0, 1, {  2,17 } }, { 0, 1, { 18,-2 } }, { 0, 1, { -1,17 } },
+ { 0, 1, { 18,17 } }, { 0, 1, { 17, 2 } }, { 1, 2, { 18,-2 } },
+ { 1, 1, {  1,17 } }, { 0, 3, { 18, 2 } }, { 0, 1, { 17,-2 } },
+ { 0, 1, { 18,-2 } }, { 1, 2, { 17,-3 } }, { 0, 1, { 18, 3 } },
+ { 0, 1, { 18,18 } }, { 1, 1, {  1, 3 } }, { 1, 1, { 18, 3 } },
+ { 1, 1, {  1, 3 } }, { 0, 2, { 18,17 } }, { 1, 1, {  1,17 } },
+ { 1, 1, { 17, 3 } }, { 0, 3, { 18,17 } }, { 0, 1, { 18,18 } },
+ { 1, 1, {  1, 3 } }, { 1, 1, {  1,18 } }, { 0, 1, { 18,-2 } },
+ { 0, 2, { 18,17 } }, { 0, 1, { -1,18 } }, { 1, 1, { 17, 3 } },
+ { 0, 1, { 17, 2 } }, { 0, 1, { 17, 3 } }, { 1, 1, { 18, 2 } },
+ { 1, 1, { 17,-2 } }, { 0, 1, {  1,-2 } }, { 0, 2, { 18,17 } },
+ { 0, 1, { 17,-2 } }, { 1, 1, { 17,-2 } }, { 0, 1, { 18, 3 } },
+ { 0, 1, {  2,17 } }, { 1, 2, { 18,-3 } }, { 1, 2, {  1,18 } },
+ { 1, 2, { 18, 2 } }, { 0, 1, { 17,-1 } }, { 0, 1, { 17,-2 } },
+ { 1, 1, { 17,-2 } }, { 1, 1, {  1, 3 } }, { 0, 1, {  1,17 } },
+ { 1, 2, { 18,-2 } }, { 1, 2, { 17,-3 } }, { 0, 2, { 18,17 } },
+ { 0, 2, { 18,17 } }, { 1, 1, { 17, 2 } }, { 1, 2, { 18,18 } },
+ { 0, 1, { 17, 2 } }, { 0, 1, { 18,17 } }, { 1, 1, {  1,17 } },
+ { 1, 1, { 17, 2 } }, { 0, 2, { 18,18 } }, { 0, 2, { 18,17 } },
+ { 1, 2, { 17,-3 } }, { 1, 6, {  1, 2 } }, { 0, 3, { 17,17 } },
+ { 0, 1, {  1,18 } }, { 0, 1, {  1,-2 } }, { 1, 1, { 17, 2 } },
+ { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } }, { 1, 1, { 18, 3 } },
+ { 1, 2, { 17,-3 } }, { 0, 1, { 17, 2 } }, { 0, 1, { 17, 3 } },
+ { 0, 1, { 18,-2 } }, { 1, 1, { 18,18 } }, { 1, 6, {  1, 2 } },
+ { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } }, { 0, 1, { -1,17 } },
+ { 1, 1, { 18, 3 } }, { 0, 1, { 17,18 } }, { 1, 1, { 17, 3 } },
+ { 0, 1, { 18, 3 } }, { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } },
+ { 1, 2, { 18, 2 } }, { 0, 1, { -2, 3 } }, { 0, 4, { 18,-1 } },
+ { 0, 2, { 18,18 } }, { 0, 1, { -2, 3 } }, { 1, 1, { 17,-2 } },
+ { 0, 1, { 17, 3 } }, { 0, 2, { 18,17 } }, { 0, 2, { -1,18 } },
+ { 1, 1, {  2,17 } }, { 0, 2, { 17,-2 } }, { 0, 1, { 17, 2 } },
+ { 1, 2, { 18,-3 } }, { 0, 1, { 17,-2 } }, { 0, 2, { 18,17 } },
+ { 0, 2, { 18,17 } }, { 1, 1, { 17,-2 } }, { 1, 2, { 17,-3 } },
+ { 1, 1, {  1, 3 } }, { 1, 1, {  2,17 } }, { 1, 2, { 18, 2 } },
+ { 1, 1, {  2,17 } }, { 1, 1, { 18, 2 } }, { 0, 2, { 18,17 } },
+ { 0, 2, { 18,17 } }, { 0, 1, { 17,-2 } }, { 0, 2, { 18,17 } },
+ { 0, 2, { 17,-1 } }, { 0, 2, { 18,-2 } }, { 0, 2, { 18,17 } },
+ { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } }, { 1, 1, {  1, 3 } },
+ { 0, 2, { -2,17 } }, { 0, 2, { 18,-2 } }, { 0, 2, { 17,-2 } },
+ { 1, 1, {  2,17 } }, { 1, 1, {  1, 3 } }, { 0, 1, {  2,17 } },
+ { 0, 2, { 18,17 } }, { 0, 3, { -1,17 } }, { 1, 1, {  2,17 } },
+ { 0, 2, { 18,18 } }, { 0, 1, { 17, 2 } }, { 1, 4, { 18,-3 } },
+ { 1, 1, { 18, 1 } }, { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } },
+ { 1, 2, { 18,-1 } }, { 0, 1, { -1,18 } }, { 1, 6, {  1, 2 } },
+ { 1, 1, { 17, 2 } }, { 1, 4, { 18, 3 } }, { 0, 1, {  1,17 } },
+ { 0, 1, { 18, 2 } }, { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } },
+ { 1, 2, { 17, 2 } }, { 0, 2, { 18,-2 } }, { 0, 1, {  1,18 } },
+ { 1, 2, { 18,-3 } }, { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } },
+ { 0, 2, { 18,17 } }, { 1, 2, { 18,18 } }, { 1, 3, { 17,17 } },
+ { 0, 1, { -2,17 } }, { 0, 1, { 17,18 } }, { 0, 1, { -1, 3 } },
+ { 1, 1, {  2,17 } }, { 0, 2, { 18,-1 } }, { 0, 2, { 18,17 } },
+ { 0, 2, { 18,17 } }, { 1, 1, { 17,-2 } }, { 1, 2, { 17, 2 } },
+ { 1, 1, { 18, 3 } }, { 0, 1, { 18, 2 } }, { 1, 2, { 17,-3 } },
+ { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } }, { 0, 1, { -2,17 } },
+ { 0, 1, { 17,-1 } }, { 0, 1, { 18,-1 } }, { 0, 2, { 18,17 } },
+ { 1, 2, { 17,-3 } }, { 1, 1, {  1,18 } }, { 1, 3, { 18, 2 } },
+ { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } },
+ { 0, 2, { 18,17 } }, { 0, 3, { 18,18 } }, { 0, 1, {  1,-2 } },
+ { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } },
+ { 1, 2, { 17,-3 } }, { 1, 1, { 18,18 } }, { 0, 2, { 18, 2 } },
+ { 0, 1, { 17,18 } }, { 1, 2, { 18, 2 } }, { 1, 1, { 17,-2 } },
+ { 0, 2, { 17,-1 } }, { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } },
+ { 0, 2, { 18,17 } }, { 0, 1, {  1,-2 } }, { 0, 1, { 18, 1 } },
+ { 1, 2, { 18,-2 } }, { 0, 1, { 17, 2 } }, { 0, 2, { 18,17 } },
+ { 0, 2, { 18,17 } }, { 1, 1, { 17, 3 } }, { 0, 1, { 17,-1 } },
+ { 0, 1, { 18, 2 } }, { 1, 1, { 17, 3 } }, { 1, 1, { 17,-2 } },
+ { 0, 1, { 18,18 } }, { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } },
+ { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } },
+ { 1, 1, { 17,18 } }, { 0, 1, { -2, 3 } }, { 0, 2, { 18,17 } },
+ { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } }, { 1, 2, { 18,-3 } },
+ { 0, 2, { 18,17 } }, { 0, 3, { 18, 2 } }, { 0, 1, {  1,18 } },
+ { 0, 2, { 18,17 } }, { 0, 1, { 17,-1 } }, { 0, 2, { 18,17 } },
+ { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } }, { 0, 1, { -2, 3 } },
+ { 0, 3, { 17,17 } }, { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } },
+ { 1, 1, { 17, 2 } }, { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } },
+ { 1, 1, { 17, 2 } }, { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } },
+ { 0, 2, { 18,17 } }, { 0, 2, { 18, 2 } }, { 0, 2, { 18,17 } },
+ { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } },
+ { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } },
+ { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } }, { 0, 2, { 18,17 } },
+ { 0, 2, { 18,17 } },
+};
+
+static const WavPackDecorrSpec default_specs[] = {
+ { 1, 2, { 18,18, 2,17, 3 } }, { 0, 2, { 18,17,-1, 3, 2 } },
+ { 1, 1, { 17,18,18,-2, 2 } }, { 0, 2, { 18,17, 3,-2,17 } },
+ { 1, 2, { 18,17, 2,17, 3 } }, { 0, 1, { 18,18,-1, 2,17 } },
+ { 0, 1, { 17,17,-2, 2, 3 } }, { 0, 1, { 18,-2,18, 2,17 } },
+ { 1, 2, { 18,18,-1, 2, 3 } }, { 0, 2, { 18,17, 3, 2, 5 } },
+ { 1, 1, { 18,17,18, 2, 5 } }, { 0, 1, { 17,17,-2, 2, 3 } },
+ { 0, 1, { 18,-2,18, 2, 5 } }, { 0, 1, { 17,-2,17, 2,-3 } },
+ { 1, 1, { 17,-2,17, 1, 2 } }, { 0, 1, { 17,17,-2, 2, 3 } },
+ { 1, 1, { 18, 3, 1, 5, 4 } }, { 1, 4, { 18,18, 2, 3,-2 } },
+ { 0, 1, {  1,-1,-1, 2,17 } }, { 0, 2, { 18,17, 3, 2, 5 } },
+ { 0, 1, { 18,18,18, 2,17 } }, { 0, 1, { 18,17,-1, 2,18 } },
+ { 1, 1, { 17, 3, 2, 1, 7 } }, { 0, 2, { 18,-2,18, 2, 3 } },
+ { 1, 3, { 18,-3,18, 2, 3 } }, { 0, 3, { 18,17, 2, 3,17 } },
+ { 1, 1, { 17,17, 2, 1, 4 } }, { 0, 1, { 17,18,-2, 2,17 } },
+ { 1, 1, { 18,18, 3, 5, 2 } }, { 0, 1, { 17,17, 2,18, 4 } },
+ { 0, 1, { 18,17, 1, 4, 6 } }, { 1, 1, {  3,17,18, 2,17 } },
+ { 1, 1, { 17, 3, 2, 1, 7 } }, { 0, 1, { 18,17,-1, 2, 3 } },
+ { 1, 1, { 17,17, 2, 1, 4 } }, { 1, 2, { 18,17,-1,17, 3 } },
+ { 1, 2, { 18,17, 2, 3,-1 } }, { 0, 2, { 18,18,-2, 2,17 } },
+ { 0, 1, { 17,17, 2,18, 4 } }, { 0, 5, { -2,18,18,18, 2 } },
+ { 1, 1, { 18,18,-1, 6, 3 } }, { 0, 1, { 17,17,-2, 2, 3 } },
+ { 1, 1, { 18,17,18, 2,17 } }, { 0, 1, { 18,17, 4, 3, 1 } },
+ { 0, 1, { -2,18, 2, 2,18 } }, { 1, 2, { 18,18,-2, 2,-1 } },
+ { 1, 1, { 17,17, 2, 1, 4 } }, { 0, 1, { 17,18,-2, 2,17 } },
+ { 1, 1, { 17, 3, 2, 1, 7 } }, { 1, 3, { 18,-3,18, 2, 3 } },
+ { 1, 2, { 18,18,-2, 2,-1 } }, { 1, 1, { 18,18, 3, 5, 2 } },
+ { 0, 2, { 18,18,-1, 2,17 } }, { 0, 1, { 18,-1,17,18, 2 } },
+ { 0, 1, { 17,-1, 2, 3, 6 } }, { 0, 1, { 18,-2,18, 2, 5 } },
+ { 1, 2, { 18,18,-2, 2,-1 } }, { 0, 3, { 18,18, 2, 3,17 } },
+ { 0, 1, { 17,17, 2,18, 4 } }, { 1, 1, { 17,-2,17, 1, 2 } },
+ { 0, 1, { -1, 3, 5, 4, 7 } }, { 0, 3, { 18,18, 3, 2, 5 } },
+ { 0, 1, { 17,17, 2,18, 4 } }, { 0, 1, { 18,17,-2,18, 3 } },
+ { 0, 2, { 18,18,-2, 2,17 } }, { 0, 3, { 18,17,-2, 2, 3 } },
+ { 1, 1, { 18,18,-2, 2,17 } }, { 0, 1, { 18,17, 4, 3, 1 } },
+ { 1, 2, {  3,18,17, 2,17 } }, { 1, 2, { 18,18, 2,-2,18 } },
+ { 1, 2, { 18,18,-1,18, 2 } }, { 0, 2, { 18,18,-2, 2,17 } },
+ { 1, 3, { 18,18, 2, 3,-2 } }, { 0, 3, { 18,18, 3, 2, 5 } },
+ { 0, 1, { 18,-2,18, 2, 5 } }, { 1, 1, { 17, 3, 2, 1, 7 } },
+ { 1, 3, { 18,18,-2, 2,18 } }, { 1, 1, { 17,18,18,-2, 2 } },
+ { 0, 1, { 18,-2,18, 2, 5 } }, { 0, 2, { 18,-2,18, 2, 3 } },
+ { 0, 1, { -1, 3, 4, 5, 7 } }, { 1, 1, { 17,17, 2,-1, 7 } },
+ { 0, 1, { 18,-1,-1, 2,-2 } }, { 0, 2, { 18,17, 2, 3,17 } },
+ { 0, 1, { 18,17, 2,18, 2 } }, { 0, 2, { 18,17,-1, 2,17 } },
+ { 0, 1, {  1,18, 3, 2, 5 } }, { 0, 2, { 18,-2, 4,18, 2 } },
+ { 1, 1, { 18, 3, 1, 5, 4 } }, { 0, 1, { 18,17,18, 2, 5 } },
+ { 1, 1, { 18, 3, 1, 5, 4 } }, { 0, 4, { 18,18,-2, 2,18 } },
+ { 1, 1, { 18,18, 3, 2, 5 } }, { 1, 1, { 17,17, 2, 1, 4 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 1, 1, { 18,18, 2, 1, 3 } }, { 1, 1, { 17,17, 2, 1, 4 } },
+ { 1, 2, { 17,17, 2,18, 3 } }, { 0, 1, { 18,17, 1, 4, 6 } },
+ { 1, 2, { 18,18,-2, 2,-1 } }, { 0, 1, { 18,-2,18, 2, 5 } },
+ { 1, 1, { 17, 2,18, 2,17 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 0, 1, { 18,18, 3, 6,-1 } }, { 0, 1, { 18,17, 2,18, 3 } },
+ { 0, 1, { 18,17,-2, 2,17 } }, { 1, 1, {  3,17,18, 2,17 } },
+ { 1, 3, { 18,-3,18, 2, 3 } }, { 1, 3, { 18,18,-3,18, 2 } },
+ { 1, 1, { 18, 3, 1, 5, 4 } }, { 0, 1, { 17,-2,17, 2,-3 } },
+ { 1, 1, { 18,18, 3, 5, 2 } }, { 1, 2, { 18,18,-2, 2,-1 } },
+ { 0, 1, { 18,-1,-1, 2,-2 } }, { 1, 1, { 18, 3, 1, 5, 4 } },
+ { 0, 3, { 18,17,-1, 2,17 } }, { 1, 3, { 18,17, 2,18,-2 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 1, 2, { 18,18,-2, 2,-1 } },
+ { 1, 1, { 18, 3, 1, 5, 4 } }, { 0, 4, {  3,18,18, 2,17 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 1, 1, { 18,17,-1,18, 2 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 1, 1, { 18,18,18, 3, 2 } }, { 0, 1, { 17,-1, 2, 3, 6 } },
+ { 0, 1, { 17,-1, 2, 3, 6 } }, { 0, 2, { 18,17,-2, 3, 2 } },
+ { 1, 3, { 18,17, 2,-2,18 } }, { 0, 2, { 18,18, 2,17, 3 } },
+ { 0, 1, { 18,18, 2,18,-2 } }, { 0, 2, { 18,-2, 4,18, 2 } },
+ { 0, 1, { -2,18, 2, 2,18 } }, { 0, 2, { 18,17, 3, 6, 2 } },
+ { 0, 1, { 18,17,18, 2, 5 } }, { 0, 3, { 18,18,-2, 3, 2 } },
+ { 1, 1, { 18,18, 2,18, 5 } }, { 0, 1, { 17,-1, 2, 3, 6 } },
+ { 1, 4, { 18,18, 2, 3,-2 } }, { 0, 2, { 18,17,18, 2,-2 } },
+ { 0, 1, {  1,18, 3, 2, 5 } }, { 1, 4, { 18,-2,18, 2, 3 } },
+ { 1, 2, { 18, 2,18, 3,-2 } }, { 0, 2, { 18,18,18, 2, 4 } },
+ { 0, 2, {  3,17,18, 2,17 } }, { 1, 1, { 18,-1,18, 2,17 } },
+ { 1, 2, { 17,17, 2,18, 3 } }, { 0, 2, { 18,17,-2, 3, 2 } },
+ { 0, 1, {  1,-1,-1, 2,17 } }, { 0, 3, {  3,18,18, 2,17 } },
+ { 0, 1, { 18,-1,17,18, 2 } }, { 0, 1, { 18,17, 2,18, 3 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 1, { 18,17, 2,18, 2 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 1, 2, { 17,17, 2,18, 3 } }, { 0, 1, { 18,17,-2, 2, 3 } },
+ { 0, 1, { 18,-2,18, 2, 5 } }, { 1, 4, { 18,-2,18, 2, 3 } },
+ { 1, 3, { 18,17, 2, 3, 6 } }, { 0, 2, { 18,18, 2,17, 3 } },
+ { 0, 2, { 18,17, 2,18, 2 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 1, 1, { 18,18, 3, 5, 2 } }, { 0, 2, { 18,18,-2, 2, 3 } },
+ { 1, 2, { 18,17, 2,17, 3 } }, { 0, 1, { 18,17, 2, 3,18 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 1, 4, { 18,18, 2, 3,-2 } },
+ { 0, 1, { 17,-2,17, 2,-3 } }, { 0, 1, { 17,17, 2,18, 4 } },
+ { 1, 1, { 18,18,18, 2, 4 } }, { 1, 2, { 18, 2,18, 3,-2 } },
+ { 1, 1, { 18,18,-2, 2,17 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 0, 2, { 18,18, 2,17, 3 } }, { 0, 2, { 18,18,18, 2, 4 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 2, { 18,17,-2, 3, 2 } },
+ { 0, 1, {  1,-1,-1, 2,17 } }, { 1, 4, { 18,18, 2, 3,-2 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 1, { 18,-2,18, 3, 2 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 0, 1, { 18,18,-2, 2,17 } }, { 0, 3, { 18,17, 2, 3,17 } },
+ { 1, 2, { 18,18, 2,-2,18 } }, { 0, 1, { -1, 3, 5, 4, 7 } },
+ { 1, 1, { 18, 3, 1, 5, 4 } }, { 1, 1, { 18,18,-2,18, 3 } },
+ { 0, 2, { 18,17,18, 2,-2 } }, { 0, 2, { 18,18, 2,17, 3 } },
+ { 1, 2, { 18, 2,18, 3,-2 } }, { 1, 4, { 18,18, 2, 3,-2 } },
+ { 1, 3, { 18,17, 2, 3, 6 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 1, 2, { 18,17,-2,-1,17 } }, { 0, 1, { 17,-1, 2, 3, 6 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 2, { 18,18,-2, 2, 3 } },
+ { 1, 1, { 18,18,18, 2, 5 } }, { 0, 1, { 17,17,-2, 2, 3 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 2, { 18,17, 3, 6, 2 } },
+ { 0, 2, { 18,17,18, 2, 3 } }, { 0, 3, { 18,17,-3,18, 2 } },
+ { 0, 1, { 18,18,18, 2, 3 } }, { 0, 1, { 18,-2,-3, 2, 6 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 1, 1, { 18,17,18, 2, 5 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 1, 1, { 18,17,18, 2, 5 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 0, 1, { 18,18,18, 2, 3 } }, { 1, 1, { 17,-2,17, 1, 2 } },
+ { 1, 1, { 17,17, 2,-1, 7 } }, { 0, 1, { 18,17, 4, 3, 1 } },
+ { 1, 3, { 18,-3,18, 2, 3 } }, { 0, 1, {  1,18, 3, 2, 5 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 0, 1, { 18,18, 3, 6, 2 } }, { 0, 1, { 17,17, 2,18, 4 } },
+ { 0, 1, { 17,17, 2,18, 4 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 1, 2, { 18,-2,18, 3, 2 } }, { 1, 1, { 17,-2,17, 1, 2 } },
+ { 1, 1, { 18,18, 3, 2, 5 } }, { 0, 1, { 18,18,-1, 2, 3 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 0, 1, { 18,17,18, 2, 5 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 1, {  3,18,18, 2,17 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 2, { 18,18,-2,18, 2 } },
+ { 0, 2, { 18,18,-2,18, 2 } }, { 0, 2, { 18,18,-2,18, 2 } },
+};
+
+static const WavPackDecorrSpec high_specs[] = {
+ { 1, 2, { 18,18,18,-2, 2, 3, 5,-1,17, 4 } }, { 0, 1, { 18,17,-2, 2,18, 3, 7, 2, 5, 4 } },
+ { 1, 2, {  1,18, 3, 6,-2,18, 2, 3, 4, 5 } }, { 0, 2, { 18,18,-2, 2,18, 3, 6, 2,17, 4 } },
+ { 1, 2, { 18,18, 2,18, 3, 2,-1, 4,18, 5 } }, { 1, 1, {  7, 6, 5, 3, 4, 2, 5, 4, 3, 7 } },
+ { 1, 1, { 17, 3,18, 7, 2, 6, 1, 4, 3, 5 } }, { 1, 1, { -2,18,18,18, 3,-2, 6, 5, 2, 1 } },
+ { 1, 2, { 18,18,-1,18, 2, 3, 6,-2,17, 5 } }, { 0, 1, { 17,17,18, 3, 6, 4, 5, 2,18,-2 } },
+ { 1, 2, {  1,18,-2, 3, 5, 2, 4,-1, 6, 1 } }, { 0, 2, { 18,18, 3, 6,18, 2, 4, 8, 5, 3 } },
+ { 0, 1, { -2, 1,18, 2,-2, 7,18, 2,-1, 5 } }, { 1, 1, {  4, 3, 8, 1, 5, 2, 5, 6, 2, 8 } },
+ { 1, 1, { 17,18, 2, 6, 3, 4,-1, 1, 8, 6 } }, { 0, 1, { 18,18, 3, 6, 3,-2, 2, 5,-1, 1 } },
+ { 0, 1, { 18,18,17,-1, 2,-2,18, 3, 4, 5 } }, { 1, 2, { 18,17, 2,-2,18, 3, 5, 7, 2, 4 } },
+ { 1, 2, { 18,18, 3, 6,-2,18, 2, 5, 8, 3 } }, { 0, 1, { 18,17, 2,18,18, 2, 6, 5,17, 7 } },
+ { 1, 2, { 18,17, 2,18, 3, 2, 6,18,-1, 4 } }, { 1, 1, {  5, 3, 6, 5, 3, 4, 1, 2, 4, 7 } },
+ { 1, 1, {  5, 3, 6, 5, 3, 4, 1, 2, 4, 7 } }, { 0, 1, { -2,18,18,18,-2, 3, 2, 4, 6, 5 } },
+ { 1, 2, { 18,17,-3, 3,-1,18, 2, 3, 6, 5 } }, { 0, 1, { 17,18, 7, 3,-2, 7, 1, 2, 4, 5 } },
+ { 1, 1, {  2,18,18,-2, 2, 4,-1,18, 3, 6 } }, { 0, 3, {  1,18, 4, 3, 5, 2, 4,18, 2, 3 } },
+ { 0, 1, { -2,18, 2,18, 3, 7,18, 2, 6,-2 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 1, { 18,18, 5, 4, 6, 4, 5, 1, 4, 3 } }, { 1, 1, { 18, 3, 6, 5, 7, 8, 2, 3, 1,-1 } },
+ { 1, 1, { 18,18,18, 2,-2, 3, 5,18, 2, 8 } }, { 0, 2, { 18,17,-2, 2, 3,18,-3, 5, 2, 7 } },
+ { 1, 1, {  1, 1,-1, 8,17, 3,-2, 2, 6,17 } }, { 0, 2, { 18,18,17, 2,-2, 3, 2, 4,18, 5 } },
+ { 1, 1, { 17,18, 2,-1, 5, 7,18, 3, 4, 6 } }, { 1, 1, {  5, 4, 5,17, 3, 6, 3, 4, 7, 2 } },
+ { 0, 1, { 17, 3, 1, 7, 4, 2, 5,-2,18, 6 } }, { 0, 1, { 17,18, 2,18, 4, 3, 5, 7,-3, 6 } },
+ { 1, 2, { 17,17,-3,-2, 2, 8,18,-1, 3, 5 } }, { 0, 1, { 17,17,18, 2, 3, 6,-2, 8, 1, 7 } },
+ { 1, 1, {  1, 2, 6,-2,18, 2, 5,-3, 7,-2 } }, { 0, 1, { 18,18, 3,18, 6, 8,-2, 2, 3, 5 } },
+ { 0, 1, { 18,17, 2,18,-2, 3, 7, 6, 2, 4 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 1, { 18,18, 2,-1, 3, 6, 1, 3, 4, 8 } }, { 0, 1, { 18,18, 3, 6, 5, 3,-2, 2,18,-1 } },
+ { 0, 1, { 18,17,-3,18, 2, 4,-2, 3, 6,17 } }, { 1, 3, {  1, 2,17, 3,18, 7,-1, 5, 2, 4 } },
+ { 1, 1, { 18, 3,18, 6, 8,18,-2, 5, 7, 2 } }, { 0, 1, { 17, 2,18, 6, 3, 2, 5, 4, 8, 1 } },
+ { 0, 1, { 18,17,-1, 2, 3,18,18, 2, 3,17 } }, { 1, 1, { 18, 7, 6, 5, 5, 3, 1, 4, 2, 4 } },
+ { 1, 1, {  6,17, 3, 8, 1, 5, 7,-1, 2, 1 } }, { 1, 1, { 18,-2,18, 3,-2, 2, 7, 4, 6,18 } },
+ { 1, 3, { 18,-3,18, 2, 3,18,-1, 7, 2, 5 } }, { 0, 2, { 18,-2, 7, 1, 3, 2, 4, 6,-3, 7 } },
+ { 1, 1, { 18,-2, 2,-3,18,-2,17,-1, 4, 2 } }, { 0, 3, { 17,17, 2, 5, 3, 7,18, 6, 4, 2 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 1, { 18,17, 4, 6, 6, 4, 5, 3, 4, 1 } }, { 0, 1, { 18, 5, 3, 6, 2, 3, 8, 1, 3, 7 } },
+ { 1, 2, { 18,17,-2, 2,18, 3, 5, 7,-1, 2 } }, { 0, 1, {  1,18,18, 3, 6,-1, 4, 8, 5, 2 } },
+ { 1, 1, {  1, 5, 3, 4, 1, 1, 3, 5, 7, 3 } }, { 0, 1, {  3,18,18, 2,18,18,-1, 2, 3,18 } },
+ { 1, 2, { 18,18,-1,18, 2, 3, 4, 6,18, 5 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 1, { 18, 3, 1, 4, 5, 2, 7, 1, 3, 6 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 2, { 18,18,-1,18, 2, 3, 5,-2, 6, 8 } }, { 1, 1, { 17,18, 4, 8, 3, 2, 5, 2, 7, 6 } },
+ { 1, 4, {  1, 2, 5,18,-2, 2, 3, 7,-1, 4 } }, { 0, 2, { 18,17,-1, 3, 6,18, 2, 3, 7, 5 } },
+ { 0, 1, { -2,18, 2,-3, 6,18, 4, 3,-2, 5 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, { 17,17, 6, 2, 4, 8, 3, 5,-1,17 } }, { 1, 1, { 18, 3,18, 6, 8,18,-2, 5, 7, 2 } },
+ { 1, 2, { 17,17,-3, 2,18,-2, 8, 3, 6,-1 } }, { 1, 1, { 18,-2,17,18, 2, 3,-2, 6, 5, 4 } },
+ { 1, 2, { 18,17,-1, 3,18, 2, 5, 3, 6,-3 } }, { 0, 1, { 18,17, 2,18, 7,18, 2, 4, 3,17 } },
+ { 1, 3, { 18,18, 5, 6, 4, 3, 4,18, 6, 5 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 1, {  7, 6, 5, 3, 4, 2, 5, 4, 3, 7 } }, { 0, 1, { -2,18,18,18, 3, 6, 4, 2, 5, 2 } },
+ { 0, 3, { 18,17,-3,18, 3, 2, 5,-1,17, 3 } }, { 1, 1, { 17,18, 7, 3, 1, 7, 4, 2, 6, 5 } },
+ { 1, 1, { 18, 2,-2,-1,18, 5, 3,-2, 1, 2 } }, { 0, 3, { 18,18,-1, 3, 2, 7, 5,18, 4, 3 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 1, { 17,18, 2,-2, 4, 8,18, 3, 6, 5 } }, { 0, 2, { 18,17, 3, 5,-2, 7, 2,18, 3,-1 } },
+ { 1, 1, { 18, 2,-2,-1,18, 5, 3,-2, 1, 2 } }, { 0, 2, {  3,17,18,18, 2, 5, 7, 6,18, 3 } },
+ { 1, 1, { 17,18,18, 4, 3, 2,18, 7, 8,-1 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, { 17, 1, 2, 3, 5, 6, 1, 4, 8,17 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 2, { 18,17,-1,18,-3, 2, 8, 3, 6,17 } }, { 1, 1, { 17,17, 1, 2, 4, 5,-1, 2, 1, 6 } },
+ { 1, 1, {  1, 2, 6,-2,18, 2,-3, 3,-2, 5 } }, { 0, 1, { 18, 3,18, 6,18, 5, 2, 4,-1, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 1, { 18,18,-1, 2,18, 3, 6, 4,-2, 7 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 2, { -1,18,18,18, 2,-2, 4, 7, 2, 3 } }, { 0, 3, {  3,17,-2, 5, 2, 7,18, 6, 4, 5 } },
+ { 0, 1, { 17, 6,18, 3, 8, 4, 5, 3, 8,18 } }, { 0, 2, { 18, 2, 6, 2,18, 3, 2, 4, 5, 8 } },
+ { 0, 1, {  3,18,18, 2,18,-1, 2,18, 2,17 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, {  3, 6,17,-2, 5, 1, 2, 7, 4, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 3, {  3,18,17, 5, 6, 2, 7,-2, 8,18 } }, { 1, 1, { 18,-1, 3, 1, 7, 2,-1, 4, 6,17 } },
+ { 1, 1, { 18, 2,-2,-1,18, 5, 3,-2, 1, 2 } }, { 0, 2, { 18, 1, 2,18, 3, 6, 5, 2, 4, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 1, { 17,-2, 2,18,18, 8, 5, 3, 2, 6 } }, { 0, 1, { 18,17, 2,18, 3, 2, 7,-2,18, 4 } },
+ { 1, 2, {  1,18, 2, 3,-1, 5, 6, 4, 7,17 } }, { 0, 2, { 18,17, 3, 6,-2, 2, 3, 8, 5,17 } },
+ { 0, 2, { 18,18, 3, 2,18,-1, 2, 4, 3,17 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 2, { 17,-1,18, 2, 3,-2, 5,18, 2, 7 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 2, { 18,-3,18, 2, 3,-2,18, 5, 6,-3 } }, { 0, 2, { 18,17, 3, 5,-2, 7, 2,18, 3,-1 } },
+ { 1, 1, {  1,18,-1, 2, 3, 1,-2, 8, 2, 5 } }, { 0, 1, { 18,18, 3, 6,18, 2, 3, 4, 8, 5 } },
+ { 0, 1, { -2, 1,18, 2,-2, 5, 7,18, 2,-1 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 1, { 17,18,-1, 2, 8, 3, 4, 5, 1, 7 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 2, { 18,18,-1, 2,18, 3,-2, 5, 4, 2 } }, { 1, 1, { 18,17, 2,18, 3, 8, 5, 2, 7,17 } },
+ { 0, 1, { 18,18, 3,18, 6, 8,-2, 2, 3, 5 } }, { 0, 1, { 18,18, 2,18, 2, 6,18, 2,17, 7 } },
+ { 1, 3, { 18,17,18, 2, 8,18, 5,-1, 3, 6 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 1, { 18, 7, 6, 5, 5, 3, 1, 4, 2, 4 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 2, { 18,17,-1, 3, 6,18, 2, 5, 8, 3 } }, { 0, 1, { 17,18,18, 4, 7, 2, 3,-2,18, 5 } },
+ { 1, 2, { 18, 1, 2, 6, 2, 5,18, 2, 4, 8 } }, { 0, 4, { 18, 4, 1, 2, 3, 5, 4, 1, 2, 6 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 2, { 18,17, 2,-1,18, 3,-3, 5, 2, 4 } },
+ { 0, 1, { 17,17, 3, 6, 3, 5,-2, 2,18,-1 } }, { 0, 2, { 18,18, 3,-2,18, 2,-3, 5, 3, 6 } },
+ { 1, 1, { 17,17, 2, 4, 1, 3, 5, 2, 6,-3 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, { 17, 1, 3, 2, 7, 1, 6, 3, 4, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, { 17,-1,18, 2, 1, 5, 3, 8,-1,-2 } }, { 1, 1, { 17,18,-1, 8, 2, 5, 3, 4, 1, 6 } },
+ { 1, 2, {  1,18, 3,-1, 5, 1, 2, 4, 7, 6 } }, { 0, 1, { 18,18, 3, 6, 5, 3,-2, 2,18,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, {  1,18,-1, 3, 8, 5, 6, 1, 2, 3 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 2, { 18,18, 2, 3, 6,18,-1, 4, 2, 3 } }, { 1, 1, {  1, 3, 5,18, 2, 6, 7, 2, 3, 1 } },
+ { 1, 1, {  1, 3, 8,18, 5, 2, 7, 1, 3,-2 } }, { 0, 2, { 17, 2,18, 3, 6, 2, 4, 5, 8, 3 } },
+ { 0, 1, { 18,17, 2,18, 3, 2, 7,-2,18, 4 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 2, { 18,-3,18,-1, 3,-2, 5, 7, 1, 2 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 3, { 18,18, 2, 6,18, 5,18, 2, 3,17 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 3, {  1,-1, 1, 3,-2, 2, 5, 7,-3,18 } }, { 1, 2, { 18, 7, 3,-3, 2, 8, 2, 5, 4,17 } },
+ { 1, 1, {  1, 4, 5, 1, 3, 4, 6, 7, 8, 3 } }, { 0, 1, { 18,17, 2,18,-1, 2, 3,18, 2, 4 } },
+ { 0, 2, { 18,18,-2,18, 2, 3, 4, 7, 5,17 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 1, { 17,18, 2, 1, 3, 2, 5, 1, 2, 3 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 2, { 18,18,-1, 2, 3, 5, 8, 6, 1,-2 } }, { 0, 1, { 17,18, 8, 3, 4, 6, 5, 2, 8, 7 } },
+ { 1, 2, {  1, 3,-2,18, 2, 5, 1, 7,-1,-2 } }, { 0, 3, { 18,17,-1, 3,18, 2, 3, 6, 4,17 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 2, { 18,18, 4,18, 6, 7, 8, 3,18, 2 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 2, { 17,-3,17, 2,-2, 8, 3,18, 4,-3 } }, { 1, 1, { 18,17, 3, 5, 6, 2, 8, 1, 3, 7 } },
+ { 0, 1, { 18,18, 3, 6, 5, 3,-2, 2,18,-1 } }, { 0, 3, { 18,18, 2, 6,18, 5,18, 2, 3,17 } },
+ { 1, 1, { 18,18, 5, 4, 6, 4, 5, 1, 4, 3 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 2, {  3,17,18,-3, 2, 5,18, 6,-1, 7 } }, { 1, 1, { 17,18, 3, 2, 5,-1, 6, 8, 4, 7 } },
+ { 1, 1, { 18, 1,-2, 3, 2, 1, 7, 6, 3, 4 } }, { 0, 3, {  1, 2,17, 3,18, 2, 7, 5, 4,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 1, { 17,-2, 2,18,18, 8, 5, 3, 2, 6 } }, { 0, 2, { 18, 5,18, 2, 3, 7,-2, 1, 6, 8 } },
+ { 0, 1, {  2,-1,18,-1, 2, 4,-3, 5,18, 3 } }, { 0, 1, {  3,17,18, 5, 2,18, 7, 3, 6, 5 } },
+ { 1, 4, {  1, 2, 5,18,-2, 2, 3, 7,-1, 4 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, {  1,18, 2, 1, 3, 4, 1, 5, 2, 7 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { 17,17,18, 2, 4, 5,18,-2, 6, 3 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 2, { 18,18,-1, 3, 5, 6, 8,18, 2, 3 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, { 18,18, 4, 6, 8,18, 7, 3, 2, 5 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 2, { -1,18,18,18, 2, 4,-2, 2, 3, 6 } }, { 0, 2, { 18,-2, 7, 1, 3, 2, 4, 6,-3, 7 } },
+ { 1, 1, { 17,18, 8, 3, 4, 6,-2, 5, 3, 8 } }, { 0, 2, { 18, 1, 2, 6, 2, 8, 3,18, 5, 4 } },
+ { 1, 1, {  3,18,18, 2,18, 2,18, 3, 2,18 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 1, 1, {  3,17,18, 5, 2, 6, 7, 1, 4, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } }, { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2, 8 } },
+};
+
+static const WavPackDecorrSpec very_high_specs[] = {
+ { 1, 2, { 18,18, 2, 3,-2,18, 2, 4, 7, 5, 3, 6, 8,-1,18, 2 } },
+ { 0, 1, { 18,18,-1,18, 2, 3, 4, 6, 5, 7,18,-3, 8, 2,-1, 3 } },
+ { 1, 2, {  1,18,-2, 4,18, 2, 3, 6,-1, 7, 5,-2,18, 8, 2, 4 } },
+ { 0, 1, { 17,17, 2, 3, 4,18,-1, 5, 6, 7,18, 2, 8,17, 3,-2 } },
+ { 1, 1, { 18,18, 2,18, 3, 2,18, 4,-1, 3,18, 2, 6, 8,17, 5 } },
+ { 0, 2, { 18,17, 2, 3,-2, 5,18,-3, 2, 4, 7, 3, 6, 8, 5,17 } },
+ { 1, 1, { 18,-2, 2,-3,18, 5,-2,18, 2, 3, 6, 2,17, 4, 7,-1 } },
+ { 1, 1, { 17, 8,18, 3,-2, 2, 5, 4,18, 6, 3, 8, 7, 2, 5, 4 } },
+ { 0, 2, { 18,17,-2, 2,18, 3, 2, 5,-3, 4, 7,18, 3, 8, 6, 2 } },
+ { 1, 1, {  3, 6, 5, 5, 1, 3, 7, 4, 2, 6, 4,18, 3, 7, 5, 6 } },
+ { 1, 2, {  1,18, 3, 2,-2, 1, 5, 4, 6, 2, 7, 1, 8, 3,-1, 1 } },
+ { 0, 1, { 18,18, 2, 3, 6, 3, 5,-2, 2, 4,18, 3,-2,-1, 6, 7 } },
+ { 0, 1, { -2,18, 2,18, 7, 2, 6,-2, 3, 4,18,18, 2,-3, 8, 5 } },
+ { 0, 2, { 18,18,18, 2, 4, 3,18, 5, 3, 6,-2, 2, 4,18, 8, 7 } },
+ { 0, 1, { -2, 1,18, 2,-2,18,-1, 5, 7, 2, 3, 4,18, 2, 6, 2 } },
+ { 1, 1, { 17,18, 3, 2, 1, 7,-1, 2, 4, 3, 5, 6,-2,18, 7, 8 } },
+ { 1, 1, { 18,18, 2,18, 3, 4, 6,-2,18, 5, 8, 2, 3, 7, 4,-1 } },
+ { 0, 1, { 18,18,18,-1, 2, 3, 4, 6, 8,18, 3, 5, 2, 6, 7, 4 } },
+ { 1, 1, { 17,-2,18,18, 2, 5, 3, 8, 2,-1, 6, 1, 3, 4, 7, 5 } },
+ { 0, 1, { 17,17,18, 2, 3, 6,-2, 8, 1, 7, 5, 2, 3, 1, 4, 8 } },
+ { 1, 1, { 17,17, 3, 2, 7, 1, 4, 3, 6, 2, 5,-2, 8, 7,18, 6 } },
+ { 0, 1, { 18,17,-2, 2,18, 3,-3, 7, 6, 5, 2, 4,-1, 8, 3,17 } },
+ { 1, 1, {  2,18,18,-2, 2, 4,-1, 5,18, 3, 8, 6, 2, 7,17, 4 } },
+ { 0, 1, { 17, 3, 6, 8, 5, 4, 3, 8, 1,18, 7, 2, 4, 5, 6, 3 } },
+ { 1, 2, { 17,18, 4, 8, 3, 2, 5, 7, 6, 8, 2, 7,-2,18, 3, 4 } },
+ { 1, 1, {  6, 5, 5, 3, 4, 7, 3, 2, 4, 6, 3, 7, 1, 5, 2, 4 } },
+ { 1, 1, {  1,18,-1, 2, 1, 3, 8,-2, 2, 5, 6, 3, 8, 7,18, 4 } },
+ { 0, 1, {  1,17,-1,18, 3, 2, 5, 4, 6, 7, 8, 3, 4, 2, 1,-2 } },
+ { 0, 1, { 18, 2,18,18, 2,18, 6,-2,18, 7, 5, 4, 3, 2,18,-2 } },
+ { 0, 3, {  1, 4,18, 3, 2, 4, 1, 5, 2, 3, 6,18, 8, 7, 2, 4 } },
+ { 0, 1, { 17,-2, 1,-3, 2,18, 3,-2, 4,18, 3, 6, 7,-3, 2, 8 } },
+ { 1, 1, { 17,18,18, 4, 2, 3, 7, 6,18, 8, 5,-1, 4, 2, 3,17 } },
+ { 1, 2, { 18,-1,17,18, 2, 3,-2,18, 5, 8, 2, 4, 3, 7, 6,-1 } },
+ { 1, 1, { 18,18,18,-2, 4, 2, 3,18, 5, 8, 2, 4, 6, 7,-2, 3 } },
+ { 1, 2, { 18,18,-2,18,-1, 3, 2, 5,18,-2, 7, 2, 3, 4, 6, 8 } },
+ { 0, 1, { 17,18,-1, 2, 4,18, 8, 3, 6, 5, 7,-3, 2, 4, 3,17 } },
+ { 1, 1, { 18,18,17, 2,-1,18, 3, 2,18, 6, 5, 4,18, 7, 2,-1 } },
+ { 0, 2, {  1,18,-1,18, 3, 2, 4, 6,-3, 7,-1, 5, 1, 2, 3, 8 } },
+ { 1, 1, {  1,17,-2, 2,-3, 6, 3, 5, 1, 2, 7, 6, 8,-2, 4, 1 } },
+ { 0, 1, { 17,-1, 5, 1, 4, 3, 6, 2,-2,18, 3, 2, 4, 5, 8,-1 } },
+ { 0, 2, { 18,18,17, 2, 3,-2, 5,18, 2, 4, 7, 8, 6,17, 3, 5 } },
+ { 1, 1, {  1, 5, 1, 3, 4, 3, 7, 5, 1, 3, 6, 1, 2, 4, 3, 8 } },
+ { 1, 2, {  1,-1, 3, 2,18, 7,-2, 5, 2, 6, 4, 3,-1,18, 8, 7 } },
+ { 0, 2, { 18,17, 3,18, 2, 5, 4, 3, 6, 2, 7, 8,18, 3, 4, 5 } },
+ { 1, 1, {  3, 6,17, 8, 7, 5,18,-1, 1, 2, 3, 4, 2, 6, 8, 1 } },
+ { 0, 2, { 18,18, 3,-3,18, 2, 6, 5, 3, 7,18, 4,-2, 8, 2, 3 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 1, { 17, 1, 7, 2, 3,18,-2, 3, 6, 4, 2, 7, 8, 5, 3,17 } },
+ { 1, 1, {  3, 6, 5, 5, 1, 3, 7, 4, 2, 6, 4,18, 3, 7, 5, 6 } },
+ { 0, 1, { 18,18,18, 2, 4,-1,18, 8,-1, 2, 3, 4, 6,-2, 1, 7 } },
+ { 1, 1, { 18,-2,17,18, 2, 6, 3,-2, 5, 4, 7, 1,-3, 8, 2, 6 } },
+ { 0, 1, { 17,18,18, 4, 2, 7, 3, 6,-2,18, 8, 4, 5, 2, 7,17 } },
+ { 1, 1, { 18,18, 5, 4, 6, 4, 1, 5, 4, 3, 2, 5, 6, 1, 4, 5 } },
+ { 0, 1, { 18,18,-2,18, 2,-3, 3, 8, 5,18, 6, 4, 3,-1, 7, 2 } },
+ { 1, 1, { 18, 2,-2,-3,18, 5, 2, 3,-2, 4, 6, 1,-3, 2, 7, 8 } },
+ { 0, 1, { 18, 3, 5, 8, 2, 6, 7, 3, 1, 5, 2,-1, 8, 6, 7, 4 } },
+ { 1, 1, {  4, 3, 8, 1, 5, 6, 2, 5, 8,-2, 2, 7, 3,18, 5, 4 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 1, { 17, 3,18,18, 7, 2, 4,18, 6, 2, 3,-1, 8, 5,18,-3 } },
+ { 0, 1, {  3,17,18, 2,18, 6, 7,-3,18, 2, 5, 6, 3, 8, 7,-1 } },
+ { 1, 1, { 18,18, 2,18,18, 2,-1, 7, 3,18, 5, 2, 6, 4,-1,18 } },
+ { 0, 3, { 18, 3, 4, 1, 5, 2,18, 4, 2, 3,18, 7, 6, 1, 2, 4 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 1, { 17, 1,18, 2, 3, 6, 4, 5, 7,18, 3, 8, 2, 4,-2,17 } },
+ { 1, 2, { 18,17, 2, 3, 5,18, 6,-2, 7, 3, 2, 4,18, 8,-1, 5 } },
+ { 0, 2, {  1,18,-1,18, 3, 2, 4, 6,-3, 7,-1, 5, 1, 2, 3, 8 } },
+ { 1, 1, {  1,18,-1, 8, 2, 6, 3,-2, 1, 2, 5, 4,-3, 8, 6, 3 } },
+ { 0, 1, { 18,18, 2,18, 2,18, 7, 6,18, 2,-2, 3, 5, 4,18, 8 } },
+ { 1, 2, { 18,17, 2, 3,18,-1, 2, 3, 6,18, 5, 4, 3, 7, 2, 8 } },
+ { 1, 2, { 18,18, 3,-2, 4,18, 5, 7, 6, 2, 4,-3, 8, 5,18, 3 } },
+ { 1, 1, { 17,-2,18,18, 2, 5, 3, 8, 2,-1, 6, 1, 3, 4, 7, 5 } },
+ { 1, 1, {  3,17,18, 5, 7, 2, 4, 6, 1, 8,-1, 3, 7, 4, 1, 2 } },
+ { 0, 2, {  1,-2, 2,18, 3, 5, 2, 4, 7,-1, 2, 3, 5,18,-2, 4 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 1, {  1, 2,-2, 6,18,-3, 2, 7, 3,-2, 5, 6, 1, 8, 2, 4 } },
+ { 0, 1, { 18,18,18, 3,-2, 6,18, 2, 4, 3, 5, 8, 7, 6, 2,-2 } },
+ { 1, 1, {  1, 5, 1, 3, 4, 3, 7, 5, 1, 3, 6, 1, 2, 4, 3, 8 } },
+ { 0, 1, {  3,17,18, 2, 5,18, 6, 7, 5,-2, 2, 4,18, 3, 6, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 2, { 17,-1,18, 2, 4,-1, 8, 3,18, 7,-3, 4, 5, 1, 2,-2 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 8, 6, 4, 5, 7,-1 } },
+ { 1, 1, { 18,18, 3, 6, 4, 8,-2, 2, 5, 3, 7,18, 6, 8, 4, 2 } },
+ { 1, 1, { 17,18,18,-2, 5, 2, 3, 1, 4,-1, 8, 6, 5, 3, 2,18 } },
+ { 1, 1, { 17,17, 1, 2, 4, 5, 2, 6,-1, 3, 1, 1,-2, 4, 2, 7 } },
+ { 1, 1, { 17, 1, 7, 2, 3,18,-2, 3, 6, 4, 2, 7, 8, 5, 3,17 } },
+ { 0, 1, { 18,17,-2,-3, 1, 2, 3, 2, 5, 4, 7,-3, 6,-2, 2, 1 } },
+ { 1, 1, {  1, 3, 5,18, 1, 2, 7, 3, 6, 2, 5, 8,-1, 1, 4, 7 } },
+ { 1, 1, { 17, 3, 6, 8, 1, 4, 5, 3,-2, 7, 2, 8, 5, 6,18, 3 } },
+ { 1, 1, { 17,18, 2, 4, 8,-2, 3, 1, 5, 6, 7, 1, 2, 3, 4, 7 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 1, {  3, 1, 8,18, 5, 2, 3,18, 6, 7,-2, 4, 3, 2, 8,18 } },
+ { 0, 1, { 18,17, 2,18, 3, 4,-1,18, 7, 6, 2, 8, 4,18,18, 5 } },
+ { 0, 1, { 18,18, 2,18,18, 2, 7,-2, 6, 5, 4, 3,18, 3, 2,17 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 1, { 17, 8,18, 3, 2, 1, 5, 4, 6,-1, 3,-3, 8,18, 7, 2 } },
+ { 1, 2, { 18,17,18, 2, 3, 5,-2,18, 6,-1, 2, 3, 7, 4, 8,17 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 8, 6, 4, 5, 7,-1 } },
+ { 1, 2, { 18,18,-2,17, 2,18, 3, 4,18, 8, 7,-1, 2, 4, 5,17 } },
+ { 0, 2, { 17,-3,17, 3, 2,-2,18, 8, 4,-3, 2,18, 5, 3,-2, 6 } },
+ { 0, 1, { 18,18, 2,18,18, 2, 7,-2, 6, 5, 4, 3,18, 3, 2,17 } },
+ { 0, 2, {  1,18,-1, 3, 5, 2,-3,18, 7, 3,-1, 6, 4, 2,17, 5 } },
+ { 1, 1, { 17,-2,17, 2,-3, 1, 5,-1, 4, 6, 3, 2, 8, 7,-2, 5 } },
+ { 1, 1, {  1,18, 1, 3, 5, 8, 6, 2, 3,-1, 7, 1, 4, 8, 5,-3 } },
+ { 0, 2, {  3,18,18, 2,18,-2, 6, 5, 7, 2, 4,18, 3, 6,-3, 5 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 1, {  3, 6,17, 8, 7, 5,18,-1, 1, 2, 3, 4, 2, 6, 8, 1 } },
+ { 0, 4, { 18, 2,17, 3,18,-2, 2, 6,18, 2, 7, 3, 5, 4, 8,18 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { 18,18, 2, 3, 6, 3, 5,-2, 2, 4,18, 3,-2,-1, 6, 7 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 1, { 17, 1, 2, 5, 3,-2, 1, 4, 3, 7, 6,-3, 2, 1, 1, 2 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 1, { 18,18,-2,18,-2, 2, 3, 6,18, 4,-1, 2, 3, 8, 1, 4 } },
+ { 1, 1, { 17,-2,17, 2,-3, 1, 5,-1, 4, 6, 3, 2, 8, 7,-2, 5 } },
+ { 0, 1, { 17,17,18, 3, 2,18,18, 6, 8, 2,-2, 3, 5, 4,17,18 } },
+ { 1, 1, {  1, 5, 1, 3, 4, 3, 7, 5, 1, 3, 6, 1, 2, 4, 3, 8 } },
+ { 1, 1, {  1, 3,-3,18,18, 6, 5,18, 2,-1, 3, 8, 7,-3, 4,17 } },
+ { 1, 1, { 18, 1, 2, 1, 3, 8, 7, 4, 1, 5, 2,-1,-3,18, 6, 2 } },
+ { 0, 1, { 18, 3, 5, 2, 6, 8,18, 5, 7, 2, 3,-1, 6, 7, 8, 5 } },
+ { 0, 2, { 18, 3,-2, 7, 8, 2, 5, 4,-3, 8, 3, 2,18, 5, 4, 6 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 3, {  1, 1, 2, 5, 2, 7, 4, 3,-1,18,-2, 8, 2, 1, 6, 7 } },
+ { 0, 1, {  3,17,18, 5, 2, 6, 7,18, 4, 5, 3, 6,18, 2, 7, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, {  1,18, 1, 2, 3, 5, 1, 2, 6, 7, 4, 3, 8, 1,17, 5 } },
+ { 1, 2, { 17,-1,18,-2, 2, 3, 5,18, 2, 4, 6, 7, 3,-1, 5, 8 } },
+ { 1, 1, { 18,18,-3,18,-2, 2, 3,-2,18, 6, 4, 5, 8, 3,17,-3 } },
+ { 1, 1, { 18, 7, 6, 5, 5, 3, 1, 4, 2, 7, 3, 4,-3, 6,18, 8 } },
+ { 0, 2, { 18,18, 2, 3, 5,18, 2, 4, 3, 6,18, 7, 8,-1, 5, 2 } },
+ { 0, 1, { 18,17,-1, 2,18, 3, 2,18, 4, 3,18, 2, 6, 5, 8,17 } },
+ { 0, 2, { 18,17, 2, 3,18, 5,-1, 6, 7, 8, 2, 3, 4, 5,18, 6 } },
+ { 1, 2, { 18,-3,18, 2, 3,-2,-3, 5,18, 7, 6, 2, 4, 3, 8,-2 } },
+ { 1, 1, { 17,18,18,-2, 2, 3, 5, 4, 8,18,-1, 5, 3, 6,-2, 7 } },
+ { 1, 2, { 18,17, 2,-2,18, 3,-1, 4,18, 2, 7, 5, 3, 8, 6, 4 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 1, {  1, 5, 1, 3, 4, 3, 7, 5, 1, 3, 6, 1, 2, 4, 3, 8 } },
+ { 0, 2, { 18,18, 3, 3,-2, 2, 5,18, 6, 3,-1, 4, 7,-1, 1, 2 } },
+ { 0, 1, { -2, 1,18, 2,-2, 5, 7,18, 3, 2, 6, 2,-1, 4,-2,17 } },
+ { 0, 2, { 18,18,18, 2, 3,-2,18, 5, 4, 2, 6, 8, 3,-2, 4,18 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 1, { 17,18,-1, 3, 2, 5, 1, 3, 2, 8, 4, 7, 6, 2,-1, 5 } },
+ { 1, 1, { 17,18,18, 4, 2, 3, 7, 6,18, 8, 5,-1, 4, 2, 3,17 } },
+ { 0, 1, { 18,18,-2,18, 2, 3, 4, 5, 6,18, 8, 2, 3, 7,-2, 4 } },
+ { 0, 1, { 18,-2,18,18,-3,-2, 2, 3, 5, 8, 1, 2, 6, 4, 7,-1 } },
+ { 0, 1, { 18,17, 2,18, 3,-2, 2, 7, 6, 4,18, 3, 8, 7, 4, 2 } },
+ { 1, 1, { 17,18,18, 4, 2, 3, 7, 6,18, 8, 5,-1, 4, 2, 3,17 } },
+ { 1, 1, { 18,17,18, 2, 5, 3,-2,18, 6, 2, 3, 4, 8, 7, 5,-1 } },
+ { 0, 1, {  2,-1,18,-1, 2, 4,-3,18, 5, 3, 6,18, 2, 4, 7, 8 } },
+ { 1, 1, { 17,18, 8, 3, 6, 4,-1, 5, 2, 7, 3, 8, 6, 5,18, 4 } },
+ { 0, 2, { 18, 3,-2, 7, 8, 2, 5, 4,-3, 8, 3, 2,18, 5, 4, 6 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 1, {  1,18,-1, 8, 2, 6, 3,-2, 1, 2, 5, 4,-3, 8, 6, 3 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { 17,18,18, 4, 2, 7, 3, 6,-2,18, 8, 4, 5, 2, 7,17 } },
+ { 1, 2, { 18,-1,18, 3,-2,18, 2, 5, 3, 6, 7, 2,-1,18, 8, 4 } },
+ { 1, 2, {  1,18,-2, 4,18, 2, 3, 6,-1, 7, 5,-2,18, 8, 2, 4 } },
+ { 1, 2, {  1,18,-3, 2, 3,18,-1, 5, 6, 2, 8, 3, 4, 1,-2, 7 } },
+ { 0, 1, {  1,17,-1,18, 3, 2, 5, 4, 6, 7, 8, 3, 4, 2, 1,-2 } },
+ { 1, 1, { 18,17,18, 4, 3, 5, 1, 2, 6, 3, 4, 7, 1, 8, 5, 2 } },
+ { 0, 1, { 18,-2, 7, 1, 3, 2,-3, 4, 6,-2, 7, 8, 1, 5, 4, 3 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 2, { 18,18,18,-2, 2, 5, 3, 7,18, 2, 4,-3, 5, 6, 3, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 3, {  3,18,-1, 5, 2, 7,18, 6, 5, 2, 4, 3,-1, 7,18, 6 } },
+ { 0, 2, { 18,18,18, 4, 3, 2, 6, 4, 8,18, 5, 3, 2, 7,-2, 6 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 2, { 18,18,18, 2, 3,-2,18, 5, 4, 2, 6, 8, 3,-2, 4,18 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 1, { 17, 8,18, 3, 2, 1, 5, 4, 6,-1, 3,-3, 8,18, 7, 2 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18,18, 2, 4, 6,-2, 2, 8, 3, 4,18, 7,-1, 6 } },
+ { 0, 1, { 18, 1,-2, 2, 4, 1, 3,-1, 2, 5, 7, 1, 6, 8,-2,17 } },
+ { 0, 1, { 17,17,18, 2, 5, 4,18, 3, 8, 7, 4, 6, 8, 1, 5, 2 } },
+ { 1, 2, { 18,18, 5, 4, 6, 3, 4,18, 8, 4,-1, 7, 5, 3, 6, 2 } },
+ { 0, 1, { 18,18,-3,18, 3, 6, 2, 5, 7,18, 3, 8,-1, 4, 5, 2 } },
+ { 1, 1, { 18, 2,-2,-3,18, 5, 2,-2, 4, 3, 6,18, 8,-1, 2, 7 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 1, { 17, 1, 7, 2, 3,18,-2, 3, 6, 4, 2, 7, 8, 5, 3,17 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { 17,18, 3,18, 2, 5, 4, 7,-3, 6, 3, 2,18, 4, 7, 3 } },
+ { 1, 1, {  1, 7, 4, 5, 3, 4, 5, 1, 3, 6, 3, 2, 4, 8,-2, 7 } },
+ { 0, 1, {  1,18,-1,-2,18, 3, 2,-1, 6, 7, 4, 5, 3,18, 2,-3 } },
+ { 1, 1, { 18,18,-1, 3, 6,18, 5, 4, 8, 2, 3, 6,18, 7, 4,-2 } },
+ { 0, 2, { 18,18, 2, 6,18, 2,18, 5, 3,18, 2, 4, 7, 8, 3,18 } },
+ { 1, 1, {  3,18,18, 5,18, 6, 2, 4, 7,-2,18, 5, 8, 6, 3, 2 } },
+ { 0, 1, { 18,-2, 7, 1, 3, 2,-3, 4, 6,-2, 7, 8, 1, 5, 4, 3 } },
+ { 1, 1, { 18,-2,18, 2, 5,18, 3,-2, 4, 7, 2,-1, 8, 6, 5, 1 } },
+ { 1, 1, { 17,17, 5,18, 4, 1, 2, 8, 6, 4,-2, 3, 5,-1, 1, 8 } },
+ { 0, 2, {  1, 2,17, 3, 7,18, 2,-1, 4, 5,18, 2, 7, 3, 6, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 1, {  3, 6,17, 8, 7, 5,18,-1, 1, 2, 3, 4, 2, 6, 8, 1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 2, { 18,18,18, 2,-2, 3, 6, 4, 8,18, 2, 5, 7, 4, 3, 6 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 1, { 18, 1, 8, 3, 5, 6, 4,-1, 8, 3, 7,18, 2, 5, 8, 4 } },
+ { 1, 1, { 17,18, 5, 2, 4, 3, 1, 6,-2, 1, 3, 2, 4, 5,-1,17 } },
+ { 1, 1, { 18,17, 2,18, 3,-3, 7, 2, 6, 4, 3, 5,18, 8, 2,-2 } },
+ { 1, 1, { 18,17,18, 4, 3, 5,-1,18, 2, 7, 8, 4, 6, 3,18, 5 } },
+ { 0, 1, { 18,17,18,-2, 2,-3, 3, 4, 8, 5, 2,18, 6, 3, 7,-2 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 1, { 17,18, 8, 3, 4, 6,18, 5,-2, 3, 8, 5, 2, 4, 7, 6 } },
+ { 0, 1, { 18,-2, 3, 5, 1, 7, 3, 2, 6,-3, 4, 1, 5, 8, 3,-2 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 1, {  3,17,18, 5,-1,18, 2, 6, 7,18, 5, 3,-3,-1, 6, 2 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 3, { 18,17,-2, 3,-1,18, 2, 5, 3, 7, 6, 2, 4, 8,18, 5 } },
+ { 0, 1, { 18,-1,18, 2,18, 3, 5,18, 2, 8,18, 5, 4,-1, 6, 2 } },
+ { 1, 2, { 18,-2,18,18, 2, 3, 4,-3, 2, 5,18, 7, 4, 3, 8, 6 } },
+ { 0, 2, { 17,-1,18, 2,-1, 1, 7, 3, 8, 5,-2, 4, 1, 2,-3, 6 } },
+ { 0, 1, { 18,17, 2,18, 2,18, 6, 7, 4, 3,18, 5, 2,-2,17, 8 } },
+ { 0, 3, { 18,17, 2, 3,-3,-1,18, 2, 4, 5,18, 7, 3, 2,-3, 6 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 2, {  3,18,18,18, 2, 6, 5,18, 7, 2, 4, 6,18, 5, 3, 8 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { 18,18, 3, 6, 3,-2, 2,18, 5,-1, 7, 3, 4,-2, 2, 6 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 1, 1, { 18,17,18,18,-2, 2, 3,-3,18, 6, 4, 2,-2, 8, 3, 7 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { 18,18,18, 4, 2, 7, 8,18, 3, 2,-2, 4, 7, 6,17, 5 } },
+ { 1, 1, { 18,18,-1,-2, 8, 3,18, 6, 3, 5, 8, 2, 4, 7, 1, 6 } },
+ { 1, 1, {  1,-3, 3,18,18, 2,-1, 3, 6, 5,18, 4, 7,-2, 8, 3 } },
+ { 1, 1, {  1,18, 4, 2, 5,18, 1, 3,-1, 6, 1, 4, 8, 2, 5, 1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+ { 0, 1, { -1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 } },
+};
+
+static const WavPackDecorrSpec const *decorr_filters[] = {
+    &fast_specs[0], &default_specs[0], &high_specs[0], &very_high_specs[0],
+};
+
+static const uint16_t decorr_filter_sizes[] = {
+    FF_ARRAY_ELEMS(fast_specs),
+    FF_ARRAY_ELEMS(default_specs),
+    FF_ARRAY_ELEMS(high_specs),
+    FF_ARRAY_ELEMS(very_high_specs),
+};
+
+static const uint8_t decorr_filter_nterms[] = { 2, 5, 10, 16 };
+
+static const int8_t nbits_table[] = {
+ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
+};
+
+#endif /* AVCODEC_WAVPACKENC_H */
diff --git a/libavcodec/wma.c b/libavcodec/wma.c
index 1e6ca61..0122ee6 100644
--- a/libavcodec/wma.c
+++ b/libavcodec/wma.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "avcodec.h"
 #include "sinewin.h"
 #include "wma.h"
@@ -30,9 +31,9 @@
 
 /* XXX: use same run/length optimization as mpeg decoders */
 //FIXME maybe split decode / encode or pass flag
-static void init_coef_vlc(VLC *vlc, uint16_t **prun_table,
-                          float **plevel_table, uint16_t **pint_table,
-                          const CoefVLCTable *vlc_table)
+static av_cold void init_coef_vlc(VLC *vlc, uint16_t **prun_table,
+                                  float **plevel_table, uint16_t **pint_table,
+                                  const CoefVLCTable *vlc_table)
 {
     int n = vlc_table->n;
     const uint8_t  *table_bits   = vlc_table->huffbits;
@@ -68,7 +69,7 @@
     av_free(level_table);
 }
 
-int ff_wma_init(AVCodecContext *avctx, int flags2)
+av_cold int ff_wma_init(AVCodecContext *avctx, int flags2)
 {
     WMACodecContext *s = avctx->priv_data;
     int i;
@@ -307,7 +308,7 @@
     }
 #endif
 
-    /* init MDCT windows : simple sinus window */
+    /* init MDCT windows : simple sine window */
     for (i = 0; i < s->nb_block_sizes; i++) {
         ff_init_ff_sine_windows(s->frame_len_bits - i);
         s->windows[i] = ff_sine_windows[s->frame_len_bits - i];
diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c
index 0648c1e..d46eb33 100644
--- a/libavcodec/wmadec.c
+++ b/libavcodec/wmadec.c
@@ -33,6 +33,7 @@
  * should be 4 extra bytes for v1 data and 6 extra bytes for v2 data.
  */
 
+#include "libavutil/attributes.h"
 #include "avcodec.h"
 #include "internal.h"
 #include "wma.h"
@@ -66,7 +67,7 @@
 }
 #endif
 
-static int wma_decode_init(AVCodecContext * avctx)
+static av_cold int wma_decode_init(AVCodecContext * avctx)
 {
     WMACodecContext *s = avctx->priv_data;
     int i, flags2;
@@ -150,7 +151,7 @@
     return s->lsp_pow_e_table[e] * (a + b * t.f);
 }
 
-static void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len)
+static av_cold void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len)
 {
     float wdel, a, b;
     int i, e, m;
diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c
index 799535e..1ca733b 100644
--- a/libavcodec/wmaenc.c
+++ b/libavcodec/wmaenc.c
@@ -19,13 +19,15 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "avcodec.h"
 #include "internal.h"
 #include "wma.h"
 #include "libavutil/avassert.h"
 
 
-static int encode_init(AVCodecContext * avctx){
+static av_cold int encode_init(AVCodecContext *avctx)
+{
     WMACodecContext *s = avctx->priv_data;
     int i, flags1, flags2, block_align;
     uint8_t *extradata;
@@ -175,7 +177,7 @@
     }
 
     s->block_len = 1 << s->block_len_bits;
-//     assert((s->block_pos + s->block_len) <= s->frame_len);
+//     av_assert0((s->block_pos + s->block_len) <= s->frame_len);
     bsize = s->frame_len_bits - s->block_len_bits;
 
     //FIXME factor
@@ -374,6 +376,11 @@
 
     while(total_gain <= 128 && error > 0)
         error = encode_frame(s, s->coefs, avpkt->data, avpkt->size, total_gain++);
+    if (error > 0) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid input data or requested bitrate too low, cannot encode\n");
+        avpkt->size = 0;
+        return AVERROR(EINVAL);
+    }
     av_assert0((put_bits_count(&s->pb) & 7) == 0);
     i= avctx->block_align - (put_bits_count(&s->pb)+7)/8;
     av_assert0(i>=0);
diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c
index 90a0109..50927ca 100644
--- a/libavcodec/wmalosslessdec.c
+++ b/libavcodec/wmalosslessdec.c
@@ -66,7 +66,7 @@
 typedef struct WmallDecodeCtx {
     /* generic decoder variables */
     AVCodecContext  *avctx;
-    AVFrame         frame;
+    AVFrame         *frame;
     uint8_t         frame_data[MAX_FRAMESIZE + FF_INPUT_BUFFER_PADDING_SIZE];  ///< compressed frame data
     PutBitContext   pb;                             ///< context for filling the frame_data buffer
 
@@ -261,8 +261,10 @@
         return AVERROR_PATCHWELCOME;
     }
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame    = &s->frame;
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
+
     avctx->channel_layout = channel_mask;
     return 0;
 }
@@ -908,7 +910,7 @@
     } else if (!s->cdlms[0][0].order) {
         av_log(s->avctx, AV_LOG_DEBUG,
                "Waiting for seekable tile\n");
-        s->frame.nb_samples = 0;
+        av_frame_unref(s->frame);
         return -1;
     }
 
@@ -1015,15 +1017,15 @@
     GetBitContext* gb = &s->gb;
     int more_frames = 0, len = 0, i, ret;
 
-    s->frame.nb_samples = s->samples_per_frame;
-    if ((ret = ff_get_buffer(s->avctx, &s->frame, 0)) < 0) {
+    s->frame->nb_samples = s->samples_per_frame;
+    if ((ret = ff_get_buffer(s->avctx, s->frame, 0)) < 0) {
         /* return an error if no frame could be decoded at all */
         s->packet_loss = 1;
         return ret;
     }
     for (i = 0; i < s->num_channels; i++) {
-        s->samples_16[i] = (int16_t *)s->frame.extended_data[i];
-        s->samples_32[i] = (int32_t *)s->frame.extended_data[i];
+        s->samples_16[i] = (int16_t *)s->frame->extended_data[i];
+        s->samples_32[i] = (int32_t *)s->frame->extended_data[i];
     }
 
     /* get frame length */
@@ -1170,7 +1172,7 @@
     int buf_size       = avpkt->size;
     int num_bits_prev_frame, packet_sequence_number, spliced_packet;
 
-    s->frame.nb_samples = 0;
+    s->frame->nb_samples = 0;
 
     if (s->packet_done || s->packet_loss) {
         s->packet_done = 0;
@@ -1263,8 +1265,8 @@
         save_bits(s, gb, remaining_bits(s, gb), 0);
     }
 
-    *got_frame_ptr   = s->frame.nb_samples > 0;
-    av_frame_move_ref(data, &s->frame);
+    *got_frame_ptr   = s->frame->nb_samples > 0;
+    av_frame_move_ref(data, s->frame);
 
     s->packet_offset = get_bits_count(gb) & 7;
 
@@ -1280,16 +1282,26 @@
     s->frame_offset      = 0;
     s->next_packet_start = 0;
     s->cdlms[0][0].order = 0;
-    s->frame.nb_samples  = 0;
+    s->frame->nb_samples = 0;
     init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);
 }
 
+static av_cold int decode_close(AVCodecContext *avctx)
+{
+    WmallDecodeCtx *s = avctx->priv_data;
+
+    av_frame_free(&s->frame);
+
+    return 0;
+}
+
 AVCodec ff_wmalossless_decoder = {
     .name           = "wmalossless",
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_WMALOSSLESS,
     .priv_data_size = sizeof(WmallDecodeCtx),
     .init           = decode_init,
+    .close          = decode_close,
     .decode         = decode_packet,
     .flush          = flush,
     .capabilities   = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1 | CODEC_CAP_DELAY,
diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c
index 07cc223..4bd2d36 100644
--- a/libavcodec/wmaprodec.c
+++ b/libavcodec/wmaprodec.c
@@ -106,6 +106,7 @@
 
 #define WMAPRO_BLOCK_MIN_BITS  6                                           ///< log2 of min block size
 #define WMAPRO_BLOCK_MAX_BITS 13                                           ///< log2 of max block size
+#define WMAPRO_BLOCK_MIN_SIZE (1 << WMAPRO_BLOCK_MIN_BITS)                 ///< minimum block size
 #define WMAPRO_BLOCK_MAX_SIZE (1 << WMAPRO_BLOCK_MAX_BITS)                 ///< maximum block size
 #define WMAPRO_BLOCK_SIZES    (WMAPRO_BLOCK_MAX_BITS - WMAPRO_BLOCK_MIN_BITS + 1) ///< possible block sizes
 
@@ -124,7 +125,7 @@
 static VLC              vec2_vlc;         ///< 2 coefficients per symbol
 static VLC              vec1_vlc;         ///< 1 coefficient per symbol
 static VLC              coef_vlc[2];      ///< coefficient run length vlc codes
-static float            sin64[33];        ///< sinus table for decorrelation
+static float            sin64[33];        ///< sine table for decorrelation
 
 /**
  * @brief frame specific decoder context for a single channel
@@ -305,6 +306,10 @@
 
     /** generic init */
     s->log2_frame_size = av_log2(avctx->block_align) + 4;
+    if (s->log2_frame_size > 25) {
+        avpriv_request_sample(avctx, "Large block align");
+        return AVERROR_PATCHWELCOME;
+    }
 
     /** frame info */
     s->skip_frame  = 1; /* skip first frame */
@@ -336,7 +341,7 @@
         return AVERROR_INVALIDDATA;
     }
 
-    if (s->min_samples_per_subframe < (1<<WMAPRO_BLOCK_MIN_BITS)) {
+    if (s->min_samples_per_subframe < WMAPRO_BLOCK_MIN_SIZE) {
         av_log(avctx, AV_LOG_ERROR, "min_samples_per_subframe of %d too small\n",
                s->min_samples_per_subframe);
         return AVERROR_INVALIDDATA;
@@ -438,8 +443,10 @@
                            + s->sfb_offsets[i][b + 1] - 1) << i) >> 1;
             for (x = 0; x < num_possible_block_sizes; x++) {
                 int v = 0;
-                while (s->sfb_offsets[x][v + 1] << x < offset)
-                    ++v;
+                while (s->sfb_offsets[x][v + 1] << x < offset) {
+                    v++;
+                    av_assert0(v < MAX_BANDS);
+                }
                 s->sf_offsets[i][x][b] = v;
             }
         }
@@ -451,7 +458,7 @@
                      1.0 / (1 << (WMAPRO_BLOCK_MIN_BITS + i - 1))
                      / (1 << (s->bits_per_sample - 1)));
 
-    /** init MDCT windows: simple sinus window */
+    /** init MDCT windows: simple sine window */
     for (i = 0; i < WMAPRO_BLOCK_SIZES; i++) {
         const int win_idx = WMAPRO_BLOCK_MAX_BITS - i;
         ff_init_ff_sine_windows(win_idx);
@@ -726,6 +733,7 @@
                     if (get_bits1(&s->gb)) {
                         avpriv_request_sample(s->avctx,
                                               "Unknown channel transform type");
+                        return AVERROR_PATCHWELCOME;
                     }
                 } else {
                     chgroup->transform = 1;
@@ -1128,11 +1136,12 @@
     cur_subwoofer_cutoff = s->subwoofer_cutoffs[s->table_idx];
 
     /** configure the decoder for the current subframe */
+    offset += s->samples_per_frame >> 1;
+
     for (i = 0; i < s->channels_for_cur_subframe; i++) {
         int c = s->channel_indexes_for_cur_subframe[i];
 
-        s->channel[c].coeffs = &s->channel[c].out[(s->samples_per_frame >> 1)
-                                                  + offset];
+        s->channel[c].coeffs = &s->channel[c].out[offset];
     }
 
     s->subframe_len = subframe_len;
@@ -1188,6 +1197,7 @@
                     av_log(s->avctx, AV_LOG_ERROR, "num_vec_coeffs %d is too large\n", num_vec_coeffs);
                     return AVERROR_INVALIDDATA;
                 }
+                av_assert0(num_vec_coeffs + offset <= FF_ARRAY_ELEMS(s->channel[c].out));
                 s->channel[c].num_vec_coeffs = num_vec_coeffs;
             }
         } else {
@@ -1469,6 +1479,8 @@
         return;
     }
 
+    av_assert0(len <= put_bits_left(&s->pb));
+
     s->num_saved_bits += len;
     if (!append) {
         avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3),
@@ -1581,7 +1593,8 @@
             (frame_size = show_bits(gb, s->log2_frame_size)) &&
             frame_size <= remaining_bits(s, gb)) {
             save_bits(s, gb, frame_size, 0);
-            s->packet_done = !decode_frame(s, data, got_frame_ptr);
+            if (!s->packet_loss)
+                s->packet_done = !decode_frame(s, data, got_frame_ptr);
         } else if (!s->len_prefix
                    && s->num_saved_bits > get_bits_count(&s->gb)) {
             /** when the frames do not have a length prefix, we don't know
diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c
index 19f8965..c0fd823 100644
--- a/libavcodec/wmavoice.c
+++ b/libavcodec/wmavoice.c
@@ -303,6 +303,20 @@
  */
 static av_cold int decode_vbmtree(GetBitContext *gb, int8_t vbm_tree[25])
 {
+    int cntr[8] = { 0 }, n, res;
+
+    memset(vbm_tree, 0xff, sizeof(vbm_tree[0]) * 25);
+    for (n = 0; n < 17; n++) {
+        res = get_bits(gb, 3);
+        if (cntr[res] > 3) // should be >= 3 + (res == 7))
+            return -1;
+        vbm_tree[res * 3 + cntr[res]++] = n;
+    }
+    return 0;
+}
+
+static av_cold void wmavoice_init_static_data(AVCodec *codec)
+{
     static const uint8_t bits[] = {
          2,  2,  2,  4,  4,  4,
          6,  6,  6,  8,  8,  8,
@@ -318,18 +332,9 @@
           0x0ffc, 0x0ffd, 0x0ffe,        //   1111111111+00/01/10
           0x3ffc, 0x3ffd, 0x3ffe, 0x3fff // 111111111111+xx
     };
-    int cntr[8] = { 0 }, n, res;
 
-    memset(vbm_tree, 0xff, sizeof(vbm_tree[0]) * 25);
-    for (n = 0; n < 17; n++) {
-        res = get_bits(gb, 3);
-        if (cntr[res] > 3) // should be >= 3 + (res == 7))
-            return -1;
-        vbm_tree[res * 3 + cntr[res]++] = n;
-    }
     INIT_VLC_STATIC(&frame_type_vlc, VLC_NBITS, sizeof(bits),
                     bits, 1, 1, codes, 2, 2, 132);
-    return 0;
 }
 
 /**
@@ -352,7 +357,7 @@
         av_log(ctx, AV_LOG_ERROR,
                "Invalid extradata size %d (should be 46)\n",
                ctx->extradata_size);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     flags                = AV_RL32(ctx->extradata + 18);
     s->spillover_bitsize = 3 + av_ceil_log2(ctx->block_align);
@@ -375,7 +380,7 @@
         av_log(ctx, AV_LOG_ERROR,
                "Invalid denoise filter strength %d (max=11)\n",
                s->denoise_strength);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     s->denoise_tilt_corr = !!(flags & 0x40);
     s->dc_level          =   (flags >> 7) & 0xF;
@@ -397,7 +402,7 @@
     init_get_bits(&s->gb, ctx->extradata + 22, (ctx->extradata_size - 22) << 3);
     if (decode_vbmtree(&s->gb, s->vbm_tree) < 0) {
         av_log(ctx, AV_LOG_ERROR, "Invalid VBM tree; broken extradata?\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     s->min_pitch_val    = ((ctx->sample_rate << 8)      /  400 + 50) >> 8;
@@ -405,7 +410,7 @@
     pitch_range         = s->max_pitch_val - s->min_pitch_val;
     if (pitch_range <= 0) {
         av_log(ctx, AV_LOG_ERROR, "Invalid pitch range; broken extradata?\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     s->pitch_nbits      = av_ceil_log2(pitch_range);
     s->last_pitch_val   = 40;
@@ -420,7 +425,7 @@
                "Unsupported samplerate %d (min=%d, max=%d)\n",
                ctx->sample_rate, min_sr, max_sr); // 322-22097 Hz
 
-        return -1;
+        return AVERROR(ENOSYS);
     }
 
     s->block_conv_table[0]      = s->min_pitch_val;
@@ -430,7 +435,7 @@
     s->block_delta_pitch_hrange = (pitch_range >> 3) & ~0xF;
     if (s->block_delta_pitch_hrange <= 0) {
         av_log(ctx, AV_LOG_ERROR, "Invalid delta pitch hrange; broken extradata?\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     s->block_delta_pitch_nbits  = 1 + av_ceil_log2(s->block_delta_pitch_hrange);
     s->block_pitch_range        = s->block_conv_table[2] +
@@ -605,7 +610,7 @@
 
         /* 70.57 =~ 1/log10(1.0331663) */
         idx = (pwr * gain_mul - 0.0295) * 70.570526123;
-        if (idx > 127) { // fallback if index falls outside table range
+        if (idx > 127) { // fall back if index falls outside table range
             coeffs[n] = wmavoice_energy_table[127] *
                         powf(1.0331663, idx - 127);
         } else
@@ -613,7 +618,7 @@
     }
 
     /* calculate the Hilbert transform of the gains, which we do (since this
-     * is a sinus input) by doing a phase shift (in theory, H(sin())=cos()).
+     * is a sine input) by doing a phase shift (in theory, H(sin())=cos()).
      * Hilbert_Transform(RDFT(x)) = Laplace_Transform(x), which calculates the
      * "moment" of the LPCs in this filter. */
     s->dct.dct_calc(&s->dct, lpcs);
@@ -1045,9 +1050,10 @@
  * @param gb bit I/O context
  * @param block_idx block index in frame [0, 1]
  * @param fcb structure containing fixed codebook vector info
+ * @return -1 on error, 0 otherwise
  */
-static void aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb,
-                          int block_idx, AMRFixed *fcb)
+static int aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb,
+                         int block_idx, AMRFixed *fcb)
 {
     uint16_t use_mask_mem[9]; // only 5 are used, rest is padding
     uint16_t *use_mask = use_mask_mem + 2;
@@ -1109,7 +1115,7 @@
             else if (use_mask[2]) idx = 0x2F;
             else if (use_mask[3]) idx = 0x3F;
             else if (use_mask[4]) idx = 0x4F;
-            else                  return;
+            else return -1;
             idx -= av_log2_16bit(use_mask[idx >> 4]);
         }
         if (use_mask[idx >> 4] & (0x8000 >> (idx & 15))) {
@@ -1126,6 +1132,7 @@
     /* set offset for next block, relative to start of that block */
     n = (MAX_FRAMESIZE / 2 - start_off) % fcb->pitch_lag;
     s->aw_next_pulse_off_cache = n ? fcb->pitch_lag - n : 0;
+    return 0;
 }
 
 /**
@@ -1288,7 +1295,18 @@
      * (fixed) codebook pulses of the speech signal. */
     if (frame_desc->fcb_type == FCB_TYPE_AW_PULSES) {
         aw_pulse_set1(s, gb, block_idx, &fcb);
-        aw_pulse_set2(s, gb, block_idx, &fcb);
+        if (aw_pulse_set2(s, gb, block_idx, &fcb)) {
+            /* Conceal the block with silence and return.
+             * Skip the correct amount of bits to read the next
+             * block from the correct offset. */
+            int r_idx = pRNG(s->frame_cntr, block_idx, size);
+
+            for (n = 0; n < size; n++)
+                excitation[n] =
+                    wmavoice_std_codebook[r_idx + n] * s->silence_gain;
+            skip_bits(gb, 7 + 1);
+            return;
+        }
     } else /* FCB_TYPE_EXC_PULSES */ {
         int offset_nbits = 5 - frame_desc->log_n_blocks;
 
@@ -1445,7 +1463,7 @@
     if (bd_idx < 0) {
         av_log(ctx, AV_LOG_ERROR,
                "Invalid frame type VLC code, skipping\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     block_nsamples = MAX_FRAMESIZE / frame_descs[bd_idx].n_blocks;
@@ -1642,7 +1660,7 @@
  *                does not modify the state of the bitreader; it
  *                only uses it to copy the current stream position
  * @param s WMA Voice decoding context private data
- * @return -1 if unsupported, 1 on not enough bits or 0 if OK.
+ * @return < 0 on error, 1 on not enough bits or 0 if OK.
  */
 static int check_bits_for_superframe(GetBitContext *orig_gb,
                                      WMAVoiceContext *s)
@@ -1660,7 +1678,7 @@
     if (get_bits_left(gb) < 14)
         return 1;
     if (!get_bits1(gb))
-        return -1;                        // WMAPro-in-WMAVoice superframe
+        return AVERROR(ENOSYS);           // WMAPro-in-WMAVoice superframe
     if (get_bits1(gb)) skip_bits(gb, 12); // number of  samples in superframe
     if (s->has_residual_lsps) {           // residual LSPs (for all frames)
         if (get_bits_left(gb) < s->sframe_lsp_bitsize)
@@ -1678,7 +1696,7 @@
         }
         bd_idx = s->vbm_tree[get_vlc2(gb, frame_type_vlc.table, 6, 3)];
         if (bd_idx < 0)
-            return -1;                   // invalid frame type VLC code
+            return AVERROR_INVALIDDATA; // invalid frame type VLC code
         frame_desc = &frame_descs[bd_idx];
         if (frame_desc->acb_type == ACB_TYPE_ASYMMETRIC) {
             if (get_bits_left(gb) < s->pitch_nbits)
@@ -1756,7 +1774,8 @@
     if ((res = check_bits_for_superframe(gb, s)) == 1) {
         *got_frame_ptr = 0;
         return 1;
-    }
+    } else if (res < 0)
+        return res;
 
     /* First bit is speech/music bit, it differentiates between WMAVoice
      * speech samples (the actual codec) and WMAVoice music samples, which
@@ -1773,7 +1792,7 @@
             av_log(ctx, AV_LOG_ERROR,
                    "Superframe encodes >480 samples (%d), not allowed\n",
                    n_samples);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
     /* Parse LSPs, if global for the superframe (can also be per-frame). */
@@ -2042,14 +2061,15 @@
 }
 
 AVCodec ff_wmavoice_decoder = {
-    .name           = "wmavoice",
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_WMAVOICE,
-    .priv_data_size = sizeof(WMAVoiceContext),
-    .init           = wmavoice_decode_init,
-    .close          = wmavoice_decode_end,
-    .decode         = wmavoice_decode_packet,
-    .capabilities   = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
-    .flush          = wmavoice_flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio Voice"),
+    .name             = "wmavoice",
+    .type             = AVMEDIA_TYPE_AUDIO,
+    .id               = AV_CODEC_ID_WMAVOICE,
+    .priv_data_size   = sizeof(WMAVoiceContext),
+    .init             = wmavoice_decode_init,
+    .init_static_data = wmavoice_init_static_data,
+    .close            = wmavoice_decode_end,
+    .decode           = wmavoice_decode_packet,
+    .capabilities     = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
+    .flush            = wmavoice_flush,
+    .long_name        = NULL_IF_CONFIG_SMALL("Windows Media Audio Voice"),
 };
diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile
index 50e64f7..e881ef2 100644
--- a/libavcodec/x86/Makefile
+++ b/libavcodec/x86/Makefile
@@ -4,6 +4,7 @@
 OBJS-$(CONFIG_AAC_DECODER)             += x86/sbrdsp_init.o
 OBJS-$(CONFIG_AC3DSP)                  += x86/ac3dsp_init.o
 OBJS-$(CONFIG_CAVS_DECODER)            += x86/cavsdsp.o
+OBJS-$(CONFIG_DCT)                     += x86/dct_init.o
 OBJS-$(CONFIG_DNXHD_ENCODER)           += x86/dnxhdenc.o
 OBJS-$(CONFIG_FFT)                     += x86/fft_init.o
 OBJS-$(CONFIG_H264CHROMA)              += x86/h264chroma_init.o
@@ -13,7 +14,7 @@
 OBJS-$(CONFIG_HPELDSP)                 += x86/hpeldsp_init.o
 OBJS-$(CONFIG_LPC)                     += x86/lpc.o
 OBJS-$(CONFIG_MLP_DECODER)             += x86/mlpdsp.o
-OBJS-$(CONFIG_MPEGAUDIODSP)            += x86/mpegaudiodec.o
+OBJS-$(CONFIG_MPEGAUDIODSP)            += x86/mpegaudiodsp.o
 OBJS-$(CONFIG_MPEGVIDEO)               += x86/mpegvideo.o
 OBJS-$(CONFIG_MPEGVIDEOENC)            += x86/mpegvideoenc.o
 OBJS-$(CONFIG_PNG_DECODER)             += x86/pngdsp_init.o
@@ -34,19 +35,28 @@
 OBJS-$(CONFIG_WEBP_DECODER)            += x86/vp8dsp_init.o
 OBJS-$(CONFIG_XMM_CLOBBER_TEST)        += x86/w64xmmtest.o
 
-MMX-OBJS-$(CONFIG_DSPUTIL)             += x86/dsputil_mmx.o             \
+MMX-OBJS-$(CONFIG_DSPUTIL)             += x86/dsputil_init.o            \
+                                          x86/dsputil_mmx.o             \
                                           x86/fdct.o                    \
+                                          x86/fpel_mmx.o                \
                                           x86/idct_mmx_xvid.o           \
                                           x86/idct_sse2_xvid.o          \
+                                          x86/rnd_mmx.o                 \
                                           x86/simple_idct.o             \
 
 MMX-OBJS-$(CONFIG_ENCODERS)            += x86/dsputilenc_mmx.o          \
                                           x86/motion_est.o
 MMX-OBJS-$(CONFIG_DIRAC_DECODER)       += x86/dirac_dwt.o
+MMX-OBJS-$(CONFIG_HPELDSP)             += x86/fpel_mmx.o                \
+                                          x86/hpeldsp_mmx.o             \
+                                          x86/rnd_mmx.o
 MMX-OBJS-$(CONFIG_SNOW_DECODER)        += x86/snowdsp.o
 MMX-OBJS-$(CONFIG_SNOW_ENCODER)        += x86/snowdsp.o
 MMX-OBJS-$(CONFIG_VC1_DECODER)         += x86/vc1dsp_mmx.o
 
+YASM-OBJS                              += x86/deinterlace.o             \
+                                          x86/fmtconvert.o              \
+
 YASM-OBJS-$(CONFIG_AAC_DECODER)        += x86/sbrdsp.o
 YASM-OBJS-$(CONFIG_AC3DSP)             += x86/ac3dsp.o
 YASM-OBJS-$(CONFIG_DCT)                += x86/dct32.o
@@ -91,6 +101,3 @@
 YASM-OBJS-$(CONFIG_VP6_DECODER)        += x86/vp56dsp.o
 YASM-OBJS-$(CONFIG_VP8_DECODER)        += x86/vp8dsp.o
 YASM-OBJS-$(CONFIG_WEBP_DECODER)       += x86/vp8dsp.o
-
-YASM-OBJS                              += x86/deinterlace.o             \
-                                          x86/fmtconvert.o              \
diff --git a/libavcodec/x86/ac3dsp.asm b/libavcodec/x86/ac3dsp.asm
index 98fb446..89a64f5 100644
--- a/libavcodec/x86/ac3dsp.asm
+++ b/libavcodec/x86/ac3dsp.asm
@@ -379,42 +379,6 @@
 %endif
 %endmacro
 
-%if HAVE_AMD3DNOW_EXTERNAL
-INIT_MMX 3dnow
-cglobal ac3_extract_exponents, 3, 3, 0, exp, coef, len
-    add      expq, lenq
-    lea     coefq, [coefq+4*lenq]
-    neg      lenq
-    movq       m3, [pd_1]
-    movq       m4, [pd_151]
-.loop:
-    movq       m0, [coefq+4*lenq  ]
-    movq       m1, [coefq+4*lenq+8]
-    PABSD      m0, m2
-    PABSD      m1, m2
-    pslld      m0, 1
-    por        m0, m3
-    pi2fd      m2, m0
-    psrld      m2, 23
-    movq       m0, m4
-    psubd      m0, m2
-    pslld      m1, 1
-    por        m1, m3
-    pi2fd      m2, m1
-    psrld      m2, 23
-    movq       m1, m4
-    psubd      m1, m2
-    packssdw   m0, m0
-    packuswb   m0, m0
-    packssdw   m1, m1
-    packuswb   m1, m1
-    punpcklwd  m0, m1
-    movd  [expq+lenq], m0
-    add      lenq, 4
-    jl .loop
-    REP_RET
-%endif
-
 %macro AC3_EXTRACT_EXPONENTS 0
 cglobal ac3_extract_exponents, 3, 3, 4, exp, coef, len
     add     expq, lenq
diff --git a/libavcodec/x86/ac3dsp_init.c b/libavcodec/x86/ac3dsp_init.c
index d7c5902..8c94db0 100644
--- a/libavcodec/x86/ac3dsp_init.c
+++ b/libavcodec/x86/ac3dsp_init.c
@@ -22,7 +22,7 @@
 #include "libavutil/mem.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 #include "libavcodec/ac3.h"
 #include "libavcodec/ac3dsp.h"
 
@@ -185,47 +185,46 @@
 
 av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (EXTERNAL_MMX(mm_flags)) {
+    if (EXTERNAL_MMX(cpu_flags)) {
         c->ac3_exponent_min = ff_ac3_exponent_min_mmx;
         c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_mmx;
         c->ac3_lshift_int16 = ff_ac3_lshift_int16_mmx;
         c->ac3_rshift_int32 = ff_ac3_rshift_int32_mmx;
     }
-    if (EXTERNAL_AMD3DNOW(mm_flags)) {
-        c->extract_exponents = ff_ac3_extract_exponents_3dnow;
+    if (EXTERNAL_AMD3DNOW(cpu_flags)) {
         if (!bit_exact) {
             c->float_to_fixed24 = ff_float_to_fixed24_3dnow;
         }
     }
-    if (EXTERNAL_MMXEXT(mm_flags)) {
+    if (EXTERNAL_MMXEXT(cpu_flags)) {
         c->ac3_exponent_min = ff_ac3_exponent_min_mmxext;
         c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_mmxext;
     }
-    if (EXTERNAL_SSE(mm_flags)) {
+    if (EXTERNAL_SSE(cpu_flags)) {
         c->float_to_fixed24 = ff_float_to_fixed24_sse;
     }
-    if (EXTERNAL_SSE2(mm_flags)) {
+    if (EXTERNAL_SSE2(cpu_flags)) {
         c->ac3_exponent_min = ff_ac3_exponent_min_sse2;
         c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_sse2;
         c->float_to_fixed24 = ff_float_to_fixed24_sse2;
         c->compute_mantissa_size = ff_ac3_compute_mantissa_size_sse2;
         c->extract_exponents = ff_ac3_extract_exponents_sse2;
-        if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW)) {
+        if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW)) {
             c->ac3_lshift_int16 = ff_ac3_lshift_int16_sse2;
             c->ac3_rshift_int32 = ff_ac3_rshift_int32_sse2;
         }
     }
-    if (EXTERNAL_SSSE3(mm_flags)) {
+    if (EXTERNAL_SSSE3(cpu_flags)) {
         c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_ssse3;
-        if (!(mm_flags & AV_CPU_FLAG_ATOM)) {
+        if (!(cpu_flags & AV_CPU_FLAG_ATOM)) {
             c->extract_exponents = ff_ac3_extract_exponents_ssse3;
         }
     }
 
 #if HAVE_SSE_INLINE && HAVE_7REGS
-    if (INLINE_SSE(mm_flags)) {
+    if (INLINE_SSE(cpu_flags)) {
         c->downmix = ac3_downmix_sse;
     }
 #endif
diff --git a/libavcodec/x86/cabac.h b/libavcodec/x86/cabac.h
index 2c9f77e..ee5885f 100644
--- a/libavcodec/x86/cabac.h
+++ b/libavcodec/x86/cabac.h
@@ -27,6 +27,13 @@
 #include "libavutil/internal.h"
 #include "config.h"
 
+#if   (defined(__i386) && defined(__clang__) && (__clang_major__<2 || (__clang_major__==2 && __clang_minor__<10)))\
+   || (                  !defined(__clang__) && defined(__llvm__) && __GNUC__==4 && __GNUC_MINOR__==2 && __GNUC_PATCHLEVEL__<=1)
+#       define BROKEN_COMPILER 1
+#else
+#       define BROKEN_COMPILER 0
+#endif
+
 #if HAVE_INLINE_ASM
 
 #ifdef BROKEN_RELOCATIONS
@@ -149,9 +156,7 @@
 
 #endif /* BROKEN_RELOCATIONS */
 
-
-#if HAVE_7REGS && !(defined(__i386) && defined(__clang__) && (__clang_major__<2 || (__clang_major__==2 && __clang_minor__<10)))\
-               && !(                  !defined(__clang__) && defined(__llvm__) && __GNUC__==4 && __GNUC_MINOR__==2 && __GNUC_PATCHLEVEL__<=1)
+#if HAVE_7REGS && !BROKEN_COMPILER
 #define get_cabac_inline get_cabac_inline_x86
 static av_always_inline int get_cabac_inline_x86(CABACContext *c,
                                                  uint8_t *const state)
@@ -225,5 +230,47 @@
     return val;
 }
 
+#if !BROKEN_COMPILER
+#define get_cabac_bypass get_cabac_bypass_x86
+static av_always_inline int get_cabac_bypass_x86(CABACContext *c)
+{
+    x86_reg tmp;
+    int res;
+    __asm__ volatile(
+        "movl        %c6(%2), %k1       \n\t"
+        "movl        %c3(%2), %%eax     \n\t"
+        "shl             $17, %k1       \n\t"
+        "add           %%eax, %%eax     \n\t"
+        "sub             %k1, %%eax     \n\t"
+        "cltd                           \n\t"
+        "and           %%edx, %k1       \n\t"
+        "add             %k1, %%eax     \n\t"
+        "inc           %%edx            \n\t"
+        "test           %%ax, %%ax      \n\t"
+        "jnz              1f            \n\t"
+        "mov         %c4(%2), %1        \n\t"
+        "subl        $0xFFFF, %%eax     \n\t"
+        "movzwl         (%1), %%ecx     \n\t"
+        "bswap         %%ecx            \n\t"
+        "shrl            $15, %%ecx     \n\t"
+        "addl          %%ecx, %%eax     \n\t"
+        "cmp         %c5(%2), %1        \n\t"
+        "jge              1f            \n\t"
+        "add"OPSIZE"      $2, %c4(%2)   \n\t"
+        "1:                             \n\t"
+        "movl          %%eax, %c3(%2)   \n\t"
+
+        : "=&d"(res), "=&r"(tmp)
+        : "r"(c),
+          "i"(offsetof(CABACContext, low)),
+          "i"(offsetof(CABACContext, bytestream)),
+          "i"(offsetof(CABACContext, bytestream_end)),
+          "i"(offsetof(CABACContext, range))
+        : "%eax", "%ecx", "memory"
+    );
+    return res;
+}
+#endif /* !BROKEN_COMPILER */
+
 #endif /* HAVE_INLINE_ASM */
 #endif /* AVCODEC_X86_CABAC_H */
diff --git a/libavcodec/x86/cavsdsp.c b/libavcodec/x86/cavsdsp.c
index 0401e27..f190a66 100644
--- a/libavcodec/x86/cavsdsp.c
+++ b/libavcodec/x86/cavsdsp.c
@@ -28,7 +28,8 @@
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
 #include "libavcodec/cavsdsp.h"
-#include "dsputil_mmx.h"
+#include "constants.h"
+#include "dsputil_x86.h"
 #include "config.h"
 
 #if HAVE_MMX_INLINE
@@ -122,6 +123,17 @@
     );
 }
 
+#define SBUTTERFLY(a,b,t,n,m)\
+    "mov" #m " " #a ", " #t "         \n\t" /* abcd */\
+    "punpckl" #n " " #b ", " #a "     \n\t" /* aebf */\
+    "punpckh" #n " " #b ", " #t "     \n\t" /* cgdh */\
+
+#define TRANSPOSE4(a,b,c,d,t)\
+    SBUTTERFLY(a,b,t,wd,q) /* a=aebf t=cgdh */\
+    SBUTTERFLY(c,d,b,wd,q) /* c=imjn b=kolp */\
+    SBUTTERFLY(a,c,d,dq,q) /* a=aeim d=bfjn */\
+    SBUTTERFLY(t,b,c,dq,q) /* t=cgko c=dhlp */
+
 static void cavs_idct8_add_mmx(uint8_t *dst, int16_t *block, int stride)
 {
     int i;
@@ -413,22 +425,22 @@
 }\
 
 #define CAVS_MC(OPNAME, SIZE, MMX) \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc20_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc20_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
 {\
     OPNAME ## cavs_qpel ## SIZE ## _h_ ## MMX(dst, src, stride, stride);\
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc01_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc01_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
 {\
     OPNAME ## cavs_qpel ## SIZE ## _v1_ ## MMX(dst, src, stride, stride);\
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc02_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc02_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
 {\
     OPNAME ## cavs_qpel ## SIZE ## _v2_ ## MMX(dst, src, stride, stride);\
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc03_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc03_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
 {\
     OPNAME ## cavs_qpel ## SIZE ## _v3_ ## MMX(dst, src, stride, stride);\
 }\
@@ -446,24 +458,48 @@
 #endif /* (HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE) */
 
 #if HAVE_MMX_INLINE
+static void put_cavs_qpel8_mc00_mmx(uint8_t *dst, uint8_t *src,
+                                    ptrdiff_t stride)
+{
+    ff_put_pixels8_mmx(dst, src, stride, 8);
+}
+
+static void avg_cavs_qpel8_mc00_mmx(uint8_t *dst, uint8_t *src,
+                                    ptrdiff_t stride)
+{
+    ff_avg_pixels8_mmx(dst, src, stride, 8);
+}
+
+static void put_cavs_qpel16_mc00_mmx(uint8_t *dst, uint8_t *src,
+                                     ptrdiff_t stride)
+{
+    ff_put_pixels16_mmx(dst, src, stride, 16);
+}
+
+static void avg_cavs_qpel16_mc00_mmx(uint8_t *dst, uint8_t *src,
+                                     ptrdiff_t stride)
+{
+    ff_avg_pixels16_mmx(dst, src, stride, 16);
+}
+
 static av_cold void cavsdsp_init_mmx(CAVSDSPContext *c,
                                      AVCodecContext *avctx)
 {
-    c->put_cavs_qpel_pixels_tab[0][0] = ff_put_cavs_qpel16_mc00_mmx;
-    c->put_cavs_qpel_pixels_tab[1][0] = ff_put_cavs_qpel8_mc00_mmx;
-    c->avg_cavs_qpel_pixels_tab[0][0] = ff_avg_cavs_qpel16_mc00_mmx;
-    c->avg_cavs_qpel_pixels_tab[1][0] = ff_avg_cavs_qpel8_mc00_mmx;
+    c->put_cavs_qpel_pixels_tab[0][0] = put_cavs_qpel16_mc00_mmx;
+    c->put_cavs_qpel_pixels_tab[1][0] = put_cavs_qpel8_mc00_mmx;
+    c->avg_cavs_qpel_pixels_tab[0][0] = avg_cavs_qpel16_mc00_mmx;
+    c->avg_cavs_qpel_pixels_tab[1][0] = avg_cavs_qpel8_mc00_mmx;
 
     c->cavs_idct8_add = cavs_idct8_add_mmx;
     c->idct_perm      = FF_TRANSPOSE_IDCT_PERM;
 }
 #endif /* HAVE_MMX_INLINE */
 
-#define DSPFUNC(PFX, IDX, NUM, EXT)                                                              \
-    c->PFX ## _cavs_qpel_pixels_tab[IDX][ 2] = ff_ ## PFX ## _cavs_qpel ## NUM ## _mc20_ ## EXT; \
-    c->PFX ## _cavs_qpel_pixels_tab[IDX][ 4] = ff_ ## PFX ## _cavs_qpel ## NUM ## _mc01_ ## EXT; \
-    c->PFX ## _cavs_qpel_pixels_tab[IDX][ 8] = ff_ ## PFX ## _cavs_qpel ## NUM ## _mc02_ ## EXT; \
-    c->PFX ## _cavs_qpel_pixels_tab[IDX][12] = ff_ ## PFX ## _cavs_qpel ## NUM ## _mc03_ ## EXT; \
+#define DSPFUNC(PFX, IDX, NUM, EXT)                                                       \
+    c->PFX ## _cavs_qpel_pixels_tab[IDX][ 2] = PFX ## _cavs_qpel ## NUM ## _mc20_ ## EXT; \
+    c->PFX ## _cavs_qpel_pixels_tab[IDX][ 4] = PFX ## _cavs_qpel ## NUM ## _mc01_ ## EXT; \
+    c->PFX ## _cavs_qpel_pixels_tab[IDX][ 8] = PFX ## _cavs_qpel ## NUM ## _mc02_ ## EXT; \
+    c->PFX ## _cavs_qpel_pixels_tab[IDX][12] = PFX ## _cavs_qpel ## NUM ## _mc03_ ## EXT; \
 
 #if HAVE_MMXEXT_INLINE
 QPEL_CAVS(put_,        PUT_OP, mmxext)
@@ -474,8 +510,8 @@
 CAVS_MC(avg_,  8, mmxext)
 CAVS_MC(avg_, 16, mmxext)
 
-static av_cold void ff_cavsdsp_init_mmxext(CAVSDSPContext *c,
-                                           AVCodecContext *avctx)
+static av_cold void cavsdsp_init_mmxext(CAVSDSPContext *c,
+                                        AVCodecContext *avctx)
 {
     DSPFUNC(put, 0, 16, mmxext);
     DSPFUNC(put, 1,  8, mmxext);
@@ -493,8 +529,8 @@
 CAVS_MC(avg_, 8, 3dnow)
 CAVS_MC(avg_, 16,3dnow)
 
-static av_cold void ff_cavsdsp_init_3dnow(CAVSDSPContext *c,
-                                          AVCodecContext *avctx)
+static av_cold void cavsdsp_init_3dnow(CAVSDSPContext *c,
+                                       AVCodecContext *avctx)
 {
     DSPFUNC(put, 0, 16, 3dnow);
     DSPFUNC(put, 1,  8, 3dnow);
@@ -506,15 +542,17 @@
 av_cold void ff_cavsdsp_init_x86(CAVSDSPContext *c, AVCodecContext *avctx)
 {
 #if HAVE_MMX_INLINE
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (mm_flags & AV_CPU_FLAG_MMX)
+    if (cpu_flags & AV_CPU_FLAG_MMX)
         cavsdsp_init_mmx(c, avctx);
 #endif /* HAVE_MMX_INLINE */
 #if HAVE_MMXEXT_INLINE
-    if (mm_flags & AV_CPU_FLAG_MMXEXT) ff_cavsdsp_init_mmxext(c, avctx);
+    if (cpu_flags & AV_CPU_FLAG_MMXEXT)
+        cavsdsp_init_mmxext(c, avctx);
 #endif /* HAVE_MMXEXT_INLINE */
 #if HAVE_AMD3DNOW_INLINE
-    if (mm_flags & AV_CPU_FLAG_3DNOW) ff_cavsdsp_init_3dnow(c, avctx);
+    if (cpu_flags & AV_CPU_FLAG_3DNOW)
+        cavsdsp_init_3dnow(c, avctx);
 #endif /* HAVE_AMD3DNOW_INLINE */
 }
diff --git a/libavcodec/x86/constants.c b/libavcodec/x86/constants.c
index b532e6b..3bba80b 100644
--- a/libavcodec/x86/constants.c
+++ b/libavcodec/x86/constants.c
@@ -20,6 +20,7 @@
 
 #include "libavutil/mem.h"
 #include "libavutil/x86/asm.h" // for xmm_reg
+#include "constants.h"
 
 DECLARE_ALIGNED(8,  const uint64_t, ff_wtwo) = 0x0002000200020002ULL;
 
diff --git a/libavcodec/x86/constants.h b/libavcodec/x86/constants.h
new file mode 100644
index 0000000..8097bc4
--- /dev/null
+++ b/libavcodec/x86/constants.h
@@ -0,0 +1,51 @@
+/*
+ * MMX/SSE constants used across x86 dsp optimizations.
+ *
+ * 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
+ */
+
+#ifndef AVCODEC_X86_CONSTANTS_H
+#define AVCODEC_X86_CONSTANTS_H
+
+#include <stdint.h>
+
+#include "libavutil/x86/asm.h"
+
+extern const uint64_t ff_wtwo;
+
+extern const xmm_reg  ff_pw_3;
+extern const xmm_reg  ff_pw_4;
+extern const xmm_reg  ff_pw_5;
+extern const xmm_reg  ff_pw_8;
+extern const uint64_t ff_pw_15;
+extern const xmm_reg  ff_pw_16;
+extern const xmm_reg  ff_pw_18;
+extern const uint64_t ff_pw_20;
+extern const xmm_reg  ff_pw_32;
+extern const uint64_t ff_pw_42;
+extern const uint64_t ff_pw_53;
+extern const xmm_reg  ff_pw_64;
+extern const uint64_t ff_pw_96;
+extern const uint64_t ff_pw_128;
+extern const uint64_t ff_pw_255;
+
+extern const xmm_reg  ff_pb_1;
+extern const xmm_reg  ff_pb_3;
+extern const xmm_reg  ff_pb_F8;
+extern const uint64_t ff_pb_FC;
+
+#endif /* AVCODEC_X86_CONSTANTS_H */
diff --git a/libavcodec/x86/dct_init.c b/libavcodec/x86/dct_init.c
new file mode 100644
index 0000000..85e2d0c
--- /dev/null
+++ b/libavcodec/x86/dct_init.c
@@ -0,0 +1,39 @@
+/*
+ * 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
+ */
+
+#include "config.h"
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/x86/cpu.h"
+#include "libavcodec/dct.h"
+
+void ff_dct32_float_sse(FFTSample *out, const FFTSample *in);
+void ff_dct32_float_sse2(FFTSample *out, const FFTSample *in);
+void ff_dct32_float_avx(FFTSample *out, const FFTSample *in);
+
+av_cold void ff_dct_init_x86(DCTContext *s)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+    if (EXTERNAL_SSE(cpu_flags))
+        s->dct32 = ff_dct32_float_sse;
+    if (EXTERNAL_SSE2(cpu_flags))
+        s->dct32 = ff_dct32_float_sse2;
+    if (EXTERNAL_AVX(cpu_flags))
+        s->dct32 = ff_dct32_float_avx;
+}
diff --git a/libavcodec/x86/dirac_dwt.c b/libavcodec/x86/dirac_dwt.c
index fbb25a4..04c514f 100644
--- a/libavcodec/x86/dirac_dwt.c
+++ b/libavcodec/x86/dirac_dwt.c
@@ -21,7 +21,7 @@
  */
 
 #include "libavutil/x86/asm.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 #include "dirac_dwt.h"
 
 #define COMPOSE_VERTICAL(ext, align) \
diff --git a/libavcodec/x86/diracdsp_mmx.c b/libavcodec/x86/diracdsp_mmx.c
index cb6465f..a28bb82 100644
--- a/libavcodec/x86/diracdsp_mmx.c
+++ b/libavcodec/x86/diracdsp_mmx.c
@@ -18,7 +18,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 #include "diracdsp_mmx.h"
 
 void ff_put_rect_clamped_mmx(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height);
diff --git a/libavcodec/x86/dsputil_init.c b/libavcodec/x86/dsputil_init.c
new file mode 100644
index 0000000..166be65
--- /dev/null
+++ b/libavcodec/x86/dsputil_init.c
@@ -0,0 +1,733 @@
+/*
+ * Copyright (c) 2000, 2001 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * 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
+ */
+
+#include "config.h"
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/x86/asm.h"
+#include "libavcodec/dsputil.h"
+#include "libavcodec/simple_idct.h"
+#include "dsputil_x86.h"
+#include "idct_xvid.h"
+
+void ff_put_pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
+                              int dstStride, int src1Stride, int h);
+void ff_put_no_rnd_pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1,
+                                     uint8_t *src2, int dstStride,
+                                     int src1Stride, int h);
+void ff_avg_pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
+                              int dstStride, int src1Stride, int h);
+void ff_put_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
+                               int dstStride, int src1Stride, int h);
+void ff_avg_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
+                               int dstStride, int src1Stride, int h);
+void ff_put_no_rnd_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
+                                      int dstStride, int src1Stride, int h);
+void ff_put_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                         int dstStride, int srcStride, int h);
+void ff_avg_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                         int dstStride, int srcStride, int h);
+void ff_put_no_rnd_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                                 int dstStride, int srcStride,
+                                                 int h);
+void ff_put_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                        int dstStride, int srcStride, int h);
+void ff_avg_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                        int dstStride, int srcStride, int h);
+void ff_put_no_rnd_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                                int dstStride, int srcStride,
+                                                int h);
+void ff_put_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                         int dstStride, int srcStride);
+void ff_avg_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                         int dstStride, int srcStride);
+void ff_put_no_rnd_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                                 int dstStride, int srcStride);
+void ff_put_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                        int dstStride, int srcStride);
+void ff_avg_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                        int dstStride, int srcStride);
+void ff_put_no_rnd_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                                int dstStride, int srcStride);
+#define ff_put_no_rnd_pixels16_mmxext ff_put_pixels16_mmxext
+#define ff_put_no_rnd_pixels8_mmxext ff_put_pixels8_mmxext
+
+void ff_h263_v_loop_filter_mmx(uint8_t *src, int stride, int qscale);
+void ff_h263_h_loop_filter_mmx(uint8_t *src, int stride, int qscale);
+
+int32_t ff_scalarproduct_int16_mmxext(const int16_t *v1, const int16_t *v2,
+                                      int order);
+int32_t ff_scalarproduct_int16_sse2(const int16_t *v1, const int16_t *v2,
+                                    int order);
+int32_t ff_scalarproduct_and_madd_int16_mmxext(int16_t *v1, const int16_t *v2,
+                                               const int16_t *v3,
+                                               int order, int mul);
+int32_t ff_scalarproduct_and_madd_int16_sse2(int16_t *v1, const int16_t *v2,
+                                             const int16_t *v3,
+                                             int order, int mul);
+int32_t ff_scalarproduct_and_madd_int16_ssse3(int16_t *v1, const int16_t *v2,
+                                              const int16_t *v3,
+                                              int order, int mul);
+
+void ff_apply_window_int16_round_mmxext(int16_t *output, const int16_t *input,
+                                        const int16_t *window, unsigned int len);
+void ff_apply_window_int16_round_sse2(int16_t *output, const int16_t *input,
+                                      const int16_t *window, unsigned int len);
+void ff_apply_window_int16_mmxext(int16_t *output, const int16_t *input,
+                                  const int16_t *window, unsigned int len);
+void ff_apply_window_int16_sse2(int16_t *output, const int16_t *input,
+                                const int16_t *window, unsigned int len);
+void ff_apply_window_int16_ssse3(int16_t *output, const int16_t *input,
+                                 const int16_t *window, unsigned int len);
+void ff_apply_window_int16_ssse3_atom(int16_t *output, const int16_t *input,
+                                      const int16_t *window, unsigned int len);
+
+void ff_bswap32_buf_ssse3(uint32_t *dst, const uint32_t *src, int w);
+void ff_bswap32_buf_sse2(uint32_t *dst, const uint32_t *src, int w);
+
+void ff_add_hfyu_median_prediction_mmxext(uint8_t *dst, const uint8_t *top,
+                                          const uint8_t *diff, int w,
+                                          int *left, int *left_top);
+int  ff_add_hfyu_left_prediction_ssse3(uint8_t *dst, const uint8_t *src,
+                                       int w, int left);
+int  ff_add_hfyu_left_prediction_sse4(uint8_t *dst, const uint8_t *src,
+                                      int w, int left);
+
+void ff_vector_clip_int32_mmx     (int32_t *dst, const int32_t *src,
+                                   int32_t min, int32_t max, unsigned int len);
+void ff_vector_clip_int32_sse2    (int32_t *dst, const int32_t *src,
+                                   int32_t min, int32_t max, unsigned int len);
+void ff_vector_clip_int32_int_sse2(int32_t *dst, const int32_t *src,
+                                   int32_t min, int32_t max, unsigned int len);
+void ff_vector_clip_int32_sse4    (int32_t *dst, const int32_t *src,
+                                   int32_t min, int32_t max, unsigned int len);
+
+#if HAVE_YASM
+
+PIXELS16(static, ff_avg, , , _mmxext)
+PIXELS16(static, ff_put, , , _mmxext)
+
+#define QPEL_OP(OPNAME, RND, MMX)                                       \
+static void OPNAME ## qpel8_mc00_ ## MMX (uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    ff_ ## OPNAME ## pixels8_ ## MMX(dst, src, stride, 8);              \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc10_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t temp[8];                                                   \
+    uint8_t * const half = (uint8_t*)temp;                              \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8,        \
+                                                   stride, 8);          \
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src, half,                 \
+                                        stride, stride, 8);             \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc20_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    ff_ ## OPNAME ## mpeg4_qpel8_h_lowpass_ ## MMX(dst, src, stride,    \
+                                                   stride, 8);          \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc30_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t temp[8];                                                   \
+    uint8_t * const half = (uint8_t*)temp;                              \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8,        \
+                                                   stride, 8);          \
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src + 1, half, stride,     \
+                                        stride, 8);                     \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc01_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t temp[8];                                                   \
+    uint8_t * const half = (uint8_t*)temp;                              \
+    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src,           \
+                                                   8, stride);          \
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src, half,                 \
+                                        stride, stride, 8);             \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc02_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, src,            \
+                                                   stride, stride);     \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc03_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t temp[8];                                                   \
+    uint8_t * const half = (uint8_t*)temp;                              \
+    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src,           \
+                                                   8, stride);          \
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src + stride, half, stride,\
+                                        stride, 8);                     \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc11_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t half[8 + 9];                                               \
+    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
+                                                   stride, 9);          \
+    ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8,           \
+                                        stride, 9);                     \
+    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV,             \
+                                        stride, 8, 8);                  \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc31_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t half[8 + 9];                                               \
+    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
+                                                   stride, 9);          \
+    ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8,       \
+                                        stride, 9);                     \
+    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV,             \
+                                        stride, 8, 8);                  \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc13_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t half[8 + 9];                                               \
+    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
+                                                   stride, 9);          \
+    ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8,           \
+                                        stride, 9);                     \
+    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV,         \
+                                        stride, 8, 8);                  \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc33_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t half[8 + 9];                                               \
+    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
+                                                   stride, 9);          \
+    ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8,       \
+                                        stride, 9);                     \
+    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV,         \
+                                        stride, 8, 8);                  \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc21_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t half[8 + 9];                                               \
+    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
+                                                   stride, 9);          \
+    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV,             \
+                                        stride, 8, 8);                  \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc23_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t half[8 + 9];                                               \
+    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
+                                                   stride, 9);          \
+    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV,         \
+                                        stride, 8, 8);                  \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc12_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t half[8 + 9];                                               \
+    uint8_t * const halfH = ((uint8_t*)half);                           \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
+                                                   stride, 9);          \
+    ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH,              \
+                                        8, stride, 9);                  \
+    ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH,          \
+                                                   stride, 8);          \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc32_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t half[8 + 9];                                               \
+    uint8_t * const halfH = ((uint8_t*)half);                           \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
+                                                   stride, 9);          \
+    ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8,       \
+                                        stride, 9);                     \
+    ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH,          \
+                                                   stride, 8);          \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc22_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t half[9];                                                   \
+    uint8_t * const halfH = ((uint8_t*)half);                           \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
+                                                   stride, 9);          \
+    ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH,          \
+                                                   stride, 8);          \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc00_ ## MMX (uint8_t *dst, uint8_t *src,  \
+                                           ptrdiff_t stride)            \
+{                                                                       \
+    ff_ ## OPNAME ## pixels16_ ## MMX(dst, src, stride, 16);            \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc10_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t temp[32];                                                  \
+    uint8_t * const half = (uint8_t*)temp;                              \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16,      \
+                                                    stride, 16);        \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride,        \
+                                         stride, 16);                   \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc20_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    ff_ ## OPNAME ## mpeg4_qpel16_h_lowpass_ ## MMX(dst, src,           \
+                                                    stride, stride, 16);\
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc30_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t temp[32];                                                  \
+    uint8_t * const half = (uint8_t*)temp;                              \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16,      \
+                                                    stride, 16);        \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src + 1, half,            \
+                                         stride, stride, 16);           \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc01_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t temp[32];                                                  \
+    uint8_t * const half = (uint8_t*)temp;                              \
+    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16,      \
+                                                    stride);            \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride,        \
+                                         stride, 16);                   \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc02_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, src,           \
+                                                    stride, stride);    \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc03_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t temp[32];                                                  \
+    uint8_t * const half = (uint8_t*)temp;                              \
+    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16,      \
+                                                    stride);            \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src+stride, half,         \
+                                         stride, stride, 16);           \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc11_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t half[16 * 2 + 17 * 2];                                     \
+    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
+                                                    stride, 17);        \
+    ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16,         \
+                                         stride, 17);                   \
+    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
+                                                    16, 16);            \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV,            \
+                                         stride, 16, 16);               \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc31_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t half[16 * 2 + 17 * 2];                                     \
+    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
+                                                    stride, 17);        \
+    ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16,     \
+                                         stride, 17);                   \
+    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
+                                                    16, 16);            \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV,            \
+                                         stride, 16, 16);               \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc13_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t half[16 * 2 + 17 * 2];                                     \
+    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
+                                                    stride, 17);        \
+    ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16,         \
+                                         stride, 17);                   \
+    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
+                                                    16, 16);            \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV,       \
+                                         stride, 16, 16);               \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc33_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t half[16 * 2 + 17 * 2];                                     \
+    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
+                                                    stride, 17);        \
+    ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16,     \
+                                         stride, 17);                   \
+    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
+                                                    16, 16);            \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV,       \
+                                         stride, 16, 16);               \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc21_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t half[16 * 2 + 17 * 2];                                     \
+    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
+                                                    stride, 17);        \
+    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
+                                                    16, 16);            \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV,            \
+                                         stride, 16, 16);               \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc23_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t half[16 * 2 + 17 * 2];                                     \
+    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
+                                                    stride, 17);        \
+    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
+                                                    16, 16);            \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV,       \
+                                         stride, 16, 16);               \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc12_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t half[17 * 2];                                              \
+    uint8_t * const halfH = ((uint8_t*)half);                           \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
+                                                    stride, 17);        \
+    ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16,         \
+                                         stride, 17);                   \
+    ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH,         \
+                                                    stride, 16);        \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc32_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t half[17 * 2];                                              \
+    uint8_t * const halfH = ((uint8_t*)half);                           \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
+                                                    stride, 17);        \
+    ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16,     \
+                                         stride, 17);                   \
+    ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH,         \
+                                                    stride, 16);        \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc22_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t half[17 * 2];                                              \
+    uint8_t * const halfH = ((uint8_t*)half);                           \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
+                                                    stride, 17);        \
+    ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH,         \
+                                                    stride, 16);        \
+}
+
+QPEL_OP(put_,        _,        mmxext)
+QPEL_OP(avg_,        _,        mmxext)
+QPEL_OP(put_no_rnd_, _no_rnd_, mmxext)
+#endif /* HAVE_YASM */
+
+#define SET_QPEL_FUNCS(PFX, IDX, SIZE, CPU, PREFIX)                          \
+    do {                                                                     \
+    c->PFX ## _pixels_tab[IDX][ 0] = PREFIX ## PFX ## SIZE ## _mc00_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 1] = PREFIX ## PFX ## SIZE ## _mc10_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 2] = PREFIX ## PFX ## SIZE ## _mc20_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 3] = PREFIX ## PFX ## SIZE ## _mc30_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 4] = PREFIX ## PFX ## SIZE ## _mc01_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 5] = PREFIX ## PFX ## SIZE ## _mc11_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 6] = PREFIX ## PFX ## SIZE ## _mc21_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 7] = PREFIX ## PFX ## SIZE ## _mc31_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 8] = PREFIX ## PFX ## SIZE ## _mc02_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 9] = PREFIX ## PFX ## SIZE ## _mc12_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][10] = PREFIX ## PFX ## SIZE ## _mc22_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][11] = PREFIX ## PFX ## SIZE ## _mc32_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][12] = PREFIX ## PFX ## SIZE ## _mc03_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][13] = PREFIX ## PFX ## SIZE ## _mc13_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][14] = PREFIX ## PFX ## SIZE ## _mc23_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][15] = PREFIX ## PFX ## SIZE ## _mc33_ ## CPU; \
+    } while (0)
+
+static av_cold void dsputil_init_mmx(DSPContext *c, AVCodecContext *avctx,
+                                     int cpu_flags)
+{
+#if HAVE_MMX_INLINE
+    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
+
+    c->put_pixels_clamped        = ff_put_pixels_clamped_mmx;
+    c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_mmx;
+    c->add_pixels_clamped        = ff_add_pixels_clamped_mmx;
+
+    if (!high_bit_depth) {
+        c->clear_block  = ff_clear_block_mmx;
+        c->clear_blocks = ff_clear_blocks_mmx;
+        c->draw_edges   = ff_draw_edges_mmx;
+    }
+
+#if CONFIG_VIDEODSP && (ARCH_X86_32 || !HAVE_YASM)
+    c->gmc = ff_gmc_mmx;
+#endif
+
+    c->add_bytes = ff_add_bytes_mmx;
+#endif /* HAVE_MMX_INLINE */
+
+#if HAVE_MMX_EXTERNAL
+    if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) {
+        c->h263_v_loop_filter = ff_h263_v_loop_filter_mmx;
+        c->h263_h_loop_filter = ff_h263_h_loop_filter_mmx;
+    }
+
+    c->vector_clip_int32 = ff_vector_clip_int32_mmx;
+#endif /* HAVE_MMX_EXTERNAL */
+}
+
+static av_cold void dsputil_init_mmxext(DSPContext *c, AVCodecContext *avctx,
+                                        int cpu_flags)
+{
+#if HAVE_MMXEXT_EXTERNAL
+    SET_QPEL_FUNCS(avg_qpel,        0, 16, mmxext, );
+    SET_QPEL_FUNCS(avg_qpel,        1,  8, mmxext, );
+
+    SET_QPEL_FUNCS(put_qpel,        0, 16, mmxext, );
+    SET_QPEL_FUNCS(put_qpel,        1,  8, mmxext, );
+    SET_QPEL_FUNCS(put_no_rnd_qpel, 0, 16, mmxext, );
+    SET_QPEL_FUNCS(put_no_rnd_qpel, 1,  8, mmxext, );
+
+    /* slower than cmov version on AMD */
+    if (!(cpu_flags & AV_CPU_FLAG_3DNOW))
+        c->add_hfyu_median_prediction = ff_add_hfyu_median_prediction_mmxext;
+
+    c->scalarproduct_int16          = ff_scalarproduct_int16_mmxext;
+    c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_mmxext;
+
+    if (avctx->flags & CODEC_FLAG_BITEXACT) {
+        c->apply_window_int16 = ff_apply_window_int16_mmxext;
+    } else {
+        c->apply_window_int16 = ff_apply_window_int16_round_mmxext;
+    }
+#endif /* HAVE_MMXEXT_EXTERNAL */
+}
+
+static av_cold void dsputil_init_sse(DSPContext *c, AVCodecContext *avctx,
+                                     int cpu_flags)
+{
+#if HAVE_SSE_INLINE
+    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
+
+    if (!high_bit_depth) {
+        if (!(CONFIG_MPEG_XVMC_DECODER && avctx->xvmc_acceleration > 1)) {
+            /* XvMCCreateBlocks() may not allocate 16-byte aligned blocks */
+            c->clear_block  = ff_clear_block_sse;
+            c->clear_blocks = ff_clear_blocks_sse;
+        }
+    }
+
+    c->vector_clipf = ff_vector_clipf_sse;
+#endif /* HAVE_SSE_INLINE */
+
+#if HAVE_YASM
+#if HAVE_INLINE_ASM && CONFIG_VIDEODSP
+    c->gmc = ff_gmc_sse;
+#endif
+#endif /* HAVE_YASM */
+}
+
+static av_cold void dsputil_init_sse2(DSPContext *c, AVCodecContext *avctx,
+                                      int cpu_flags)
+{
+#if HAVE_SSE2_INLINE
+    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
+
+    if (!high_bit_depth && avctx->idct_algo == FF_IDCT_XVIDMMX && avctx->lowres == 0) {
+        c->idct_put              = ff_idct_xvid_sse2_put;
+        c->idct_add              = ff_idct_xvid_sse2_add;
+        c->idct                  = ff_idct_xvid_sse2;
+        c->idct_permutation_type = FF_SSE2_IDCT_PERM;
+    }
+#endif /* HAVE_SSE2_INLINE */
+
+#if HAVE_SSE2_EXTERNAL
+    c->scalarproduct_int16          = ff_scalarproduct_int16_sse2;
+    c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_sse2;
+    if (cpu_flags & AV_CPU_FLAG_ATOM) {
+        c->vector_clip_int32 = ff_vector_clip_int32_int_sse2;
+    } else {
+        c->vector_clip_int32 = ff_vector_clip_int32_sse2;
+    }
+    if (avctx->flags & CODEC_FLAG_BITEXACT) {
+        c->apply_window_int16 = ff_apply_window_int16_sse2;
+    } else if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW)) {
+        c->apply_window_int16 = ff_apply_window_int16_round_sse2;
+    }
+    c->bswap_buf = ff_bswap32_buf_sse2;
+#endif /* HAVE_SSE2_EXTERNAL */
+}
+
+static av_cold void dsputil_init_ssse3(DSPContext *c, AVCodecContext *avctx,
+                                       int cpu_flags)
+{
+#if HAVE_SSSE3_EXTERNAL
+    c->add_hfyu_left_prediction = ff_add_hfyu_left_prediction_ssse3;
+    if (cpu_flags & AV_CPU_FLAG_SSE4) // not really SSE4, just slow on Conroe
+        c->add_hfyu_left_prediction = ff_add_hfyu_left_prediction_sse4;
+
+    if (cpu_flags & AV_CPU_FLAG_ATOM)
+        c->apply_window_int16 = ff_apply_window_int16_ssse3_atom;
+    else
+        c->apply_window_int16 = ff_apply_window_int16_ssse3;
+    if (!(cpu_flags & (AV_CPU_FLAG_SSE42 | AV_CPU_FLAG_3DNOW))) // cachesplit
+        c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_ssse3;
+    c->bswap_buf = ff_bswap32_buf_ssse3;
+#endif /* HAVE_SSSE3_EXTERNAL */
+}
+
+static av_cold void dsputil_init_sse4(DSPContext *c, AVCodecContext *avctx,
+                                      int cpu_flags)
+{
+#if HAVE_SSE4_EXTERNAL
+    c->vector_clip_int32 = ff_vector_clip_int32_sse4;
+#endif /* HAVE_SSE4_EXTERNAL */
+}
+
+av_cold void ff_dsputil_init_mmx(DSPContext *c, AVCodecContext *avctx)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+#if HAVE_7REGS && HAVE_INLINE_ASM
+    if (cpu_flags & AV_CPU_FLAG_CMOV)
+        c->add_hfyu_median_prediction = ff_add_hfyu_median_prediction_cmov;
+#endif
+
+    if (cpu_flags & AV_CPU_FLAG_MMX) {
+#if HAVE_INLINE_ASM
+        const int idct_algo = avctx->idct_algo;
+
+        if (avctx->lowres == 0 && avctx->bits_per_raw_sample <= 8) {
+            if (idct_algo == FF_IDCT_AUTO || idct_algo == FF_IDCT_SIMPLEMMX) {
+                c->idct_put              = ff_simple_idct_put_mmx;
+                c->idct_add              = ff_simple_idct_add_mmx;
+                c->idct                  = ff_simple_idct_mmx;
+                c->idct_permutation_type = FF_SIMPLE_IDCT_PERM;
+            } else if (idct_algo == FF_IDCT_XVIDMMX) {
+                if (cpu_flags & AV_CPU_FLAG_SSE2) {
+                    c->idct_put              = ff_idct_xvid_sse2_put;
+                    c->idct_add              = ff_idct_xvid_sse2_add;
+                    c->idct                  = ff_idct_xvid_sse2;
+                    c->idct_permutation_type = FF_SSE2_IDCT_PERM;
+                } else if (cpu_flags & AV_CPU_FLAG_MMXEXT) {
+                    c->idct_put              = ff_idct_xvid_mmxext_put;
+                    c->idct_add              = ff_idct_xvid_mmxext_add;
+                    c->idct                  = ff_idct_xvid_mmxext;
+                } else {
+                    c->idct_put              = ff_idct_xvid_mmx_put;
+                    c->idct_add              = ff_idct_xvid_mmx_add;
+                    c->idct                  = ff_idct_xvid_mmx;
+                }
+            }
+        }
+#endif /* HAVE_INLINE_ASM */
+
+        dsputil_init_mmx(c, avctx, cpu_flags);
+    }
+
+    if (cpu_flags & AV_CPU_FLAG_MMXEXT)
+        dsputil_init_mmxext(c, avctx, cpu_flags);
+
+    if (cpu_flags & AV_CPU_FLAG_SSE)
+        dsputil_init_sse(c, avctx, cpu_flags);
+
+    if (cpu_flags & AV_CPU_FLAG_SSE2)
+        dsputil_init_sse2(c, avctx, cpu_flags);
+
+    if (cpu_flags & AV_CPU_FLAG_SSSE3)
+        dsputil_init_ssse3(c, avctx, cpu_flags);
+
+    if (cpu_flags & AV_CPU_FLAG_SSE4)
+        dsputil_init_sse4(c, avctx, cpu_flags);
+
+    if (CONFIG_ENCODERS)
+        ff_dsputilenc_init_mmx(c, avctx);
+}
diff --git a/libavcodec/x86/dsputil_mmx.c b/libavcodec/x86/dsputil_mmx.c
index 95c3c2a..421a6c2 100644
--- a/libavcodec/x86/dsputil_mmx.c
+++ b/libavcodec/x86/dsputil_mmx.c
@@ -22,120 +22,17 @@
  * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
  */
 
-#include "libavutil/attributes.h"
+#include "config.h"
+#include "libavutil/avassert.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
-#include "libavcodec/dsputil.h"
-#include "libavcodec/h264dsp.h"
-#include "libavcodec/mpegvideo.h"
-#include "libavcodec/simple_idct.h"
 #include "libavcodec/videodsp.h"
-#include "dsputil_mmx.h"
-#include "idct_xvid.h"
+#include "constants.h"
+#include "dsputil_x86.h"
 #include "diracdsp_mmx.h"
 
-//#undef NDEBUG
-//#include <assert.h>
-
-DECLARE_ALIGNED(16, const double, ff_pd_1)[2] = { 1.0, 1.0 };
-DECLARE_ALIGNED(16, const double, ff_pd_2)[2] = { 2.0, 2.0 };
-
-
-#if HAVE_YASM
-void ff_put_pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
-                              int dstStride, int src1Stride, int h);
-void ff_put_no_rnd_pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1,
-                                     uint8_t *src2, int dstStride,
-                                     int src1Stride, int h);
-void ff_avg_pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
-                              int dstStride, int src1Stride, int h);
-void ff_put_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
-                               int dstStride, int src1Stride, int h);
-void ff_avg_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
-                               int dstStride, int src1Stride, int h);
-void ff_put_no_rnd_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
-                                      int dstStride, int src1Stride, int h);
-
-static void ff_put_pixels16_mmxext(uint8_t *block, const uint8_t *pixels,
-                                   ptrdiff_t line_size, int h)
-{
-    ff_put_pixels8_mmxext(block,     pixels,     line_size, h);
-    ff_put_pixels8_mmxext(block + 8, pixels + 8, line_size, h);
-}
-
-void ff_put_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
-                                         int dstStride, int srcStride, int h);
-void ff_avg_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
-                                         int dstStride, int srcStride, int h);
-void ff_put_no_rnd_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
-                                                 int dstStride, int srcStride,
-                                                 int h);
-void ff_put_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
-                                        int dstStride, int srcStride, int h);
-void ff_avg_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
-                                        int dstStride, int srcStride, int h);
-void ff_put_no_rnd_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
-                                                int dstStride, int srcStride,
-                                                int h);
-void ff_put_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
-                                         int dstStride, int srcStride);
-void ff_avg_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
-                                         int dstStride, int srcStride);
-void ff_put_no_rnd_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
-                                                 int dstStride, int srcStride);
-void ff_put_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
-                                        int dstStride, int srcStride);
-void ff_avg_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
-                                        int dstStride, int srcStride);
-void ff_put_no_rnd_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
-                                                int dstStride, int srcStride);
-#define ff_put_no_rnd_pixels16_mmxext ff_put_pixels16_mmxext
-#define ff_put_no_rnd_pixels8_mmxext ff_put_pixels8_mmxext
-#endif /* HAVE_YASM */
-
-
 #if HAVE_INLINE_ASM
 
-/***********************************/
-/* MMX rounding */
-
-#define DEF(x, y) x ## _ ## y ## _mmx
-#define SET_RND  MOVQ_WTWO
-#define PAVGBP(a, b, c, d, e, f)        PAVGBP_MMX(a, b, c, d, e, f)
-#define PAVGB(a, b, c, e)               PAVGB_MMX(a, b, c, e)
-#define OP_AVG(a, b, c, e)              PAVGB_MMX(a, b, c, e)
-
-#include "dsputil_rnd_template.c"
-
-#undef DEF
-#undef SET_RND
-#undef PAVGBP
-#undef PAVGB
-#undef OP_AVG
-
-#endif /* HAVE_INLINE_ASM */
-
-
-#if HAVE_YASM
-
-/***********************************/
-/* MMXEXT specific */
-
-//FIXME the following could be optimized too ...
-static void ff_avg_pixels16_mmxext(uint8_t *block, const uint8_t *pixels,
-                                   int line_size, int h)
-{
-    ff_avg_pixels8_mmxext(block,     pixels,     line_size, h);
-    ff_avg_pixels8_mmxext(block + 8, pixels + 8, line_size, h);
-}
-
-#endif /* HAVE_YASM */
-
-
-#if HAVE_INLINE_ASM
-/***********************************/
-/* standard MMX */
-
 void ff_put_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels,
                                int line_size)
 {
@@ -270,70 +167,8 @@
     } while (--i);
 }
 
-static void put_pixels8_mmx(uint8_t *block, const uint8_t *pixels,
-                            ptrdiff_t line_size, int h)
-{
-    __asm__ volatile (
-        "lea   (%3, %3), %%"REG_a"      \n\t"
-        ".p2align     3                 \n\t"
-        "1:                             \n\t"
-        "movq  (%1    ), %%mm0          \n\t"
-        "movq  (%1, %3), %%mm1          \n\t"
-        "movq     %%mm0, (%2)           \n\t"
-        "movq     %%mm1, (%2, %3)       \n\t"
-        "add  %%"REG_a", %1             \n\t"
-        "add  %%"REG_a", %2             \n\t"
-        "movq  (%1    ), %%mm0          \n\t"
-        "movq  (%1, %3), %%mm1          \n\t"
-        "movq     %%mm0, (%2)           \n\t"
-        "movq     %%mm1, (%2, %3)       \n\t"
-        "add  %%"REG_a", %1             \n\t"
-        "add  %%"REG_a", %2             \n\t"
-        "subl        $4, %0             \n\t"
-        "jnz         1b                 \n\t"
-        : "+g"(h), "+r"(pixels),  "+r"(block)
-        : "r"((x86_reg)line_size)
-        : "%"REG_a, "memory"
-        );
-}
-
-static void put_pixels16_mmx(uint8_t *block, const uint8_t *pixels,
-                             ptrdiff_t line_size, int h)
-{
-    __asm__ volatile (
-        "lea   (%3, %3), %%"REG_a"      \n\t"
-        ".p2align     3                 \n\t"
-        "1:                             \n\t"
-        "movq  (%1    ), %%mm0          \n\t"
-        "movq 8(%1    ), %%mm4          \n\t"
-        "movq  (%1, %3), %%mm1          \n\t"
-        "movq 8(%1, %3), %%mm5          \n\t"
-        "movq     %%mm0,  (%2)          \n\t"
-        "movq     %%mm4, 8(%2)          \n\t"
-        "movq     %%mm1,  (%2, %3)      \n\t"
-        "movq     %%mm5, 8(%2, %3)      \n\t"
-        "add  %%"REG_a", %1             \n\t"
-        "add  %%"REG_a", %2             \n\t"
-        "movq  (%1    ), %%mm0          \n\t"
-        "movq 8(%1    ), %%mm4          \n\t"
-        "movq  (%1, %3), %%mm1          \n\t"
-        "movq 8(%1, %3), %%mm5          \n\t"
-        "movq     %%mm0,  (%2)          \n\t"
-        "movq     %%mm4, 8(%2)          \n\t"
-        "movq     %%mm1,  (%2, %3)      \n\t"
-        "movq     %%mm5, 8(%2, %3)      \n\t"
-        "add  %%"REG_a", %1             \n\t"
-        "add  %%"REG_a", %2             \n\t"
-        "subl        $4, %0             \n\t"
-        "jnz         1b                 \n\t"
-        : "+g"(h), "+r"(pixels),  "+r"(block)
-        : "r"((x86_reg)line_size)
-        : "%"REG_a, "memory"
-        );
-}
-
 #define CLEAR_BLOCKS(name, n)                           \
-static void name(int16_t *blocks)                       \
+void name(int16_t *blocks)                              \
 {                                                       \
     __asm__ volatile (                                  \
         "pxor %%mm7, %%mm7              \n\t"           \
@@ -350,10 +185,10 @@
         : "%"REG_a                                      \
         );                                              \
 }
-CLEAR_BLOCKS(clear_blocks_mmx, 6)
-CLEAR_BLOCKS(clear_block_mmx, 1)
+CLEAR_BLOCKS(ff_clear_blocks_mmx, 6)
+CLEAR_BLOCKS(ff_clear_block_mmx, 1)
 
-static void clear_block_sse(int16_t *block)
+void ff_clear_block_sse(int16_t *block)
 {
     __asm__ volatile (
         "xorps  %%xmm0, %%xmm0          \n"
@@ -370,7 +205,7 @@
     );
 }
 
-static void clear_blocks_sse(int16_t *blocks)
+void ff_clear_blocks_sse(int16_t *blocks)
 {
     __asm__ volatile (
         "xorps  %%xmm0, %%xmm0              \n"
@@ -392,7 +227,7 @@
     );
 }
 
-static void add_bytes_mmx(uint8_t *dst, uint8_t *src, int w)
+void ff_add_bytes_mmx(uint8_t *dst, uint8_t *src, int w)
 {
     x86_reg i = 0;
     __asm__ volatile (
@@ -418,9 +253,9 @@
 }
 
 #if HAVE_7REGS
-static void add_hfyu_median_prediction_cmov(uint8_t *dst, const uint8_t *top,
-                                            const uint8_t *diff, int w,
-                                            int *left, int *left_top)
+void ff_add_hfyu_median_prediction_cmov(uint8_t *dst, const uint8_t *top,
+                                        const uint8_t *diff, int w,
+                                        int *left, int *left_top)
 {
     x86_reg w2 = -w;
     x86_reg x;
@@ -457,8 +292,8 @@
 
 /* Draw the edges of width 'w' of an image of size width, height
  * this MMX version can only handle w == 8 || w == 16. */
-static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height,
-                           int w, int h, int sides)
+void ff_draw_edges_mmx(uint8_t *buf, int wrap, int width, int height,
+                       int w, int h, int sides)
 {
     uint8_t *ptr, *last_line;
     int i;
@@ -569,414 +404,6 @@
         }
     }
 }
-#endif /* HAVE_INLINE_ASM */
-
-
-#if HAVE_YASM
-#define QPEL_OP(OPNAME, ROUNDER, RND, MMX)                              \
-static void OPNAME ## qpel8_mc00_ ## MMX (uint8_t *dst, uint8_t *src,   \
-                                          ptrdiff_t stride)             \
-{                                                                       \
-    ff_ ## OPNAME ## pixels8_ ## MMX(dst, src, stride, 8);              \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc10_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         ptrdiff_t stride)              \
-{                                                                       \
-    uint64_t temp[8];                                                   \
-    uint8_t * const half = (uint8_t*)temp;                              \
-    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8,        \
-                                                   stride, 8);          \
-    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src, half,                 \
-                                        stride, stride, 8);             \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc20_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         ptrdiff_t stride)              \
-{                                                                       \
-    ff_ ## OPNAME ## mpeg4_qpel8_h_lowpass_ ## MMX(dst, src, stride,    \
-                                                   stride, 8);          \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc30_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         ptrdiff_t stride)              \
-{                                                                       \
-    uint64_t temp[8];                                                   \
-    uint8_t * const half = (uint8_t*)temp;                              \
-    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8,        \
-                                                   stride, 8);          \
-    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src + 1, half, stride,     \
-                                        stride, 8);                     \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc01_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         ptrdiff_t stride)              \
-{                                                                       \
-    uint64_t temp[8];                                                   \
-    uint8_t * const half = (uint8_t*)temp;                              \
-    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src,           \
-                                                   8, stride);          \
-    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src, half,                 \
-                                        stride, stride, 8);             \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc02_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         ptrdiff_t stride)              \
-{                                                                       \
-    ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, src,            \
-                                                   stride, stride);     \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc03_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         ptrdiff_t stride)              \
-{                                                                       \
-    uint64_t temp[8];                                                   \
-    uint8_t * const half = (uint8_t*)temp;                              \
-    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src,           \
-                                                   8, stride);          \
-    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src + stride, half, stride,\
-                                        stride, 8);                     \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc11_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         ptrdiff_t stride)              \
-{                                                                       \
-    uint64_t half[8 + 9];                                               \
-    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
-                                                   stride, 9);          \
-    ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8,           \
-                                        stride, 9);                     \
-    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
-    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV,             \
-                                        stride, 8, 8);                  \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc31_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         ptrdiff_t stride)              \
-{                                                                       \
-    uint64_t half[8 + 9];                                               \
-    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
-                                                   stride, 9);          \
-    ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8,       \
-                                        stride, 9);                     \
-    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
-    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV,             \
-                                        stride, 8, 8);                  \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc13_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         ptrdiff_t stride)              \
-{                                                                       \
-    uint64_t half[8 + 9];                                               \
-    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
-                                                   stride, 9);          \
-    ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8,           \
-                                        stride, 9);                     \
-    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
-    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV,         \
-                                        stride, 8, 8);                  \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc33_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         ptrdiff_t stride)              \
-{                                                                       \
-    uint64_t half[8 + 9];                                               \
-    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
-                                                   stride, 9);          \
-    ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8,       \
-                                        stride, 9);                     \
-    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
-    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV,         \
-                                        stride, 8, 8);                  \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc21_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         ptrdiff_t stride)              \
-{                                                                       \
-    uint64_t half[8 + 9];                                               \
-    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
-                                                   stride, 9);          \
-    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
-    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV,             \
-                                        stride, 8, 8);                  \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc23_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         ptrdiff_t stride)              \
-{                                                                       \
-    uint64_t half[8 + 9];                                               \
-    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
-                                                   stride, 9);          \
-    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
-    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV,         \
-                                        stride, 8, 8);                  \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc12_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         ptrdiff_t stride)              \
-{                                                                       \
-    uint64_t half[8 + 9];                                               \
-    uint8_t * const halfH = ((uint8_t*)half);                           \
-    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
-                                                   stride, 9);          \
-    ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH,              \
-                                        8, stride, 9);                  \
-    ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH,          \
-                                                   stride, 8);          \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc32_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         ptrdiff_t stride)              \
-{                                                                       \
-    uint64_t half[8 + 9];                                               \
-    uint8_t * const halfH = ((uint8_t*)half);                           \
-    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
-                                                   stride, 9);          \
-    ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8,       \
-                                        stride, 9);                     \
-    ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH,          \
-                                                   stride, 8);          \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc22_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         ptrdiff_t stride)              \
-{                                                                       \
-    uint64_t half[9];                                                   \
-    uint8_t * const halfH = ((uint8_t*)half);                           \
-    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
-                                                   stride, 9);          \
-    ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH,          \
-                                                   stride, 8);          \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc00_ ## MMX (uint8_t *dst, uint8_t *src,  \
-                                           ptrdiff_t stride)            \
-{                                                                       \
-    ff_ ## OPNAME ## pixels16_ ## MMX(dst, src, stride, 16);            \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc10_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          ptrdiff_t stride)             \
-{                                                                       \
-    uint64_t temp[32];                                                  \
-    uint8_t * const half = (uint8_t*)temp;                              \
-    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16,      \
-                                                    stride, 16);        \
-    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride,        \
-                                         stride, 16);                   \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc20_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          ptrdiff_t stride)             \
-{                                                                       \
-    ff_ ## OPNAME ## mpeg4_qpel16_h_lowpass_ ## MMX(dst, src,           \
-                                                    stride, stride, 16);\
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc30_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          ptrdiff_t stride)             \
-{                                                                       \
-    uint64_t temp[32];                                                  \
-    uint8_t * const half = (uint8_t*)temp;                              \
-    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16,      \
-                                                    stride, 16);        \
-    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src + 1, half,            \
-                                         stride, stride, 16);           \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc01_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          ptrdiff_t stride)             \
-{                                                                       \
-    uint64_t temp[32];                                                  \
-    uint8_t * const half = (uint8_t*)temp;                              \
-    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16,      \
-                                                    stride);            \
-    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride,        \
-                                         stride, 16);                   \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc02_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          ptrdiff_t stride)             \
-{                                                                       \
-    ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, src,           \
-                                                    stride, stride);    \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc03_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          ptrdiff_t stride)             \
-{                                                                       \
-    uint64_t temp[32];                                                  \
-    uint8_t * const half = (uint8_t*)temp;                              \
-    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16,      \
-                                                    stride);            \
-    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src+stride, half,         \
-                                         stride, stride, 16);           \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc11_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          ptrdiff_t stride)             \
-{                                                                       \
-    uint64_t half[16 * 2 + 17 * 2];                                     \
-    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
-                                                    stride, 17);        \
-    ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16,         \
-                                         stride, 17);                   \
-    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
-                                                    16, 16);            \
-    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV,            \
-                                         stride, 16, 16);               \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc31_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          ptrdiff_t stride)             \
-{                                                                       \
-    uint64_t half[16 * 2 + 17 * 2];                                     \
-    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
-                                                    stride, 17);        \
-    ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16,     \
-                                         stride, 17);                   \
-    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
-                                                    16, 16);            \
-    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV,            \
-                                         stride, 16, 16);               \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc13_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          ptrdiff_t stride)             \
-{                                                                       \
-    uint64_t half[16 * 2 + 17 * 2];                                     \
-    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
-                                                    stride, 17);        \
-    ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16,         \
-                                         stride, 17);                   \
-    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
-                                                    16, 16);            \
-    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV,       \
-                                         stride, 16, 16);               \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc33_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          ptrdiff_t stride)             \
-{                                                                       \
-    uint64_t half[16 * 2 + 17 * 2];                                     \
-    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
-                                                    stride, 17);        \
-    ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16,     \
-                                         stride, 17);                   \
-    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
-                                                    16, 16);            \
-    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV,       \
-                                         stride, 16, 16);               \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc21_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          ptrdiff_t stride)             \
-{                                                                       \
-    uint64_t half[16 * 2 + 17 * 2];                                     \
-    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
-                                                    stride, 17);        \
-    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
-                                                    16, 16);            \
-    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV,            \
-                                         stride, 16, 16);               \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc23_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          ptrdiff_t stride)             \
-{                                                                       \
-    uint64_t half[16 * 2 + 17 * 2];                                     \
-    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
-                                                    stride, 17);        \
-    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
-                                                    16, 16);            \
-    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV,       \
-                                         stride, 16, 16);               \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc12_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          ptrdiff_t stride)             \
-{                                                                       \
-    uint64_t half[17 * 2];                                              \
-    uint8_t * const halfH = ((uint8_t*)half);                           \
-    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
-                                                    stride, 17);        \
-    ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16,         \
-                                         stride, 17);                   \
-    ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH,         \
-                                                    stride, 16);        \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc32_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          ptrdiff_t stride)             \
-{                                                                       \
-    uint64_t half[17 * 2];                                              \
-    uint8_t * const halfH = ((uint8_t*)half);                           \
-    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
-                                                    stride, 17);        \
-    ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16,     \
-                                         stride, 17);                   \
-    ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH,         \
-                                                    stride, 16);        \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc22_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          ptrdiff_t stride)             \
-{                                                                       \
-    uint64_t half[17 * 2];                                              \
-    uint8_t * const halfH = ((uint8_t*)half);                           \
-    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
-                                                    stride, 17);        \
-    ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH,         \
-                                                    stride, 16);        \
-}
-
-QPEL_OP(put_,          ff_pw_16, _,        mmxext)
-QPEL_OP(avg_,          ff_pw_16, _,        mmxext)
-QPEL_OP(put_no_rnd_,   ff_pw_15, _no_rnd_, mmxext)
-#endif /* HAVE_YASM */
-
-
-#if HAVE_INLINE_ASM
-void ff_put_rv40_qpel8_mc33_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
-{
-  put_pixels8_xy2_mmx(dst, src, stride, 8);
-}
-void ff_put_rv40_qpel16_mc33_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
-{
-  put_pixels16_xy2_mmx(dst, src, stride, 16);
-}
-void ff_avg_rv40_qpel8_mc33_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
-{
-  avg_pixels8_xy2_mmx(dst, src, stride, 8);
-}
-void ff_avg_rv40_qpel16_mc33_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
-{
-  avg_pixels16_xy2_mmx(dst, src, stride, 16);
-}
 
 typedef void emulated_edge_mc_func(uint8_t *dst, const uint8_t *src,
                                    ptrdiff_t linesize, int block_w, int block_h,
@@ -1108,32 +535,31 @@
     }
 }
 
-
 #if CONFIG_VIDEODSP
 #if HAVE_YASM
 #if ARCH_X86_32
-static void gmc_mmx(uint8_t *dst, uint8_t *src,
-                    int stride, int h, int ox, int oy,
-                    int dxx, int dxy, int dyx, int dyy,
-                    int shift, int r, int width, int height)
+void ff_gmc_mmx(uint8_t *dst, uint8_t *src,
+                int stride, int h, int ox, int oy,
+                int dxx, int dxy, int dyx, int dyy,
+                int shift, int r, int width, int height)
 {
     gmc(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, shift, r,
         width, height, &ff_emulated_edge_mc_8);
 }
 #endif
-static void gmc_sse(uint8_t *dst, uint8_t *src,
-                    int stride, int h, int ox, int oy,
-                    int dxx, int dxy, int dyx, int dyy,
-                    int shift, int r, int width, int height)
+void ff_gmc_sse(uint8_t *dst, uint8_t *src,
+                int stride, int h, int ox, int oy,
+                int dxx, int dxy, int dyx, int dyy,
+                int shift, int r, int width, int height)
 {
     gmc(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, shift, r,
         width, height, &ff_emulated_edge_mc_8);
 }
 #else
-static void gmc_mmx(uint8_t *dst, uint8_t *src,
-                    int stride, int h, int ox, int oy,
-                    int dxx, int dxy, int dyx, int dyy,
-                    int shift, int r, int width, int height)
+void ff_gmc_mmx(uint8_t *dst, uint8_t *src,
+                int stride, int h, int ox, int oy,
+                int dxx, int dxy, int dyx, int dyy,
+                int shift, int r, int width, int height)
 {
     gmc(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, shift, r,
         width, height, &ff_emulated_edge_mc_8);
@@ -1141,34 +567,6 @@
 #endif
 #endif
 
-/* CAVS-specific */
-void ff_put_cavs_qpel8_mc00_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
-{
-    put_pixels8_mmx(dst, src, stride, 8);
-}
-
-void ff_avg_cavs_qpel8_mc00_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
-{
-    avg_pixels8_mmx(dst, src, stride, 8);
-}
-
-void ff_put_cavs_qpel16_mc00_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
-{
-    put_pixels16_mmx(dst, src, stride, 16);
-}
-
-void ff_avg_cavs_qpel16_mc00_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
-{
-    avg_pixels16_mmx(dst, src, stride, 16);
-}
-
-/* VC-1-specific */
-void ff_put_vc1_mspel_mc00_mmx(uint8_t *dst, const uint8_t *src,
-                               ptrdiff_t stride, int rnd)
-{
-    put_pixels8_mmx(dst, src, stride, 8);
-}
-
 #if CONFIG_DIRAC_DECODER
 #define DIRAC_PIXOP(OPNAME2, OPNAME, EXT)\
 void ff_ ## OPNAME2 ## _dirac_pixels8_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\
@@ -1196,8 +594,9 @@
 }
 
 #if HAVE_MMX_INLINE
-DIRAC_PIXOP(put, put, mmx)
-DIRAC_PIXOP(avg, avg, mmx)
+PIXELS16(static, ff_avg, , , _mmxext)
+DIRAC_PIXOP(put, ff_put, mmx)
+DIRAC_PIXOP(avg, ff_avg, mmx)
 #endif
 
 #if HAVE_YASM
@@ -1238,8 +637,8 @@
 #endif
 #endif
 
-static void vector_clipf_sse(float *dst, const float *src,
-                             float min, float max, int len)
+void ff_vector_clipf_sse(float *dst, const float *src,
+                         float min, float max, int len)
 {
     x86_reg i = (len - 16) * 4;
     __asm__ volatile (
@@ -1273,274 +672,3 @@
 }
 
 #endif /* HAVE_INLINE_ASM */
-
-void ff_h263_v_loop_filter_mmx(uint8_t *src, int stride, int qscale);
-void ff_h263_h_loop_filter_mmx(uint8_t *src, int stride, int qscale);
-
-int32_t ff_scalarproduct_int16_mmxext(const int16_t *v1, const int16_t *v2,
-                                      int order);
-int32_t ff_scalarproduct_int16_sse2(const int16_t *v1, const int16_t *v2,
-                                    int order);
-int32_t ff_scalarproduct_and_madd_int16_mmxext(int16_t *v1, const int16_t *v2,
-                                               const int16_t *v3,
-                                               int order, int mul);
-int32_t ff_scalarproduct_and_madd_int16_sse2(int16_t *v1, const int16_t *v2,
-                                             const int16_t *v3,
-                                             int order, int mul);
-int32_t ff_scalarproduct_and_madd_int16_ssse3(int16_t *v1, const int16_t *v2,
-                                              const int16_t *v3,
-                                              int order, int mul);
-
-void ff_apply_window_int16_round_mmxext(int16_t *output, const int16_t *input,
-                                        const int16_t *window, unsigned int len);
-void ff_apply_window_int16_round_sse2(int16_t *output, const int16_t *input,
-                                      const int16_t *window, unsigned int len);
-void ff_apply_window_int16_mmxext(int16_t *output, const int16_t *input,
-                                  const int16_t *window, unsigned int len);
-void ff_apply_window_int16_sse2(int16_t *output, const int16_t *input,
-                                const int16_t *window, unsigned int len);
-void ff_apply_window_int16_ssse3(int16_t *output, const int16_t *input,
-                                 const int16_t *window, unsigned int len);
-void ff_apply_window_int16_ssse3_atom(int16_t *output, const int16_t *input,
-                                      const int16_t *window, unsigned int len);
-
-void ff_bswap32_buf_ssse3(uint32_t *dst, const uint32_t *src, int w);
-void ff_bswap32_buf_sse2(uint32_t *dst, const uint32_t *src, int w);
-
-void ff_add_hfyu_median_prediction_mmxext(uint8_t *dst, const uint8_t *top,
-                                          const uint8_t *diff, int w,
-                                          int *left, int *left_top);
-int  ff_add_hfyu_left_prediction_ssse3(uint8_t *dst, const uint8_t *src,
-                                       int w, int left);
-int  ff_add_hfyu_left_prediction_sse4(uint8_t *dst, const uint8_t *src,
-                                      int w, int left);
-
-void ff_vector_clip_int32_mmx     (int32_t *dst, const int32_t *src,
-                                   int32_t min, int32_t max, unsigned int len);
-void ff_vector_clip_int32_sse2    (int32_t *dst, const int32_t *src,
-                                   int32_t min, int32_t max, unsigned int len);
-void ff_vector_clip_int32_int_sse2(int32_t *dst, const int32_t *src,
-                                   int32_t min, int32_t max, unsigned int len);
-void ff_vector_clip_int32_sse4    (int32_t *dst, const int32_t *src,
-                                   int32_t min, int32_t max, unsigned int len);
-
-#define SET_QPEL_FUNCS(PFX, IDX, SIZE, CPU, PREFIX)                          \
-    do {                                                                     \
-    c->PFX ## _pixels_tab[IDX][ 0] = PREFIX ## PFX ## SIZE ## _mc00_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][ 1] = PREFIX ## PFX ## SIZE ## _mc10_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][ 2] = PREFIX ## PFX ## SIZE ## _mc20_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][ 3] = PREFIX ## PFX ## SIZE ## _mc30_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][ 4] = PREFIX ## PFX ## SIZE ## _mc01_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][ 5] = PREFIX ## PFX ## SIZE ## _mc11_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][ 6] = PREFIX ## PFX ## SIZE ## _mc21_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][ 7] = PREFIX ## PFX ## SIZE ## _mc31_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][ 8] = PREFIX ## PFX ## SIZE ## _mc02_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][ 9] = PREFIX ## PFX ## SIZE ## _mc12_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][10] = PREFIX ## PFX ## SIZE ## _mc22_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][11] = PREFIX ## PFX ## SIZE ## _mc32_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][12] = PREFIX ## PFX ## SIZE ## _mc03_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][13] = PREFIX ## PFX ## SIZE ## _mc13_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][14] = PREFIX ## PFX ## SIZE ## _mc23_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][15] = PREFIX ## PFX ## SIZE ## _mc33_ ## CPU; \
-    } while (0)
-
-static av_cold void dsputil_init_mmx(DSPContext *c, AVCodecContext *avctx,
-                                     int mm_flags)
-{
-#if HAVE_INLINE_ASM
-    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
-
-    c->put_pixels_clamped        = ff_put_pixels_clamped_mmx;
-    c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_mmx;
-    c->add_pixels_clamped        = ff_add_pixels_clamped_mmx;
-
-    if (!high_bit_depth) {
-        c->clear_block  = clear_block_mmx;
-        c->clear_blocks = clear_blocks_mmx;
-        c->draw_edges   = draw_edges_mmx;
-    }
-
-#if CONFIG_VIDEODSP && (ARCH_X86_32 || !HAVE_YASM)
-    c->gmc = gmc_mmx;
-#endif
-
-    c->add_bytes = add_bytes_mmx;
-#endif /* HAVE_INLINE_ASM */
-
-#if HAVE_YASM
-    if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) {
-        c->h263_v_loop_filter = ff_h263_v_loop_filter_mmx;
-        c->h263_h_loop_filter = ff_h263_h_loop_filter_mmx;
-    }
-
-    c->vector_clip_int32 = ff_vector_clip_int32_mmx;
-#endif /* HAVE_YASM */
-}
-
-static av_cold void dsputil_init_mmxext(DSPContext *c, AVCodecContext *avctx,
-                                        int mm_flags)
-{
-#if HAVE_MMXEXT_EXTERNAL
-    SET_QPEL_FUNCS(avg_qpel,        0, 16, mmxext, );
-    SET_QPEL_FUNCS(avg_qpel,        1,  8, mmxext, );
-
-    SET_QPEL_FUNCS(put_qpel,        0, 16, mmxext, );
-    SET_QPEL_FUNCS(put_qpel,        1,  8, mmxext, );
-    SET_QPEL_FUNCS(put_no_rnd_qpel, 0, 16, mmxext, );
-    SET_QPEL_FUNCS(put_no_rnd_qpel, 1,  8, mmxext, );
-
-    /* slower than cmov version on AMD */
-    if (!(mm_flags & AV_CPU_FLAG_3DNOW))
-        c->add_hfyu_median_prediction = ff_add_hfyu_median_prediction_mmxext;
-
-    c->scalarproduct_int16          = ff_scalarproduct_int16_mmxext;
-    c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_mmxext;
-
-    if (avctx->flags & CODEC_FLAG_BITEXACT) {
-        c->apply_window_int16 = ff_apply_window_int16_mmxext;
-    } else {
-        c->apply_window_int16 = ff_apply_window_int16_round_mmxext;
-    }
-#endif /* HAVE_MMXEXT_EXTERNAL */
-}
-
-static av_cold void dsputil_init_sse(DSPContext *c, AVCodecContext *avctx,
-                                     int mm_flags)
-{
-#if HAVE_INLINE_ASM
-    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
-
-    if (!high_bit_depth) {
-        if (!(CONFIG_MPEG_XVMC_DECODER && avctx->xvmc_acceleration > 1)) {
-            /* XvMCCreateBlocks() may not allocate 16-byte aligned blocks */
-            c->clear_block  = clear_block_sse;
-            c->clear_blocks = clear_blocks_sse;
-        }
-    }
-
-    c->vector_clipf = vector_clipf_sse;
-#endif /* HAVE_INLINE_ASM */
-
-#if HAVE_YASM
-#if HAVE_INLINE_ASM && CONFIG_VIDEODSP
-    c->gmc = gmc_sse;
-#endif
-#endif /* HAVE_YASM */
-}
-
-static av_cold void dsputil_init_sse2(DSPContext *c, AVCodecContext *avctx,
-                                      int mm_flags)
-{
-#if HAVE_SSE2_INLINE
-    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
-
-    if (!high_bit_depth && avctx->idct_algo == FF_IDCT_XVIDMMX) {
-        c->idct_put              = ff_idct_xvid_sse2_put;
-        c->idct_add              = ff_idct_xvid_sse2_add;
-        c->idct                  = ff_idct_xvid_sse2;
-        c->idct_permutation_type = FF_SSE2_IDCT_PERM;
-    }
-#endif /* HAVE_SSE2_INLINE */
-
-#if HAVE_SSE2_EXTERNAL
-    c->scalarproduct_int16          = ff_scalarproduct_int16_sse2;
-    c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_sse2;
-    if (mm_flags & AV_CPU_FLAG_ATOM) {
-        c->vector_clip_int32 = ff_vector_clip_int32_int_sse2;
-    } else {
-        c->vector_clip_int32 = ff_vector_clip_int32_sse2;
-    }
-    if (avctx->flags & CODEC_FLAG_BITEXACT) {
-        c->apply_window_int16 = ff_apply_window_int16_sse2;
-    } else if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW)) {
-        c->apply_window_int16 = ff_apply_window_int16_round_sse2;
-    }
-    c->bswap_buf = ff_bswap32_buf_sse2;
-#endif /* HAVE_SSE2_EXTERNAL */
-}
-
-static av_cold void dsputil_init_ssse3(DSPContext *c, AVCodecContext *avctx,
-                                       int mm_flags)
-{
-#if HAVE_SSSE3_EXTERNAL
-    c->add_hfyu_left_prediction = ff_add_hfyu_left_prediction_ssse3;
-    if (mm_flags & AV_CPU_FLAG_SSE4) // not really sse4, just slow on Conroe
-        c->add_hfyu_left_prediction = ff_add_hfyu_left_prediction_sse4;
-
-    if (mm_flags & AV_CPU_FLAG_ATOM)
-        c->apply_window_int16 = ff_apply_window_int16_ssse3_atom;
-    else
-        c->apply_window_int16 = ff_apply_window_int16_ssse3;
-    if (!(mm_flags & (AV_CPU_FLAG_SSE42|AV_CPU_FLAG_3DNOW))) // cachesplit
-        c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_ssse3;
-    c->bswap_buf = ff_bswap32_buf_ssse3;
-#endif /* HAVE_SSSE3_EXTERNAL */
-}
-
-static av_cold void dsputil_init_sse4(DSPContext *c, AVCodecContext *avctx,
-                                      int mm_flags)
-{
-#if HAVE_SSE4_EXTERNAL
-    c->vector_clip_int32 = ff_vector_clip_int32_sse4;
-#endif /* HAVE_SSE4_EXTERNAL */
-}
-
-av_cold void ff_dsputil_init_mmx(DSPContext *c, AVCodecContext *avctx)
-{
-    int mm_flags = av_get_cpu_flags();
-
-#if HAVE_7REGS && HAVE_INLINE_ASM
-    if (mm_flags & AV_CPU_FLAG_CMOV)
-        c->add_hfyu_median_prediction = add_hfyu_median_prediction_cmov;
-#endif
-
-    if (mm_flags & AV_CPU_FLAG_MMX) {
-#if HAVE_INLINE_ASM
-        const int idct_algo = avctx->idct_algo;
-
-        if (avctx->lowres == 0 && avctx->bits_per_raw_sample <= 8) {
-            if (idct_algo == FF_IDCT_AUTO || idct_algo == FF_IDCT_SIMPLEMMX) {
-                c->idct_put              = ff_simple_idct_put_mmx;
-                c->idct_add              = ff_simple_idct_add_mmx;
-                c->idct                  = ff_simple_idct_mmx;
-                c->idct_permutation_type = FF_SIMPLE_IDCT_PERM;
-            } else if (idct_algo == FF_IDCT_XVIDMMX) {
-                if (mm_flags & AV_CPU_FLAG_SSE2) {
-                    c->idct_put              = ff_idct_xvid_sse2_put;
-                    c->idct_add              = ff_idct_xvid_sse2_add;
-                    c->idct                  = ff_idct_xvid_sse2;
-                    c->idct_permutation_type = FF_SSE2_IDCT_PERM;
-                } else if (mm_flags & AV_CPU_FLAG_MMXEXT) {
-                    c->idct_put              = ff_idct_xvid_mmxext_put;
-                    c->idct_add              = ff_idct_xvid_mmxext_add;
-                    c->idct                  = ff_idct_xvid_mmxext;
-                } else {
-                    c->idct_put              = ff_idct_xvid_mmx_put;
-                    c->idct_add              = ff_idct_xvid_mmx_add;
-                    c->idct                  = ff_idct_xvid_mmx;
-                }
-            }
-        }
-#endif /* HAVE_INLINE_ASM */
-
-        dsputil_init_mmx(c, avctx, mm_flags);
-    }
-
-    if (mm_flags & AV_CPU_FLAG_MMXEXT)
-        dsputil_init_mmxext(c, avctx, mm_flags);
-
-    if (mm_flags & AV_CPU_FLAG_SSE)
-        dsputil_init_sse(c, avctx, mm_flags);
-
-    if (mm_flags & AV_CPU_FLAG_SSE2)
-        dsputil_init_sse2(c, avctx, mm_flags);
-
-    if (mm_flags & AV_CPU_FLAG_SSSE3)
-        dsputil_init_ssse3(c, avctx, mm_flags);
-
-    if (mm_flags & AV_CPU_FLAG_SSE4)
-        dsputil_init_sse4(c, avctx, mm_flags);
-
-    if (CONFIG_ENCODERS)
-        ff_dsputilenc_init_mmx(c, avctx);
-}
diff --git a/libavcodec/x86/dsputil_mmx.h b/libavcodec/x86/dsputil_x86.h
similarity index 68%
rename from libavcodec/x86/dsputil_mmx.h
rename to libavcodec/x86/dsputil_x86.h
index 8fc871c..356b2c1 100644
--- a/libavcodec/x86/dsputil_mmx.h
+++ b/libavcodec/x86/dsputil_x86.h
@@ -27,43 +27,7 @@
 
 #include "libavcodec/dsputil.h"
 #include "libavutil/x86/asm.h"
-
-extern const uint64_t ff_wtwo;
-
-extern const xmm_reg  ff_pw_3;
-extern const xmm_reg  ff_pw_4;
-extern const xmm_reg  ff_pw_5;
-extern const xmm_reg  ff_pw_8;
-extern const uint64_t ff_pw_15;
-extern const xmm_reg  ff_pw_16;
-extern const xmm_reg  ff_pw_18;
-extern const uint64_t ff_pw_20;
-extern const xmm_reg  ff_pw_32;
-extern const uint64_t ff_pw_42;
-extern const uint64_t ff_pw_53;
-extern const xmm_reg  ff_pw_64;
-extern const uint64_t ff_pw_96;
-extern const uint64_t ff_pw_128;
-extern const uint64_t ff_pw_255;
-
-extern const xmm_reg  ff_pb_1;
-extern const xmm_reg  ff_pb_3;
-extern const xmm_reg  ff_pb_F8;
-extern const uint64_t ff_pb_FC;
-
-extern const double ff_pd_1[2];
-extern const double ff_pd_2[2];
-
-#define SBUTTERFLY(a,b,t,n,m)\
-    "mov" #m " " #a ", " #t "         \n\t" /* abcd */\
-    "punpckl" #n " " #b ", " #a "     \n\t" /* aebf */\
-    "punpckh" #n " " #b ", " #t "     \n\t" /* cgdh */\
-
-#define TRANSPOSE4(a,b,c,d,t)\
-    SBUTTERFLY(a,b,t,wd,q) /* a=aebf t=cgdh */\
-    SBUTTERFLY(c,d,b,wd,q) /* c=imjn b=kolp */\
-    SBUTTERFLY(a,c,d,dq,q) /* a=aeim d=bfjn */\
-    SBUTTERFLY(t,b,c,dq,q) /* t=cgko c=dhlp */
+#include "constants.h"
 
 #define MOVQ_WONE(regd) \
     __asm__ volatile ( \
@@ -146,6 +110,41 @@
 void ff_put_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, int line_size);
 void ff_put_signed_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, int line_size);
 
+void ff_clear_block_mmx(int16_t *block);
+void ff_clear_block_sse(int16_t *block);
+void ff_clear_blocks_mmx(int16_t *blocks);
+void ff_clear_blocks_sse(int16_t *blocks);
+
+void ff_add_bytes_mmx(uint8_t *dst, uint8_t *src, int w);
+
+void ff_add_hfyu_median_prediction_cmov(uint8_t *dst, const uint8_t *top,
+                                        const uint8_t *diff, int w,
+                                        int *left, int *left_top);
+
+void ff_draw_edges_mmx(uint8_t *buf, int wrap, int width, int height,
+                       int w, int h, int sides);
+
+void ff_gmc_mmx(uint8_t *dst, uint8_t *src,
+                int stride, int h, int ox, int oy,
+                int dxx, int dxy, int dyx, int dyy,
+                int shift, int r, int width, int height);
+
+void ff_gmc_sse(uint8_t *dst, uint8_t *src,
+                int stride, int h, int ox, int oy,
+                int dxx, int dxy, int dyx, int dyy,
+                int shift, int r, int width, int height);
+
+void ff_vector_clipf_sse(float *dst, const float *src,
+                         float min, float max, int len);
+
+void ff_avg_pixels8_mmx(uint8_t *block, const uint8_t *pixels,
+                        ptrdiff_t line_size, int h);
+void ff_avg_pixels16_mmx(uint8_t *block, const uint8_t *pixels,
+                         ptrdiff_t line_size, int h);
+void ff_put_pixels8_mmx(uint8_t *block, const uint8_t *pixels,
+                        ptrdiff_t line_size, int h);
+void ff_put_pixels16_mmx(uint8_t *block, const uint8_t *pixels,
+                         ptrdiff_t line_size, int h);
 void ff_avg_pixels8_mmxext(uint8_t *block, const uint8_t *pixels,
                            ptrdiff_t line_size, int h);
 void ff_put_pixels8_mmxext(uint8_t *block, const uint8_t *pixels,
@@ -155,22 +154,23 @@
 void ff_put_pixels16_sse2(uint8_t *block, const uint8_t *pixels,
                           ptrdiff_t line_size, int h);
 
-void ff_put_cavs_qpel8_mc00_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
-void ff_avg_cavs_qpel8_mc00_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
-void ff_put_cavs_qpel16_mc00_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
-void ff_avg_cavs_qpel16_mc00_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
+void ff_avg_pixels8_x2_mmx(uint8_t *block, const uint8_t *pixels,
+                           ptrdiff_t line_size, int h);
 
-void ff_put_vc1_mspel_mc00_mmx(uint8_t *dst, const uint8_t *src, ptrdiff_t stride, int rnd);
+void ff_avg_pixels8_xy2_mmx(uint8_t *block, const uint8_t *pixels,
+                            ptrdiff_t line_size, int h);
+void ff_avg_pixels16_xy2_mmx(uint8_t *block, const uint8_t *pixels,
+                             ptrdiff_t line_size, int h);
 
-void ff_put_rv40_qpel8_mc33_mmx(uint8_t *block, uint8_t *pixels, ptrdiff_t stride);
-void ff_put_rv40_qpel16_mc33_mmx(uint8_t *block, uint8_t *pixels, ptrdiff_t stride);
-void ff_avg_rv40_qpel8_mc33_mmx(uint8_t *block, uint8_t *pixels, ptrdiff_t stride);
-void ff_avg_rv40_qpel16_mc33_mmx(uint8_t *block, uint8_t *pixels, ptrdiff_t stride);
+void ff_put_pixels8_xy2_mmx(uint8_t *block, const uint8_t *pixels,
+                            ptrdiff_t line_size, int h);
+void ff_put_pixels16_xy2_mmx(uint8_t *block, const uint8_t *pixels,
+                             ptrdiff_t line_size, int h);
+
 
 void ff_mmx_idct(int16_t *block);
 void ff_mmxext_idct(int16_t *block);
 
-
 void ff_deinterlace_line_mmx(uint8_t *dst,
                              const uint8_t *lum_m4, const uint8_t *lum_m3,
                              const uint8_t *lum_m2, const uint8_t *lum_m1,
@@ -183,4 +183,16 @@
                                      const uint8_t *lum_m1,
                                      const uint8_t *lum, int size);
 
+#define PIXELS16(STATIC, PFX1, PFX2, TYPE, CPUEXT)                      \
+STATIC void PFX1 ## _pixels16 ## TYPE ## CPUEXT(uint8_t *block,         \
+                                                const uint8_t *pixels,  \
+                                                ptrdiff_t line_size,    \
+                                                int h)                  \
+{                                                                       \
+    PFX2 ## PFX1 ## _pixels8 ## TYPE ## CPUEXT(block,      pixels,      \
+                                               line_size, h);           \
+    PFX2 ## PFX1 ## _pixels8 ## TYPE ## CPUEXT(block + 8,  pixels + 8,  \
+                                               line_size, h);           \
+}
+
 #endif /* AVCODEC_X86_DSPUTIL_MMX_H */
diff --git a/libavcodec/x86/dsputilenc_mmx.c b/libavcodec/x86/dsputilenc_mmx.c
index 49e3019..01352cd 100644
--- a/libavcodec/x86/dsputilenc_mmx.c
+++ b/libavcodec/x86/dsputilenc_mmx.c
@@ -30,7 +30,7 @@
 #include "libavcodec/dsputil.h"
 #include "libavcodec/mpegvideo.h"
 #include "libavcodec/mathops.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 
 void ff_get_pixels_mmx(int16_t *block, const uint8_t *pixels, int line_size);
 void ff_get_pixels_sse2(int16_t *block, const uint8_t *pixels, int line_size);
@@ -946,12 +946,12 @@
 
 av_cold void ff_dsputilenc_init_mmx(DSPContext *c, AVCodecContext *avctx)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
 #if HAVE_YASM
     int bit_depth = avctx->bits_per_raw_sample;
 
-    if (EXTERNAL_MMX(mm_flags)) {
+    if (EXTERNAL_MMX(cpu_flags)) {
         if (bit_depth <= 8)
             c->get_pixels = ff_get_pixels_mmx;
         c->diff_pixels = ff_diff_pixels_mmx;
@@ -959,19 +959,19 @@
 
         c->pix_norm1 = ff_pix_norm1_mmx;
     }
-    if (EXTERNAL_SSE2(mm_flags))
+    if (EXTERNAL_SSE2(cpu_flags))
         if (bit_depth <= 8)
             c->get_pixels = ff_get_pixels_sse2;
 #endif /* HAVE_YASM */
 
 #if HAVE_INLINE_ASM
-    if (mm_flags & AV_CPU_FLAG_MMX) {
+    if (cpu_flags & AV_CPU_FLAG_MMX) {
         const int dct_algo = avctx->dct_algo;
         if (avctx->bits_per_raw_sample <= 8 &&
             (dct_algo==FF_DCT_AUTO || dct_algo==FF_DCT_MMX)) {
-            if(mm_flags & AV_CPU_FLAG_SSE2){
+            if (cpu_flags & AV_CPU_FLAG_SSE2) {
                 c->fdct = ff_fdct_sse2;
-            } else if (mm_flags & AV_CPU_FLAG_MMXEXT) {
+            } else if (cpu_flags & AV_CPU_FLAG_MMXEXT) {
                 c->fdct = ff_fdct_mmxext;
             }else{
                 c->fdct = ff_fdct_mmx;
@@ -999,7 +999,7 @@
 
         c->ssd_int8_vs_int16 = ssd_int8_vs_int16_mmx;
 
-        if (mm_flags & AV_CPU_FLAG_MMXEXT) {
+        if (cpu_flags & AV_CPU_FLAG_MMXEXT) {
             c->sum_abs_dctelem = sum_abs_dctelem_mmxext;
             c->vsad[4]         = vsad_intra16_mmxext;
 
@@ -1010,12 +1010,12 @@
             c->sub_hfyu_median_prediction = sub_hfyu_median_prediction_mmxext;
         }
 
-        if(mm_flags & AV_CPU_FLAG_SSE2){
+        if (cpu_flags & AV_CPU_FLAG_SSE2) {
             c->sum_abs_dctelem= sum_abs_dctelem_sse2;
         }
 
 #if HAVE_SSSE3_INLINE
-        if(mm_flags & AV_CPU_FLAG_SSSE3){
+        if (cpu_flags & AV_CPU_FLAG_SSSE3) {
             if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
                 c->try_8x8basis= try_8x8basis_ssse3;
             }
@@ -1024,7 +1024,7 @@
         }
 #endif
 
-        if(mm_flags & AV_CPU_FLAG_3DNOW){
+        if (cpu_flags & AV_CPU_FLAG_3DNOW) {
             if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
                 c->try_8x8basis= try_8x8basis_3dnow;
             }
@@ -1033,16 +1033,16 @@
     }
 #endif /* HAVE_INLINE_ASM */
 
-    if (EXTERNAL_MMX(mm_flags)) {
+    if (EXTERNAL_MMX(cpu_flags)) {
         c->hadamard8_diff[0] = ff_hadamard8_diff16_mmx;
         c->hadamard8_diff[1] = ff_hadamard8_diff_mmx;
 
-        if (EXTERNAL_MMXEXT(mm_flags)) {
+        if (EXTERNAL_MMXEXT(cpu_flags)) {
             c->hadamard8_diff[0] = ff_hadamard8_diff16_mmxext;
             c->hadamard8_diff[1] = ff_hadamard8_diff_mmxext;
         }
 
-        if (EXTERNAL_SSE2(mm_flags)) {
+        if (EXTERNAL_SSE2(cpu_flags)) {
             c->sse[0] = ff_sse16_sse2;
 
 #if HAVE_ALIGNED_STACK
@@ -1051,7 +1051,7 @@
 #endif
         }
 
-        if (EXTERNAL_SSSE3(mm_flags) && HAVE_ALIGNED_STACK) {
+        if (EXTERNAL_SSSE3(cpu_flags) && HAVE_ALIGNED_STACK) {
             c->hadamard8_diff[0] = ff_hadamard8_diff16_ssse3;
             c->hadamard8_diff[1] = ff_hadamard8_diff_ssse3;
         }
diff --git a/libavcodec/x86/fft.h b/libavcodec/x86/fft.h
index 3f8b21d..398091e 100644
--- a/libavcodec/x86/fft.h
+++ b/libavcodec/x86/fft.h
@@ -34,8 +34,5 @@
 void ff_imdct_calc_sse(FFTContext *s, FFTSample *output, const FFTSample *input);
 void ff_imdct_half_sse(FFTContext *s, FFTSample *output, const FFTSample *input);
 void ff_imdct_half_avx(FFTContext *s, FFTSample *output, const FFTSample *input);
-void ff_dct32_float_sse(FFTSample *out, const FFTSample *in);
-void ff_dct32_float_sse2(FFTSample *out, const FFTSample *in);
-void ff_dct32_float_avx(FFTSample *out, const FFTSample *in);
 
 #endif /* AVCODEC_X86_FFT_H */
diff --git a/libavcodec/x86/fft_init.c b/libavcodec/x86/fft_init.c
index bfa7947..5682230 100644
--- a/libavcodec/x86/fft_init.c
+++ b/libavcodec/x86/fft_init.c
@@ -16,29 +16,31 @@
  * 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 "libavcodec/dct.h"
 #include "fft.h"
 
 av_cold void ff_fft_init_x86(FFTContext *s)
 {
-    int has_vectors = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
+
 #if ARCH_X86_32
-    if (EXTERNAL_AMD3DNOW(has_vectors)) {
+    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(has_vectors)) {
+    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
-    if (EXTERNAL_SSE(has_vectors)) {
+    if (EXTERNAL_SSE(cpu_flags)) {
         /* SSE for P3/P4/K8 */
         s->imdct_calc  = ff_imdct_calc_sse;
         s->imdct_half  = ff_imdct_half_sse;
@@ -46,23 +48,10 @@
         s->fft_calc    = ff_fft_calc_sse;
         s->fft_permutation = FF_FFT_PERM_SWAP_LSBS;
     }
-    if (EXTERNAL_AVX(has_vectors) && s->nbits >= 5) {
+    if (EXTERNAL_AVX(cpu_flags) && s->nbits >= 5) {
         /* AVX for SB */
         s->imdct_half      = ff_imdct_half_avx;
         s->fft_calc        = ff_fft_calc_avx;
         s->fft_permutation = FF_FFT_PERM_AVX;
     }
 }
-
-#if CONFIG_DCT
-av_cold void ff_dct_init_x86(DCTContext *s)
-{
-    int has_vectors = av_get_cpu_flags();
-    if (EXTERNAL_SSE(has_vectors))
-        s->dct32 = ff_dct32_float_sse;
-    if (EXTERNAL_SSE2(has_vectors))
-        s->dct32 = ff_dct32_float_sse2;
-    if (EXTERNAL_AVX(has_vectors))
-        s->dct32 = ff_dct32_float_avx;
-}
-#endif
diff --git a/libavcodec/x86/fmtconvert.asm b/libavcodec/x86/fmtconvert.asm
index 1bd13fc..60078e2 100644
--- a/libavcodec/x86/fmtconvert.asm
+++ b/libavcodec/x86/fmtconvert.asm
@@ -32,7 +32,7 @@
 %endmacro
 
 ;---------------------------------------------------------------------------------
-; void int32_to_float_fmul_scalar(float *dst, const int *src, float mul, int len);
+; void int32_to_float_fmul_scalar(float *dst, const int32_t *src, float mul, int len);
 ;---------------------------------------------------------------------------------
 %macro INT32_TO_FLOAT_FMUL_SCALAR 1
 %if UNIX64
diff --git a/libavcodec/x86/fmtconvert_init.c b/libavcodec/x86/fmtconvert_init.c
index 91a4cb7..da9fdc8 100644
--- a/libavcodec/x86/fmtconvert_init.c
+++ b/libavcodec/x86/fmtconvert_init.c
@@ -30,8 +30,8 @@
 
 #if HAVE_YASM
 
-void ff_int32_to_float_fmul_scalar_sse (float *dst, const int *src, float mul, int len);
-void ff_int32_to_float_fmul_scalar_sse2(float *dst, const int *src, float mul, int len);
+void ff_int32_to_float_fmul_scalar_sse (float *dst, const int32_t *src, float mul, int len);
+void ff_int32_to_float_fmul_scalar_sse2(float *dst, const int32_t *src, float mul, int len);
 
 void ff_float_to_int16_3dnow(int16_t *dst, const float *src, long len);
 void ff_float_to_int16_sse  (int16_t *dst, const float *src, long len);
@@ -116,29 +116,29 @@
 av_cold void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx)
 {
 #if HAVE_YASM
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (EXTERNAL_MMX(mm_flags)) {
+    if (EXTERNAL_MMX(cpu_flags)) {
         c->float_interleave = float_interleave_mmx;
 
-        if (EXTERNAL_AMD3DNOW(mm_flags)) {
+        if (EXTERNAL_AMD3DNOW(cpu_flags)) {
             if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
                 c->float_to_int16 = ff_float_to_int16_3dnow;
                 c->float_to_int16_interleave = float_to_int16_interleave_3dnow;
             }
         }
-        if (EXTERNAL_AMD3DNOWEXT(mm_flags)) {
+        if (EXTERNAL_AMD3DNOWEXT(cpu_flags)) {
             if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
                 c->float_to_int16_interleave = float_to_int16_interleave_3dnowext;
             }
         }
-        if (EXTERNAL_SSE(mm_flags)) {
+        if (EXTERNAL_SSE(cpu_flags)) {
             c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse;
             c->float_to_int16 = ff_float_to_int16_sse;
             c->float_to_int16_interleave = float_to_int16_interleave_sse;
             c->float_interleave = float_interleave_sse;
         }
-        if (EXTERNAL_SSE2(mm_flags)) {
+        if (EXTERNAL_SSE2(cpu_flags)) {
             c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse2;
             c->float_to_int16 = ff_float_to_int16_sse2;
             c->float_to_int16_interleave = float_to_int16_interleave_sse2;
diff --git a/libavcodec/x86/fpel_mmx.c b/libavcodec/x86/fpel_mmx.c
new file mode 100644
index 0000000..384ab89
--- /dev/null
+++ b/libavcodec/x86/fpel_mmx.c
@@ -0,0 +1,139 @@
+/*
+ * MMX-optimized avg/put pixel routines
+ *
+ * Copyright (c) 2000, 2001 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * 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
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "config.h"
+#include "dsputil_x86.h"
+
+#if HAVE_MMX_INLINE
+
+// in case more speed is needed - unrolling would certainly help
+void ff_avg_pixels8_mmx(uint8_t *block, const uint8_t *pixels,
+                        ptrdiff_t line_size, int h)
+{
+    MOVQ_BFE(mm6);
+    JUMPALIGN();
+    do {
+        __asm__ volatile(
+             "movq  %0, %%mm0           \n\t"
+             "movq  %1, %%mm1           \n\t"
+             PAVGB_MMX(%%mm0, %%mm1, %%mm2, %%mm6)
+             "movq  %%mm2, %0           \n\t"
+             :"+m"(*block)
+             :"m"(*pixels)
+             :"memory");
+        pixels += line_size;
+        block += line_size;
+    }
+    while (--h);
+}
+
+void ff_avg_pixels16_mmx(uint8_t *block, const uint8_t *pixels,
+                         ptrdiff_t line_size, int h)
+{
+    MOVQ_BFE(mm6);
+    JUMPALIGN();
+    do {
+        __asm__ volatile(
+             "movq  %0, %%mm0           \n\t"
+             "movq  %1, %%mm1           \n\t"
+             PAVGB_MMX(%%mm0, %%mm1, %%mm2, %%mm6)
+             "movq  %%mm2, %0           \n\t"
+             "movq  8%0, %%mm0          \n\t"
+             "movq  8%1, %%mm1          \n\t"
+             PAVGB_MMX(%%mm0, %%mm1, %%mm2, %%mm6)
+             "movq  %%mm2, 8%0          \n\t"
+             :"+m"(*block)
+             :"m"(*pixels)
+             :"memory");
+        pixels += line_size;
+        block += line_size;
+    }
+    while (--h);
+}
+
+void ff_put_pixels8_mmx(uint8_t *block, const uint8_t *pixels,
+                        ptrdiff_t line_size, int h)
+{
+    __asm__ volatile (
+        "lea   (%3, %3), %%"REG_a"      \n\t"
+        ".p2align     3                 \n\t"
+        "1:                             \n\t"
+        "movq  (%1    ), %%mm0          \n\t"
+        "movq  (%1, %3), %%mm1          \n\t"
+        "movq     %%mm0, (%2)           \n\t"
+        "movq     %%mm1, (%2, %3)       \n\t"
+        "add  %%"REG_a", %1             \n\t"
+        "add  %%"REG_a", %2             \n\t"
+        "movq  (%1    ), %%mm0          \n\t"
+        "movq  (%1, %3), %%mm1          \n\t"
+        "movq     %%mm0, (%2)           \n\t"
+        "movq     %%mm1, (%2, %3)       \n\t"
+        "add  %%"REG_a", %1             \n\t"
+        "add  %%"REG_a", %2             \n\t"
+        "subl        $4, %0             \n\t"
+        "jnz         1b                 \n\t"
+        : "+g"(h), "+r"(pixels),  "+r"(block)
+        : "r"((x86_reg)line_size)
+        : "%"REG_a, "memory"
+        );
+}
+
+void ff_put_pixels16_mmx(uint8_t *block, const uint8_t *pixels,
+                         ptrdiff_t line_size, int h)
+{
+    __asm__ volatile (
+        "lea   (%3, %3), %%"REG_a"      \n\t"
+        ".p2align     3                 \n\t"
+        "1:                             \n\t"
+        "movq  (%1    ), %%mm0          \n\t"
+        "movq 8(%1    ), %%mm4          \n\t"
+        "movq  (%1, %3), %%mm1          \n\t"
+        "movq 8(%1, %3), %%mm5          \n\t"
+        "movq     %%mm0,  (%2)          \n\t"
+        "movq     %%mm4, 8(%2)          \n\t"
+        "movq     %%mm1,  (%2, %3)      \n\t"
+        "movq     %%mm5, 8(%2, %3)      \n\t"
+        "add  %%"REG_a", %1             \n\t"
+        "add  %%"REG_a", %2             \n\t"
+        "movq  (%1    ), %%mm0          \n\t"
+        "movq 8(%1    ), %%mm4          \n\t"
+        "movq  (%1, %3), %%mm1          \n\t"
+        "movq 8(%1, %3), %%mm5          \n\t"
+        "movq     %%mm0,  (%2)          \n\t"
+        "movq     %%mm4, 8(%2)          \n\t"
+        "movq     %%mm1,  (%2, %3)      \n\t"
+        "movq     %%mm5, 8(%2, %3)      \n\t"
+        "add  %%"REG_a", %1             \n\t"
+        "add  %%"REG_a", %2             \n\t"
+        "subl        $4, %0             \n\t"
+        "jnz         1b                 \n\t"
+        : "+g"(h), "+r"(pixels),  "+r"(block)
+        : "r"((x86_reg)line_size)
+        : "%"REG_a, "memory"
+        );
+}
+
+#endif /* HAVE_MMX_INLINE */
diff --git a/libavcodec/x86/h264_idct.asm b/libavcodec/x86/h264_idct.asm
index 17bf794..88cd3ff 100644
--- a/libavcodec/x86/h264_idct.asm
+++ b/libavcodec/x86/h264_idct.asm
@@ -30,7 +30,6 @@
 
 SECTION_RODATA
 
-; FIXME this table is a duplicate from h264data.h, and will be removed once the tables from, h264 have been split
 scan8_mem: db  4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8
            db  6+ 1*8, 7+ 1*8, 6+ 2*8, 7+ 2*8
            db  4+ 3*8, 5+ 3*8, 4+ 4*8, 5+ 4*8
diff --git a/libavcodec/x86/h264_intrapred_init.c b/libavcodec/x86/h264_intrapred_init.c
index f5b5e3e..ad2984b 100644
--- a/libavcodec/x86/h264_intrapred_init.c
+++ b/libavcodec/x86/h264_intrapred_init.c
@@ -185,10 +185,10 @@
                                    const int bit_depth,
                                    const int chroma_format_idc)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
     if (bit_depth == 8) {
-        if (EXTERNAL_MMX(mm_flags)) {
+        if (EXTERNAL_MMX(cpu_flags)) {
             h->pred16x16[VERT_PRED8x8         ] = ff_pred16x16_vertical_8_mmx;
             h->pred16x16[HOR_PRED8x8          ] = ff_pred16x16_horizontal_8_mmx;
             if (chroma_format_idc == 1) {
@@ -203,7 +203,7 @@
                 if (chroma_format_idc == 1)
                     h->pred8x8  [PLANE_PRED8x8] = ff_pred8x8_plane_8_mmx;
                 if (codec_id == AV_CODEC_ID_SVQ3) {
-                    if (mm_flags & AV_CPU_FLAG_CMOV)
+                    if (cpu_flags & AV_CPU_FLAG_CMOV)
                         h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_8_mmx;
                 } else if (codec_id == AV_CODEC_ID_RV40) {
                     h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_rv40_8_mmx;
@@ -213,7 +213,7 @@
             }
         }
 
-        if (EXTERNAL_MMXEXT(mm_flags)) {
+        if (EXTERNAL_MMXEXT(cpu_flags)) {
             h->pred16x16[HOR_PRED8x8            ] = ff_pred16x16_horizontal_8_mmxext;
             h->pred16x16[DC_PRED8x8             ] = ff_pred16x16_dc_8_mmxext;
             if (chroma_format_idc == 1)
@@ -265,11 +265,11 @@
             }
         }
 
-        if (EXTERNAL_SSE(mm_flags)) {
+        if (EXTERNAL_SSE(cpu_flags)) {
             h->pred16x16[VERT_PRED8x8] = ff_pred16x16_vertical_8_sse;
         }
 
-        if (EXTERNAL_SSE2(mm_flags)) {
+        if (EXTERNAL_SSE2(cpu_flags)) {
             h->pred16x16[DC_PRED8x8           ] = ff_pred16x16_dc_8_sse2;
             h->pred8x8l [DIAG_DOWN_LEFT_PRED  ] = ff_pred8x8l_down_left_8_sse2;
             h->pred8x8l [DIAG_DOWN_RIGHT_PRED ] = ff_pred8x8l_down_right_8_sse2;
@@ -292,7 +292,7 @@
             }
         }
 
-        if (EXTERNAL_SSSE3(mm_flags)) {
+        if (EXTERNAL_SSSE3(cpu_flags)) {
             h->pred16x16[HOR_PRED8x8          ] = ff_pred16x16_horizontal_8_ssse3;
             h->pred16x16[DC_PRED8x8           ] = ff_pred16x16_dc_8_ssse3;
             if (chroma_format_idc == 1)
@@ -323,7 +323,7 @@
             }
         }
     } else if (bit_depth == 10) {
-        if (EXTERNAL_MMXEXT(mm_flags)) {
+        if (EXTERNAL_MMXEXT(cpu_flags)) {
             h->pred4x4[DC_PRED             ] = ff_pred4x4_dc_10_mmxext;
             h->pred4x4[HOR_UP_PRED         ] = ff_pred4x4_horizontal_up_10_mmxext;
 
@@ -339,7 +339,7 @@
             h->pred16x16[VERT_PRED8x8      ] = ff_pred16x16_vertical_10_mmxext;
             h->pred16x16[HOR_PRED8x8       ] = ff_pred16x16_horizontal_10_mmxext;
         }
-        if (EXTERNAL_SSE2(mm_flags)) {
+        if (EXTERNAL_SSE2(cpu_flags)) {
             h->pred4x4[DIAG_DOWN_LEFT_PRED ] = ff_pred4x4_down_left_10_sse2;
             h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_sse2;
             h->pred4x4[VERT_LEFT_PRED      ] = ff_pred4x4_vertical_left_10_sse2;
@@ -371,7 +371,7 @@
             h->pred16x16[VERT_PRED8x8      ] = ff_pred16x16_vertical_10_sse2;
             h->pred16x16[HOR_PRED8x8       ] = ff_pred16x16_horizontal_10_sse2;
         }
-        if (EXTERNAL_SSSE3(mm_flags)) {
+        if (EXTERNAL_SSSE3(cpu_flags)) {
             h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_ssse3;
             h->pred4x4[VERT_RIGHT_PRED     ] = ff_pred4x4_vertical_right_10_ssse3;
             h->pred4x4[HOR_DOWN_PRED       ] = ff_pred4x4_horizontal_down_10_ssse3;
@@ -382,7 +382,7 @@
             h->pred8x8l[VERT_RIGHT_PRED     ] = ff_pred8x8l_vertical_right_10_ssse3;
             h->pred8x8l[HOR_UP_PRED         ] = ff_pred8x8l_horizontal_up_10_ssse3;
         }
-        if (EXTERNAL_AVX(mm_flags)) {
+        if (EXTERNAL_AVX(cpu_flags)) {
             h->pred4x4[DIAG_DOWN_LEFT_PRED ] = ff_pred4x4_down_left_10_avx;
             h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_avx;
             h->pred4x4[VERT_LEFT_PRED      ] = ff_pred4x4_vertical_left_10_avx;
diff --git a/libavcodec/x86/h264_qpel.c b/libavcodec/x86/h264_qpel.c
index 85f1420..fd6068f 100644
--- a/libavcodec/x86/h264_qpel.c
+++ b/libavcodec/x86/h264_qpel.c
@@ -25,25 +25,13 @@
 #include "libavutil/x86/cpu.h"
 #include "libavcodec/h264qpel.h"
 #include "libavcodec/mpegvideo.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 
 #if HAVE_YASM
 void ff_put_pixels4_mmxext(uint8_t *block, const uint8_t *pixels,
                            ptrdiff_t line_size, int h);
 void ff_avg_pixels4_mmxext(uint8_t *block, const uint8_t *pixels,
                            ptrdiff_t line_size, int h);
-static void ff_put_pixels16_mmxext(uint8_t *block, const uint8_t *pixels,
-                                   ptrdiff_t line_size, int h)
-{
-    ff_put_pixels8_mmxext(block,     pixels,     line_size, h);
-    ff_put_pixels8_mmxext(block + 8, pixels + 8, line_size, h);
-}
-static void ff_avg_pixels16_mmxext(uint8_t *block, const uint8_t *pixels,
-                                   ptrdiff_t line_size, int h)
-{
-    ff_avg_pixels8_mmxext(block,     pixels,     line_size, h);
-    ff_avg_pixels8_mmxext(block + 8, pixels + 8, line_size, h);
-}
 void ff_put_pixels4_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
                               int dstStride, int src1Stride, int h);
 void ff_avg_pixels4_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
@@ -61,6 +49,9 @@
 #define ff_put_pixels16_l2_sse2 ff_put_pixels16_l2_mmxext
 #define ff_avg_pixels16_l2_sse2 ff_avg_pixels16_l2_mmxext
 
+PIXELS16(static, ff_avg, , , _mmxext)
+PIXELS16(static, ff_put, , , _mmxext)
+
 #define DEF_QPEL(OPNAME)\
 void ff_ ## OPNAME ## _h264_qpel4_h_lowpass_mmxext(uint8_t *dst, uint8_t *src, int dstStride, int srcStride);\
 void ff_ ## OPNAME ## _h264_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src, int dstStride, int srcStride);\
@@ -206,7 +197,12 @@
     ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\
 }
 
-static av_always_inline void ff_put_h264_qpel8or16_hv1_lowpass_sse2(int16_t *tmp, uint8_t *src, int tmpStride, int srcStride, int size){
+static av_always_inline void put_h264_qpel8or16_hv1_lowpass_sse2(int16_t *tmp,
+                                                                 uint8_t *src,
+                                                                 int tmpStride,
+                                                                 int srcStride,
+                                                                 int size)
+{
     int w = (size+8)>>3;
     src -= 2*srcStride+2;
     while(w--){
@@ -218,7 +214,7 @@
 
 #define QPEL_H264_HV_XMM(OPNAME, OP, MMX)\
 static av_always_inline void ff_ ## OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride, int size){\
-    ff_put_h264_qpel8or16_hv1_lowpass_sse2(tmp, src, tmpStride, srcStride, size);\
+    put_h264_qpel8or16_hv1_lowpass_sse2(tmp, src, tmpStride, srcStride, size);\
     ff_ ## OPNAME ## h264_qpel8or16_hv2_lowpass_ ## MMX(dst, tmp, dstStride, tmpStride, size);\
 }\
 static av_always_inline void ff_ ## OPNAME ## h264_qpel8_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\
@@ -546,9 +542,9 @@
 {
 #if HAVE_YASM
     int high_bit_depth = bit_depth > 8;
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (EXTERNAL_MMXEXT(mm_flags)) {
+    if (EXTERNAL_MMXEXT(cpu_flags)) {
         if (!high_bit_depth) {
             SET_QPEL_FUNCS(put_h264_qpel, 0, 16, mmxext, );
             SET_QPEL_FUNCS(put_h264_qpel, 1,  8, mmxext, );
@@ -568,8 +564,8 @@
         }
     }
 
-    if (EXTERNAL_SSE2(mm_flags)) {
-        if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW) && !high_bit_depth) {
+    if (EXTERNAL_SSE2(cpu_flags)) {
+        if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW) && !high_bit_depth) {
             // these functions are slower than mmx on AMD, but faster on Intel
             H264_QPEL_FUNCS(0, 0, sse2);
         }
@@ -600,7 +596,7 @@
         }
     }
 
-    if (EXTERNAL_SSSE3(mm_flags)) {
+    if (EXTERNAL_SSSE3(cpu_flags)) {
         if (!high_bit_depth) {
             H264_QPEL_FUNCS(1, 0, ssse3);
             H264_QPEL_FUNCS(1, 1, ssse3);
@@ -623,7 +619,7 @@
         }
     }
 
-    if (EXTERNAL_AVX(mm_flags)) {
+    if (EXTERNAL_AVX(cpu_flags)) {
         /* AVX implies 64 byte cache lines without the need to avoid unaligned
          * memory accesses that cross the boundary between two cache lines.
          * TODO: Port X264_CPU_CACHELINE_32/64 detection from x264 to avoid
diff --git a/libavcodec/x86/h264chroma_init.c b/libavcodec/x86/h264chroma_init.c
index b5c078f..3d8d5b0 100644
--- a/libavcodec/x86/h264chroma_init.c
+++ b/libavcodec/x86/h264chroma_init.c
@@ -19,6 +19,7 @@
 #include <stdint.h>
 
 #include "config.h"
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/cpu.h"
 #include "libavcodec/h264chroma.h"
@@ -66,49 +67,49 @@
 CHROMA_MC(put, 8, 10, avx)
 CHROMA_MC(avg, 8, 10, avx)
 
-void ff_h264chroma_init_x86(H264ChromaContext *c, int bit_depth)
+av_cold void ff_h264chroma_init_x86(H264ChromaContext *c, int bit_depth)
 {
 #if HAVE_YASM
     int high_bit_depth = bit_depth > 8;
-    int mm_flags       = av_get_cpu_flags();
+    int cpu_flags      = av_get_cpu_flags();
 
-    if (EXTERNAL_MMX(mm_flags) && !high_bit_depth) {
+    if (EXTERNAL_MMX(cpu_flags) && !high_bit_depth) {
         c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_rnd_mmx;
         c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_mmx;
     }
 
-    if (EXTERNAL_AMD3DNOW(mm_flags) && !high_bit_depth) {
+    if (EXTERNAL_AMD3DNOW(cpu_flags) && !high_bit_depth) {
         c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_rnd_3dnow;
         c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_3dnow;
     }
 
-    if (EXTERNAL_MMXEXT(mm_flags) && !high_bit_depth) {
+    if (EXTERNAL_MMXEXT(cpu_flags) && !high_bit_depth) {
         c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_rnd_mmxext;
         c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_mmxext;
         c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_mmxext;
         c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_mmxext;
     }
 
-    if (EXTERNAL_MMXEXT(mm_flags) && bit_depth > 8 && bit_depth <= 10) {
+    if (EXTERNAL_MMXEXT(cpu_flags) && bit_depth > 8 && bit_depth <= 10) {
         c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_10_mmxext;
         c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_10_mmxext;
         c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_10_mmxext;
         c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_10_mmxext;
     }
 
-    if (EXTERNAL_SSE2(mm_flags) && bit_depth > 8 && bit_depth <= 10) {
+    if (EXTERNAL_SSE2(cpu_flags) && bit_depth > 8 && bit_depth <= 10) {
         c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_10_sse2;
         c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_10_sse2;
     }
 
-    if (EXTERNAL_SSSE3(mm_flags) && !high_bit_depth) {
+    if (EXTERNAL_SSSE3(cpu_flags) && !high_bit_depth) {
         c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_rnd_ssse3;
         c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_rnd_ssse3;
         c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_ssse3;
         c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_ssse3;
     }
 
-    if (EXTERNAL_AVX(mm_flags) && bit_depth > 8 && bit_depth <= 10) {
+    if (EXTERNAL_AVX(cpu_flags) && bit_depth > 8 && bit_depth <= 10) {
         // AVX implies !cache64.
         // TODO: Port cache(32|64) detection from x264.
         c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_10_avx;
diff --git a/libavcodec/x86/h264dsp_init.c b/libavcodec/x86/h264dsp_init.c
index 11aae77..52cb963 100644
--- a/libavcodec/x86/h264dsp_init.c
+++ b/libavcodec/x86/h264dsp_init.c
@@ -23,7 +23,7 @@
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
 #include "libavcodec/h264dsp.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 
 /***********************************/
 /* IDCT */
@@ -132,8 +132,8 @@
 
 #if ARCH_X86_32 && HAVE_MMXEXT_EXTERNAL
 LF_FUNC(v8, luma, 8, mmxext)
-static void ff_deblock_v_luma_8_mmxext(uint8_t *pix, int stride, int alpha,
-                                       int beta, int8_t *tc0)
+static void deblock_v_luma_8_mmxext(uint8_t *pix, int stride, int alpha,
+                                    int beta, int8_t *tc0)
 {
     if ((tc0[0] & tc0[1]) >= 0)
         ff_deblock_v8_luma_8_mmxext(pix + 0, stride, alpha, beta, tc0);
@@ -141,8 +141,8 @@
         ff_deblock_v8_luma_8_mmxext(pix + 8, stride, alpha, beta, tc0 + 2);
 }
 LF_IFUNC(v8, luma_intra, 8, mmxext)
-static void ff_deblock_v_luma_intra_8_mmxext(uint8_t *pix, int stride,
-                                             int alpha, int beta)
+static void deblock_v_luma_intra_8_mmxext(uint8_t *pix, int stride,
+                                          int alpha, int beta)
 {
     ff_deblock_v8_luma_intra_8_mmxext(pix + 0, stride, alpha, beta);
     ff_deblock_v8_luma_intra_8_mmxext(pix + 8, stride, alpha, beta);
@@ -212,13 +212,13 @@
                                  const int chroma_format_idc)
 {
 #if HAVE_YASM
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (chroma_format_idc == 1 && EXTERNAL_MMXEXT(mm_flags))
+    if (chroma_format_idc == 1 && EXTERNAL_MMXEXT(cpu_flags))
         c->h264_loop_filter_strength = ff_h264_loop_filter_strength_mmxext;
 
     if (bit_depth == 8) {
-        if (EXTERNAL_MMX(mm_flags)) {
+        if (EXTERNAL_MMX(cpu_flags)) {
             c->h264_idct_dc_add   =
             c->h264_idct_add      = ff_h264_idct_add_8_mmx;
             c->h264_idct8_dc_add  =
@@ -229,10 +229,10 @@
             if (chroma_format_idc == 1)
                 c->h264_idct_add8 = ff_h264_idct_add8_8_mmx;
             c->h264_idct_add16intra = ff_h264_idct_add16intra_8_mmx;
-            if (mm_flags & AV_CPU_FLAG_CMOV)
+            if (cpu_flags & AV_CPU_FLAG_CMOV)
                 c->h264_luma_dc_dequant_idct = ff_h264_luma_dc_dequant_idct_mmx;
 
-            if (EXTERNAL_MMXEXT(mm_flags)) {
+            if (EXTERNAL_MMXEXT(cpu_flags)) {
                 c->h264_idct_dc_add  = ff_h264_idct_dc_add_8_mmxext;
                 c->h264_idct8_dc_add = ff_h264_idct8_dc_add_8_mmxext;
                 c->h264_idct_add16   = ff_h264_idct_add16_8_mmxext;
@@ -248,9 +248,9 @@
                     c->h264_h_loop_filter_chroma_intra = ff_deblock_h_chroma_intra_8_mmxext;
                 }
 #if ARCH_X86_32 && HAVE_MMXEXT_EXTERNAL
-                c->h264_v_loop_filter_luma       = ff_deblock_v_luma_8_mmxext;
+                c->h264_v_loop_filter_luma       = deblock_v_luma_8_mmxext;
                 c->h264_h_loop_filter_luma       = ff_deblock_h_luma_8_mmxext;
-                c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_mmxext;
+                c->h264_v_loop_filter_luma_intra = deblock_v_luma_intra_8_mmxext;
                 c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_mmxext;
 #endif /* ARCH_X86_32 && HAVE_MMXEXT_EXTERNAL */
                 c->weight_h264_pixels_tab[0] = ff_h264_weight_16_mmxext;
@@ -261,7 +261,7 @@
                 c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_mmxext;
                 c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_mmxext;
 
-                if (EXTERNAL_SSE2(mm_flags)) {
+                if (EXTERNAL_SSE2(cpu_flags)) {
                     c->h264_idct8_add  = ff_h264_idct8_add_8_sse2;
 
                     c->h264_idct_add16 = ff_h264_idct_add16_8_sse2;
@@ -282,11 +282,11 @@
                     c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_sse2;
                     c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_sse2;
                 }
-                if (EXTERNAL_SSSE3(mm_flags)) {
+                if (EXTERNAL_SSSE3(cpu_flags)) {
                     c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_ssse3;
                     c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_ssse3;
                 }
-                if (EXTERNAL_AVX(mm_flags)) {
+                if (EXTERNAL_AVX(cpu_flags)) {
                     c->h264_v_loop_filter_luma       = ff_deblock_v_luma_8_avx;
                     c->h264_h_loop_filter_luma       = ff_deblock_h_luma_8_avx;
                     c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_avx;
@@ -295,8 +295,8 @@
             }
         }
     } else if (bit_depth == 10) {
-        if (EXTERNAL_MMX(mm_flags)) {
-            if (EXTERNAL_MMXEXT(mm_flags)) {
+        if (EXTERNAL_MMX(cpu_flags)) {
+            if (EXTERNAL_MMXEXT(cpu_flags)) {
 #if ARCH_X86_32
                 c->h264_v_loop_filter_chroma       = ff_deblock_v_chroma_10_mmxext;
                 c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_10_mmxext;
@@ -306,7 +306,7 @@
                 c->h264_h_loop_filter_luma_intra   = ff_deblock_h_luma_intra_10_mmxext;
 #endif /* ARCH_X86_32 */
                 c->h264_idct_dc_add = ff_h264_idct_dc_add_10_mmxext;
-                if (EXTERNAL_SSE2(mm_flags)) {
+                if (EXTERNAL_SSE2(cpu_flags)) {
                     c->h264_idct_add     = ff_h264_idct_add_10_sse2;
                     c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_sse2;
 
@@ -336,7 +336,7 @@
                     c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_10_sse2;
 #endif /* HAVE_ALIGNED_STACK */
                 }
-                if (EXTERNAL_SSE4(mm_flags)) {
+                if (EXTERNAL_SSE4(cpu_flags)) {
                     c->weight_h264_pixels_tab[0] = ff_h264_weight_16_10_sse4;
                     c->weight_h264_pixels_tab[1] = ff_h264_weight_8_10_sse4;
                     c->weight_h264_pixels_tab[2] = ff_h264_weight_4_10_sse4;
@@ -345,7 +345,7 @@
                     c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_10_sse4;
                     c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_10_sse4;
                 }
-                if (EXTERNAL_AVX(mm_flags)) {
+                if (EXTERNAL_AVX(cpu_flags)) {
                     c->h264_idct_dc_add  =
                     c->h264_idct_add     = ff_h264_idct_add_10_avx;
                     c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_avx;
diff --git a/libavcodec/x86/hpeldsp_avg_template.c b/libavcodec/x86/hpeldsp_avg_template.c
deleted file mode 100644
index b9a8f83..0000000
--- a/libavcodec/x86/hpeldsp_avg_template.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * DSP utils : average functions are compiled twice for 3dnow/mmxext
- * Copyright (c) 2000, 2001 Fabrice Bellard
- * Copyright (c) 2002-2004 Michael Niedermayer
- *
- * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
- * mostly rewritten by Michael Niedermayer <michaelni@gmx.at>
- * and improved by Zdenek Kabelac <kabi@users.sf.net>
- *
- * 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
- */
-
-//FIXME the following could be optimized too ...
-static void DEF(ff_put_no_rnd_pixels16_x2)(uint8_t *block,
-                                           const uint8_t *pixels,
-                                           ptrdiff_t line_size, int h)
-{
-    DEF(ff_put_no_rnd_pixels8_x2)(block,     pixels,     line_size, h);
-    DEF(ff_put_no_rnd_pixels8_x2)(block + 8, pixels + 8, line_size, h);
-}
-
-static void DEF(ff_put_pixels16_y2)(uint8_t *block, const uint8_t *pixels,
-                                    ptrdiff_t line_size, int h)
-{
-    DEF(ff_put_pixels8_y2)(block,     pixels,     line_size, h);
-    DEF(ff_put_pixels8_y2)(block + 8, pixels + 8, line_size, h);
-}
-
-static void DEF(ff_put_no_rnd_pixels16_y2)(uint8_t *block,
-                                           const uint8_t *pixels,
-                                           ptrdiff_t line_size, int h)
-{
-    DEF(ff_put_no_rnd_pixels8_y2)(block,     pixels,     line_size, h);
-    DEF(ff_put_no_rnd_pixels8_y2)(block + 8, pixels + 8, line_size, h);
-}
-
-static void DEF(ff_avg_pixels16)(uint8_t *block, const uint8_t *pixels,
-                                 ptrdiff_t line_size, int h)
-{
-    DEF(ff_avg_pixels8)(block,     pixels,     line_size, h);
-    DEF(ff_avg_pixels8)(block + 8, pixels + 8, line_size, h);
-}
-
-static void DEF(ff_avg_pixels16_x2)(uint8_t *block, const uint8_t *pixels,
-                                    ptrdiff_t line_size, int h)
-{
-    DEF(ff_avg_pixels8_x2)(block,     pixels,     line_size, h);
-    DEF(ff_avg_pixels8_x2)(block + 8, pixels + 8, line_size, h);
-}
-
-static void DEF(ff_avg_pixels16_y2)(uint8_t *block, const uint8_t *pixels,
-                                    ptrdiff_t line_size, int h)
-{
-    DEF(ff_avg_pixels8_y2)(block,     pixels,     line_size, h);
-    DEF(ff_avg_pixels8_y2)(block + 8, pixels + 8, line_size, h);
-}
-
-static void DEF(ff_avg_pixels16_xy2)(uint8_t *block, const uint8_t *pixels,
-                                     ptrdiff_t line_size, int h)
-{
-    DEF(ff_avg_pixels8_xy2)(block,     pixels,     line_size, h);
-    DEF(ff_avg_pixels8_xy2)(block + 8, pixels + 8, line_size, h);
-}
diff --git a/libavcodec/x86/hpeldsp_init.c b/libavcodec/x86/hpeldsp_init.c
index e313265..197a404 100644
--- a/libavcodec/x86/hpeldsp_init.c
+++ b/libavcodec/x86/hpeldsp_init.c
@@ -25,7 +25,7 @@
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
 #include "libavcodec/hpeldsp.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 
 void ff_put_pixels8_x2_mmxext(uint8_t *block, const uint8_t *pixels,
                               ptrdiff_t line_size, int h);
@@ -74,25 +74,44 @@
 void ff_avg_pixels8_xy2_3dnow(uint8_t *block, const uint8_t *pixels,
                               ptrdiff_t line_size, int h);
 
+#define avg_pixels8_mmx         ff_avg_pixels8_mmx
+#define avg_pixels8_x2_mmx      ff_avg_pixels8_x2_mmx
+#define avg_pixels16_mmx        ff_avg_pixels16_mmx
+#define avg_pixels8_xy2_mmx     ff_avg_pixels8_xy2_mmx
+#define avg_pixels16_xy2_mmx    ff_avg_pixels16_xy2_mmx
+#define put_pixels8_mmx         ff_put_pixels8_mmx
+#define put_pixels16_mmx        ff_put_pixels16_mmx
+#define put_pixels8_xy2_mmx     ff_put_pixels8_xy2_mmx
+#define put_pixels16_xy2_mmx    ff_put_pixels16_xy2_mmx
+#define avg_no_rnd_pixels16_mmx ff_avg_pixels16_mmx
+#define put_no_rnd_pixels8_mmx  ff_put_pixels8_mmx
+#define put_no_rnd_pixels16_mmx ff_put_pixels16_mmx
 
 #if HAVE_INLINE_ASM
 
 /***********************************/
 /* MMX no rounding */
-#define NO_RND 1
 #define DEF(x, y) x ## _no_rnd_ ## y ## _mmx
 #define SET_RND  MOVQ_WONE
 #define PAVGBP(a, b, c, d, e, f)        PAVGBP_MMX_NO_RND(a, b, c, d, e, f)
 #define PAVGB(a, b, c, e)               PAVGB_MMX_NO_RND(a, b, c, e)
-#define OP_AVG(a, b, c, e)              PAVGB_MMX(a, b, c, e)
+#define STATIC static
 
+#include "rnd_template.c"
 #include "hpeldsp_rnd_template.c"
 
 #undef DEF
 #undef SET_RND
 #undef PAVGBP
 #undef PAVGB
-#undef NO_RND
+#undef STATIC
+
+PIXELS16(static, avg_no_rnd, , _y2, _mmx)
+PIXELS16(static, put_no_rnd, , _y2, _mmx)
+
+PIXELS16(static, avg_no_rnd, , _xy2, _mmx)
+PIXELS16(static, put_no_rnd, , _xy2, _mmx)
+
 /***********************************/
 /* MMX rounding */
 
@@ -107,107 +126,29 @@
 #undef SET_RND
 #undef PAVGBP
 #undef PAVGB
-#undef OP_AVG
+
+PIXELS16(static, avg, , _y2, _mmx)
+PIXELS16(static, put, , _y2, _mmx)
 
 #endif /* HAVE_INLINE_ASM */
 
 
 #if HAVE_YASM
-#define ff_put_pixels8_mmx ff_put_pixels8_mmxext
 
-/***********************************/
-/* 3Dnow specific */
+#define HPELDSP_AVG_PIXELS16(CPUEXT)                \
+    PIXELS16(static, put_no_rnd, ff_,  _x2, CPUEXT) \
+    PIXELS16(static, put,        ff_,  _y2, CPUEXT) \
+    PIXELS16(static, put_no_rnd, ff_,  _y2, CPUEXT) \
+    PIXELS16(static, avg,        ff_,     , CPUEXT) \
+    PIXELS16(static, avg,        ff_,  _x2, CPUEXT) \
+    PIXELS16(static, avg,        ff_,  _y2, CPUEXT) \
+    PIXELS16(static, avg,        ff_, _xy2, CPUEXT)
 
-#define DEF(x) x ## _3dnow
-
-#include "hpeldsp_avg_template.c"
-
-#undef DEF
-
-/***********************************/
-/* MMXEXT specific */
-
-#define DEF(x) x ## _mmxext
-
-#include "hpeldsp_avg_template.c"
-
-#undef DEF
+HPELDSP_AVG_PIXELS16(_3dnow)
+HPELDSP_AVG_PIXELS16(_mmxext)
 
 #endif /* HAVE_YASM */
 
-
-#if HAVE_INLINE_ASM
-#define put_no_rnd_pixels16_mmx put_pixels16_mmx
-#define put_no_rnd_pixels8_mmx put_pixels8_mmx
-#define put_pixels16_mmxext put_pixels16_mmx
-#define put_pixels8_mmxext put_pixels8_mmx
-#define put_pixels4_mmxext put_pixels4_mmx
-#define put_no_rnd_pixels16_mmxext put_no_rnd_pixels16_mmx
-#define put_no_rnd_pixels8_mmxext put_no_rnd_pixels8_mmx
-
-static void put_pixels8_mmx(uint8_t *block, const uint8_t *pixels,
-                            ptrdiff_t line_size, int h)
-{
-    __asm__ volatile (
-        "lea   (%3, %3), %%"REG_a"      \n\t"
-        ".p2align     3                 \n\t"
-        "1:                             \n\t"
-        "movq  (%1    ), %%mm0          \n\t"
-        "movq  (%1, %3), %%mm1          \n\t"
-        "movq     %%mm0, (%2)           \n\t"
-        "movq     %%mm1, (%2, %3)       \n\t"
-        "add  %%"REG_a", %1             \n\t"
-        "add  %%"REG_a", %2             \n\t"
-        "movq  (%1    ), %%mm0          \n\t"
-        "movq  (%1, %3), %%mm1          \n\t"
-        "movq     %%mm0, (%2)           \n\t"
-        "movq     %%mm1, (%2, %3)       \n\t"
-        "add  %%"REG_a", %1             \n\t"
-        "add  %%"REG_a", %2             \n\t"
-        "subl        $4, %0             \n\t"
-        "jnz         1b                 \n\t"
-        : "+g"(h), "+r"(pixels),  "+r"(block)
-        : "r"((x86_reg)line_size)
-        : "%"REG_a, "memory"
-        );
-}
-
-static void put_pixels16_mmx(uint8_t *block, const uint8_t *pixels,
-                             ptrdiff_t line_size, int h)
-{
-    __asm__ volatile (
-        "lea   (%3, %3), %%"REG_a"      \n\t"
-        ".p2align     3                 \n\t"
-        "1:                             \n\t"
-        "movq  (%1    ), %%mm0          \n\t"
-        "movq 8(%1    ), %%mm4          \n\t"
-        "movq  (%1, %3), %%mm1          \n\t"
-        "movq 8(%1, %3), %%mm5          \n\t"
-        "movq     %%mm0,  (%2)          \n\t"
-        "movq     %%mm4, 8(%2)          \n\t"
-        "movq     %%mm1,  (%2, %3)      \n\t"
-        "movq     %%mm5, 8(%2, %3)      \n\t"
-        "add  %%"REG_a", %1             \n\t"
-        "add  %%"REG_a", %2             \n\t"
-        "movq  (%1    ), %%mm0          \n\t"
-        "movq 8(%1    ), %%mm4          \n\t"
-        "movq  (%1, %3), %%mm1          \n\t"
-        "movq 8(%1, %3), %%mm5          \n\t"
-        "movq     %%mm0,  (%2)          \n\t"
-        "movq     %%mm4, 8(%2)          \n\t"
-        "movq     %%mm1,  (%2, %3)      \n\t"
-        "movq     %%mm5, 8(%2, %3)      \n\t"
-        "add  %%"REG_a", %1             \n\t"
-        "add  %%"REG_a", %2             \n\t"
-        "subl        $4, %0             \n\t"
-        "jnz         1b                 \n\t"
-        : "+g"(h), "+r"(pixels),  "+r"(block)
-        : "r"((x86_reg)line_size)
-        : "%"REG_a, "memory"
-        );
-}
-#endif /* HAVE_INLINE_ASM */
-
 #define SET_HPEL_FUNCS(PFX, IDX, SIZE, CPU)                                     \
     do {                                                                        \
         c->PFX ## _pixels_tab IDX [0] = PFX ## _pixels ## SIZE ## _     ## CPU; \
@@ -216,9 +157,9 @@
         c->PFX ## _pixels_tab IDX [3] = PFX ## _pixels ## SIZE ## _xy2_ ## CPU; \
     } while (0)
 
-static void hpeldsp_init_mmx(HpelDSPContext *c, int flags, int mm_flags)
+static void hpeldsp_init_mmx(HpelDSPContext *c, int flags, int cpu_flags)
 {
-#if HAVE_INLINE_ASM
+#if HAVE_MMX_INLINE
     SET_HPEL_FUNCS(put,        [0], 16, mmx);
     SET_HPEL_FUNCS(put_no_rnd, [0], 16, mmx);
     SET_HPEL_FUNCS(avg,        [0], 16, mmx);
@@ -226,18 +167,18 @@
     SET_HPEL_FUNCS(put,        [1],  8, mmx);
     SET_HPEL_FUNCS(put_no_rnd, [1],  8, mmx);
     SET_HPEL_FUNCS(avg,        [1],  8, mmx);
-#endif /* HAVE_INLINE_ASM */
+#endif /* HAVE_MMX_INLINE */
 }
 
-static void hpeldsp_init_mmxext(HpelDSPContext *c, int flags, int mm_flags)
+static void hpeldsp_init_mmxext(HpelDSPContext *c, int flags, int cpu_flags)
 {
-#if HAVE_YASM
+#if HAVE_MMXEXT_EXTERNAL
     c->put_pixels_tab[0][1] = ff_put_pixels16_x2_mmxext;
-    c->put_pixels_tab[0][2] = ff_put_pixels16_y2_mmxext;
+    c->put_pixels_tab[0][2] = put_pixels16_y2_mmxext;
 
-    c->avg_pixels_tab[0][0] = ff_avg_pixels16_mmxext;
-    c->avg_pixels_tab[0][1] = ff_avg_pixels16_x2_mmxext;
-    c->avg_pixels_tab[0][2] = ff_avg_pixels16_y2_mmxext;
+    c->avg_pixels_tab[0][0] = avg_pixels16_mmxext;
+    c->avg_pixels_tab[0][1] = avg_pixels16_x2_mmxext;
+    c->avg_pixels_tab[0][2] = avg_pixels16_y2_mmxext;
 
     c->put_pixels_tab[1][1] = ff_put_pixels8_x2_mmxext;
     c->put_pixels_tab[1][2] = ff_put_pixels8_y2_mmxext;
@@ -247,12 +188,12 @@
     c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_mmxext;
 
     if (!(flags & CODEC_FLAG_BITEXACT)) {
-        c->put_no_rnd_pixels_tab[0][1] = ff_put_no_rnd_pixels16_x2_mmxext;
-        c->put_no_rnd_pixels_tab[0][2] = ff_put_no_rnd_pixels16_y2_mmxext;
+        c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_mmxext;
+        c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_mmxext;
         c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_mmxext;
         c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_mmxext;
 
-        c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_mmxext;
+        c->avg_pixels_tab[0][3] = avg_pixels16_xy2_mmxext;
         c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_mmxext;
     }
 
@@ -260,18 +201,18 @@
         c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_exact_mmxext;
         c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_exact_mmxext;
     }
-#endif /* HAVE_YASM */
+#endif /* HAVE_MMXEXT_EXTERNAL */
 }
 
-static void hpeldsp_init_3dnow(HpelDSPContext *c, int flags, int mm_flags)
+static void hpeldsp_init_3dnow(HpelDSPContext *c, int flags, int cpu_flags)
 {
-#if HAVE_YASM
+#if HAVE_AMD3DNOW_EXTERNAL
     c->put_pixels_tab[0][1] = ff_put_pixels16_x2_3dnow;
-    c->put_pixels_tab[0][2] = ff_put_pixels16_y2_3dnow;
+    c->put_pixels_tab[0][2] = put_pixels16_y2_3dnow;
 
-    c->avg_pixels_tab[0][0] = ff_avg_pixels16_3dnow;
-    c->avg_pixels_tab[0][1] = ff_avg_pixels16_x2_3dnow;
-    c->avg_pixels_tab[0][2] = ff_avg_pixels16_y2_3dnow;
+    c->avg_pixels_tab[0][0] = avg_pixels16_3dnow;
+    c->avg_pixels_tab[0][1] = avg_pixels16_x2_3dnow;
+    c->avg_pixels_tab[0][2] = avg_pixels16_y2_3dnow;
 
     c->put_pixels_tab[1][1] = ff_put_pixels8_x2_3dnow;
     c->put_pixels_tab[1][2] = ff_put_pixels8_y2_3dnow;
@@ -281,12 +222,12 @@
     c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_3dnow;
 
     if (!(flags & CODEC_FLAG_BITEXACT)){
-        c->put_no_rnd_pixels_tab[0][1] = ff_put_no_rnd_pixels16_x2_3dnow;
-        c->put_no_rnd_pixels_tab[0][2] = ff_put_no_rnd_pixels16_y2_3dnow;
+        c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_3dnow;
+        c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_3dnow;
         c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_3dnow;
         c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_3dnow;
 
-        c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_3dnow;
+        c->avg_pixels_tab[0][3] = avg_pixels16_xy2_3dnow;
         c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_3dnow;
     }
 
@@ -294,34 +235,34 @@
         c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_exact_3dnow;
         c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_exact_3dnow;
     }
-#endif /* HAVE_YASM */
+#endif /* HAVE_AMD3DNOW_EXTERNAL */
 }
 
-static void hpeldsp_init_sse2(HpelDSPContext *c, int flags, int mm_flags)
+static void hpeldsp_init_sse2(HpelDSPContext *c, int flags, int cpu_flags)
 {
-#if HAVE_YASM
-    if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW)) {
+#if HAVE_SSE2_EXTERNAL
+    if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW)) {
         // these functions are slower than mmx on AMD, but faster on Intel
         c->put_pixels_tab[0][0]        = ff_put_pixels16_sse2;
         c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_sse2;
         c->avg_pixels_tab[0][0]        = ff_avg_pixels16_sse2;
     }
-#endif /* HAVE_YASM */
+#endif /* HAVE_SSE2_EXTERNAL */
 }
 
 void ff_hpeldsp_init_x86(HpelDSPContext *c, int flags)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (HAVE_MMX && mm_flags & AV_CPU_FLAG_MMX)
-        hpeldsp_init_mmx(c, flags, mm_flags);
+    if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX)
+        hpeldsp_init_mmx(c, flags, cpu_flags);
 
-    if (mm_flags & AV_CPU_FLAG_MMXEXT)
-        hpeldsp_init_mmxext(c, flags, mm_flags);
+    if (cpu_flags & AV_CPU_FLAG_MMXEXT)
+        hpeldsp_init_mmxext(c, flags, cpu_flags);
 
-    if (mm_flags & AV_CPU_FLAG_3DNOW)
-        hpeldsp_init_3dnow(c, flags, mm_flags);
+    if (cpu_flags & AV_CPU_FLAG_3DNOW)
+        hpeldsp_init_3dnow(c, flags, cpu_flags);
 
-    if (mm_flags & AV_CPU_FLAG_SSE2)
-        hpeldsp_init_sse2(c, flags, mm_flags);
+    if (cpu_flags & AV_CPU_FLAG_SSE2)
+        hpeldsp_init_sse2(c, flags, cpu_flags);
 }
diff --git a/libavcodec/x86/hpeldsp_mmx.c b/libavcodec/x86/hpeldsp_mmx.c
new file mode 100644
index 0000000..50db36d
--- /dev/null
+++ b/libavcodec/x86/hpeldsp_mmx.c
@@ -0,0 +1,52 @@
+/*
+ * MMX-optimized avg/put pixel routines
+ *
+ * Copyright (c) 2001 Fabrice Bellard
+ *
+ * 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
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "config.h"
+#include "dsputil_x86.h"
+
+#if HAVE_MMX_INLINE
+
+void ff_avg_pixels8_x2_mmx(uint8_t *block, const uint8_t *pixels,
+                           ptrdiff_t line_size, int h)
+{
+    MOVQ_BFE(mm6);
+    JUMPALIGN();
+    do {
+        __asm__ volatile(
+            "movq  %1, %%mm0            \n\t"
+            "movq  1%1, %%mm1           \n\t"
+            "movq  %0, %%mm3            \n\t"
+            PAVGB_MMX(%%mm0, %%mm1, %%mm2, %%mm6)
+            PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6)
+            "movq  %%mm0, %0            \n\t"
+            :"+m"(*block)
+            :"m"(*pixels)
+            :"memory");
+        pixels += line_size;
+        block += line_size;
+    } while (--h);
+}
+
+#endif /* HAVE_MMX_INLINE */
diff --git a/libavcodec/x86/hpeldsp_rnd_template.c b/libavcodec/x86/hpeldsp_rnd_template.c
index 5b5866d..94e06d8 100644
--- a/libavcodec/x86/hpeldsp_rnd_template.c
+++ b/libavcodec/x86/hpeldsp_rnd_template.c
@@ -24,8 +24,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "dsputil_rnd_template.c"
-
 // put_pixels
 static void DEF(put, pixels8_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
@@ -134,28 +132,6 @@
         :REG_a, "memory");
 }
 
-#ifndef NO_RND
-static void DEF(avg, pixels8_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
-{
-    MOVQ_BFE(mm6);
-    JUMPALIGN();
-    do {
-        __asm__ volatile(
-            "movq  %1, %%mm0            \n\t"
-            "movq  1%1, %%mm1           \n\t"
-            "movq  %0, %%mm3            \n\t"
-            PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
-            OP_AVG(%%mm3, %%mm2, %%mm0, %%mm6)
-            "movq  %%mm0, %0            \n\t"
-            :"+m"(*block)
-            :"m"(*pixels)
-            :"memory");
-        pixels += line_size;
-        block += line_size;
-    } while (--h);
-}
-#endif // NO_RND
-
 static void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     MOVQ_BFE(mm6);
@@ -166,13 +142,13 @@
             "movq  1%1, %%mm1           \n\t"
             "movq  %0, %%mm3            \n\t"
             PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
-            OP_AVG(%%mm3, %%mm2, %%mm0, %%mm6)
+            PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6)
             "movq  %%mm0, %0            \n\t"
             "movq  8%1, %%mm0           \n\t"
             "movq  9%1, %%mm1           \n\t"
             "movq  8%0, %%mm3           \n\t"
             PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
-            OP_AVG(%%mm3, %%mm2, %%mm0, %%mm6)
+            PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6)
             "movq  %%mm0, 8%0           \n\t"
             :"+m"(*block)
             :"m"(*pixels)
@@ -194,9 +170,9 @@
         "movq   (%1, %%"REG_a"), %%mm2  \n\t"
         PAVGBP(%%mm1, %%mm0, %%mm4,   %%mm2, %%mm1, %%mm5)
         "movq   (%2), %%mm3             \n\t"
-        OP_AVG(%%mm3, %%mm4, %%mm0, %%mm6)
+        PAVGB_MMX(%%mm3, %%mm4, %%mm0, %%mm6)
         "movq   (%2, %3), %%mm3         \n\t"
-        OP_AVG(%%mm3, %%mm5, %%mm1, %%mm6)
+        PAVGB_MMX(%%mm3, %%mm5, %%mm1, %%mm6)
         "movq   %%mm0, (%2)             \n\t"
         "movq   %%mm1, (%2, %3)         \n\t"
         "add    %%"REG_a", %1           \n\t"
@@ -206,9 +182,9 @@
         "movq   (%1, %%"REG_a"), %%mm0  \n\t"
         PAVGBP(%%mm1, %%mm2, %%mm4,   %%mm0, %%mm1, %%mm5)
         "movq   (%2), %%mm3             \n\t"
-        OP_AVG(%%mm3, %%mm4, %%mm2, %%mm6)
+        PAVGB_MMX(%%mm3, %%mm4, %%mm2, %%mm6)
         "movq   (%2, %3), %%mm3         \n\t"
-        OP_AVG(%%mm3, %%mm5, %%mm1, %%mm6)
+        PAVGB_MMX(%%mm3, %%mm5, %%mm1, %%mm6)
         "movq   %%mm2, (%2)             \n\t"
         "movq   %%mm1, (%2, %3)         \n\t"
         "add    %%"REG_a", %1           \n\t"
@@ -220,14 +196,3 @@
         :"r"((x86_reg)line_size)
         :REG_a, "memory");
 }
-
-//FIXME optimize
-static void DEF(put, pixels16_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){
-    DEF(put, pixels8_y2)(block  , pixels  , line_size, h);
-    DEF(put, pixels8_y2)(block+8, pixels+8, line_size, h);
-}
-
-static void DEF(avg, pixels16_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){
-    DEF(avg, pixels8_y2)(block  , pixels  , line_size, h);
-    DEF(avg, pixels8_y2)(block+8, pixels+8, line_size, h);
-}
diff --git a/libavcodec/x86/idct_mmx_xvid.c b/libavcodec/x86/idct_mmx_xvid.c
index 5e9f405..f66519b 100644
--- a/libavcodec/x86/idct_mmx_xvid.c
+++ b/libavcodec/x86/idct_mmx_xvid.c
@@ -44,7 +44,7 @@
 #include "config.h"
 #include "libavcodec/avcodec.h"
 #include "libavutil/mem.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 #include "idct_xvid.h"
 
 #if HAVE_INLINE_ASM
diff --git a/libavcodec/x86/idct_sse2_xvid.c b/libavcodec/x86/idct_sse2_xvid.c
index b51466c..ee2a08d 100644
--- a/libavcodec/x86/idct_sse2_xvid.c
+++ b/libavcodec/x86/idct_sse2_xvid.c
@@ -41,7 +41,7 @@
 #include "libavutil/mem.h"
 #include "libavutil/x86/asm.h"
 #include "idct_xvid.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 
 #if HAVE_INLINE_ASM
 
diff --git a/libavcodec/x86/lpc.c b/libavcodec/x86/lpc.c
index 1962212..e44ab60 100644
--- a/libavcodec/x86/lpc.c
+++ b/libavcodec/x86/lpc.c
@@ -22,8 +22,12 @@
 #include "libavutil/x86/asm.h"
 #include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
+#include "libavutil/mem.h"
 #include "libavcodec/lpc.h"
 
+DECLARE_ASM_CONST(16, double, pd_1)[2] = { 1.0, 1.0 };
+DECLARE_ASM_CONST(16, double, pd_2)[2] = { 2.0, 2.0 };
+
 #if HAVE_SSE2_INLINE
 
 static void lpc_apply_welch_window_sse2(const int32_t *data, int len,
@@ -35,8 +39,8 @@
     x86_reg j =  n2*sizeof(int32_t);
     __asm__ volatile(
         "movsd   %4,     %%xmm7                \n\t"
-        "movapd  "MANGLE(ff_pd_1)", %%xmm6     \n\t"
-        "movapd  "MANGLE(ff_pd_2)", %%xmm5     \n\t"
+        "movapd  "MANGLE(pd_1)", %%xmm6        \n\t"
+        "movapd  "MANGLE(pd_2)", %%xmm5        \n\t"
         "movlhps %%xmm7, %%xmm7                \n\t"
         "subpd   %%xmm5, %%xmm7                \n\t"
         "addsd   %%xmm6, %%xmm7                \n\t"
@@ -85,9 +89,9 @@
         x86_reg i = -len*sizeof(double);
         if(j == lag-2) {
             __asm__ volatile(
-                "movsd    "MANGLE(ff_pd_1)", %%xmm0 \n\t"
-                "movsd    "MANGLE(ff_pd_1)", %%xmm1 \n\t"
-                "movsd    "MANGLE(ff_pd_1)", %%xmm2 \n\t"
+                "movsd    "MANGLE(pd_1)", %%xmm0    \n\t"
+                "movsd    "MANGLE(pd_1)", %%xmm1    \n\t"
+                "movsd    "MANGLE(pd_1)", %%xmm2    \n\t"
                 "1:                                 \n\t"
                 "movapd   (%2,%0), %%xmm3           \n\t"
                 "movupd -8(%3,%0), %%xmm4           \n\t"
@@ -115,8 +119,8 @@
             );
         } else {
             __asm__ volatile(
-                "movsd    "MANGLE(ff_pd_1)", %%xmm0 \n\t"
-                "movsd    "MANGLE(ff_pd_1)", %%xmm1 \n\t"
+                "movsd    "MANGLE(pd_1)", %%xmm0    \n\t"
+                "movsd    "MANGLE(pd_1)", %%xmm1    \n\t"
                 "1:                                 \n\t"
                 "movapd   (%3,%0), %%xmm3           \n\t"
                 "movupd -8(%4,%0), %%xmm4           \n\t"
@@ -144,9 +148,9 @@
 av_cold void ff_lpc_init_x86(LPCContext *c)
 {
 #if HAVE_SSE2_INLINE
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (mm_flags & (AV_CPU_FLAG_SSE2|AV_CPU_FLAG_SSE2SLOW)) {
+    if (cpu_flags & (AV_CPU_FLAG_SSE2 | AV_CPU_FLAG_SSE2SLOW)) {
         c->lpc_apply_welch_window = lpc_apply_welch_window_sse2;
         c->lpc_compute_autocorr   = lpc_compute_autocorr_sse2;
     }
diff --git a/libavcodec/x86/mathops.h b/libavcodec/x86/mathops.h
index 79e29e6..9c48afe 100644
--- a/libavcodec/x86/mathops.h
+++ b/libavcodec/x86/mathops.h
@@ -68,13 +68,13 @@
 
 #endif /* ARCH_X86_32 */
 
-#if HAVE_CMOV
+#if HAVE_I686
 /* median of 3 */
 #define mid_pred mid_pred
 static inline av_const int mid_pred(int a, int b, int c)
 {
     int i=b;
-    __asm__ volatile(
+    __asm__ (
         "cmp    %2, %1 \n\t"
         "cmovg  %1, %0 \n\t"
         "cmovg  %2, %1 \n\t"
@@ -87,9 +87,7 @@
     );
     return i;
 }
-#endif
 
-#if HAVE_CMOV
 #define COPY3_IF_LT(x, y, a, b, c, d)\
 __asm__ volatile(\
     "cmpl  %0, %3       \n\t"\
@@ -99,7 +97,7 @@
     : "+&r" (x), "+&r" (a), "+r" (c)\
     : "r" (y), "r" (b), "r" (d)\
 );
-#endif
+#endif /* HAVE_I686 */
 
 #define MASK_ABS(mask, level)                   \
     __asm__ ("cltd                   \n\t"      \
diff --git a/libavcodec/x86/mlpdsp.c b/libavcodec/x86/mlpdsp.c
index 81cab5a..94849b7 100644
--- a/libavcodec/x86/mlpdsp.c
+++ b/libavcodec/x86/mlpdsp.c
@@ -20,7 +20,9 @@
  */
 
 #include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
 #include "libavcodec/mlpdsp.h"
 #include "libavcodec/mlp.h"
 
@@ -177,6 +179,8 @@
 av_cold void ff_mlpdsp_init_x86(MLPDSPContext *c)
 {
 #if HAVE_7REGS && HAVE_INLINE_ASM
-    c->mlp_filter_channel = mlp_filter_channel_x86;
+    int cpu_flags = av_get_cpu_flags();
+    if (INLINE_MMX(cpu_flags))
+        c->mlp_filter_channel = mlp_filter_channel_x86;
 #endif
 }
diff --git a/libavcodec/x86/motion_est.c b/libavcodec/x86/motion_est.c
index 3ffb002..3e926e2 100644
--- a/libavcodec/x86/motion_est.c
+++ b/libavcodec/x86/motion_est.c
@@ -26,7 +26,7 @@
 #include "libavutil/avassert.h"
 #include "libavutil/mem.h"
 #include "libavutil/x86/asm.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 
 #if HAVE_INLINE_ASM
 
@@ -435,9 +435,9 @@
 av_cold void ff_dsputil_init_pix_mmx(DSPContext *c, AVCodecContext *avctx)
 {
 #if HAVE_INLINE_ASM
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (mm_flags & AV_CPU_FLAG_MMX) {
+    if (cpu_flags & AV_CPU_FLAG_MMX) {
         c->pix_abs[0][0] = sad16_mmx;
         c->pix_abs[0][1] = sad16_x2_mmx;
         c->pix_abs[0][2] = sad16_y2_mmx;
@@ -450,7 +450,7 @@
         c->sad[0]= sad16_mmx;
         c->sad[1]= sad8_mmx;
     }
-    if (mm_flags & AV_CPU_FLAG_MMXEXT) {
+    if (cpu_flags & AV_CPU_FLAG_MMXEXT) {
         c->pix_abs[0][0] = sad16_mmxext;
         c->pix_abs[1][0] = sad8_mmxext;
 
@@ -466,7 +466,7 @@
             c->pix_abs[1][3] = sad8_xy2_mmxext;
         }
     }
-    if ((mm_flags & AV_CPU_FLAG_SSE2) && !(mm_flags & AV_CPU_FLAG_3DNOW) && avctx->codec_id != AV_CODEC_ID_SNOW) {
+    if ((cpu_flags & AV_CPU_FLAG_SSE2) && !(cpu_flags & AV_CPU_FLAG_3DNOW) && avctx->codec_id != AV_CODEC_ID_SNOW) {
         c->sad[0]= sad16_sse2;
     }
 #endif /* HAVE_INLINE_ASM */
diff --git a/libavcodec/x86/mpegaudiodec.c b/libavcodec/x86/mpegaudiodsp.c
similarity index 96%
rename from libavcodec/x86/mpegaudiodec.c
rename to libavcodec/x86/mpegaudiodsp.c
index 287d8ff..ea070f6 100644
--- a/libavcodec/x86/mpegaudiodec.c
+++ b/libavcodec/x86/mpegaudiodsp.c
@@ -235,7 +235,7 @@
 
 av_cold void ff_mpadsp_init_x86(MPADSPContext *s)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
     int i, j;
     for (j = 0; j < 4; j++) {
@@ -252,21 +252,21 @@
     }
 
 #if HAVE_SSE2_INLINE
-    if (mm_flags & AV_CPU_FLAG_SSE2) {
+    if (cpu_flags & AV_CPU_FLAG_SSE2) {
         s->apply_window_float = apply_window_mp3;
     }
 #endif /* HAVE_SSE2_INLINE */
 
 #if HAVE_YASM
-    if (EXTERNAL_AVX(mm_flags)) {
+    if (EXTERNAL_AVX(cpu_flags)) {
         s->imdct36_blocks_float = imdct36_blocks_avx;
-    } else if (EXTERNAL_SSSE3(mm_flags)) {
+    } else if (EXTERNAL_SSSE3(cpu_flags)) {
         s->imdct36_blocks_float = imdct36_blocks_ssse3;
-    } else if (EXTERNAL_SSE3(mm_flags)) {
+    } else if (EXTERNAL_SSE3(cpu_flags)) {
         s->imdct36_blocks_float = imdct36_blocks_sse3;
-    } else if (EXTERNAL_SSE2(mm_flags)) {
+    } else if (EXTERNAL_SSE2(cpu_flags)) {
         s->imdct36_blocks_float = imdct36_blocks_sse2;
-    } else if (EXTERNAL_SSE(mm_flags)) {
+    } else if (EXTERNAL_SSE(cpu_flags)) {
         s->imdct36_blocks_float = imdct36_blocks_sse;
     }
 #endif /* HAVE_YASM */
diff --git a/libavcodec/x86/mpegvideo.c b/libavcodec/x86/mpegvideo.c
index 49e9fd3..693f058 100644
--- a/libavcodec/x86/mpegvideo.c
+++ b/libavcodec/x86/mpegvideo.c
@@ -24,9 +24,9 @@
 #include "libavutil/x86/asm.h"
 #include "libavcodec/avcodec.h"
 #include "libavcodec/mpegvideo.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 
-#if HAVE_INLINE_ASM
+#if HAVE_MMX_INLINE
 
 static void dct_unquantize_h263_intra_mmx(MpegEncContext *s,
                                   int16_t *block, int n, int qscale)
@@ -164,28 +164,6 @@
         );
 }
 
-
-/*
-  We can suppose that result of two multiplications can't be greater than 0xFFFF
-  i.e. is 16-bit, so we use here only PMULLW instruction and can avoid
-  a complex multiplication.
-=====================================================
- Full formula for multiplication of 2 integer numbers
- which are represent as high:low words:
- input: value1 = high1:low1
-        value2 = high2:low2
- output: value3 = value1*value2
- value3=high3:low3 (on overflow: modulus 2^32 wrap-around)
- this mean that for 0x123456 * 0x123456 correct result is 0x766cb0ce4
- but this algorithm will compute only 0x66cb0ce4
- this limited by 16-bit size of operands
- ---------------------------------
- tlow1 = high1*low2
- tlow2 = high2*low1
- tlow1 = tlow1 + tlow2
- high3:low3 = low1*low2
- high3 += tlow1
-*/
 static void dct_unquantize_mpeg1_intra_mmx(MpegEncContext *s,
                                      int16_t *block, int n, int qscale)
 {
@@ -574,14 +552,14 @@
     );
 }
 
-#endif /* HAVE_INLINE_ASM */
+#endif /* HAVE_MMX_INLINE */
 
 av_cold void ff_MPV_common_init_x86(MpegEncContext *s)
 {
-#if HAVE_INLINE_ASM
-    int mm_flags = av_get_cpu_flags();
+#if HAVE_MMX_INLINE
+    int cpu_flags = av_get_cpu_flags();
 
-    if (mm_flags & AV_CPU_FLAG_MMX) {
+    if (cpu_flags & AV_CPU_FLAG_MMX) {
         s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_mmx;
         s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_mmx;
         s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_mmx;
@@ -590,11 +568,11 @@
             s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_mmx;
         s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_mmx;
 
-        if (mm_flags & AV_CPU_FLAG_SSE2) {
+        if (cpu_flags & AV_CPU_FLAG_SSE2) {
             s->denoise_dct= denoise_dct_sse2;
         } else {
                 s->denoise_dct= denoise_dct_mmx;
         }
     }
-#endif /* HAVE_INLINE_ASM */
+#endif /* HAVE_MMX_INLINE */
 }
diff --git a/libavcodec/x86/mpegvideoenc.c b/libavcodec/x86/mpegvideoenc.c
index eda0b76..97aa3c7 100644
--- a/libavcodec/x86/mpegvideoenc.c
+++ b/libavcodec/x86/mpegvideoenc.c
@@ -26,7 +26,7 @@
 #include "libavcodec/avcodec.h"
 #include "libavcodec/dct.h"
 #include "libavcodec/mpegvideo.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 
 extern uint16_t ff_inv_zigzag_direct16[64];
 
@@ -87,20 +87,20 @@
 
     if (dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX) {
 #if HAVE_MMX_INLINE
-        int mm_flags = av_get_cpu_flags();
-        if (INLINE_MMX(mm_flags))
+        int cpu_flags = av_get_cpu_flags();
+        if (INLINE_MMX(cpu_flags))
             s->dct_quantize = dct_quantize_MMX;
 #endif
 #if HAVE_MMXEXT_INLINE
-        if (INLINE_MMXEXT(mm_flags))
+        if (INLINE_MMXEXT(cpu_flags))
             s->dct_quantize = dct_quantize_MMXEXT;
 #endif
 #if HAVE_SSE2_INLINE
-        if (INLINE_SSE2(mm_flags))
+        if (INLINE_SSE2(cpu_flags))
             s->dct_quantize = dct_quantize_SSE2;
 #endif
 #if HAVE_SSSE3_INLINE
-        if (INLINE_SSSE3(mm_flags))
+        if (INLINE_SSSE3(cpu_flags))
             s->dct_quantize = dct_quantize_SSSE3;
 #endif
     }
diff --git a/libavcodec/x86/pngdsp_init.c b/libavcodec/x86/pngdsp_init.c
index 4c54ed3..7dca62c 100644
--- a/libavcodec/x86/pngdsp_init.c
+++ b/libavcodec/x86/pngdsp_init.c
@@ -35,16 +35,16 @@
 
 av_cold void ff_pngdsp_init_x86(PNGDSPContext *dsp)
 {
-    int flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
 #if ARCH_X86_32
-    if (EXTERNAL_MMX(flags))
+    if (EXTERNAL_MMX(cpu_flags))
         dsp->add_bytes_l2         = ff_add_bytes_l2_mmx;
 #endif
-    if (EXTERNAL_MMXEXT(flags))
+    if (EXTERNAL_MMXEXT(cpu_flags))
         dsp->add_paeth_prediction = ff_add_png_paeth_prediction_mmxext;
-    if (EXTERNAL_SSE2(flags))
+    if (EXTERNAL_SSE2(cpu_flags))
         dsp->add_bytes_l2         = ff_add_bytes_l2_sse2;
-    if (EXTERNAL_SSSE3(flags))
+    if (EXTERNAL_SSSE3(cpu_flags))
         dsp->add_paeth_prediction = ff_add_png_paeth_prediction_ssse3;
 }
diff --git a/libavcodec/x86/proresdsp_init.c b/libavcodec/x86/proresdsp_init.c
index 91ff257..0273d61 100644
--- a/libavcodec/x86/proresdsp_init.c
+++ b/libavcodec/x86/proresdsp_init.c
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/x86/cpu.h"
 #include "libavcodec/dsputil.h"
 #include "libavcodec/proresdsp.h"
@@ -31,25 +32,25 @@
 void ff_prores_idct_put_10_avx (uint16_t *dst, int linesize,
                                 int16_t *block, const int16_t *qmat);
 
-void ff_proresdsp_x86_init(ProresDSPContext *dsp, AVCodecContext *avctx)
+av_cold void ff_proresdsp_x86_init(ProresDSPContext *dsp, AVCodecContext *avctx)
 {
 #if ARCH_X86_64
-    int flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
     if(avctx->flags & CODEC_FLAG_BITEXACT)
         return;
 
-    if (EXTERNAL_SSE2(flags)) {
+    if (EXTERNAL_SSE2(cpu_flags)) {
         dsp->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM;
         dsp->idct_put = ff_prores_idct_put_10_sse2;
     }
 
-    if (EXTERNAL_SSE4(flags)) {
+    if (EXTERNAL_SSE4(cpu_flags)) {
         dsp->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM;
         dsp->idct_put = ff_prores_idct_put_10_sse4;
     }
 
-    if (EXTERNAL_AVX(flags)) {
+    if (EXTERNAL_AVX(cpu_flags)) {
         dsp->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM;
         dsp->idct_put = ff_prores_idct_put_10_avx;
     }
diff --git a/libavcodec/x86/rnd_mmx.c b/libavcodec/x86/rnd_mmx.c
new file mode 100644
index 0000000..326e2f3
--- /dev/null
+++ b/libavcodec/x86/rnd_mmx.c
@@ -0,0 +1,35 @@
+/*
+ * 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
+ */
+
+#include "config.h"
+#include "dsputil_x86.h"
+
+#if HAVE_INLINE_ASM
+
+#define DEF(x, y) ff_ ## x ## _ ## y ## _mmx
+#define SET_RND  MOVQ_WTWO
+#define PAVGBP(a, b, c, d, e, f)        PAVGBP_MMX(a, b, c, d, e, f)
+#define PAVGB(a, b, c, e)               PAVGB_MMX(a, b, c, e)
+#define STATIC
+
+#include "rnd_template.c"
+
+PIXELS16(, ff_avg, , _xy2, _mmx)
+PIXELS16(, ff_put, , _xy2, _mmx)
+
+#endif /* HAVE_INLINE_ASM */
diff --git a/libavcodec/x86/dsputil_rnd_template.c b/libavcodec/x86/rnd_template.c
similarity index 76%
rename from libavcodec/x86/dsputil_rnd_template.c
rename to libavcodec/x86/rnd_template.c
index 7765309..e37fc19 100644
--- a/libavcodec/x86/dsputil_rnd_template.c
+++ b/libavcodec/x86/rnd_template.c
@@ -24,8 +24,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stddef.h>
+#include <stdint.h>
+
 // put_pixels
-static void DEF(put, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+STATIC void DEF(put, pixels8_xy2)(uint8_t *block, const uint8_t *pixels,
+                                  ptrdiff_t line_size, int h)
 {
     MOVQ_ZERO(mm7);
     SET_RND(mm6); // =2 for rnd  and  =1 for no_rnd version
@@ -92,53 +96,9 @@
 }
 
 // avg_pixels
-#ifndef NO_RND
-// in case more speed is needed - unroling would certainly help
-static void DEF(avg, pixels8)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
-{
-    MOVQ_BFE(mm6);
-    JUMPALIGN();
-    do {
-        __asm__ volatile(
-             "movq  %0, %%mm0           \n\t"
-             "movq  %1, %%mm1           \n\t"
-             OP_AVG(%%mm0, %%mm1, %%mm2, %%mm6)
-             "movq  %%mm2, %0           \n\t"
-             :"+m"(*block)
-             :"m"(*pixels)
-             :"memory");
-        pixels += line_size;
-        block += line_size;
-    }
-    while (--h);
-}
-#endif /* NO_RND */
-
-static void DEF(avg, pixels16)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
-{
-    MOVQ_BFE(mm6);
-    JUMPALIGN();
-    do {
-        __asm__ volatile(
-             "movq  %0, %%mm0           \n\t"
-             "movq  %1, %%mm1           \n\t"
-             OP_AVG(%%mm0, %%mm1, %%mm2, %%mm6)
-             "movq  %%mm2, %0           \n\t"
-             "movq  8%0, %%mm0          \n\t"
-             "movq  8%1, %%mm1          \n\t"
-             OP_AVG(%%mm0, %%mm1, %%mm2, %%mm6)
-             "movq  %%mm2, 8%0          \n\t"
-             :"+m"(*block)
-             :"m"(*pixels)
-             :"memory");
-        pixels += line_size;
-        block += line_size;
-    }
-    while (--h);
-}
-
 // this routine is 'slightly' suboptimal but mostly unused
-static void DEF(avg, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+STATIC void DEF(avg, pixels8_xy2)(uint8_t *block, const uint8_t *pixels,
+                                  ptrdiff_t line_size, int h)
 {
     MOVQ_ZERO(mm7);
     SET_RND(mm6); // =2 for rnd  and  =1 for no_rnd version
@@ -177,7 +137,7 @@
         "packuswb  %%mm5, %%mm4         \n\t"
                 "pcmpeqd %%mm2, %%mm2   \n\t"
                 "paddb %%mm2, %%mm2     \n\t"
-                OP_AVG(%%mm3, %%mm4, %%mm5, %%mm2)
+                PAVGB_MMX(%%mm3, %%mm4, %%mm5, %%mm2)
                 "movq   %%mm5, (%2, %%"REG_a")  \n\t"
         "add    %3, %%"REG_a"                \n\t"
 
@@ -201,7 +161,7 @@
         "packuswb  %%mm1, %%mm0         \n\t"
                 "pcmpeqd %%mm2, %%mm2   \n\t"
                 "paddb %%mm2, %%mm2     \n\t"
-                OP_AVG(%%mm3, %%mm0, %%mm1, %%mm2)
+                PAVGB_MMX(%%mm3, %%mm0, %%mm1, %%mm2)
                 "movq   %%mm1, (%2, %%"REG_a")  \n\t"
         "add    %3, %%"REG_a"           \n\t"
 
@@ -211,14 +171,3 @@
         :"D"(block), "r"((x86_reg)line_size)
         :REG_a, "memory");
 }
-
-//FIXME optimize
-static void DEF(put, pixels16_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){
-    DEF(put, pixels8_xy2)(block  , pixels  , line_size, h);
-    DEF(put, pixels8_xy2)(block+8, pixels+8, line_size, h);
-}
-
-static void DEF(avg, pixels16_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){
-    DEF(avg, pixels8_xy2)(block  , pixels  , line_size, h);
-    DEF(avg, pixels8_xy2)(block+8, pixels+8, line_size, h);
-}
diff --git a/libavcodec/x86/rv34dsp_init.c b/libavcodec/x86/rv34dsp_init.c
index a2dea74..5f284b8 100644
--- a/libavcodec/x86/rv34dsp_init.c
+++ b/libavcodec/x86/rv34dsp_init.c
@@ -32,14 +32,14 @@
 
 av_cold void ff_rv34dsp_init_x86(RV34DSPContext* c)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (EXTERNAL_MMX(mm_flags))
+    if (EXTERNAL_MMX(cpu_flags))
         c->rv34_idct_dc_add = ff_rv34_idct_dc_add_mmx;
-    if (EXTERNAL_MMXEXT(mm_flags)) {
+    if (EXTERNAL_MMXEXT(cpu_flags)) {
         c->rv34_inv_transform_dc = ff_rv34_idct_dc_noround_mmxext;
         c->rv34_idct_add         = ff_rv34_idct_add_mmxext;
     }
-    if (EXTERNAL_SSE4(mm_flags))
+    if (EXTERNAL_SSE4(cpu_flags))
         c->rv34_idct_dc_add = ff_rv34_idct_dc_add_sse4;
 }
diff --git a/libavcodec/x86/rv40dsp_init.c b/libavcodec/x86/rv40dsp_init.c
index 2f97518..6baad13 100644
--- a/libavcodec/x86/rv40dsp_init.c
+++ b/libavcodec/x86/rv40dsp_init.c
@@ -30,7 +30,7 @@
 #include "libavutil/attributes.h"
 #include "libavutil/mem.h"
 #include "libavutil/x86/cpu.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 
 #if HAVE_YASM
 void ff_put_rv40_chroma_mc8_mmx  (uint8_t *dst, uint8_t *src,
@@ -188,25 +188,48 @@
 
 #endif /* HAVE_YASM */
 
+#if HAVE_MMX_INLINE
+static void put_rv40_qpel8_mc33_mmx(uint8_t *dst, uint8_t *src,
+                                    ptrdiff_t stride)
+{
+    ff_put_pixels8_xy2_mmx(dst, src, stride, 8);
+}
+static void put_rv40_qpel16_mc33_mmx(uint8_t *dst, uint8_t *src,
+                                     ptrdiff_t stride)
+{
+    ff_put_pixels16_xy2_mmx(dst, src, stride, 16);
+}
+static void avg_rv40_qpel8_mc33_mmx(uint8_t *dst, uint8_t *src,
+                                    ptrdiff_t stride)
+{
+    ff_avg_pixels8_xy2_mmx(dst, src, stride, 8);
+}
+static void avg_rv40_qpel16_mc33_mmx(uint8_t *dst, uint8_t *src,
+                                     ptrdiff_t stride)
+{
+    ff_avg_pixels16_xy2_mmx(dst, src, stride, 16);
+}
+#endif /* HAVE_MMX_INLINE */
+
 av_cold void ff_rv40dsp_init_x86(RV34DSPContext *c)
 {
 #if HAVE_YASM
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (EXTERNAL_MMX(mm_flags)) {
+    if (EXTERNAL_MMX(cpu_flags)) {
         c->put_chroma_pixels_tab[0] = ff_put_rv40_chroma_mc8_mmx;
         c->put_chroma_pixels_tab[1] = ff_put_rv40_chroma_mc4_mmx;
 #if HAVE_MMX_INLINE
-        c->put_pixels_tab[0][15] = ff_put_rv40_qpel16_mc33_mmx;
-        c->put_pixels_tab[1][15] = ff_put_rv40_qpel8_mc33_mmx;
-        c->avg_pixels_tab[0][15] = ff_avg_rv40_qpel16_mc33_mmx;
-        c->avg_pixels_tab[1][15] = ff_avg_rv40_qpel8_mc33_mmx;
+        c->put_pixels_tab[0][15] = put_rv40_qpel16_mc33_mmx;
+        c->put_pixels_tab[1][15] = put_rv40_qpel8_mc33_mmx;
+        c->avg_pixels_tab[0][15] = avg_rv40_qpel16_mc33_mmx;
+        c->avg_pixels_tab[1][15] = avg_rv40_qpel8_mc33_mmx;
 #endif /* HAVE_MMX_INLINE */
 #if ARCH_X86_32
         QPEL_MC_SET(put_, _mmx)
 #endif
     }
-    if (EXTERNAL_MMXEXT(mm_flags)) {
+    if (EXTERNAL_MMXEXT(cpu_flags)) {
         c->avg_chroma_pixels_tab[0]     = ff_avg_rv40_chroma_mc8_mmxext;
         c->avg_chroma_pixels_tab[1]     = ff_avg_rv40_chroma_mc4_mmxext;
         c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_mmxext;
@@ -216,14 +239,14 @@
 #if ARCH_X86_32
         QPEL_MC_SET(avg_, _mmxext)
 #endif
-    } else if (EXTERNAL_AMD3DNOW(mm_flags)) {
+    } else if (EXTERNAL_AMD3DNOW(cpu_flags)) {
         c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_3dnow;
         c->avg_chroma_pixels_tab[1] = ff_avg_rv40_chroma_mc4_3dnow;
 #if ARCH_X86_32
         QPEL_MC_SET(avg_, _3dnow)
 #endif
     }
-    if (EXTERNAL_SSE2(mm_flags)) {
+    if (EXTERNAL_SSE2(cpu_flags)) {
         c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_sse2;
         c->rv40_weight_pixels_tab[0][1] = ff_rv40_weight_func_rnd_8_sse2;
         c->rv40_weight_pixels_tab[1][0] = ff_rv40_weight_func_nornd_16_sse2;
@@ -231,7 +254,7 @@
         QPEL_MC_SET(put_, _sse2)
         QPEL_MC_SET(avg_, _sse2)
     }
-    if (EXTERNAL_SSSE3(mm_flags)) {
+    if (EXTERNAL_SSSE3(cpu_flags)) {
         c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_ssse3;
         c->rv40_weight_pixels_tab[0][1] = ff_rv40_weight_func_rnd_8_ssse3;
         c->rv40_weight_pixels_tab[1][0] = ff_rv40_weight_func_nornd_16_ssse3;
diff --git a/libavcodec/x86/sbrdsp.asm b/libavcodec/x86/sbrdsp.asm
index 1ce5777..fc519bf 100644
--- a/libavcodec/x86/sbrdsp.asm
+++ b/libavcodec/x86/sbrdsp.asm
@@ -252,36 +252,36 @@
 ; sbr_qmf_deint_bfly(float *v, const float *src0, const float *src1)
 %macro SBR_QMF_DEINT_BFLY  0
 cglobal sbr_qmf_deint_bfly, 3,5,8, v,src0,src1,vrev,c
-    mov        cq, 64*4-2*mmsize
-    lea     vrevq, [vq + 64*4]
+    mov               cq, 64*4-2*mmsize
+    lea            vrevq, [vq + 64*4]
 .loop:
-    mova       m0, [src0q+cq]
-    mova       m1, [src1q]
-    mova       m4, [src0q+cq+mmsize]
-    mova       m5, [src1q+mmsize]
+    mova              m0, [src0q+cq]
+    mova              m1, [src1q]
+    mova              m4, [src0q+cq+mmsize]
+    mova              m5, [src1q+mmsize]
 %if cpuflag(sse2)
-    pshufd     m2, m0, q0123
-    pshufd     m3, m1, q0123
-    pshufd     m6, m4, q0123
-    pshufd     m7, m5, q0123
+    pshufd            m2, m0, q0123
+    pshufd            m3, m1, q0123
+    pshufd            m6, m4, q0123
+    pshufd            m7, m5, q0123
 %else
-    shufps     m2, m0, m0, q0123
-    shufps     m3, m1, m1, q0123
-    shufps     m6, m4, m4, q0123
-    shufps     m7, m5, m5, q0123
+    shufps            m2, m0, m0, q0123
+    shufps            m3, m1, m1, q0123
+    shufps            m6, m4, m4, q0123
+    shufps            m7, m5, m5, q0123
 %endif
-    addps      m5, m2
-    subps      m0, m7
-    addps      m1, m6
-    subps      m4, m3
-    mova  [vrevq], m1
+    addps             m5, m2
+    subps             m0, m7
+    addps             m1, m6
+    subps             m4, m3
+    mova         [vrevq], m1
     mova  [vrevq+mmsize], m5
-    mova  [vq+cq], m0
+    mova         [vq+cq], m0
     mova  [vq+cq+mmsize], m4
-    add     src1q, 2*mmsize
-    add     vrevq, 2*mmsize
-    sub        cq, 2*mmsize
-    jge     .loop
+    add            src1q, 2*mmsize
+    add            vrevq, 2*mmsize
+    sub               cq, 2*mmsize
+    jge            .loop
     REP_RET
 %endmacro
 
@@ -292,23 +292,23 @@
 SBR_QMF_DEINT_BFLY
 
 INIT_XMM sse2
-cglobal sbr_qmf_pre_shuffle, 1,4,7,z
+cglobal sbr_qmf_pre_shuffle, 1,4,6,z
 %define OFFSET  (32*4-2*mmsize)
     mov       r3q, OFFSET
     lea       r1q, [zq + (32+1)*4]
     lea       r2q, [zq + 64*4]
-    mova       m6, [ps_neg]
+    mova       m5, [ps_neg]
 .loop:
     movu       m0, [r1q]
     movu       m2, [r1q + mmsize]
     movu       m1, [zq + r3q + 4 + mmsize]
     movu       m3, [zq + r3q + 4]
 
-    pxor       m2, m6
-    pxor       m0, m6
+    pxor       m2, m5
+    pxor       m0, m5
     pshufd     m2, m2, q0123
     pshufd     m0, m0, q0123
-    SBUTTERFLY dq, 2, 3, 5
+    SBUTTERFLY dq, 2, 3, 4
     SBUTTERFLY dq, 0, 1, 4
     mova  [r2q + 2*r3q + 0*mmsize], m2
     mova  [r2q + 2*r3q + 1*mmsize], m3
@@ -317,16 +317,10 @@
     add       r1q, 2*mmsize
     sub       r3q, 2*mmsize
     jge      .loop
-    mova       m2, [zq]
+    movq       m2, [zq]
     movq    [r2q], m2
     REP_RET
 
-%if WIN64 == 0
-
-%if WIN64
-%define NREGS 0
-%define NOISE_TABLE sbr_noise_table
-%else
 %ifdef PIC
 %define NREGS 1
 %if UNIX64
@@ -338,10 +332,9 @@
 %define NREGS 0
 %define NOISE_TABLE sbr_noise_table
 %endif
-%endif
 
 %macro LOAD_NST  1
-%if NREGS
+%ifdef PIC
     lea  NOISE_TABLE, [%1]
     mova          m0, [kxq + NOISE_TABLE]
 %else
@@ -390,7 +383,7 @@
 %endif
     dec    noiseq
     shl    count, 2
-%if NREGS
+%ifdef PIC
     lea NOISE_TABLE, [sbr_noise_table]
 %endif
     lea        Yq, [Yq + 2*count]
@@ -430,5 +423,3 @@
     add    count, mmsize
     jl      .loop
     RET
-
-%endif ; WIN64 == 0
diff --git a/libavcodec/x86/sbrdsp_init.c b/libavcodec/x86/sbrdsp_init.c
index 4eff496..0fbe534 100644
--- a/libavcodec/x86/sbrdsp_init.c
+++ b/libavcodec/x86/sbrdsp_init.c
@@ -53,9 +53,9 @@
 
 av_cold void ff_sbrdsp_init_x86(SBRDSPContext *s)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (EXTERNAL_SSE(mm_flags)) {
+    if (EXTERNAL_SSE(cpu_flags)) {
         s->neg_odd_64 = ff_sbr_neg_odd_64_sse;
         s->sum_square = ff_sbr_sum_square_sse;
         s->sum64x5    = ff_sbr_sum64x5_sse;
@@ -65,14 +65,12 @@
         s->qmf_deint_bfly   = ff_sbr_qmf_deint_bfly_sse;
     }
 
-    if (EXTERNAL_SSE2(mm_flags)) {
+    if (EXTERNAL_SSE2(cpu_flags)) {
         s->qmf_deint_bfly   = ff_sbr_qmf_deint_bfly_sse2;
         s->qmf_pre_shuffle  = ff_sbr_qmf_pre_shuffle_sse2;
-#if ARCH_X86_32 || !defined(_WIN32)
         s->hf_apply_noise[0] = ff_sbr_hf_apply_noise_0_sse2;
         s->hf_apply_noise[1] = ff_sbr_hf_apply_noise_1_sse2;
         s->hf_apply_noise[2] = ff_sbr_hf_apply_noise_2_sse2;
         s->hf_apply_noise[3] = ff_sbr_hf_apply_noise_3_sse2;
-#endif
     }
 }
diff --git a/libavcodec/x86/simple_idct.c b/libavcodec/x86/simple_idct.c
index f27d2b9..c790ef5 100644
--- a/libavcodec/x86/simple_idct.c
+++ b/libavcodec/x86/simple_idct.c
@@ -21,7 +21,7 @@
  */
 #include "libavcodec/simple_idct.h"
 #include "libavutil/mem.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 
 #if HAVE_INLINE_ASM
 
diff --git a/libavcodec/x86/snowdsp.c b/libavcodec/x86/snowdsp.c
index 5505ee8..735e790 100644
--- a/libavcodec/x86/snowdsp.c
+++ b/libavcodec/x86/snowdsp.c
@@ -24,7 +24,7 @@
 #include "libavcodec/avcodec.h"
 #include "libavcodec/snow.h"
 #include "libavcodec/snow_dwt.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 
 #if HAVE_INLINE_ASM
 
diff --git a/libavcodec/x86/vc1dsp_init.c b/libavcodec/x86/vc1dsp_init.c
index 228f4dc..2ee7699 100644
--- a/libavcodec/x86/vc1dsp_init.c
+++ b/libavcodec/x86/vc1dsp_init.c
@@ -27,7 +27,7 @@
 #include "libavutil/cpu.h"
 #include "libavutil/x86/cpu.h"
 #include "libavcodec/vc1dsp.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 #include "vc1dsp.h"
 #include "config.h"
 
@@ -83,12 +83,12 @@
 
 av_cold void ff_vc1dsp_init_x86(VC1DSPContext *dsp)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (INLINE_MMX(mm_flags))
+    if (INLINE_MMX(cpu_flags))
         ff_vc1dsp_init_mmx(dsp);
 
-    if (INLINE_MMXEXT(mm_flags))
+    if (INLINE_MMXEXT(cpu_flags))
         ff_vc1dsp_init_mmxext(dsp);
 
 #define ASSIGN_LF(EXT) \
@@ -100,31 +100,31 @@
         dsp->vc1_h_loop_filter16 = vc1_h_loop_filter16_ ## EXT
 
 #if HAVE_YASM
-    if (mm_flags & AV_CPU_FLAG_MMX) {
+    if (cpu_flags & AV_CPU_FLAG_MMX) {
         dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = ff_put_vc1_chroma_mc8_nornd_mmx;
     }
 
-    if (mm_flags & AV_CPU_FLAG_MMXEXT) {
+    if (cpu_flags & AV_CPU_FLAG_MMXEXT) {
         ASSIGN_LF(mmxext);
         dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_nornd_mmxext;
 
         dsp->avg_vc1_mspel_pixels_tab[0]         = avg_vc1_mspel_mc00_mmxext;
-    } else if (mm_flags & AV_CPU_FLAG_3DNOW) {
+    } else if (cpu_flags & AV_CPU_FLAG_3DNOW) {
         dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_nornd_3dnow;
     }
 
-    if (mm_flags & AV_CPU_FLAG_SSE2) {
+    if (cpu_flags & AV_CPU_FLAG_SSE2) {
         dsp->vc1_v_loop_filter8  = ff_vc1_v_loop_filter8_sse2;
         dsp->vc1_h_loop_filter8  = ff_vc1_h_loop_filter8_sse2;
         dsp->vc1_v_loop_filter16 = vc1_v_loop_filter16_sse2;
         dsp->vc1_h_loop_filter16 = vc1_h_loop_filter16_sse2;
     }
-    if (mm_flags & AV_CPU_FLAG_SSSE3) {
+    if (cpu_flags & AV_CPU_FLAG_SSSE3) {
         ASSIGN_LF(ssse3);
         dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = ff_put_vc1_chroma_mc8_nornd_ssse3;
         dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_nornd_ssse3;
     }
-    if (mm_flags & AV_CPU_FLAG_SSE4) {
+    if (cpu_flags & AV_CPU_FLAG_SSE4) {
         dsp->vc1_h_loop_filter8  = ff_vc1_h_loop_filter8_sse4;
         dsp->vc1_h_loop_filter16 = vc1_h_loop_filter16_sse4;
     }
diff --git a/libavcodec/x86/vc1dsp_mmx.c b/libavcodec/x86/vc1dsp_mmx.c
index 92f3e20..5ceacd3 100644
--- a/libavcodec/x86/vc1dsp_mmx.c
+++ b/libavcodec/x86/vc1dsp_mmx.c
@@ -28,8 +28,9 @@
 #include "libavutil/mem.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
-#include "dsputil_mmx.h"
 #include "libavcodec/vc1dsp.h"
+#include "constants.h"
+#include "dsputil_x86.h"
 #include "vc1dsp.h"
 
 #if HAVE_INLINE_ASM
@@ -698,9 +699,15 @@
     );
 }
 
+static void put_vc1_mspel_mc00_mmx(uint8_t *dst, const uint8_t *src,
+                                   ptrdiff_t stride, int rnd)
+{
+    ff_put_pixels8_mmx(dst, src, stride, 8);
+}
+
 av_cold void ff_vc1dsp_init_mmx(VC1DSPContext *dsp)
 {
-    dsp->put_vc1_mspel_pixels_tab[ 0] = ff_put_vc1_mspel_mc00_mmx;
+    dsp->put_vc1_mspel_pixels_tab[ 0] = put_vc1_mspel_mc00_mmx;
     dsp->put_vc1_mspel_pixels_tab[ 4] = put_vc1_mspel_mc01_mmx;
     dsp->put_vc1_mspel_pixels_tab[ 8] = put_vc1_mspel_mc02_mmx;
     dsp->put_vc1_mspel_pixels_tab[12] = put_vc1_mspel_mc03_mmx;
diff --git a/libavcodec/x86/videodsp_init.c b/libavcodec/x86/videodsp_init.c
index 902450e..9d3d6ca 100644
--- a/libavcodec/x86/videodsp_init.c
+++ b/libavcodec/x86/videodsp_init.c
@@ -108,20 +108,20 @@
 av_cold void ff_videodsp_init_x86(VideoDSPContext *ctx, int bpc)
 {
 #if HAVE_YASM
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
 #if ARCH_X86_32
-    if (bpc <= 8 && mm_flags & AV_CPU_FLAG_MMX) {
+    if (bpc <= 8 && cpu_flags & AV_CPU_FLAG_MMX) {
         ctx->emulated_edge_mc = emulated_edge_mc_mmx;
     }
-    if (mm_flags & AV_CPU_FLAG_3DNOW) {
+    if (cpu_flags & AV_CPU_FLAG_3DNOW) {
         ctx->prefetch = ff_prefetch_3dnow;
     }
 #endif /* ARCH_X86_32 */
-    if (mm_flags & AV_CPU_FLAG_MMXEXT) {
+    if (cpu_flags & AV_CPU_FLAG_MMXEXT) {
         ctx->prefetch = ff_prefetch_mmxext;
     }
-    if (bpc <= 8 && mm_flags & AV_CPU_FLAG_SSE) {
+    if (bpc <= 8 && cpu_flags & AV_CPU_FLAG_SSE) {
         ctx->emulated_edge_mc = emulated_edge_mc_sse;
     }
 #endif /* HAVE_YASM */
diff --git a/libavcodec/x86/vorbisdsp_init.c b/libavcodec/x86/vorbisdsp_init.c
index 08a2c09..cd3971b 100644
--- a/libavcodec/x86/vorbisdsp_init.c
+++ b/libavcodec/x86/vorbisdsp_init.c
@@ -31,13 +31,13 @@
 av_cold void ff_vorbisdsp_init_x86(VorbisDSPContext *dsp)
 {
 #if HAVE_YASM
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
 #if ARCH_X86_32
-    if (mm_flags & AV_CPU_FLAG_3DNOW)
+    if (cpu_flags & AV_CPU_FLAG_3DNOW)
         dsp->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_3dnow;
 #endif /* ARCH_X86_32 */
-    if (mm_flags & AV_CPU_FLAG_SSE)
+    if (cpu_flags & AV_CPU_FLAG_SSE)
         dsp->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_sse;
 #endif /* HAVE_YASM */
 }
diff --git a/libavcodec/x86/vp3dsp_init.c b/libavcodec/x86/vp3dsp_init.c
index 252b40a..1f02a6f 100644
--- a/libavcodec/x86/vp3dsp_init.c
+++ b/libavcodec/x86/vp3dsp_init.c
@@ -43,7 +43,7 @@
 void ff_vp3_h_loop_filter_mmxext(uint8_t *src, int stride,
                                  int *bounding_values);
 
-#if HAVE_INLINE_ASM
+#if HAVE_MMX_INLINE
 
 #define MOVQ_BFE(regd)                                  \
     __asm__ volatile (                                  \
@@ -95,24 +95,24 @@
         :"memory");
 //    STOP_TIMER("put_vp_no_rnd_pixels8_l2_mmx")
 }
-#endif /* HAVE_INLINE_ASM */
+#endif /* HAVE_MMX_INLINE */
 
 av_cold void ff_vp3dsp_init_x86(VP3DSPContext *c, int flags)
 {
-    int cpuflags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-#if HAVE_INLINE_ASM
+#if HAVE_MMX_INLINE
     c->put_no_rnd_pixels_l2 = put_vp_no_rnd_pixels8_l2_mmx;
-#endif /* HAVE_INLINE_ASM */
+#endif /* HAVE_MMX_INLINE */
 
 #if ARCH_X86_32
-    if (EXTERNAL_MMX(cpuflags)) {
+    if (EXTERNAL_MMX(cpu_flags)) {
         c->idct_put  = ff_vp3_idct_put_mmx;
         c->idct_add  = ff_vp3_idct_add_mmx;
     }
 #endif
 
-    if (EXTERNAL_MMXEXT(cpuflags)) {
+    if (EXTERNAL_MMXEXT(cpu_flags)) {
         c->idct_dc_add = ff_vp3_idct_dc_add_mmxext;
 
         if (!(flags & CODEC_FLAG_BITEXACT)) {
@@ -121,7 +121,7 @@
         }
     }
 
-    if (EXTERNAL_SSE2(cpuflags)) {
+    if (EXTERNAL_SSE2(cpu_flags)) {
         c->idct_put  = ff_vp3_idct_put_sse2;
         c->idct_add  = ff_vp3_idct_add_sse2;
     }
diff --git a/libavcodec/x86/vp56dsp_init.c b/libavcodec/x86/vp56dsp_init.c
index defc63b..09bdb10 100644
--- a/libavcodec/x86/vp56dsp_init.c
+++ b/libavcodec/x86/vp56dsp_init.c
@@ -32,16 +32,16 @@
 
 av_cold void ff_vp56dsp_init_x86(VP56DSPContext* c, enum AVCodecID codec)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
     if (CONFIG_VP6_DECODER && codec == AV_CODEC_ID_VP6) {
 #if ARCH_X86_32
-        if (EXTERNAL_MMX(mm_flags)) {
+        if (EXTERNAL_MMX(cpu_flags)) {
             c->vp6_filter_diag4 = ff_vp6_filter_diag4_mmx;
         }
 #endif
 
-        if (EXTERNAL_SSE2(mm_flags)) {
+        if (EXTERNAL_SSE2(cpu_flags)) {
             c->vp6_filter_diag4 = ff_vp6_filter_diag4_sse2;
         }
     }
diff --git a/libavcodec/x86/vp8dsp_init.c b/libavcodec/x86/vp8dsp_init.c
index 745d95a..14ce141 100644
--- a/libavcodec/x86/vp8dsp_init.c
+++ b/libavcodec/x86/vp8dsp_init.c
@@ -316,9 +316,9 @@
 av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c)
 {
 #if HAVE_YASM
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (mm_flags & AV_CPU_FLAG_MMX) {
+    if (cpu_flags & AV_CPU_FLAG_MMX) {
         c->vp8_idct_dc_add    = ff_vp8_idct_dc_add_mmx;
         c->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_mmx;
 #if ARCH_X86_32
@@ -349,7 +349,7 @@
 
     /* note that 4-tap width=16 functions are missing because w=16
      * is only used for luma, and luma is always a copy or sixtap. */
-    if (mm_flags & AV_CPU_FLAG_MMXEXT) {
+    if (cpu_flags & AV_CPU_FLAG_MMXEXT) {
         VP8_MC_FUNC(2, 4, mmxext);
         VP8_BILINEAR_MC_FUNC(2, 4, mmxext);
 #if ARCH_X86_32
@@ -373,14 +373,14 @@
 #endif
     }
 
-    if (mm_flags & AV_CPU_FLAG_SSE) {
+    if (cpu_flags & AV_CPU_FLAG_SSE) {
         c->vp8_idct_add                         = ff_vp8_idct_add_sse;
         c->vp8_luma_dc_wht                      = ff_vp8_luma_dc_wht_sse;
         c->put_vp8_epel_pixels_tab[0][0][0]     =
         c->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_sse;
     }
 
-    if (mm_flags & (AV_CPU_FLAG_SSE2|AV_CPU_FLAG_SSE2SLOW)) {
+    if (cpu_flags & (AV_CPU_FLAG_SSE2 | AV_CPU_FLAG_SSE2SLOW)) {
         VP8_LUMA_MC_FUNC(0, 16, sse2);
         VP8_MC_FUNC(1, 8, sse2);
         VP8_BILINEAR_MC_FUNC(0, 16, sse2);
@@ -395,7 +395,7 @@
         c->vp8_v_loop_filter8uv       = ff_vp8_v_loop_filter8uv_mbedge_sse2;
     }
 
-    if (mm_flags & AV_CPU_FLAG_SSE2) {
+    if (cpu_flags & AV_CPU_FLAG_SSE2) {
         c->vp8_idct_dc_add4y          = ff_vp8_idct_dc_add4y_sse2;
 
         c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_sse2;
@@ -407,7 +407,7 @@
         c->vp8_h_loop_filter8uv       = ff_vp8_h_loop_filter8uv_mbedge_sse2;
     }
 
-    if (mm_flags & AV_CPU_FLAG_SSSE3) {
+    if (cpu_flags & AV_CPU_FLAG_SSSE3) {
         VP8_LUMA_MC_FUNC(0, 16, ssse3);
         VP8_MC_FUNC(1, 8, ssse3);
         VP8_MC_FUNC(2, 4, ssse3);
@@ -429,7 +429,7 @@
         c->vp8_h_loop_filter8uv       = ff_vp8_h_loop_filter8uv_mbedge_ssse3;
     }
 
-    if (mm_flags & AV_CPU_FLAG_SSE4) {
+    if (cpu_flags & AV_CPU_FLAG_SSE4) {
         c->vp8_idct_dc_add                  = ff_vp8_idct_dc_add_sse4;
 
         c->vp8_h_loop_filter_simple   = ff_vp8_h_loop_filter_simple_sse4;
diff --git a/libavcodec/xbmdec.c b/libavcodec/xbmdec.c
index 24fe550..6b189c0 100644
--- a/libavcodec/xbmdec.c
+++ b/libavcodec/xbmdec.c
@@ -57,7 +57,7 @@
         int number, len;
 
         ptr += strcspn(ptr, "#");
-        if (sscanf(ptr, "#define %256s %u", name, &number) != 2) {
+        if (sscanf(ptr, "#define %255s %u", name, &number) != 2) {
             av_log(avctx, AV_LOG_ERROR, "Unexpected preprocessor directive\n");
             return AVERROR_INVALIDDATA;
         }
diff --git a/libavcodec/xl.c b/libavcodec/xl.c
index f50b650..ff62a0f 100644
--- a/libavcodec/xl.c
+++ b/libavcodec/xl.c
@@ -41,19 +41,18 @@
                         AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    AVFrame * const p = data;
+    int buf_size       = avpkt->size;
+    AVFrame *const p   = data;
     uint8_t *Y, *U, *V;
     int i, j, ret;
     int stride;
     uint32_t val;
     int y0, y1, y2, y3 = 0, c0 = 0, c1 = 0;
 
-    if (avctx->width & 3) {
+    if (avctx->width % 4) {
         av_log(avctx, AV_LOG_ERROR, "width is not a multiple of 4\n");
         return AVERROR_INVALIDDATA;
     }
-
     if (buf_size < avctx->width * avctx->height) {
         av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
         return AVERROR_INVALIDDATA;
@@ -76,27 +75,27 @@
 
         for (j = 0; j < avctx->width; j += 4) {
             /* value is stored in LE dword with word swapped */
-            val = AV_RL32(buf);
+            val  = AV_RL32(buf);
             buf -= 4;
-            val = ((val >> 16) & 0xFFFF) | ((val & 0xFFFF) << 16);
+            val  = ((val >> 16) & 0xFFFF) | ((val & 0xFFFF) << 16);
 
-            if(!j)
+            if (!j)
                 y0 = (val & 0x1F) << 2;
             else
                 y0 = y3 + xl_table[val & 0x1F];
             val >>= 5;
-            y1 = y0 + xl_table[val & 0x1F];
+            y1    = y0 + xl_table[val & 0x1F];
             val >>= 5;
-            y2 = y1 + xl_table[val & 0x1F];
+            y2    = y1 + xl_table[val & 0x1F];
             val >>= 6; /* align to word */
-            y3 = y2 + xl_table[val & 0x1F];
+            y3    = y2 + xl_table[val & 0x1F];
             val >>= 5;
-            if(!j)
+            if (!j)
                 c0 = (val & 0x1F) << 2;
             else
                 c0 += xl_table[val & 0x1F];
             val >>= 5;
-            if(!j)
+            if (!j)
                 c1 = (val & 0x1F) << 2;
             else
                 c1 += xl_table[val & 0x1F];
@@ -111,9 +110,9 @@
         }
 
         buf += avctx->width + 4;
-        Y += p->linesize[0];
-        U += p->linesize[1];
-        V += p->linesize[2];
+        Y   += p->linesize[0];
+        U   += p->linesize[1];
+        V   += p->linesize[2];
     }
 
     *got_frame = 1;
@@ -129,11 +128,11 @@
 }
 
 AVCodec ff_xl_decoder = {
-    .name           = "xl",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_VIXL,
-    .init           = decode_init,
-    .decode         = decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Miro VideoXL"),
+    .name         = "xl",
+    .type         = AVMEDIA_TYPE_VIDEO,
+    .id           = AV_CODEC_ID_VIXL,
+    .init         = decode_init,
+    .decode       = decode_frame,
+    .capabilities = CODEC_CAP_DR1,
+    .long_name    = NULL_IF_CONFIG_SMALL("Miro VideoXL"),
 };
diff --git a/libavcodec/xsubenc.c b/libavcodec/xsubenc.c
index cb2a908..a644edf 100644
--- a/libavcodec/xsubenc.c
+++ b/libavcodec/xsubenc.c
@@ -190,7 +190,7 @@
                         h->rects[0]->w, h->rects[0]->h >> 1))
         return -1;
 
-    // Enforce total height to be be multiple of 2
+    // Enforce total height to be a multiple of 2
     if (h->rects[0]->h & 1) {
         put_xsub_rle(&pb, h->rects[0]->w, PADDING_COLOR);
         avpriv_align_put_bits(&pb);
diff --git a/libavcodec/xwdenc.c b/libavcodec/xwdenc.c
index 9d0da29..e98de5e 100644
--- a/libavcodec/xwdenc.c
+++ b/libavcodec/xwdenc.c
@@ -43,7 +43,7 @@
     AVFrame * const p = (AVFrame *)pict;
 
     pixdepth = av_get_bits_per_pixel(desc);
-    if (desc->flags & PIX_FMT_BE)
+    if (desc->flags & AV_PIX_FMT_FLAG_BE)
         be = 1;
     switch (pix_fmt) {
     case AV_PIX_FMT_ARGB:
diff --git a/libavcodec/yop.c b/libavcodec/yop.c
index 807e170..6315add 100644
--- a/libavcodec/yop.c
+++ b/libavcodec/yop.c
@@ -118,6 +118,8 @@
     }
 
     s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
 
     return 0;
 }
diff --git a/libavcodec/zmbv.c b/libavcodec/zmbv.c
index 7f3b326..905c4cc 100644
--- a/libavcodec/zmbv.c
+++ b/libavcodec/zmbv.c
@@ -28,6 +28,7 @@
 #include <stdlib.h>
 
 #include "libavutil/common.h"
+#include "libavutil/imgutils.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "internal.h"
@@ -493,7 +494,7 @@
         c->bx = (c->width + c->bw - 1) / c->bw;
         c->by = (c->height+ c->bh - 1) / c->bh;
         if (!c->cur || !c->prev)
-            return -1;
+            return AVERROR(ENOMEM);
         memset(c->cur, 0, avctx->width * avctx->height * (c->bpp / 8));
         memset(c->prev, 0, avctx->width * avctx->height * (c->bpp / 8));
         c->decode_intra= decode_intra;
@@ -554,11 +555,8 @@
         case ZMBV_FMT_24BPP:
 #endif
         case ZMBV_FMT_32BPP:
-            for (j = 0; j < c->height; j++) {
-                memcpy(out, src, c->stride);
-                src += c->stride;
-                out += frame->linesize[0];
-            }
+            av_image_copy_plane(out, frame->linesize[0], src, c->stride,
+                                c->stride, c->height);
             break;
         default:
             av_log(avctx, AV_LOG_ERROR, "Cannot handle format %i\n", c->fmt);
diff --git a/libavcodec/zmbvenc.c b/libavcodec/zmbvenc.c
index fb782a4..b634e5a 100644
--- a/libavcodec/zmbvenc.c
+++ b/libavcodec/zmbvenc.c
@@ -44,8 +44,6 @@
  */
 typedef struct ZmbvEncContext {
     AVCodecContext *avctx;
-    AVFrame pic;
-
     int range;
     uint8_t *comp_buf, *work_buf;
     uint8_t pal[768];
@@ -121,7 +119,7 @@
                         const AVFrame *pict, int *got_packet)
 {
     ZmbvEncContext * const c = avctx->priv_data;
-    AVFrame * const p = &c->pic;
+    AVFrame * const p = (AVFrame *)pict;
     uint8_t *src, *prev, *buf;
     uint32_t *palptr;
     int keyframe, chpal;
@@ -134,7 +132,6 @@
     c->curfrm++;
     if(c->curfrm == c->keyint)
         c->curfrm = 0;
-    *p = *pict;
     p->pict_type= keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
     p->key_frame= keyframe;
     chpal = !keyframe && memcmp(p->data[1], c->pal2, 1024);
@@ -312,8 +309,6 @@
         return -1;
     }
 
-    avctx->coded_frame = &c->pic;
-
     return 0;
 }
 
diff --git a/libavdevice/Makefile b/libavdevice/Makefile
index efffa8b..424ce98 100644
--- a/libavdevice/Makefile
+++ b/libavdevice/Makefile
@@ -10,6 +10,8 @@
 OBJS    = alldevices.o                                                  \
           avdevice.o                                                    \
 
+OBJS-$(HAVE_MSVCRT) += file_open.o
+
 # input/output devices
 OBJS-$(CONFIG_ALSA_INDEV)                += alsa-audio-common.o \
                                             alsa-audio-dec.o timefilter.o
@@ -32,16 +34,20 @@
 OBJS-$(CONFIG_SDL_OUTDEV)                += sdl.o
 OBJS-$(CONFIG_SNDIO_INDEV)               += sndio_common.o sndio_dec.o
 OBJS-$(CONFIG_SNDIO_OUTDEV)              += sndio_common.o sndio_enc.o
-OBJS-$(CONFIG_V4L2_INDEV)                += v4l2.o timefilter.o
+OBJS-$(CONFIG_V4L2_INDEV)                += v4l2.o v4l2-common.o timefilter.o
+OBJS-$(CONFIG_V4L2_OUTDEV)               += v4l2enc.o v4l2-common.o
 OBJS-$(CONFIG_V4L_INDEV)                 += v4l.o
 OBJS-$(CONFIG_VFWCAP_INDEV)              += vfwcap.o
 OBJS-$(CONFIG_X11GRAB_INDEV)             += x11grab.o
+OBJS-$(CONFIG_XV_OUTDEV)                 += xv.o
 
 # external libraries
 OBJS-$(CONFIG_LIBCDIO_INDEV)             += libcdio.o
 OBJS-$(CONFIG_LIBDC1394_INDEV)           += libdc1394.o
 
 SKIPHEADERS-$(CONFIG_DSHOW_INDEV)        += dshow_capture.h
+SKIPHEADERS-$(CONFIG_V4L2_INDEV)         += v4l2-common.h
+SKIPHEADERS-$(CONFIG_V4L2_OUTDEV)        += v4l2-common.h
 SKIPHEADERS-$(HAVE_ALSA_ASOUNDLIB_H)     += alsa-audio.h
 SKIPHEADERS-$(HAVE_SNDIO_H)              += sndio_common.h
 
diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c
index daa6638..fc8d3ce 100644
--- a/libavdevice/alldevices.c
+++ b/libavdevice/alldevices.c
@@ -60,10 +60,11 @@
     REGISTER_INDEV   (PULSE,            pulse);
     REGISTER_OUTDEV  (SDL,              sdl);
     REGISTER_INOUTDEV(SNDIO,            sndio);
-    REGISTER_INDEV   (V4L2,             v4l2);
+    REGISTER_INOUTDEV(V4L2,             v4l2);
 //    REGISTER_INDEV   (V4L,              v4l
     REGISTER_INDEV   (VFWCAP,           vfwcap);
     REGISTER_INDEV   (X11GRAB,          x11grab);
+    REGISTER_OUTDEV  (XV,               xv);
 
     /* external libraries */
     REGISTER_INDEV   (LIBCDIO,          libcdio);
diff --git a/libavdevice/bktr.c b/libavdevice/bktr.c
index b0dbe60..4e25aa6 100644
--- a/libavdevice/bktr.c
+++ b/libavdevice/bktr.c
@@ -25,6 +25,7 @@
  */
 
 #include "libavformat/internal.h"
+#include "libavutil/internal.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
 #include "libavutil/parseutils.h"
@@ -135,11 +136,11 @@
     act.sa_handler = catchsignal;
     sigaction(SIGUSR1, &act, &old);
 
-    *tuner_fd = open("/dev/tuner0", O_RDONLY);
+    *tuner_fd = avpriv_open("/dev/tuner0", O_RDONLY);
     if (*tuner_fd < 0)
         av_log(NULL, AV_LOG_ERROR, "Warning. Tuner not opened, continuing: %s\n", strerror(errno));
 
-    *video_fd = open(video_device, O_RDONLY);
+    *video_fd = avpriv_open(video_device, O_RDONLY);
     if (*video_fd < 0) {
         av_log(NULL, AV_LOG_ERROR, "%s: %s\n", video_device, strerror(errno));
         return -1;
diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 8cc12f5..37efabe 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -183,7 +183,7 @@
 static int shall_we_drop(AVFormatContext *s)
 {
     struct dshow_ctx *ctx = s->priv_data;
-    const uint8_t dropscore[] = {62, 75, 87, 100};
+    static const uint8_t dropscore[] = {62, 75, 87, 100};
     const int ndropscores = FF_ARRAY_ELEMS(dropscore);
     unsigned int buffer_fullness = (ctx->curbufsize*100)/s->max_picture_buffer;
 
diff --git a/libavdevice/dv1394.c b/libavdevice/dv1394.c
index 5d94f5c..0af5ea5 100644
--- a/libavdevice/dv1394.c
+++ b/libavdevice/dv1394.c
@@ -27,6 +27,7 @@
 #include <sys/ioctl.h>
 #include <sys/mman.h>
 
+#include "libavutil/internal.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
 #include "avdevice.h"
@@ -88,7 +89,7 @@
         goto failed;
 
     /* Open and initialize DV1394 device */
-    dv->fd = open(context->filename, O_RDONLY);
+    dv->fd = avpriv_open(context->filename, O_RDONLY);
     if (dv->fd < 0) {
         av_log(context, AV_LOG_ERROR, "Failed to open DV interface: %s\n", strerror(errno));
         goto failed;
diff --git a/libavdevice/fbdev.c b/libavdevice/fbdev.c
index 30595bd..1156fb5 100644
--- a/libavdevice/fbdev.c
+++ b/libavdevice/fbdev.c
@@ -27,8 +27,6 @@
  * @see http://linux-fbdev.sourceforge.net/
  */
 
-/* #define DEBUG */
-
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
@@ -36,6 +34,7 @@
 #include <time.h>
 #include <linux/fb.h>
 
+#include "libavutil/internal.h"
 #include "libavutil/log.h"
 #include "libavutil/mem.h"
 #include "libavutil/opt.h"
@@ -59,6 +58,7 @@
     {  32,       3,           2,           8,            0,   AV_PIX_FMT_ABGR  },
     {  24,       0,           8,          16,            0,   AV_PIX_FMT_RGB24 },
     {  24,      16,           8,           0,            0,   AV_PIX_FMT_BGR24 },
+    {  16,      11,           5,           0,           16,   AV_PIX_FMT_RGB565 },
 };
 
 static enum AVPixelFormat get_pixfmt_from_fb_varinfo(struct fb_var_screeninfo *varinfo)
@@ -81,7 +81,6 @@
     AVClass *class;          ///< class for private options
     int frame_size;          ///< size in bytes of a grabbed frame
     AVRational framerate_q;  ///< framerate
-    char *framerate;         ///< framerate string set by a private option
     int64_t time_frame;      ///< time for the next frame to output (in 1/1000000 units)
 
     int fd;                  ///< framebuffer device file descriptor
@@ -102,12 +101,6 @@
     enum AVPixelFormat pix_fmt;
     int ret, flags = O_RDONLY;
 
-    ret = av_parse_video_rate(&fbdev->framerate_q, fbdev->framerate);
-    if (ret < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", fbdev->framerate);
-        return ret;
-    }
-
     if (!(st = avformat_new_stream(avctx, NULL)))
         return AVERROR(ENOMEM);
     avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in microseconds */
@@ -116,7 +109,7 @@
     if (avctx->flags & AVFMT_FLAG_NONBLOCK)
         flags |= O_NONBLOCK;
 
-    if ((fbdev->fd = open(avctx->filename, flags)) == -1) {
+    if ((fbdev->fd = avpriv_open(avctx->filename, flags)) == -1) {
         ret = AVERROR(errno);
         av_log(avctx, AV_LOG_ERROR,
                "Could not open framebuffer device '%s': %s\n",
@@ -247,7 +240,7 @@
 #define OFFSET(x) offsetof(FBDevContext, x)
 #define DEC AV_OPT_FLAG_DECODING_PARAM
 static const AVOption options[] = {
-    { "framerate","", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
+    { "framerate","", OFFSET(framerate_q), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, DEC },
     { NULL },
 };
 
diff --git a/libavdevice/file_open.c b/libavdevice/file_open.c
new file mode 100644
index 0000000..494a5d3
--- /dev/null
+++ b/libavdevice/file_open.c
@@ -0,0 +1 @@
+#include "libavutil/file_open.c"
diff --git a/libavdevice/lavfi.c b/libavdevice/lavfi.c
index c1c9cf5..559f721 100644
--- a/libavdevice/lavfi.c
+++ b/libavdevice/lavfi.c
@@ -60,7 +60,7 @@
 
     for (i = 0; i < n; i++) {
         const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(i);
-        if (!(desc->flags & PIX_FMT_HWACCEL))
+        if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
             count++;
     }
 
@@ -68,7 +68,7 @@
         return NULL;
     for (j = 0, i = 0; i < n; i++) {
         const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(i);
-        if (!(desc->flags & PIX_FMT_HWACCEL))
+        if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
             fmts[j++] = i;
     }
     fmts[j] = -1;
@@ -141,7 +141,7 @@
     if (!(lavfi->graph = avfilter_graph_alloc()))
         FAIL(AVERROR(ENOMEM));
 
-    if ((ret = avfilter_graph_parse(lavfi->graph, lavfi->graph_str,
+    if ((ret = avfilter_graph_parse_ptr(lavfi->graph, lavfi->graph_str,
                                     &input_links, &output_links, avctx)) < 0)
         FAIL(ret);
 
@@ -286,7 +286,7 @@
                                      30);
         } else if (link->type == AVMEDIA_TYPE_AUDIO) {
             st->codec->codec_id    = av_get_pcm_codec(link->format, -1);
-            st->codec->channels    = av_get_channel_layout_nb_channels(link->channel_layout);
+            st->codec->channels    = avfilter_link_get_channels(link);
             st->codec->sample_fmt  = link->format;
             st->codec->sample_rate = link->sample_rate;
             st->codec->time_base   = link->time_base;
diff --git a/libavdevice/oss_audio.c b/libavdevice/oss_audio.c
index aa40034..916908c 100644
--- a/libavdevice/oss_audio.c
+++ b/libavdevice/oss_audio.c
@@ -34,6 +34,7 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>
 
+#include "libavutil/internal.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
 #include "libavutil/time.h"
@@ -63,9 +64,9 @@
     char *flip = getenv("AUDIO_FLIP_LEFT");
 
     if (is_output)
-        audio_fd = open(audio_device, O_WRONLY);
+        audio_fd = avpriv_open(audio_device, O_WRONLY);
     else
-        audio_fd = open(audio_device, O_RDONLY);
+        audio_fd = avpriv_open(audio_device, O_RDONLY);
     if (audio_fd < 0) {
         av_log(s1, AV_LOG_ERROR, "%s: %s\n", audio_device, strerror(errno));
         return AVERROR(EIO);
diff --git a/libavdevice/timefilter.c b/libavdevice/timefilter.c
index ba2e54e..424e492 100644
--- a/libavdevice/timefilter.c
+++ b/libavdevice/timefilter.c
@@ -101,7 +101,7 @@
     for (n0 = 0; n0 < 40; n0 = 2 * n0 + 1) {
         for (n1 = 0; n1 < 10; n1 = 2 * n1 + 1) {
             double best_error = 1000000000;
-            double bestpar0   = 1;
+            double bestpar0   = n0 ? 1 : 100000;
             double bestpar1   = 1;
             int better, i;
 
@@ -150,7 +150,7 @@
             }
             ff_timefilter_destroy(tf);
 #else
-            printf(" [%f %f %9f]", bestpar0, bestpar1, best_error);
+            printf(" [%12f %11f %9f]", bestpar0, bestpar1, best_error);
 #endif
         }
         printf("\n");
diff --git a/libavdevice/v4l2-common.c b/libavdevice/v4l2-common.c
new file mode 100644
index 0000000..572f0ed
--- /dev/null
+++ b/libavdevice/v4l2-common.c
@@ -0,0 +1,96 @@
+/*
+ * 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
+ */
+
+#include "v4l2-common.h"
+
+const struct fmt_map avpriv_fmt_conversion_table[] = {
+    //ff_fmt              codec_id              v4l2_fmt
+    { AV_PIX_FMT_YUV420P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV420  },
+    { AV_PIX_FMT_YUV420P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YVU420  },
+    { AV_PIX_FMT_YUV422P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV422P },
+    { AV_PIX_FMT_YUYV422, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUYV    },
+    { AV_PIX_FMT_UYVY422, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_UYVY    },
+    { AV_PIX_FMT_YUV411P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV411P },
+    { AV_PIX_FMT_YUV410P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV410  },
+    { AV_PIX_FMT_YUV410P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YVU410  },
+    { AV_PIX_FMT_RGB555LE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB555  },
+    { AV_PIX_FMT_RGB555BE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB555X },
+    { AV_PIX_FMT_RGB565LE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB565  },
+    { AV_PIX_FMT_RGB565BE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB565X },
+    { AV_PIX_FMT_BGR24,   AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_BGR24   },
+    { AV_PIX_FMT_RGB24,   AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB24   },
+    { AV_PIX_FMT_BGR0,    AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_BGR32   },
+    { AV_PIX_FMT_0RGB,    AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB32   },
+    { AV_PIX_FMT_GRAY8,   AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_GREY    },
+#ifdef V4L2_PIX_FMT_Y16
+    { AV_PIX_FMT_GRAY16LE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_Y16     },
+#endif
+    { AV_PIX_FMT_NV12,    AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_NV12    },
+    { AV_PIX_FMT_NONE,    AV_CODEC_ID_MJPEG,    V4L2_PIX_FMT_MJPEG   },
+    { AV_PIX_FMT_NONE,    AV_CODEC_ID_MJPEG,    V4L2_PIX_FMT_JPEG    },
+#ifdef V4L2_PIX_FMT_H264
+    { AV_PIX_FMT_NONE,    AV_CODEC_ID_H264,     V4L2_PIX_FMT_H264    },
+#endif
+#ifdef V4L2_PIX_FMT_CPIA1
+    { AV_PIX_FMT_NONE,    AV_CODEC_ID_CPIA,     V4L2_PIX_FMT_CPIA1   },
+#endif
+    { AV_PIX_FMT_NONE,    AV_CODEC_ID_NONE,     0                    },
+};
+
+uint32_t avpriv_fmt_ff2v4l(enum AVPixelFormat pix_fmt, enum AVCodecID codec_id)
+{
+    int i;
+
+    for (i = 0; avpriv_fmt_conversion_table[i].codec_id != AV_CODEC_ID_NONE; i++) {
+        if ((codec_id == AV_CODEC_ID_NONE ||
+             avpriv_fmt_conversion_table[i].codec_id == codec_id) &&
+            (pix_fmt == AV_PIX_FMT_NONE ||
+             avpriv_fmt_conversion_table[i].ff_fmt == pix_fmt)) {
+            return avpriv_fmt_conversion_table[i].v4l2_fmt;
+        }
+    }
+
+    return 0;
+}
+
+enum AVPixelFormat avpriv_fmt_v4l2ff(uint32_t v4l2_fmt, enum AVCodecID codec_id)
+{
+    int i;
+
+    for (i = 0; avpriv_fmt_conversion_table[i].codec_id != AV_CODEC_ID_NONE; i++) {
+        if (avpriv_fmt_conversion_table[i].v4l2_fmt == v4l2_fmt &&
+            avpriv_fmt_conversion_table[i].codec_id == codec_id) {
+            return avpriv_fmt_conversion_table[i].ff_fmt;
+        }
+    }
+
+    return AV_PIX_FMT_NONE;
+}
+
+enum AVCodecID avpriv_fmt_v4l2codec(uint32_t v4l2_fmt)
+{
+    int i;
+
+    for (i = 0; avpriv_fmt_conversion_table[i].codec_id != AV_CODEC_ID_NONE; i++) {
+        if (avpriv_fmt_conversion_table[i].v4l2_fmt == v4l2_fmt) {
+            return avpriv_fmt_conversion_table[i].codec_id;
+        }
+    }
+
+    return AV_CODEC_ID_NONE;
+}
diff --git a/libavdevice/v4l2-common.h b/libavdevice/v4l2-common.h
new file mode 100644
index 0000000..8aef234
--- /dev/null
+++ b/libavdevice/v4l2-common.h
@@ -0,0 +1,62 @@
+/*
+ * 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
+ */
+
+#ifndef AVDEVICE_V4L2_COMMON_H
+#define AVDEVICE_V4L2_COMMON_H
+
+#undef __STRICT_ANSI__ //workaround due to broken kernel headers
+#include "config.h"
+#include "libavformat/internal.h"
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#if HAVE_SYS_VIDEOIO_H
+#include <sys/videoio.h>
+#else
+#if HAVE_ASM_TYPES_H
+#include <asm/types.h>
+#endif
+#include <linux/videodev2.h>
+#endif
+#include "libavutil/atomic.h"
+#include "libavutil/avassert.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+#include "avdevice.h"
+#include "timefilter.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/time.h"
+#include "libavutil/avstring.h"
+
+struct fmt_map {
+    enum AVPixelFormat ff_fmt;
+    enum AVCodecID codec_id;
+    uint32_t v4l2_fmt;
+};
+
+extern av_export const struct fmt_map avpriv_fmt_conversion_table[];
+
+uint32_t avpriv_fmt_ff2v4l(enum AVPixelFormat pix_fmt, enum AVCodecID codec_id);
+enum AVPixelFormat avpriv_fmt_v4l2ff(uint32_t v4l2_fmt, enum AVCodecID codec_id);
+enum AVCodecID avpriv_fmt_v4l2codec(uint32_t v4l2_fmt);
+
+#endif /* AVDEVICE_V4L2_COMMON_H */
diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index 34e3d9c..33668c1 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -30,44 +30,10 @@
  * V4L2_PIX_FMT_* and AV_PIX_FMT_*
  */
 
-#undef __STRICT_ANSI__ //workaround due to broken kernel headers
-#include "config.h"
-#include "libavformat/internal.h"
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/time.h>
-#if HAVE_SYS_VIDEOIO_H
-#include <sys/videoio.h>
-#else
-#if HAVE_ASM_TYPES_H
-#include <asm/types.h>
-#endif
-#include <linux/videodev2.h>
-#endif
-#include "libavutil/atomic.h"
-#include "libavutil/avassert.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/log.h"
-#include "libavutil/opt.h"
-#include "avdevice.h"
-#include "timefilter.h"
-#include "libavutil/parseutils.h"
-#include "libavutil/pixdesc.h"
-#include "libavutil/time.h"
-#include "libavutil/avstring.h"
+#include "v4l2-common.h"
 
 #if CONFIG_LIBV4L2
 #include <libv4l2.h>
-#else
-#define v4l2_open   open
-#define v4l2_close  close
-#define v4l2_dup    dup
-#define v4l2_ioctl  ioctl
-#define v4l2_read   read
-#define v4l2_mmap   mmap
-#define v4l2_munmap munmap
 #endif
 
 static const int desired_video_buffers = 256;
@@ -121,6 +87,15 @@
     int list_format;    /**< Set by a private option. */
     int list_standard;  /**< Set by a private option. */
     char *framerate;    /**< Set by a private option. */
+
+    int use_libv4l2;
+    int (*open_f)(const char *file, int oflag, ...);
+    int (*close_f)(int fd);
+    int (*dup_f)(int fd);
+    int (*ioctl_f)(int fd, unsigned long int request, ...);
+    ssize_t (*read_f)(int fd, void *buffer, size_t n);
+    void *(*mmap_f)(void *start, size_t length, int prot, int flags, int fd, int64_t offset);
+    int (*munmap_f)(void *_start, size_t length);
 };
 
 struct buff_data {
@@ -128,52 +103,43 @@
     int index;
 };
 
-struct fmt_map {
-    enum AVPixelFormat ff_fmt;
-    enum AVCodecID codec_id;
-    uint32_t v4l2_fmt;
-};
-
-static struct fmt_map fmt_conversion_table[] = {
-    //ff_fmt           codec_id           v4l2_fmt
-    { AV_PIX_FMT_YUV420P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV420  },
-    { AV_PIX_FMT_YUV420P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YVU420  },
-    { AV_PIX_FMT_YUV422P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV422P },
-    { AV_PIX_FMT_YUYV422, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUYV    },
-    { AV_PIX_FMT_UYVY422, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_UYVY    },
-    { AV_PIX_FMT_YUV411P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV411P },
-    { AV_PIX_FMT_YUV410P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV410  },
-    { AV_PIX_FMT_YUV410P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YVU410  },
-    { AV_PIX_FMT_RGB555LE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB555  },
-    { AV_PIX_FMT_RGB555BE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB555X },
-    { AV_PIX_FMT_RGB565LE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB565  },
-    { AV_PIX_FMT_RGB565BE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB565X },
-    { AV_PIX_FMT_BGR24,   AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_BGR24   },
-    { AV_PIX_FMT_RGB24,   AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB24   },
-    { AV_PIX_FMT_BGR0,    AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_BGR32   },
-    { AV_PIX_FMT_0RGB,    AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB32   },
-    { AV_PIX_FMT_GRAY8,   AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_GREY    },
-#ifdef V4L2_PIX_FMT_Y16
-    { AV_PIX_FMT_GRAY16LE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_Y16     },
-#endif
-    { AV_PIX_FMT_NV12,    AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_NV12    },
-    { AV_PIX_FMT_NONE,    AV_CODEC_ID_MJPEG,    V4L2_PIX_FMT_MJPEG   },
-    { AV_PIX_FMT_NONE,    AV_CODEC_ID_MJPEG,    V4L2_PIX_FMT_JPEG    },
-#ifdef V4L2_PIX_FMT_H264
-    { AV_PIX_FMT_NONE,    AV_CODEC_ID_H264,     V4L2_PIX_FMT_H264    },
-#endif
-#ifdef V4L2_PIX_FMT_CPIA1
-    { AV_PIX_FMT_NONE,    AV_CODEC_ID_CPIA,     V4L2_PIX_FMT_CPIA1   },
-#endif
-};
-
 static int device_open(AVFormatContext *ctx)
 {
+    struct video_data *s = ctx->priv_data;
     struct v4l2_capability cap;
     int fd;
     int ret;
     int flags = O_RDWR;
 
+#define SET_WRAPPERS(prefix) do {       \
+    s->open_f   = prefix ## open;       \
+    s->close_f  = prefix ## close;      \
+    s->dup_f    = prefix ## dup;        \
+    s->ioctl_f  = prefix ## ioctl;      \
+    s->read_f   = prefix ## read;       \
+    s->mmap_f   = prefix ## mmap;       \
+    s->munmap_f = prefix ## munmap;     \
+} while (0)
+
+    if (s->use_libv4l2) {
+#if CONFIG_LIBV4L2
+        SET_WRAPPERS(v4l2_);
+#else
+        av_log(ctx, AV_LOG_ERROR, "libavdevice is not build with libv4l2 support.\n");
+        return AVERROR(EINVAL);
+#endif
+    } else {
+        SET_WRAPPERS();
+    }
+
+#define v4l2_open   s->open_f
+#define v4l2_close  s->close_f
+#define v4l2_dup    s->dup_f
+#define v4l2_ioctl  s->ioctl_f
+#define v4l2_read   s->read_f
+#define v4l2_mmap   s->mmap_f
+#define v4l2_munmap s->munmap_f
+
     if (ctx->flags & AVFMT_FLAG_NONBLOCK) {
         flags |= O_NONBLOCK;
     }
@@ -259,7 +225,7 @@
     return res;
 }
 
-static int first_field(int fd)
+static int first_field(const struct video_data *s, int fd)
 {
     int res;
     v4l2_std_id std;
@@ -275,52 +241,10 @@
     return 1;
 }
 
-static uint32_t fmt_ff2v4l(enum AVPixelFormat pix_fmt, enum AVCodecID codec_id)
-{
-    int i;
-
-    for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
-        if ((codec_id == AV_CODEC_ID_NONE ||
-             fmt_conversion_table[i].codec_id == codec_id) &&
-            (pix_fmt == AV_PIX_FMT_NONE ||
-             fmt_conversion_table[i].ff_fmt == pix_fmt)) {
-            return fmt_conversion_table[i].v4l2_fmt;
-        }
-    }
-
-    return 0;
-}
-
-static enum AVPixelFormat fmt_v4l2ff(uint32_t v4l2_fmt, enum AVCodecID codec_id)
-{
-    int i;
-
-    for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
-        if (fmt_conversion_table[i].v4l2_fmt == v4l2_fmt &&
-            fmt_conversion_table[i].codec_id == codec_id) {
-            return fmt_conversion_table[i].ff_fmt;
-        }
-    }
-
-    return AV_PIX_FMT_NONE;
-}
-
-static enum AVCodecID fmt_v4l2codec(uint32_t v4l2_fmt)
-{
-    int i;
-
-    for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
-        if (fmt_conversion_table[i].v4l2_fmt == v4l2_fmt) {
-            return fmt_conversion_table[i].codec_id;
-        }
-    }
-
-    return AV_CODEC_ID_NONE;
-}
-
 #if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
 static void list_framesizes(AVFormatContext *ctx, int fd, uint32_t pixelformat)
 {
+    const struct video_data *s = ctx->priv_data;
     struct v4l2_frmsizeenum vfse = { .pixel_format = pixelformat };
 
     while(!v4l2_ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &vfse)) {
@@ -346,11 +270,12 @@
 
 static void list_formats(AVFormatContext *ctx, int fd, int type)
 {
+    const struct video_data *s = ctx->priv_data;
     struct v4l2_fmtdesc vfd = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
 
     while(!v4l2_ioctl(fd, VIDIOC_ENUM_FMT, &vfd)) {
-        enum AVCodecID codec_id = fmt_v4l2codec(vfd.pixelformat);
-        enum AVPixelFormat pix_fmt = fmt_v4l2ff(vfd.pixelformat, codec_id);
+        enum AVCodecID codec_id = avpriv_fmt_v4l2codec(vfd.pixelformat);
+        enum AVPixelFormat pix_fmt = avpriv_fmt_v4l2ff(vfd.pixelformat, codec_id);
 
         vfd.index++;
 
@@ -603,7 +528,7 @@
 
     /* Image is at s->buff_start[buf.index] */
     if (avpriv_atomic_int_get(&s->buffers_queued) == FFMAX(s->buffers / 8, 1)) {
-        /* when we start getting low on queued buffers, fallback to copying data */
+        /* when we start getting low on queued buffers, fall back on copying data */
         res = av_new_packet(pkt, buf.bytesused);
         if (res < 0) {
             av_log(ctx, AV_LOG_ERROR, "Error allocating a packet.\n");
@@ -626,7 +551,9 @@
         pkt->data     = s->buf_start[buf.index];
         pkt->size     = buf.bytesused;
 #if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
         pkt->destruct = dummy_release_buffer;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
         buf_descriptor = av_malloc(sizeof(struct buff_data));
@@ -825,7 +752,7 @@
 {
     int ret, i;
 
-    *desired_format = fmt_ff2v4l(pix_fmt, s1->video_codec_id);
+    *desired_format = avpriv_fmt_ff2v4l(pix_fmt, s1->video_codec_id);
 
     if (*desired_format) {
         ret = device_init(s1, width, height, *desired_format);
@@ -837,14 +764,14 @@
     }
 
     if (!*desired_format) {
-        for (i = 0; i<FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
+        for (i = 0; avpriv_fmt_conversion_table[i].codec_id != AV_CODEC_ID_NONE; i++) {
             if (s1->video_codec_id == AV_CODEC_ID_NONE ||
-                fmt_conversion_table[i].codec_id == s1->video_codec_id) {
+                avpriv_fmt_conversion_table[i].codec_id == s1->video_codec_id) {
                 av_log(s1, AV_LOG_DEBUG, "Trying to set codec:%s pix_fmt:%s\n",
-                       avcodec_get_name(fmt_conversion_table[i].codec_id),
-                       (char *)av_x_if_null(av_get_pix_fmt_name(fmt_conversion_table[i].ff_fmt), "none"));
+                       avcodec_get_name(avpriv_fmt_conversion_table[i].codec_id),
+                       (char *)av_x_if_null(av_get_pix_fmt_name(avpriv_fmt_conversion_table[i].ff_fmt), "none"));
 
-                *desired_format = fmt_conversion_table[i].v4l2_fmt;
+                *desired_format = avpriv_fmt_conversion_table[i].v4l2_fmt;
                 ret = device_init(s1, width, height, *desired_format);
                 if (ret >= 0)
                     break;
@@ -863,7 +790,7 @@
         }
     }
 
-    *codec_id = fmt_v4l2codec(*desired_format);
+    *codec_id = avpriv_fmt_v4l2codec(*desired_format);
     av_assert0(*codec_id != AV_CODEC_ID_NONE);
     return ret;
 }
@@ -885,7 +812,8 @@
 #if CONFIG_LIBV4L2
     /* silence libv4l2 logging. if fopen() fails v4l2_log_file will be NULL
        and errors will get sent to stderr */
-    v4l2_log_file = fopen("/dev/null", "w");
+    if (s->use_libv4l2)
+        v4l2_log_file = fopen("/dev/null", "w");
 #endif
 
     s->fd = device_open(s1);
@@ -986,7 +914,7 @@
     if ((res = v4l2_set_parameters(s1)) < 0)
         return res;
 
-    st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id);
+    st->codec->pix_fmt = avpriv_fmt_v4l2ff(desired_format, codec_id);
     s->frame_size =
         avpicture_get_size(st->codec->pix_fmt, s->width, s->height);
 
@@ -996,7 +924,7 @@
         return res;
     }
 
-    s->top_field_first = first_field(s->fd);
+    s->top_field_first = first_field(s, s->fd);
 
     st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
     st->codec->codec_id = codec_id;
@@ -1071,7 +999,7 @@
     { "default",      "use timestamps from the kernel",                           OFFSET(ts_mode),      AV_OPT_TYPE_CONST,  {.i64 = V4L_TS_DEFAULT  }, 0, 2, DEC, "timestamps" },
     { "abs",          "use absolute timestamps (wall clock)",                     OFFSET(ts_mode),      AV_OPT_TYPE_CONST,  {.i64 = V4L_TS_ABS      }, 0, 2, DEC, "timestamps" },
     { "mono2abs",     "force conversion from monotonic to absolute timestamps",   OFFSET(ts_mode),      AV_OPT_TYPE_CONST,  {.i64 = V4L_TS_MONO2ABS }, 0, 2, DEC, "timestamps" },
-
+    { "use_libv4l2",  "use libv4l2 (v4l-utils) convertion functions",             OFFSET(use_libv4l2),  AV_OPT_TYPE_INT,    {.i64 = 0}, 0, 1, DEC },
     { NULL },
 };
 
diff --git a/libavdevice/v4l2enc.c b/libavdevice/v4l2enc.c
new file mode 100644
index 0000000..21f0ef6
--- /dev/null
+++ b/libavdevice/v4l2enc.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2013 Clément Bœsch
+ *
+ * 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
+ */
+
+#include "v4l2-common.h"
+#include "avdevice.h"
+
+typedef struct {
+    int fd;
+} V4L2Context;
+
+static av_cold int write_header(AVFormatContext *s1)
+{
+    int res = 0, flags = O_RDWR;
+    struct v4l2_format fmt = {
+        .type = V4L2_BUF_TYPE_VIDEO_OUTPUT
+    };
+    V4L2Context *s = s1->priv_data;
+    AVCodecContext *enc_ctx;
+    uint32_t v4l2_pixfmt;
+
+    if (s1->flags & AVFMT_FLAG_NONBLOCK)
+        flags |= O_NONBLOCK;
+
+    s->fd = open(s1->filename, flags);
+    if (s->fd < 0) {
+        res = AVERROR(errno);
+        av_log(s1, AV_LOG_ERROR, "Unable to open V4L2 device '%s'\n", s1->filename);
+        return res;
+    }
+
+    if (s1->nb_streams != 1 ||
+        s1->streams[0]->codec->codec_type != AVMEDIA_TYPE_VIDEO ||
+        s1->streams[0]->codec->codec_id   != AV_CODEC_ID_RAWVIDEO) {
+        av_log(s1, AV_LOG_ERROR,
+               "V4L2 output device supports only a single raw video stream\n");
+        return AVERROR(EINVAL);
+    }
+
+    enc_ctx = s1->streams[0]->codec;
+
+    v4l2_pixfmt = avpriv_fmt_ff2v4l(enc_ctx->pix_fmt, AV_CODEC_ID_RAWVIDEO);
+    if (!v4l2_pixfmt) { // XXX: try to force them one by one?
+        av_log(s1, AV_LOG_ERROR, "Unknown V4L2 pixel format equivalent for %s\n",
+               av_get_pix_fmt_name(enc_ctx->pix_fmt));
+        return AVERROR(EINVAL);
+    }
+
+    if (ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
+        res = AVERROR(errno);
+        av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n", av_err2str(res));
+        return res;
+    }
+
+    fmt.fmt.pix.width       = enc_ctx->width;
+    fmt.fmt.pix.height      = enc_ctx->height;
+    fmt.fmt.pix.pixelformat = v4l2_pixfmt;
+    fmt.fmt.pix.sizeimage   = av_image_get_buffer_size(enc_ctx->pix_fmt, enc_ctx->width, enc_ctx->height, 1);
+
+    if (ioctl(s->fd, VIDIOC_S_FMT, &fmt) < 0) {
+        res = AVERROR(errno);
+        av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_S_FMT): %s\n", av_err2str(res));
+        return res;
+    }
+
+    return res;
+}
+
+static int write_packet(AVFormatContext *s1, AVPacket *pkt)
+{
+    const V4L2Context *s = s1->priv_data;
+    if (write(s->fd, pkt->data, pkt->size) == -1)
+        return AVERROR(errno);
+    return 0;
+}
+
+static int write_trailer(AVFormatContext *s1)
+{
+    const V4L2Context *s = s1->priv_data;
+    close(s->fd);
+    return 0;
+}
+
+AVOutputFormat ff_v4l2_muxer = {
+    .name           = "v4l2",
+    .long_name      = NULL_IF_CONFIG_SMALL("Video4Linux2 output device"),
+    .priv_data_size = sizeof(V4L2Context),
+    .audio_codec    = AV_CODEC_ID_NONE,
+    .video_codec    = AV_CODEC_ID_RAWVIDEO,
+    .write_header   = write_header,
+    .write_packet   = write_packet,
+    .write_trailer  = write_trailer,
+    .flags          = AVFMT_NOFILE,
+};
diff --git a/libavdevice/version.h b/libavdevice/version.h
index c03e733..1e18f51 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -28,7 +28,7 @@
 #include "libavutil/avutil.h"
 
 #define LIBAVDEVICE_VERSION_MAJOR  55
-#define LIBAVDEVICE_VERSION_MINOR   0
+#define LIBAVDEVICE_VERSION_MINOR   3
 #define LIBAVDEVICE_VERSION_MICRO 100
 
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
diff --git a/libavdevice/vfwcap.c b/libavdevice/vfwcap.c
index 66b02be..014f18c 100644
--- a/libavdevice/vfwcap.c
+++ b/libavdevice/vfwcap.c
@@ -155,7 +155,7 @@
 static int shall_we_drop(AVFormatContext *s)
 {
     struct vfw_ctx *ctx = s->priv_data;
-    const uint8_t dropscore[] = {62, 75, 87, 100};
+    static const uint8_t dropscore[] = {62, 75, 87, 100};
     const int ndropscores = FF_ARRAY_ELEMS(dropscore);
     unsigned int buffer_fullness = (ctx->curbufsize*100)/s->max_picture_buffer;
 
diff --git a/libavdevice/x11grab.c b/libavdevice/x11grab.c
index 6124006..eb23ec3 100644
--- a/libavdevice/x11grab.c
+++ b/libavdevice/x11grab.c
@@ -76,8 +76,9 @@
     int  draw_mouse;         /**< Set by a private option. */
     int  follow_mouse;       /**< Set by a private option. */
     int  show_region;        /**< set by a private option. */
-    char *framerate;         /**< Set by a private option. */
+    AVRational framerate;         /**< Set by a private option. */
 
+    Cursor c;
     Window region_win;       /**< This is used by show_region option. */
 };
 
@@ -166,7 +167,6 @@
     int use_shm;
     char *dpyname, *offset;
     int ret = 0;
-    AVRational framerate;
 
     dpyname = av_strdup(s1->filename);
     if (!dpyname)
@@ -184,10 +184,6 @@
         *offset= 0;
     }
 
-    if ((ret = av_parse_video_rate(&framerate, x11grab->framerate)) < 0) {
-        av_log(s1, AV_LOG_ERROR, "Could not parse framerate: %s.\n", x11grab->framerate);
-        goto out;
-    }
     av_log(s1, AV_LOG_INFO, "device: %s -> display: %s x: %d y: %d width: %d height: %d\n",
            s1->filename, dpyname, x_off, y_off, x11grab->width, x11grab->height);
 
@@ -308,7 +304,7 @@
 
     x11grab->frame_size = x11grab->width * x11grab->height * image->bits_per_pixel/8;
     x11grab->dpy = dpy;
-    x11grab->time_base  = av_inv_q(framerate);
+    x11grab->time_base  = av_inv_q(x11grab->framerate);
     x11grab->time_frame = av_gettime() / av_q2d(x11grab->time_base);
     x11grab->x_off = x_off;
     x11grab->y_off = y_off;
@@ -353,7 +349,6 @@
      * Anyone who performs further investigation of the xlib API likely risks
      * permanent brain damage. */
     uint8_t *pix = image->data;
-    Cursor c;
     Window w;
     XSetWindowAttributes attr;
 
@@ -361,9 +356,10 @@
     if (image->bits_per_pixel != 24 && image->bits_per_pixel != 32)
         return;
 
-    c = XCreateFontCursor(dpy, XC_left_ptr);
+    if(!s->c)
+        s->c = XCreateFontCursor(dpy, XC_left_ptr);
     w = DefaultRootWindow(dpy);
-    attr.cursor = c;
+    attr.cursor = s->c;
     XChangeWindowAttributes(dpy, w, CWCursor, &attr);
 
     xcim = XFixesGetCursorImage(dpy);
@@ -602,7 +598,7 @@
     { "centered",     "keep the mouse pointer at the center of grabbing region when following",
       0, AV_OPT_TYPE_CONST, {.i64 = -1}, INT_MIN, INT_MAX, DEC, "follow_mouse" },
 
-    { "framerate",  "set video frame rate",      OFFSET(framerate),   AV_OPT_TYPE_STRING,     {.str = "ntsc"}, 0, 0, DEC },
+    { "framerate",  "set video frame rate",      OFFSET(framerate),   AV_OPT_TYPE_VIDEO_RATE, {.str = "ntsc"}, 0, 0, DEC },
     { "show_region", "show the grabbing region", OFFSET(show_region), AV_OPT_TYPE_INT,        {.i64 = 0}, 0, 1, DEC },
     { "video_size",  "set video frame size",     OFFSET(width),       AV_OPT_TYPE_IMAGE_SIZE, {.str = "vga"}, 0, 0, DEC },
     { NULL },
diff --git a/libavdevice/xv.c b/libavdevice/xv.c
new file mode 100644
index 0000000..670c4de
--- /dev/null
+++ b/libavdevice/xv.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2013 Jeff Moguillansky
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * XVideo output device
+ *
+ * TODO:
+ * - add support to more formats
+ * - add support to window id specification
+ */
+
+#include <X11/Xlib.h>
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvlib.h>
+#include <X11/extensions/XShm.h>
+#include <sys/shm.h>
+
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "avdevice.h"
+
+typedef struct {
+    AVClass *class;
+    GC gc;
+
+    Window window;
+    char *window_title;
+    int window_width, window_height;
+    int window_x, window_y;
+
+    Display* display;
+    char *display_name;
+
+    XvImage* yuv_image;
+    int image_width, image_height;
+    XShmSegmentInfo yuv_shminfo;
+    int xv_port;
+} XVContext;
+
+static int xv_write_header(AVFormatContext *s)
+{
+    XVContext *xv = s->priv_data;
+    unsigned int num_adaptors;
+    XvAdaptorInfo *ai;
+    XvImageFormatValues *fv;
+    int num_formats = 0, j;
+    AVCodecContext *encctx = s->streams[0]->codec;
+
+    if (   s->nb_streams > 1
+        || encctx->codec_type != AVMEDIA_TYPE_VIDEO
+        || encctx->codec_id   != AV_CODEC_ID_RAWVIDEO) {
+        av_log(s, AV_LOG_ERROR, "Only supports one rawvideo stream\n");
+        return AVERROR(EINVAL);
+    }
+
+    xv->display = XOpenDisplay(xv->display_name);
+    if (!xv->display) {
+        av_log(s, AV_LOG_ERROR, "Could not open the X11 display '%s'\n", xv->display_name);
+        return AVERROR(EINVAL);
+    }
+
+    xv->image_width  = encctx->width;
+    xv->image_height = encctx->height;
+    if (!xv->window_width && !xv->window_height) {
+        xv->window_width  = encctx->width;
+        xv->window_height = encctx->height;
+    }
+    xv->window = XCreateSimpleWindow(xv->display, DefaultRootWindow(xv->display),
+                                     xv->window_x, xv->window_y,
+                                     xv->window_width, xv->window_height,
+                                     0, 0, 0);
+    if (!xv->window_title) {
+        if (!(xv->window_title = av_strdup(s->filename)))
+            return AVERROR(ENOMEM);
+    }
+    XStoreName(xv->display, xv->window, xv->window_title);
+    XMapWindow(xv->display, xv->window);
+
+    if (XvQueryAdaptors(xv->display, DefaultRootWindow(xv->display), &num_adaptors, &ai) != Success)
+        return AVERROR_EXTERNAL;
+    xv->xv_port = ai[0].base_id;
+
+    if (encctx->pix_fmt != AV_PIX_FMT_YUV420P) {
+        av_log(s, AV_LOG_ERROR,
+               "Unsupported pixel format '%s', only yuv420p is currently supported\n",
+               av_get_pix_fmt_name(encctx->pix_fmt));
+        return AVERROR_PATCHWELCOME;
+    }
+
+    fv = XvListImageFormats(xv->display, xv->xv_port, &num_formats);
+    if (!fv)
+        return AVERROR_EXTERNAL;
+    for (j = 0; j < num_formats; j++) {
+        if (fv[j].id == MKTAG('I','4','2','0')) {
+            break;
+        }
+    }
+    XFree(fv);
+
+    if (j >= num_formats) {
+        av_log(s, AV_LOG_ERROR,
+               "Device does not support pixel format yuv420p, aborting\n");
+        return AVERROR(EINVAL);
+    }
+
+    xv->gc = XCreateGC(xv->display, xv->window, 0, 0);
+    xv->image_width  = encctx->width;
+    xv->image_height = encctx->height;
+    xv->yuv_image = XvShmCreateImage(xv->display, xv->xv_port,
+                                     MKTAG('I','4','2','0'), 0,
+                                     xv->image_width, xv->image_height, &xv->yuv_shminfo);
+    xv->yuv_shminfo.shmid = shmget(IPC_PRIVATE, xv->yuv_image->data_size,
+                                   IPC_CREAT | 0777);
+    xv->yuv_shminfo.shmaddr = (char *)shmat(xv->yuv_shminfo.shmid, 0, 0);
+    xv->yuv_image->data = xv->yuv_shminfo.shmaddr;
+    xv->yuv_shminfo.readOnly = False;
+
+    XShmAttach(xv->display, &xv->yuv_shminfo);
+    XSync(xv->display, False);
+    shmctl(xv->yuv_shminfo.shmid, IPC_RMID, 0);
+
+    return 0;
+}
+
+static int xv_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    XVContext *xv = s->priv_data;
+    XvImage *img = xv->yuv_image;
+    XWindowAttributes window_attrs;
+    AVPicture pict;
+    AVCodecContext *ctx = s->streams[0]->codec;
+    int y, h;
+
+    h = img->height / 2;
+
+    avpicture_fill(&pict, pkt->data, ctx->pix_fmt, ctx->width, ctx->height);
+    for (y = 0; y < img->height; y++) {
+        memcpy(&img->data[img->offsets[0] + (y * img->pitches[0])],
+               &pict.data[0][y * pict.linesize[0]], img->pitches[0]);
+    }
+
+    for (y = 0; y < h; ++y) {
+        memcpy(&img->data[img->offsets[1] + (y * img->pitches[1])],
+               &pict.data[1][y * pict.linesize[1]], img->pitches[1]);
+        memcpy(&img->data[img->offsets[2] + (y * img->pitches[2])],
+               &pict.data[2][y * pict.linesize[2]], img->pitches[2]);
+    }
+
+    XGetWindowAttributes(xv->display, xv->window, &window_attrs);
+    if (XvShmPutImage(xv->display, xv->xv_port, xv->window, xv->gc,
+                      xv->yuv_image, 0, 0, xv->image_width, xv->image_height, 0, 0,
+                      window_attrs.width, window_attrs.height, True) != Success) {
+        av_log(s, AV_LOG_ERROR, "Could not copy image to XV shared memory buffer\n");
+        return AVERROR_EXTERNAL;
+    }
+    return 0;
+}
+
+static int xv_write_trailer(AVFormatContext *s)
+{
+    XVContext *xv = s->priv_data;
+
+    XShmDetach(xv->display, &xv->yuv_shminfo);
+    shmdt(xv->yuv_image->data);
+    XFree(xv->yuv_image);
+    XCloseDisplay(xv->display);
+    return 0;
+}
+
+#define OFFSET(x) offsetof(XVContext, x)
+static const AVOption options[] = {
+    { "display_name", "set display name",       OFFSET(display_name), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
+    { "window_size",  "set window forced size", OFFSET(window_width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
+    { "window_title", "set window title",       OFFSET(window_title), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
+    { "window_x",     "set window x offset",    OFFSET(window_x),     AV_OPT_TYPE_INT,    {.i64 = 0 }, -INT_MAX, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+    { "window_y",     "set window y offset",    OFFSET(window_y),     AV_OPT_TYPE_INT,    {.i64 = 0 }, -INT_MAX, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+    { NULL }
+
+};
+
+static const AVClass xv_class = {
+    .class_name = "xvideo outdev",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVOutputFormat ff_xv_muxer = {
+    .name           = "xv",
+    .long_name      = NULL_IF_CONFIG_SMALL("XV (XVideo) output device"),
+    .priv_data_size = sizeof(XVContext),
+    .audio_codec    = AV_CODEC_ID_NONE,
+    .video_codec    = AV_CODEC_ID_RAWVIDEO,
+    .write_header   = xv_write_header,
+    .write_packet   = xv_write_packet,
+    .write_trailer  = xv_write_trailer,
+    .flags          = AVFMT_NOFILE | AVFMT_VARIABLE_FPS | AVFMT_NOTIMESTAMPS,
+    .priv_class     = &xv_class,
+};
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 084bd30..3751d54 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -9,12 +9,14 @@
 FFLIBS-$(CONFIG_ATEMPO_FILTER)               += avcodec
 FFLIBS-$(CONFIG_DECIMATE_FILTER)             += avcodec
 FFLIBS-$(CONFIG_DESHAKE_FILTER)              += avcodec
+FFLIBS-$(CONFIG_MCDEINT_FILTER)              += avcodec
 FFLIBS-$(CONFIG_MOVIE_FILTER)                += avformat avcodec
 FFLIBS-$(CONFIG_MP_FILTER)                   += avcodec
 FFLIBS-$(CONFIG_PAN_FILTER)                  += swresample
 FFLIBS-$(CONFIG_PP_FILTER)                   += postproc
 FFLIBS-$(CONFIG_REMOVELOGO_FILTER)           += avformat avcodec swscale
 FFLIBS-$(CONFIG_RESAMPLE_FILTER)             += avresample
+FFLIBS-$(CONFIG_SAB_FILTER)                  += swscale
 FFLIBS-$(CONFIG_SCALE_FILTER)                += swscale
 FFLIBS-$(CONFIG_SHOWSPECTRUM_FILTER)         += avcodec
 FFLIBS-$(CONFIG_SMARTBLUR_FILTER)            += swscale
@@ -50,6 +52,7 @@
 OBJS-$(CONFIG_SWSCALE)                       += lswsutils.o
 
 OBJS-$(CONFIG_ACONVERT_FILTER)               += af_aconvert.o
+OBJS-$(CONFIG_AECHO_FILTER)                  += af_aecho.o
 OBJS-$(CONFIG_AFADE_FILTER)                  += af_afade.o
 OBJS-$(CONFIG_AFORMAT_FILTER)                += af_aformat.o
 OBJS-$(CONFIG_AINTERLEAVE_FILTER)            += f_interleave.o
@@ -64,20 +67,24 @@
 OBJS-$(CONFIG_ASELECT_FILTER)                += f_select.o
 OBJS-$(CONFIG_ASENDCMD_FILTER)               += f_sendcmd.o
 OBJS-$(CONFIG_ASETNSAMPLES_FILTER)           += af_asetnsamples.o
-OBJS-$(CONFIG_ASETPTS_FILTER)                += f_setpts.o
+OBJS-$(CONFIG_ASETPTS_FILTER)                += setpts.o
 OBJS-$(CONFIG_ASETRATE_FILTER)               += af_asetrate.o
 OBJS-$(CONFIG_ASETTB_FILTER)                 += f_settb.o
 OBJS-$(CONFIG_ASHOWINFO_FILTER)              += af_ashowinfo.o
 OBJS-$(CONFIG_ASPLIT_FILTER)                 += split.o
+OBJS-$(CONFIG_ASTATS_FILTER)                 += af_astats.o
 OBJS-$(CONFIG_ASTREAMSYNC_FILTER)            += af_astreamsync.o
 OBJS-$(CONFIG_ASYNCTS_FILTER)                += af_asyncts.o
 OBJS-$(CONFIG_ATEMPO_FILTER)                 += af_atempo.o
+OBJS-$(CONFIG_ATRIM_FILTER)                  += trim.o
+OBJS-$(CONFIG_AZMQ_FILTER)                   += f_zmq.o
 OBJS-$(CONFIG_BANDPASS_FILTER)               += af_biquads.o
 OBJS-$(CONFIG_BANDREJECT_FILTER)             += af_biquads.o
 OBJS-$(CONFIG_BASS_FILTER)                   += af_biquads.o
 OBJS-$(CONFIG_BIQUAD_FILTER)                 += af_biquads.o
 OBJS-$(CONFIG_CHANNELMAP_FILTER)             += af_channelmap.o
 OBJS-$(CONFIG_CHANNELSPLIT_FILTER)           += af_channelsplit.o
+OBJS-$(CONFIG_COMPAND_FILTER)                += af_compand.o
 OBJS-$(CONFIG_EARWAX_FILTER)                 += af_earwax.o
 OBJS-$(CONFIG_EBUR128_FILTER)                += f_ebur128.o
 OBJS-$(CONFIG_EQUALIZER_FILTER)              += af_biquads.o
@@ -99,12 +106,12 @@
 OBJS-$(CONFIG_ANULLSINK_FILTER)              += asink_anullsink.o
 
 OBJS-$(CONFIG_ASS_FILTER)                    += vf_subtitles.o
-OBJS-$(CONFIG_ALPHAEXTRACT_FILTER)           += vf_alphaextract.o
+OBJS-$(CONFIG_ALPHAEXTRACT_FILTER)           += vf_extractplanes.o
 OBJS-$(CONFIG_ALPHAMERGE_FILTER)             += vf_alphamerge.o
 OBJS-$(CONFIG_BBOX_FILTER)                   += bbox.o vf_bbox.o
 OBJS-$(CONFIG_BLACKDETECT_FILTER)            += vf_blackdetect.o
 OBJS-$(CONFIG_BLACKFRAME_FILTER)             += vf_blackframe.o
-OBJS-$(CONFIG_BLEND_FILTER)                  += vf_blend.o
+OBJS-$(CONFIG_BLEND_FILTER)                  += vf_blend.o dualinput.o
 OBJS-$(CONFIG_BOXBLUR_FILTER)                += vf_boxblur.o
 OBJS-$(CONFIG_COLORBALANCE_FILTER)           += vf_colorbalance.o
 OBJS-$(CONFIG_COLORCHANNELMIXER_FILTER)      += vf_colorchannelmixer.o
@@ -113,12 +120,15 @@
 OBJS-$(CONFIG_CROP_FILTER)                   += vf_crop.o
 OBJS-$(CONFIG_CROPDETECT_FILTER)             += vf_cropdetect.o
 OBJS-$(CONFIG_CURVES_FILTER)                 += vf_curves.o
+OBJS-$(CONFIG_DCTDNOIZ_FILTER)               += vf_dctdnoiz.o
 OBJS-$(CONFIG_DECIMATE_FILTER)               += vf_decimate.o
 OBJS-$(CONFIG_DELOGO_FILTER)                 += vf_delogo.o
 OBJS-$(CONFIG_DESHAKE_FILTER)                += vf_deshake.o
 OBJS-$(CONFIG_DRAWBOX_FILTER)                += vf_drawbox.o
+OBJS-$(CONFIG_DRAWGRID_FILTER)               += vf_drawbox.o
 OBJS-$(CONFIG_DRAWTEXT_FILTER)               += vf_drawtext.o
 OBJS-$(CONFIG_EDGEDETECT_FILTER)             += vf_edgedetect.o
+OBJS-$(CONFIG_EXTRACTPLANES_FILTER)          += vf_extractplanes.o
 OBJS-$(CONFIG_FADE_FILTER)                   += vf_fade.o
 OBJS-$(CONFIG_FIELD_FILTER)                  += vf_field.o
 OBJS-$(CONFIG_FIELDMATCH_FILTER)             += vf_fieldmatch.o
@@ -129,6 +139,7 @@
 OBJS-$(CONFIG_FREI0R_FILTER)                 += vf_frei0r.o
 OBJS-$(CONFIG_GEQ_FILTER)                    += vf_geq.o
 OBJS-$(CONFIG_GRADFUN_FILTER)                += vf_gradfun.o
+OBJS-$(CONFIG_HALDCLUT_FILTER)               += vf_lut3d.o dualinput.o
 OBJS-$(CONFIG_HFLIP_FILTER)                  += vf_hflip.o
 OBJS-$(CONFIG_HISTEQ_FILTER)                 += vf_histeq.o
 OBJS-$(CONFIG_HISTOGRAM_FILTER)              += vf_histogram.o
@@ -139,9 +150,11 @@
 OBJS-$(CONFIG_INTERLACE_FILTER)              += vf_interlace.o
 OBJS-$(CONFIG_INTERLEAVE_FILTER)             += f_interleave.o
 OBJS-$(CONFIG_KERNDEINT_FILTER)              += vf_kerndeint.o
+OBJS-$(CONFIG_LUT3D_FILTER)                  += vf_lut3d.o
 OBJS-$(CONFIG_LUT_FILTER)                    += vf_lut.o
 OBJS-$(CONFIG_LUTRGB_FILTER)                 += vf_lut.o
 OBJS-$(CONFIG_LUTYUV_FILTER)                 += vf_lut.o
+OBJS-$(CONFIG_MCDEINT_FILTER)                += vf_mcdeint.o
 OBJS-$(CONFIG_MP_FILTER)                     += vf_mp.o
 OBJS-$(CONFIG_MPDECIMATE_FILTER)             += vf_mpdecimate.o
 OBJS-$(CONFIG_NEGATE_FILTER)                 += vf_lut.o
@@ -149,25 +162,31 @@
 OBJS-$(CONFIG_NOISE_FILTER)                  += vf_noise.o
 OBJS-$(CONFIG_NULL_FILTER)                   += vf_null.o
 OBJS-$(CONFIG_OCV_FILTER)                    += vf_libopencv.o
-OBJS-$(CONFIG_OPENCL)                        += deshake_opencl.o
-OBJS-$(CONFIG_OVERLAY_FILTER)                += vf_overlay.o
+OBJS-$(CONFIG_OPENCL)                        += deshake_opencl.o unsharp_opencl.o
+OBJS-$(CONFIG_OVERLAY_FILTER)                += vf_overlay.o dualinput.o
+OBJS-$(CONFIG_OWDENOISE_FILTER)              += vf_owdenoise.o
 OBJS-$(CONFIG_PAD_FILTER)                    += vf_pad.o
 OBJS-$(CONFIG_PERMS_FILTER)                  += f_perms.o
+OBJS-$(CONFIG_PERSPECTIVE_FILTER)            += vf_perspective.o
 OBJS-$(CONFIG_PIXDESCTEST_FILTER)            += vf_pixdesctest.o
 OBJS-$(CONFIG_PP_FILTER)                     += vf_pp.o
+OBJS-$(CONFIG_PSNR_FILTER)                   += vf_psnr.o dualinput.o
 OBJS-$(CONFIG_REMOVELOGO_FILTER)             += bbox.o lswsutils.o lavfutils.o vf_removelogo.o
+OBJS-$(CONFIG_ROTATE_FILTER)                 += vf_rotate.o
 OBJS-$(CONFIG_SEPARATEFIELDS_FILTER)         += vf_separatefields.o
+OBJS-$(CONFIG_SAB_FILTER)                    += vf_sab.o
 OBJS-$(CONFIG_SCALE_FILTER)                  += vf_scale.o
 OBJS-$(CONFIG_SELECT_FILTER)                 += f_select.o
 OBJS-$(CONFIG_SENDCMD_FILTER)                += f_sendcmd.o
 OBJS-$(CONFIG_SETDAR_FILTER)                 += vf_aspect.o
 OBJS-$(CONFIG_SETFIELD_FILTER)               += vf_setfield.o
-OBJS-$(CONFIG_SETPTS_FILTER)                 += f_setpts.o
+OBJS-$(CONFIG_SETPTS_FILTER)                 += setpts.o
 OBJS-$(CONFIG_SETSAR_FILTER)                 += vf_aspect.o
 OBJS-$(CONFIG_SETTB_FILTER)                  += f_settb.o
 OBJS-$(CONFIG_SHOWINFO_FILTER)               += vf_showinfo.o
 OBJS-$(CONFIG_SMARTBLUR_FILTER)              += vf_smartblur.o
 OBJS-$(CONFIG_SPLIT_FILTER)                  += split.o
+OBJS-$(CONFIG_SPP_FILTER)                    += vf_spp.o
 OBJS-$(CONFIG_STEREO3D_FILTER)               += vf_stereo3d.o
 OBJS-$(CONFIG_SUBTITLES_FILTER)              += vf_subtitles.o
 OBJS-$(CONFIG_SUPER2XSAI_FILTER)             += vf_super2xsai.o
@@ -177,15 +196,19 @@
 OBJS-$(CONFIG_TILE_FILTER)                   += vf_tile.o
 OBJS-$(CONFIG_TINTERLACE_FILTER)             += vf_tinterlace.o
 OBJS-$(CONFIG_TRANSPOSE_FILTER)              += vf_transpose.o
+OBJS-$(CONFIG_TRIM_FILTER)                   += trim.o
 OBJS-$(CONFIG_UNSHARP_FILTER)                += vf_unsharp.o
 OBJS-$(CONFIG_VFLIP_FILTER)                  += vf_vflip.o
 OBJS-$(CONFIG_VIDSTABDETECT_FILTER)          += vidstabutils.o vf_vidstabdetect.o
 OBJS-$(CONFIG_VIDSTABTRANSFORM_FILTER)       += vidstabutils.o vf_vidstabtransform.o
+OBJS-$(CONFIG_VIGNETTE_FILTER)               += vf_vignette.o
 OBJS-$(CONFIG_YADIF_FILTER)                  += vf_yadif.o
+OBJS-$(CONFIG_ZMQ_FILTER)                    += f_zmq.o
 
 OBJS-$(CONFIG_CELLAUTO_FILTER)               += vsrc_cellauto.o
 OBJS-$(CONFIG_COLOR_FILTER)                  += vsrc_testsrc.o
 OBJS-$(CONFIG_FREI0R_SRC_FILTER)             += vf_frei0r.o
+OBJS-$(CONFIG_HALDCLUTSRC_FILTER)            += vsrc_testsrc.o
 OBJS-$(CONFIG_LIFE_FILTER)                   += vsrc_life.o
 OBJS-$(CONFIG_MANDELBROT_FILTER)             += vsrc_mandelbrot.o
 OBJS-$(CONFIG_MPTESTSRC_FILTER)              += vsrc_mptestsrc.o
@@ -205,21 +228,16 @@
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_fil.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_fspp.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_ilpack.o
-OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_mcdeint.o
-OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_ow.o
-OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_perspective.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_phase.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_pp7.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_pullup.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_qp.o
-OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_sab.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_softpulldown.o
-OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_spp.o
-OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_tinterlace.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_uspp.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/pullup.o
 
 # multimedia filters
+OBJS-$(CONFIG_AVECTORSCOPE_FILTER)           += avf_avectorscope.o
 OBJS-$(CONFIG_CONCAT_FILTER)                 += avf_concat.o
 OBJS-$(CONFIG_SHOWSPECTRUM_FILTER)           += avf_showspectrum.o
 OBJS-$(CONFIG_SHOWWAVES_FILTER)              += avf_showwaves.o
@@ -229,10 +247,14 @@
 OBJS-$(CONFIG_MOVIE_FILTER)                  += src_movie.o
 
 SKIPHEADERS-$(CONFIG_LIBVIDSTAB)             += vidstabutils.h
-SKIPHEADERS-$(CONFIG_OPENCL)                 += deshake_kernel.h
+SKIPHEADERS-$(CONFIG_OPENCL)                 += opencl_internal.h deshake_opencl_kernel.h unsharp_opencl_kernel.h
+
+OBJS-$(HAVE_THREADS)                         += pthread.o
 
 TOOLS     = graph2dot
 TESTPROGS = drawutils filtfmts formats
 
+TOOLS-$(CONFIG_LIBZMQ) += zmqsend
+
 clean::
 	$(RM) $(CLEANSUFFIXES:%=libavfilter/libmpcodecs/%)
diff --git a/libavfilter/af_aconvert.c b/libavfilter/af_aconvert.c
index 8a9dc6f..970e801 100644
--- a/libavfilter/af_aconvert.c
+++ b/libavfilter/af_aconvert.c
@@ -25,42 +25,48 @@
  * sample format and channel layout conversion audio filter
  */
 
-#include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
+#include "libavutil/opt.h"
 #include "libswresample/swresample.h"
 #include "avfilter.h"
 #include "audio.h"
 #include "internal.h"
 
 typedef struct {
+    const AVClass       *class;
     enum AVSampleFormat  out_sample_fmt;
     int64_t              out_chlayout;
     struct SwrContext *swr;
+    char *format_str;
+    char *channel_layout_str;
 } AConvertContext;
 
+#define OFFSET(x) offsetof(AConvertContext, x)
+#define A AV_OPT_FLAG_AUDIO_PARAM
+#define F AV_OPT_FLAG_FILTERING_PARAM
+static const AVOption aconvert_options[] = {
+    { "sample_fmt",     "", OFFSET(format_str),         AV_OPT_TYPE_STRING, .flags = A|F },
+    { "channel_layout", "", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, .flags = A|F },
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(aconvert);
+
 static av_cold int init(AVFilterContext *ctx)
 {
     AConvertContext *aconvert = ctx->priv;
-    char *arg, *ptr = NULL;
     int ret = 0;
-    char *args = av_strdup(NULL);
 
     av_log(ctx, AV_LOG_WARNING, "This filter is deprecated, use aformat instead\n");
 
     aconvert->out_sample_fmt  = AV_SAMPLE_FMT_NONE;
     aconvert->out_chlayout    = 0;
 
-    if ((arg = av_strtok(args, ":", &ptr)) && strcmp(arg, "auto")) {
-        if ((ret = ff_parse_sample_format(&aconvert->out_sample_fmt, arg, ctx)) < 0)
-            goto end;
-    }
-    if ((arg = av_strtok(NULL, ":", &ptr)) && strcmp(arg, "auto")) {
-        if ((ret = ff_parse_channel_layout(&aconvert->out_chlayout, arg, ctx)) < 0)
-            goto end;
-    }
-
-end:
-    av_freep(&args);
+    if (aconvert->format_str && strcmp(aconvert->format_str, "auto") &&
+        (ret = ff_parse_sample_format(&aconvert->out_sample_fmt, aconvert->format_str, ctx)) < 0)
+        return ret;
+    if (aconvert->channel_layout_str && strcmp(aconvert->channel_layout_str, "auto"))
+        return ff_parse_channel_layout(&aconvert->out_chlayout, aconvert->channel_layout_str, ctx);
     return ret;
 }
 
@@ -181,6 +187,7 @@
     .name          = "aconvert",
     .description   = NULL_IF_CONFIG_SMALL("Convert the input audio to sample_fmt:channel_layout."),
     .priv_size     = sizeof(AConvertContext),
+    .priv_class    = &aconvert_class,
     .init          = init,
     .uninit        = uninit,
     .query_formats = query_formats,
diff --git a/libavfilter/af_aecho.c b/libavfilter/af_aecho.c
new file mode 100644
index 0000000..e73252b
--- /dev/null
+++ b/libavfilter/af_aecho.c
@@ -0,0 +1,357 @@
+/*
+ * Copyright (c) 2013 Paul B Mahol
+ *
+ * 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
+ *
+ */
+
+#include "libavutil/avstring.h"
+#include "libavutil/opt.h"
+#include "libavutil/samplefmt.h"
+#include "libavutil/avassert.h"
+#include "avfilter.h"
+#include "audio.h"
+#include "internal.h"
+
+typedef struct AudioEchoContext {
+    const AVClass *class;
+    float in_gain, out_gain;
+    char *delays, *decays;
+    float *delay, *decay;
+    int nb_echoes;
+    int delay_index;
+    uint8_t **delayptrs;
+    int max_samples, fade_out;
+    int *samples;
+    int64_t next_pts;
+
+    void (*echo_samples)(struct AudioEchoContext *ctx, uint8_t **delayptrs,
+                         uint8_t * const *src, uint8_t **dst,
+                         int nb_samples, int channels);
+} AudioEchoContext;
+
+#define OFFSET(x) offsetof(AudioEchoContext, x)
+#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption aecho_options[] = {
+    { "in_gain",  "set signal input gain",  OFFSET(in_gain),  AV_OPT_TYPE_FLOAT,  {.dbl=0.6}, 0, 1, A },
+    { "out_gain", "set signal output gain", OFFSET(out_gain), AV_OPT_TYPE_FLOAT,  {.dbl=0.3}, 0, 1, A },
+    { "delays",   "set list of signal delays", OFFSET(delays), AV_OPT_TYPE_STRING, {.str="1000"}, 0, 0, A },
+    { "decays",   "set list of signal decays", OFFSET(decays), AV_OPT_TYPE_STRING, {.str="0.5"}, 0, 0, A },
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(aecho);
+
+static void count_items(char *item_str, int *nb_items)
+{
+    char *p;
+
+    *nb_items = 1;
+    for (p = item_str; *p; p++) {
+        if (*p == '|')
+            (*nb_items)++;
+    }
+
+}
+
+static void fill_items(char *item_str, int *nb_items, float *items)
+{
+    char *p, *saveptr = NULL;
+    int i, new_nb_items = 0;
+
+    p = item_str;
+    for (i = 0; i < *nb_items; i++) {
+        char *tstr = av_strtok(p, "|", &saveptr);
+        p = NULL;
+        new_nb_items += sscanf(tstr, "%f", &items[i]) == 1;
+    }
+
+    *nb_items = new_nb_items;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    AudioEchoContext *s = ctx->priv;
+
+    av_freep(&s->delay);
+    av_freep(&s->decay);
+    av_freep(&s->samples);
+
+    if (s->delayptrs)
+        av_freep(&s->delayptrs[0]);
+    av_freep(&s->delayptrs);
+}
+
+static av_cold int init(AVFilterContext *ctx)
+{
+    AudioEchoContext *s = ctx->priv;
+    int nb_delays, nb_decays, i;
+
+    if (!s->delays || !s->decays) {
+        av_log(ctx, AV_LOG_ERROR, "Missing delays and/or decays.\n");
+        return AVERROR(EINVAL);
+    }
+
+    count_items(s->delays, &nb_delays);
+    count_items(s->decays, &nb_decays);
+
+    s->delay = av_realloc_f(s->delay, nb_delays, sizeof(*s->delay));
+    s->decay = av_realloc_f(s->decay, nb_decays, sizeof(*s->decay));
+    if (!s->delay || !s->decay)
+        return AVERROR(ENOMEM);
+
+    fill_items(s->delays, &nb_delays, s->delay);
+    fill_items(s->decays, &nb_decays, s->decay);
+
+    if (nb_delays != nb_decays) {
+        av_log(ctx, AV_LOG_ERROR, "Number of delays %d differs from number of decays %d.\n", nb_delays, nb_decays);
+        return AVERROR(EINVAL);
+    }
+
+    s->nb_echoes = nb_delays;
+    if (!s->nb_echoes) {
+        av_log(ctx, AV_LOG_ERROR, "At least one decay & delay must be set.\n");
+        return AVERROR(EINVAL);
+    }
+
+    s->samples = av_realloc_f(s->samples, nb_delays, sizeof(*s->samples));
+    if (!s->samples)
+        return AVERROR(ENOMEM);
+
+    for (i = 0; i < nb_delays; i++) {
+        if (s->delay[i] <= 0 || s->delay[i] > 90000) {
+            av_log(ctx, AV_LOG_ERROR, "delay[%d]: %f is out of allowed range: (0, 90000]\n", i, s->delay[i]);
+            return AVERROR(EINVAL);
+        }
+        if (s->decay[i] <= 0 || s->decay[i] > 1) {
+            av_log(ctx, AV_LOG_ERROR, "decay[%d]: %f is out of allowed range: (0, 1]\n", i, s->decay[i]);
+            return AVERROR(EINVAL);
+        }
+    }
+
+    s->next_pts = AV_NOPTS_VALUE;
+
+    av_log(ctx, AV_LOG_DEBUG, "nb_echoes:%d\n", s->nb_echoes);
+    return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    AVFilterChannelLayouts *layouts;
+    AVFilterFormats *formats;
+    static const enum AVSampleFormat sample_fmts[] = {
+        AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32P,
+        AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_DBLP,
+        AV_SAMPLE_FMT_NONE
+    };
+
+    layouts = ff_all_channel_layouts();
+    if (!layouts)
+        return AVERROR(ENOMEM);
+    ff_set_common_channel_layouts(ctx, layouts);
+
+    formats = ff_make_format_list(sample_fmts);
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_set_common_formats(ctx, formats);
+
+    formats = ff_all_samplerates();
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_set_common_samplerates(ctx, formats);
+
+    return 0;
+}
+
+#define MOD(a, b) (((a) >= (b)) ? (a) - (b) : (a))
+
+#define ECHO(name, type, min, max)                                          \
+static void echo_samples_## name ##p(AudioEchoContext *ctx,                 \
+                                     uint8_t **delayptrs,                   \
+                                     uint8_t * const *src, uint8_t **dst,   \
+                                     int nb_samples, int channels)          \
+{                                                                           \
+    const double out_gain = ctx->out_gain;                                  \
+    const double in_gain = ctx->in_gain;                                    \
+    const int nb_echoes = ctx->nb_echoes;                                   \
+    const int max_samples = ctx->max_samples;                               \
+    int i, j, chan, index;                                                  \
+                                                                            \
+    for (chan = 0; chan < channels; chan++) {                               \
+        const type *s = (type *)src[chan];                                  \
+        type *d = (type *)dst[chan];                                        \
+        type *dbuf = (type *)delayptrs[chan];                               \
+                                                                            \
+        index = ctx->delay_index;                                           \
+        for (i = 0; i < nb_samples; i++, s++, d++) {                        \
+            double out, in;                                                 \
+                                                                            \
+            in = *s;                                                        \
+            out = in * in_gain;                                             \
+            for (j = 0; j < nb_echoes; j++) {                               \
+                int ix = index + max_samples - ctx->samples[j];             \
+                ix = MOD(ix, max_samples);                                  \
+                out += dbuf[ix] * ctx->decay[j];                            \
+            }                                                               \
+            out *= out_gain;                                                \
+                                                                            \
+            *d = av_clipd(out, min, max);                                   \
+            dbuf[index] = in;                                               \
+                                                                            \
+            index = MOD(index + 1, max_samples);                            \
+        }                                                                   \
+    }                                                                       \
+    ctx->delay_index = index;                                               \
+}
+
+ECHO(dbl, double,  -1.0,      1.0      )
+ECHO(flt, float,   -1.0,      1.0      )
+ECHO(s16, int16_t, INT16_MIN, INT16_MAX)
+ECHO(s32, int32_t, INT32_MIN, INT32_MAX)
+
+static int config_output(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    AudioEchoContext *s = ctx->priv;
+    float volume = 1.0;
+    int i;
+
+    for (i = 0; i < s->nb_echoes; i++) {
+        s->samples[i] = s->delay[i] * outlink->sample_rate / 1000.0;
+        s->max_samples = FFMAX(s->max_samples, s->samples[i]);
+        volume += s->decay[i];
+    }
+
+    if (s->max_samples <= 0) {
+        av_log(ctx, AV_LOG_ERROR, "Nothing to echo - missing delay samples.\n");
+        return AVERROR(EINVAL);
+    }
+    s->fade_out = s->max_samples;
+
+    if (volume * s->in_gain * s->out_gain > 1.0)
+        av_log(ctx, AV_LOG_WARNING,
+               "out_gain %f can cause saturation of output\n", s->out_gain);
+
+    switch (outlink->format) {
+    case AV_SAMPLE_FMT_DBLP: s->echo_samples = echo_samples_dblp; break;
+    case AV_SAMPLE_FMT_FLTP: s->echo_samples = echo_samples_fltp; break;
+    case AV_SAMPLE_FMT_S16P: s->echo_samples = echo_samples_s16p; break;
+    case AV_SAMPLE_FMT_S32P: s->echo_samples = echo_samples_s32p; break;
+    }
+
+
+    if (s->delayptrs)
+        av_freep(&s->delayptrs[0]);
+    av_freep(&s->delayptrs);
+
+    return av_samples_alloc_array_and_samples(&s->delayptrs, NULL,
+                                              outlink->channels,
+                                              s->max_samples,
+                                              outlink->format, 0);
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
+{
+    AVFilterContext *ctx = inlink->dst;
+    AudioEchoContext *s = ctx->priv;
+    AVFrame *out_frame;
+
+    if (av_frame_is_writable(frame)) {
+        out_frame = frame;
+    } else {
+        out_frame = ff_get_audio_buffer(inlink, frame->nb_samples);
+        if (!out_frame)
+            return AVERROR(ENOMEM);
+        av_frame_copy_props(out_frame, frame);
+    }
+
+    s->echo_samples(s, s->delayptrs, frame->data, out_frame->data,
+                    frame->nb_samples, inlink->channels);
+
+    if (frame != out_frame)
+        av_frame_free(&frame);
+
+    s->next_pts = frame->pts + av_rescale_q(frame->nb_samples, (AVRational){1, inlink->sample_rate}, inlink->time_base);
+    return ff_filter_frame(ctx->outputs[0], out_frame);
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    AudioEchoContext *s = ctx->priv;
+    int ret;
+
+    ret = ff_request_frame(ctx->inputs[0]);
+
+    if (ret == AVERROR_EOF && !ctx->is_disabled && s->fade_out) {
+        int nb_samples = FFMIN(s->fade_out, 2048);
+        AVFrame *frame;
+
+        frame = ff_get_audio_buffer(outlink, nb_samples);
+        if (!frame)
+            return AVERROR(ENOMEM);
+        s->fade_out -= nb_samples;
+
+        av_samples_set_silence(frame->extended_data, 0,
+                               frame->nb_samples,
+                               outlink->channels,
+                               frame->format);
+
+        s->echo_samples(s, s->delayptrs, frame->data, frame->data,
+                        frame->nb_samples, outlink->channels);
+
+        frame->pts = s->next_pts;
+        if (s->next_pts != AV_NOPTS_VALUE)
+            s->next_pts += av_rescale_q(nb_samples, (AVRational){1, outlink->sample_rate}, outlink->time_base);
+
+        return ff_filter_frame(outlink, frame);
+    }
+
+    return ret;
+}
+
+static const AVFilterPad aecho_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_AUDIO,
+        .filter_frame = filter_frame,
+    },
+    { NULL },
+};
+
+static const AVFilterPad aecho_outputs[] = {
+    {
+        .name          = "default",
+        .request_frame = request_frame,
+        .config_props  = config_output,
+        .type          = AVMEDIA_TYPE_AUDIO,
+    },
+    { NULL },
+};
+
+AVFilter avfilter_af_aecho = {
+    .name          = "aecho",
+    .description   = NULL_IF_CONFIG_SMALL("Add echoing to the audio."),
+    .query_formats = query_formats,
+    .priv_size     = sizeof(AudioEchoContext),
+    .priv_class    = &aecho_class,
+    .init          = init,
+    .uninit        = uninit,
+    .inputs        = aecho_inputs,
+    .outputs       = aecho_outputs,
+};
diff --git a/libavfilter/af_afade.c b/libavfilter/af_afade.c
index 35c6537..92e41cc 100644
--- a/libavfilter/af_afade.c
+++ b/libavfilter/af_afade.c
@@ -50,18 +50,18 @@
 static const AVOption afade_options[] = {
     { "type",         "set the fade direction",                      OFFSET(type),         AV_OPT_TYPE_INT,    {.i64 = 0    }, 0, 1, FLAGS, "type" },
     { "t",            "set the fade direction",                      OFFSET(type),         AV_OPT_TYPE_INT,    {.i64 = 0    }, 0, 1, FLAGS, "type" },
-    { "in",           NULL,                                          0,                    AV_OPT_TYPE_CONST,  {.i64 = 0    }, 0, 0, FLAGS, "type" },
-    { "out",          NULL,                                          0,                    AV_OPT_TYPE_CONST,  {.i64 = 1    }, 0, 0, FLAGS, "type" },
-    { "start_sample", "set expression of sample to start fading",    OFFSET(start_sample), AV_OPT_TYPE_INT64,  {.i64 = 0    }, 0, INT64_MAX, FLAGS },
-    { "ss",           "set expression of sample to start fading",    OFFSET(start_sample), AV_OPT_TYPE_INT64,  {.i64 = 0    }, 0, INT64_MAX, FLAGS },
-    { "nb_samples",   "set expression for fade duration in samples", OFFSET(nb_samples),   AV_OPT_TYPE_INT,    {.i64 = 44100}, 1, INT32_MAX, FLAGS },
-    { "ns",           "set expression for fade duration in samples", OFFSET(nb_samples),   AV_OPT_TYPE_INT,    {.i64 = 44100}, 1, INT32_MAX, FLAGS },
-    { "start_time",   "set expression of time to start fading",      OFFSET(start_time),   AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT32_MAX, FLAGS },
-    { "st",           "set expression of time to start fading",      OFFSET(start_time),   AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT32_MAX, FLAGS },
-    { "duration",     "set expression for fade duration",            OFFSET(duration),     AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT32_MAX, FLAGS },
-    { "d",            "set expression for fade duration",            OFFSET(duration),     AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT32_MAX, FLAGS },
-    { "curve",        "set expression for fade curve",               OFFSET(curve),        AV_OPT_TYPE_INT,    {.i64 = TRI  }, TRI, CBR, FLAGS, "curve" },
-    { "c",            "set expression for fade curve",               OFFSET(curve),        AV_OPT_TYPE_INT,    {.i64 = TRI  }, TRI, CBR, FLAGS, "curve" },
+    { "in",           "fade-in",                                     0,                    AV_OPT_TYPE_CONST,  {.i64 = 0    }, 0, 0, FLAGS, "type" },
+    { "out",          "fade-out",                                    0,                    AV_OPT_TYPE_CONST,  {.i64 = 1    }, 0, 0, FLAGS, "type" },
+    { "start_sample", "set number of first sample to start fading",  OFFSET(start_sample), AV_OPT_TYPE_INT64,  {.i64 = 0    }, 0, INT64_MAX, FLAGS },
+    { "ss",           "set number of first sample to start fading",  OFFSET(start_sample), AV_OPT_TYPE_INT64,  {.i64 = 0    }, 0, INT64_MAX, FLAGS },
+    { "nb_samples",   "set number of samples for fade duration",     OFFSET(nb_samples),   AV_OPT_TYPE_INT,    {.i64 = 44100}, 1, INT32_MAX, FLAGS },
+    { "ns",           "set number of samples for fade duration",     OFFSET(nb_samples),   AV_OPT_TYPE_INT,    {.i64 = 44100}, 1, INT32_MAX, FLAGS },
+    { "start_time",   "set time to start fading",                    OFFSET(start_time),   AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT32_MAX, FLAGS },
+    { "st",           "set time to start fading",                    OFFSET(start_time),   AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT32_MAX, FLAGS },
+    { "duration",     "set fade duration",                           OFFSET(duration),     AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT32_MAX, FLAGS },
+    { "d",            "set fade duration",                           OFFSET(duration),     AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT32_MAX, FLAGS },
+    { "curve",        "set fade curve type",                         OFFSET(curve),        AV_OPT_TYPE_INT,    {.i64 = TRI  }, TRI, CBR, FLAGS, "curve" },
+    { "c",            "set fade curve type",                         OFFSET(curve),        AV_OPT_TYPE_INT,    {.i64 = TRI  }, TRI, CBR, FLAGS, "curve" },
     { "tri",          "linear slope",                                0,                    AV_OPT_TYPE_CONST,  {.i64 = TRI  }, 0, 0, FLAGS, "curve" },
     { "qsin",         "quarter of sine wave",                        0,                    AV_OPT_TYPE_CONST,  {.i64 = QSIN }, 0, 0, FLAGS, "curve" },
     { "esin",         "exponential sine wave",                       0,                    AV_OPT_TYPE_CONST,  {.i64 = ESIN }, 0, 0, FLAGS, "curve" },
@@ -200,11 +200,10 @@
 FADE(s16, int16_t)
 FADE(s32, int32_t)
 
-static int config_output(AVFilterLink *outlink)
+static int config_input(AVFilterLink *inlink)
 {
-    AVFilterContext *ctx    = outlink->src;
+    AVFilterContext *ctx    = inlink->dst;
     AudioFadeContext *afade = ctx->priv;
-    AVFilterLink *inlink    = ctx->inputs[0];
 
     switch (inlink->format) {
     case AV_SAMPLE_FMT_DBL:  afade->fade_samples = fade_samples_dbl;  break;
@@ -218,9 +217,9 @@
     }
 
     if (afade->duration)
-        afade->nb_samples = afade->duration * inlink->sample_rate / AV_TIME_BASE;
+        afade->nb_samples = av_rescale(afade->duration, inlink->sample_rate, AV_TIME_BASE);
     if (afade->start_time)
-        afade->start_sample = afade->start_time * inlink->sample_rate / AV_TIME_BASE;
+        afade->start_sample = av_rescale(afade->start_time, inlink->sample_rate, AV_TIME_BASE);
 
     return 0;
 }
@@ -275,6 +274,7 @@
         .name         = "default",
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
+        .config_props = config_input,
     },
     { NULL }
 };
@@ -283,7 +283,6 @@
     {
         .name         = "default",
         .type         = AVMEDIA_TYPE_AUDIO,
-        .config_props = config_output,
     },
     { NULL }
 };
@@ -297,4 +296,5 @@
     .inputs        = avfilter_af_afade_inputs,
     .outputs       = avfilter_af_afade_outputs,
     .priv_class    = &afade_class,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/af_aformat.c b/libavfilter/af_aformat.c
index 39bd850..ddc0009 100644
--- a/libavfilter/af_aformat.c
+++ b/libavfilter/af_aformat.c
@@ -110,7 +110,7 @@
     AFormatContext *s = ctx->priv;
 
     ff_set_common_formats(ctx, s->formats ? s->formats :
-                                                  ff_all_formats(AVMEDIA_TYPE_AUDIO));
+                                            ff_all_formats(AVMEDIA_TYPE_AUDIO));
     ff_set_common_samplerates(ctx, s->sample_rates ? s->sample_rates :
                                                      ff_all_samplerates());
     ff_set_common_channel_layouts(ctx, s->channel_layouts ? s->channel_layouts :
diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c
index 75736e6..8cecdaf 100644
--- a/libavfilter/af_amix.c
+++ b/libavfilter/af_amix.c
@@ -28,6 +28,7 @@
  * output.
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/audio_fifo.h"
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
@@ -483,7 +484,7 @@
     return ret;
 }
 
-static int init(AVFilterContext *ctx)
+static av_cold int init(AVFilterContext *ctx)
 {
     MixContext *s = ctx->priv;
     int i;
@@ -505,7 +506,7 @@
     return 0;
 }
 
-static void uninit(AVFilterContext *ctx)
+static av_cold void uninit(AVFilterContext *ctx)
 {
     int i;
     MixContext *s = ctx->priv;
diff --git a/libavfilter/af_anull.c b/libavfilter/af_anull.c
index c61da3b..7a0b3f7 100644
--- a/libavfilter/af_anull.c
+++ b/libavfilter/af_anull.c
@@ -31,7 +31,6 @@
     {
         .name             = "default",
         .type             = AVMEDIA_TYPE_AUDIO,
-        .get_audio_buffer = ff_null_get_audio_buffer,
     },
     { NULL }
 };
@@ -47,12 +46,7 @@
 AVFilter avfilter_af_anull = {
     .name      = "anull",
     .description = NULL_IF_CONFIG_SMALL("Pass the source unchanged to the output."),
-
-    .priv_size = 0,
-
     .query_formats = ff_query_formats_all,
-
     .inputs    = avfilter_af_anull_inputs,
-
     .outputs   = avfilter_af_anull_outputs,
 };
diff --git a/libavfilter/af_apad.c b/libavfilter/af_apad.c
index 66738f6..710baaa 100644
--- a/libavfilter/af_apad.c
+++ b/libavfilter/af_apad.c
@@ -89,7 +89,7 @@
 
     ret = ff_request_frame(ctx->inputs[0]);
 
-    if (ret == AVERROR_EOF) {
+    if (ret == AVERROR_EOF && !ctx->is_disabled) {
         int n_out = apad->packet_size;
         AVFrame *outsamplesref;
 
@@ -152,4 +152,5 @@
     .inputs        = apad_inputs,
     .outputs       = apad_outputs,
     .priv_class    = &apad_class,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/af_aresample.c b/libavfilter/af_aresample.c
index b88c5f8..dbeb0de 100644
--- a/libavfilter/af_aresample.c
+++ b/libavfilter/af_aresample.c
@@ -59,9 +59,7 @@
         AVDictionaryEntry *e = NULL;
 
         while ((e = av_dict_get(*opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
-            const char *token = e->key;
-            const char *value = e->value;
-            if ((ret = av_opt_set(aresample->swr, token, value, 0)) < 0)
+            if ((ret = av_opt_set(aresample->swr, e->key, e->value, 0)) < 0)
                 goto end;
         }
         av_dict_free(opts);
diff --git a/libavfilter/af_asetnsamples.c b/libavfilter/af_asetnsamples.c
index 25e062a..e4c77ab 100644
--- a/libavfilter/af_asetnsamples.c
+++ b/libavfilter/af_asetnsamples.c
@@ -73,9 +73,8 @@
 static int config_props_output(AVFilterLink *outlink)
 {
     ASNSContext *asns = outlink->src->priv;
-    int nb_channels = av_get_channel_layout_nb_channels(outlink->channel_layout);
 
-    asns->fifo = av_audio_fifo_alloc(outlink->format, nb_channels, asns->nb_out_samples);
+    asns->fifo = av_audio_fifo_alloc(outlink->format, outlink->channels, asns->nb_out_samples);
     if (!asns->fifo)
         return AVERROR(ENOMEM);
     outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP;
@@ -109,7 +108,7 @@
 
     if (nb_pad_samples)
         av_samples_set_silence(outsamples->extended_data, nb_out_samples - nb_pad_samples,
-                               nb_pad_samples, av_get_channel_layout_nb_channels(outlink->channel_layout),
+                               nb_pad_samples, outlink->channels,
                                outlink->format);
     outsamples->nb_samples     = nb_out_samples;
     outsamples->channel_layout = outlink->channel_layout;
diff --git a/libavfilter/af_ashowinfo.c b/libavfilter/af_ashowinfo.c
index f53584e..08a6395 100644
--- a/libavfilter/af_ashowinfo.c
+++ b/libavfilter/af_ashowinfo.c
@@ -27,6 +27,7 @@
 #include <stddef.h>
 
 #include "libavutil/adler32.h"
+#include "libavutil/attributes.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
 #include "libavutil/mem.h"
@@ -42,14 +43,9 @@
      * Scratch space for individual plane checksums for planar audio
      */
     uint32_t *plane_checksums;
-
-    /**
-     * Frame counter
-     */
-    uint64_t frame;
 } AShowInfoContext;
 
-static void uninit(AVFilterContext *ctx)
+static av_cold void uninit(AVFilterContext *ctx)
 {
     AShowInfoContext *s = ctx->priv;
     av_freep(&s->plane_checksums);
@@ -61,7 +57,7 @@
     AShowInfoContext *s  = ctx->priv;
     char chlayout_str[128];
     uint32_t checksum = 0;
-    int channels    = av_get_channel_layout_nb_channels(buf->channel_layout);
+    int channels    = inlink->channels;
     int planar      = av_sample_fmt_is_planar(buf->format);
     int block_align = av_get_bytes_per_sample(buf->format) * (planar ? 1 : channels);
     int data_size   = buf->nb_samples * block_align;
@@ -85,10 +81,10 @@
                                  buf->channel_layout);
 
     av_log(ctx, AV_LOG_INFO,
-           "n:%"PRIu64" pts:%s pts_time:%s pos:%"PRId64" "
+           "n:%"PRId64" pts:%s pts_time:%s pos:%"PRId64" "
            "fmt:%s channels:%d chlayout:%s rate:%d nb_samples:%d "
            "checksum:%08X ",
-           s->frame,
+           inlink->frame_count,
            av_ts2str(buf->pts), av_ts2timestr(buf->pts, &inlink->time_base),
            av_frame_get_pkt_pos(buf),
            av_get_sample_fmt_name(buf->format), av_frame_get_channels(buf), chlayout_str,
@@ -100,7 +96,6 @@
         av_log(ctx, AV_LOG_INFO, "%08X ", s->plane_checksums[i]);
     av_log(ctx, AV_LOG_INFO, "]\n");
 
-    s->frame++;
     return ff_filter_frame(inlink->dst->outputs[0], buf);
 }
 
diff --git a/libavfilter/af_astats.c b/libavfilter/af_astats.c
new file mode 100644
index 0000000..9d002a5
--- /dev/null
+++ b/libavfilter/af_astats.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2009 Rob Sykes <robs@users.sourceforge.net>
+ * Copyright (c) 2013 Paul B Mahol
+ *
+ * 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
+ */
+
+#include <float.h>
+
+#include "libavutil/opt.h"
+#include "audio.h"
+#include "avfilter.h"
+#include "internal.h"
+
+typedef struct ChannelStats {
+    double last;
+    double sigma_x, sigma_x2;
+    double avg_sigma_x2, min_sigma_x2, max_sigma_x2;
+    double min, max;
+    double min_run, max_run;
+    double min_runs, max_runs;
+    uint64_t min_count, max_count;
+    uint64_t nb_samples;
+} ChannelStats;
+
+typedef struct {
+    const AVClass *class;
+    ChannelStats *chstats;
+    int nb_channels;
+    uint64_t tc_samples;
+    double time_constant;
+    double mult;
+} AudioStatsContext;
+
+#define OFFSET(x) offsetof(AudioStatsContext, x)
+#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption astats_options[] = {
+    { "length", "set the window length", OFFSET(time_constant), AV_OPT_TYPE_DOUBLE, {.dbl=.05}, .01, 10, FLAGS },
+    {NULL},
+};
+
+AVFILTER_DEFINE_CLASS(astats);
+
+static int query_formats(AVFilterContext *ctx)
+{
+    AVFilterFormats *formats;
+    AVFilterChannelLayouts *layouts;
+    static const enum AVSampleFormat sample_fmts[] = {
+        AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBLP,
+        AV_SAMPLE_FMT_NONE
+    };
+
+    layouts = ff_all_channel_layouts();
+    if (!layouts)
+        return AVERROR(ENOMEM);
+    ff_set_common_channel_layouts(ctx, layouts);
+
+    formats = ff_make_format_list(sample_fmts);
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_set_common_formats(ctx, formats);
+
+    formats = ff_all_samplerates();
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_set_common_samplerates(ctx, formats);
+
+    return 0;
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+    AudioStatsContext *s = outlink->src->priv;
+    int c;
+
+    s->chstats = av_calloc(sizeof(*s->chstats), outlink->channels);
+    if (!s->chstats)
+        return AVERROR(ENOMEM);
+    s->nb_channels = outlink->channels;
+    s->mult = exp((-1 / s->time_constant / outlink->sample_rate));
+    s->tc_samples = 5 * s->time_constant * outlink->sample_rate + .5;
+
+    for (c = 0; c < s->nb_channels; c++) {
+        ChannelStats *p = &s->chstats[c];
+
+        p->min = p->min_sigma_x2 = DBL_MAX;
+        p->max = p->max_sigma_x2 = DBL_MIN;
+    }
+
+    return 0;
+}
+
+static inline void update_stat(AudioStatsContext *s, ChannelStats *p, double d)
+{
+    if (d < p->min) {
+        p->min = d;
+        p->min_run = 1;
+        p->min_runs = 0;
+        p->min_count = 1;
+    } else if (d == p->min) {
+        p->min_count++;
+        p->min_run = d == p->last ? p->min_run + 1 : 1;
+    } else if (p->last == p->min) {
+        p->min_runs += p->min_run * p->min_run;
+    }
+
+    if (d > p->max) {
+        p->max = d;
+        p->max_run = 1;
+        p->max_runs = 0;
+        p->max_count = 1;
+    } else if (d == p->max) {
+        p->max_count++;
+        p->max_run = d == p->last ? p->max_run + 1 : 1;
+    } else if (p->last == p->max) {
+        p->max_runs += p->max_run * p->max_run;
+    }
+
+    p->sigma_x += d;
+    p->sigma_x2 += d * d;
+    p->avg_sigma_x2 = p->avg_sigma_x2 * s->mult + (1.0 - s->mult) * d * d;
+    p->last = d;
+
+    if (p->nb_samples >= s->tc_samples) {
+        p->max_sigma_x2 = FFMAX(p->max_sigma_x2, p->avg_sigma_x2);
+        p->min_sigma_x2 = FFMIN(p->min_sigma_x2, p->avg_sigma_x2);
+    }
+    p->nb_samples++;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
+{
+    AudioStatsContext *s = inlink->dst->priv;
+    const int channels = s->nb_channels;
+    const double *src;
+    int i, c;
+
+    switch (inlink->format) {
+    case AV_SAMPLE_FMT_DBLP:
+        for (c = 0; c < channels; c++) {
+            ChannelStats *p = &s->chstats[c];
+            src = (const double *)buf->extended_data[c];
+
+            for (i = 0; i < buf->nb_samples; i++, src++)
+                update_stat(s, p, *src);
+        }
+        break;
+    case AV_SAMPLE_FMT_DBL:
+        src = (const double *)buf->extended_data[0];
+
+        for (i = 0; i < buf->nb_samples; i++) {
+            for (c = 0; c < channels; c++, src++)
+                update_stat(s, &s->chstats[c], *src);
+        }
+        break;
+    }
+
+    return ff_filter_frame(inlink->dst->outputs[0], buf);
+}
+
+#define LINEAR_TO_DB(x) (log10(x) * 20)
+
+static void print_stats(AVFilterContext *ctx)
+{
+    AudioStatsContext *s = ctx->priv;
+    uint64_t min_count = 0, max_count = 0, nb_samples = 0;
+    double min_runs = 0, max_runs = 0,
+           min = DBL_MAX, max = DBL_MIN,
+           max_sigma_x = 0,
+           sigma_x = 0,
+           sigma_x2 = 0,
+           min_sigma_x2 = DBL_MAX,
+           max_sigma_x2 = DBL_MIN;
+    int c;
+
+    for (c = 0; c < s->nb_channels; c++) {
+        ChannelStats *p = &s->chstats[c];
+
+        if (p->nb_samples < s->tc_samples)
+            p->min_sigma_x2 = p->max_sigma_x2 = p->sigma_x2 / p->nb_samples;
+
+        min = FFMIN(min, p->min);
+        max = FFMAX(max, p->max);
+        min_sigma_x2 = FFMIN(min_sigma_x2, p->min_sigma_x2);
+        max_sigma_x2 = FFMAX(max_sigma_x2, p->max_sigma_x2);
+        sigma_x += p->sigma_x;
+        sigma_x2 += p->sigma_x2;
+        min_count += p->min_count;
+        max_count += p->max_count;
+        min_runs += p->min_runs;
+        max_runs += p->max_runs;
+        nb_samples += p->nb_samples;
+        if (fabs(p->sigma_x) > fabs(max_sigma_x))
+            max_sigma_x = p->sigma_x;
+
+        av_log(ctx, AV_LOG_INFO, "Channel: %d\n", c + 1);
+        av_log(ctx, AV_LOG_INFO, "DC offset: %f\n", p->sigma_x / p->nb_samples);
+        av_log(ctx, AV_LOG_INFO, "Min level: %f\n", p->min);
+        av_log(ctx, AV_LOG_INFO, "Max level: %f\n", p->max);
+        av_log(ctx, AV_LOG_INFO, "Peak level dB: %f\n", LINEAR_TO_DB(FFMAX(-p->min, p->max)));
+        av_log(ctx, AV_LOG_INFO, "RMS level dB: %f\n", LINEAR_TO_DB(sqrt(p->sigma_x2 / p->nb_samples)));
+        av_log(ctx, AV_LOG_INFO, "RMS peak dB: %f\n", LINEAR_TO_DB(sqrt(p->max_sigma_x2)));
+        if (p->min_sigma_x2 != 1)
+            av_log(ctx, AV_LOG_INFO, "RMS trough dB: %f\n",LINEAR_TO_DB(sqrt(p->min_sigma_x2)));
+        av_log(ctx, AV_LOG_INFO, "Crest factor: %f\n", p->sigma_x2 ? FFMAX(-p->min, p->max) / sqrt(p->sigma_x2 / p->nb_samples) : 1);
+        av_log(ctx, AV_LOG_INFO, "Flat factor: %f\n", LINEAR_TO_DB((p->min_runs + p->max_runs) / (p->min_count + p->max_count)));
+        av_log(ctx, AV_LOG_INFO, "Peak count: %"PRId64"\n", p->min_count + p->max_count);
+    }
+
+    av_log(ctx, AV_LOG_INFO, "Overall\n");
+    av_log(ctx, AV_LOG_INFO, "DC offset: %f\n", max_sigma_x / (nb_samples / s->nb_channels));
+    av_log(ctx, AV_LOG_INFO, "Min level: %f\n", min);
+    av_log(ctx, AV_LOG_INFO, "Max level: %f\n", max);
+    av_log(ctx, AV_LOG_INFO, "Peak level dB: %f\n", LINEAR_TO_DB(FFMAX(-min, max)));
+    av_log(ctx, AV_LOG_INFO, "RMS level dB: %f\n", LINEAR_TO_DB(sqrt(sigma_x2 / nb_samples)));
+    av_log(ctx, AV_LOG_INFO, "RMS peak dB: %f\n", LINEAR_TO_DB(sqrt(max_sigma_x2)));
+    if (min_sigma_x2 != 1)
+        av_log(ctx, AV_LOG_INFO, "RMS trough dB: %f\n", LINEAR_TO_DB(sqrt(min_sigma_x2)));
+    av_log(ctx, AV_LOG_INFO, "Flat factor: %f\n", LINEAR_TO_DB((min_runs + max_runs) / (min_count + max_count)));
+    av_log(ctx, AV_LOG_INFO, "Peak count: %f\n", (min_count + max_count) / (double)s->nb_channels);
+    av_log(ctx, AV_LOG_INFO, "Number of samples: %"PRId64"\n", nb_samples / s->nb_channels);
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    AudioStatsContext *s = ctx->priv;
+
+    print_stats(ctx);
+    av_freep(&s->chstats);
+}
+
+static const AVFilterPad astats_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_AUDIO,
+        .filter_frame = filter_frame,
+    },
+    { NULL }
+};
+
+static const AVFilterPad astats_outputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_AUDIO,
+        .config_props = config_output,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_af_astats = {
+    .name          = "astats",
+    .description   = NULL_IF_CONFIG_SMALL("Show time domain statistics about audio frames."),
+    .query_formats = query_formats,
+    .priv_size     = sizeof(AudioStatsContext),
+    .priv_class    = &astats_class,
+    .uninit        = uninit,
+    .inputs        = astats_inputs,
+    .outputs       = astats_outputs,
+};
diff --git a/libavfilter/af_asyncts.c b/libavfilter/af_asyncts.c
index 13c5a91..a30ce3d 100644
--- a/libavfilter/af_asyncts.c
+++ b/libavfilter/af_asyncts.c
@@ -17,6 +17,7 @@
  */
 
 #include "libavresample/avresample.h"
+#include "libavutil/attributes.h"
 #include "libavutil/audio_fifo.h"
 #include "libavutil/common.h"
 #include "libavutil/mathematics.h"
@@ -60,7 +61,7 @@
 
 AVFILTER_DEFINE_CLASS(asyncts);
 
-static int init(AVFilterContext *ctx)
+static av_cold int init(AVFilterContext *ctx)
 {
     ASyncContext *s = ctx->priv;
 
@@ -70,7 +71,7 @@
     return 0;
 }
 
-static void uninit(AVFilterContext *ctx)
+static av_cold void uninit(AVFilterContext *ctx)
 {
     ASyncContext *s = ctx->priv;
 
@@ -232,18 +233,23 @@
         }
 
         if (s->first_frame && delta > 0) {
+            int planar = av_sample_fmt_is_planar(buf_out->format);
+            int planes = planar ?  nb_channels : 1;
+            int block_size = av_get_bytes_per_sample(buf_out->format) *
+                             (planar ? 1 : nb_channels);
+
             int ch;
 
             av_samples_set_silence(buf_out->extended_data, 0, delta,
                                    nb_channels, buf->format);
 
-            for (ch = 0; ch < nb_channels; ch++)
-                buf_out->extended_data[ch] += delta;
+            for (ch = 0; ch < planes; ch++)
+                buf_out->extended_data[ch] += delta * block_size;
 
             avresample_read(s->avr, buf_out->extended_data, out_size);
 
-            for (ch = 0; ch < nb_channels; ch++)
-                buf_out->extended_data[ch] -= delta;
+            for (ch = 0; ch < planes; ch++)
+                buf_out->extended_data[ch] -= delta * block_size;
         } else {
             avresample_read(s->avr, buf_out->extended_data, out_size);
 
diff --git a/libavfilter/af_biquads.c b/libavfilter/af_biquads.c
index 0141ffd..d203d0c 100644
--- a/libavfilter/af_biquads.c
+++ b/libavfilter/af_biquads.c
@@ -83,7 +83,7 @@
 
 enum WidthType {
     NONE,
-    HZ,
+    HERTZ,
     OCTAVE,
     QFACTOR,
     SLOPE,
@@ -250,7 +250,7 @@
     case NONE:
         alpha = 0.0;
         break;
-    case HZ:
+    case HERTZ:
         alpha = sin(w0) / (2 * p->frequency / p->width);
         break;
     case OCTAVE:
@@ -470,8 +470,8 @@
 static const AVOption equalizer_options[] = {
     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
-    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HZ, SLOPE, FLAGS, "width_type"},
-    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HZ}, 0, 0, FLAGS, "width_type"},
+    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
+    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
@@ -488,8 +488,8 @@
 static const AVOption bass_options[] = {
     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
-    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HZ, SLOPE, FLAGS, "width_type"},
-    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HZ}, 0, 0, FLAGS, "width_type"},
+    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
+    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
@@ -506,8 +506,8 @@
 static const AVOption treble_options[] = {
     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
-    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HZ, SLOPE, FLAGS, "width_type"},
-    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HZ}, 0, 0, FLAGS, "width_type"},
+    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
+    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
@@ -524,8 +524,8 @@
 static const AVOption bandpass_options[] = {
     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
-    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HZ, SLOPE, FLAGS, "width_type"},
-    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HZ}, 0, 0, FLAGS, "width_type"},
+    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
+    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
@@ -541,8 +541,8 @@
 static const AVOption bandreject_options[] = {
     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
-    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HZ, SLOPE, FLAGS, "width_type"},
-    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HZ}, 0, 0, FLAGS, "width_type"},
+    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
+    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
@@ -557,8 +557,8 @@
 static const AVOption lowpass_options[] = {
     {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
     {"f",         "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
-    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HZ, SLOPE, FLAGS, "width_type"},
-    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HZ}, 0, 0, FLAGS, "width_type"},
+    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
+    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
@@ -575,8 +575,8 @@
 static const AVOption highpass_options[] = {
     {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
     {"f",         "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
-    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HZ, SLOPE, FLAGS, "width_type"},
-    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HZ}, 0, 0, FLAGS, "width_type"},
+    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
+    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
@@ -593,8 +593,8 @@
 static const AVOption allpass_options[] = {
     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
-    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HZ}, HZ, SLOPE, FLAGS, "width_type"},
-    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HZ}, 0, 0, FLAGS, "width_type"},
+    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, SLOPE, FLAGS, "width_type"},
+    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
diff --git a/libavfilter/af_channelmap.c b/libavfilter/af_channelmap.c
index c6ba347..4daf62c 100644
--- a/libavfilter/af_channelmap.c
+++ b/libavfilter/af_channelmap.c
@@ -69,7 +69,7 @@
 #define OFFSET(x) offsetof(ChannelMapContext, x)
 #define A AV_OPT_FLAG_AUDIO_PARAM
 #define F AV_OPT_FLAG_FILTERING_PARAM
-static const AVOption options[] = {
+static const AVOption channelmap_options[] = {
     { "map", "A comma-separated list of input channel numbers in output order.",
           OFFSET(mapping_str),        AV_OPT_TYPE_STRING, .flags = A|F },
     { "channel_layout", "Output channel layout.",
@@ -77,12 +77,7 @@
     { NULL },
 };
 
-static const AVClass channelmap_class = {
-    .class_name = "channel map filter",
-    .item_name  = av_default_item_name,
-    .option     = options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
+AVFILTER_DEFINE_CLASS(channelmap);
 
 static char* split(char *message, char delim) {
     char *next = strchr(message, delim);
@@ -123,7 +118,6 @@
 static av_cold int channelmap_init(AVFilterContext *ctx)
 {
     ChannelMapContext *s = ctx->priv;
-    int ret = 0;
     char *mapping, separator = '|';
     int map_entries = 0;
     char buf[256];
@@ -173,8 +167,7 @@
 
     if (map_entries > MAX_CH) {
         av_log(ctx, AV_LOG_ERROR, "Too many channels mapped: '%d'.\n", map_entries);
-        ret = AVERROR(EINVAL);
-        goto fail;
+        return AVERROR(EINVAL);
     }
 
     for (i = 0; i < map_entries; i++) {
@@ -184,9 +177,8 @@
         switch (mode) {
         case MAP_ONE_INT:
             if (get_channel_idx(&mapping, &in_ch_idx, separator, MAX_CH) < 0) {
-                ret = AVERROR(EINVAL);
                 av_log(ctx, AV_LOG_ERROR, err);
-                goto fail;
+                return AVERROR(EINVAL);
             }
             s->map[i].in_channel_idx  = in_ch_idx;
             s->map[i].out_channel_idx = i;
@@ -194,8 +186,7 @@
         case MAP_ONE_STR:
             if (!get_channel(&mapping, &in_ch, separator)) {
                 av_log(ctx, AV_LOG_ERROR, err);
-                ret = AVERROR(EINVAL);
-                goto fail;
+                return AVERROR(EINVAL);
             }
             s->map[i].in_channel      = in_ch;
             s->map[i].out_channel_idx = i;
@@ -204,8 +195,7 @@
             if (get_channel_idx(&mapping, &in_ch_idx, '-', MAX_CH) < 0 ||
                 get_channel_idx(&mapping, &out_ch_idx, separator, MAX_CH) < 0) {
                 av_log(ctx, AV_LOG_ERROR, err);
-                ret = AVERROR(EINVAL);
-                goto fail;
+                return AVERROR(EINVAL);
             }
             s->map[i].in_channel_idx  = in_ch_idx;
             s->map[i].out_channel_idx = out_ch_idx;
@@ -215,8 +205,7 @@
                 get_channel(&mapping, &out_ch, separator) < 0 ||
                 out_ch & out_ch_mask) {
                 av_log(ctx, AV_LOG_ERROR, err);
-                ret = AVERROR(EINVAL);
-                goto fail;
+                return AVERROR(EINVAL);
             }
             s->map[i].in_channel_idx  = in_ch_idx;
             s->map[i].out_channel     = out_ch;
@@ -226,8 +215,7 @@
             if (get_channel(&mapping, &in_ch, '-') < 0 ||
                 get_channel_idx(&mapping, &out_ch_idx, separator, MAX_CH) < 0) {
                 av_log(ctx, AV_LOG_ERROR, err);
-                ret = AVERROR(EINVAL);
-                goto fail;
+                return AVERROR(EINVAL);
             }
             s->map[i].in_channel      = in_ch;
             s->map[i].out_channel_idx = out_ch_idx;
@@ -237,8 +225,7 @@
                 get_channel(&mapping, &out_ch, separator) < 0 ||
                 out_ch & out_ch_mask) {
                 av_log(ctx, AV_LOG_ERROR, err);
-                ret = AVERROR(EINVAL);
-                goto fail;
+                return AVERROR(EINVAL);
             }
             s->map[i].in_channel = in_ch;
             s->map[i].out_channel = out_ch;
@@ -256,8 +243,7 @@
         if ((fmt = av_get_channel_layout(s->channel_layout_str)) == 0) {
             av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout: '%s'.\n",
                    s->channel_layout_str);
-            ret = AVERROR(EINVAL);
-            goto fail;
+            return AVERROR(EINVAL);
         }
         if (mode == MAP_NONE) {
             int i;
@@ -271,17 +257,21 @@
             av_log(ctx, AV_LOG_ERROR,
                    "Output channel layout '%s' does not match the list of channel mapped: '%s'.\n",
                    s->channel_layout_str, buf);
-            ret = AVERROR(EINVAL);
-            goto fail;
+            return AVERROR(EINVAL);
         } else if (s->nch != av_get_channel_layout_nb_channels(fmt)) {
             av_log(ctx, AV_LOG_ERROR,
                    "Output channel layout %s does not match the number of channels mapped %d.\n",
                    s->channel_layout_str, s->nch);
-            ret = AVERROR(EINVAL);
-            goto fail;
+            return AVERROR(EINVAL);
         }
         s->output_layout = fmt;
     }
+    if (!s->output_layout) {
+        av_log(ctx, AV_LOG_ERROR, "Output channel layout is not set and "
+               "cannot be guessed from the maps.\n");
+        return AVERROR(EINVAL);
+    }
+
     ff_add_channel_layout(&s->channel_layouts, s->output_layout);
 
     if (mode == MAP_PAIR_INT_STR || mode == MAP_PAIR_STR_STR) {
@@ -291,9 +281,7 @@
         }
     }
 
-fail:
-    av_opt_free(s);
-    return ret;
+    return 0;
 }
 
 static int channelmap_query_formats(AVFilterContext *ctx)
diff --git a/libavfilter/af_channelsplit.c b/libavfilter/af_channelsplit.c
index c14c676..42c8156 100644
--- a/libavfilter/af_channelsplit.c
+++ b/libavfilter/af_channelsplit.c
@@ -23,6 +23,7 @@
  * Split an audio stream into per-channel streams.
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/internal.h"
 #include "libavutil/opt.h"
@@ -49,7 +50,7 @@
 
 AVFILTER_DEFINE_CLASS(channelsplit);
 
-static int init(AVFilterContext *ctx)
+static av_cold int init(AVFilterContext *ctx)
 {
     ChannelSplitContext *s = ctx->priv;
     int nb_channels;
diff --git a/libavfilter/af_compand.c b/libavfilter/af_compand.c
new file mode 100644
index 0000000..6cbfbf4
--- /dev/null
+++ b/libavfilter/af_compand.c
@@ -0,0 +1,515 @@
+/*
+ * Copyright (c) 1999 Chris Bagwell
+ * Copyright (c) 1999 Nick Bailey
+ * Copyright (c) 2007 Rob Sykes <robs@users.sourceforge.net>
+ * Copyright (c) 2013 Paul B Mahol
+ *
+ * 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
+ *
+ */
+
+#include "libavutil/avstring.h"
+#include "libavutil/opt.h"
+#include "libavutil/samplefmt.h"
+#include "avfilter.h"
+#include "audio.h"
+#include "internal.h"
+
+typedef struct ChanParam {
+    double attack;
+    double decay;
+    double volume;
+} ChanParam;
+
+typedef struct CompandSegment {
+    double x, y;
+    double a, b;
+} CompandSegment;
+
+typedef struct CompandContext {
+    const AVClass *class;
+    char *attacks, *decays, *points;
+    CompandSegment *segments;
+    ChanParam *channels;
+    double in_min_lin;
+    double out_min_lin;
+    double curve_dB;
+    double gain_dB;
+    double initial_volume;
+    double delay;
+    uint8_t **delayptrs;
+    int delay_samples;
+    int delay_count;
+    int delay_index;
+    int64_t pts;
+
+    int (*compand)(AVFilterContext *ctx, AVFrame *frame);
+} CompandContext;
+
+#define OFFSET(x) offsetof(CompandContext, x)
+#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption compand_options[] = {
+    { "attacks", "set time over which increase of volume is determined", OFFSET(attacks), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A },
+    { "decays", "set time over which decrease of volume is determined", OFFSET(decays), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A },
+    { "points", "set points of transfer function", OFFSET(points), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A },
+    { "soft-knee", "set soft-knee", OFFSET(curve_dB), AV_OPT_TYPE_DOUBLE, {.dbl=0.01}, 0.01, 900, A },
+    { "gain", "set output gain", OFFSET(gain_dB), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, A },
+    { "volume", "set initial volume", OFFSET(initial_volume), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 0, A },
+    { "delay", "set delay for samples before sending them to volume adjuster", OFFSET(delay), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 20, A },
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(compand);
+
+static av_cold int init(AVFilterContext *ctx)
+{
+    CompandContext *s = ctx->priv;
+
+    if (!s->attacks || !s->decays || !s->points) {
+        av_log(ctx, AV_LOG_ERROR, "Missing attacks and/or decays and/or points.\n");
+        return AVERROR(EINVAL);
+    }
+
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    CompandContext *s = ctx->priv;
+
+    av_freep(&s->channels);
+    av_freep(&s->segments);
+    if (s->delayptrs)
+        av_freep(&s->delayptrs[0]);
+    av_freep(&s->delayptrs);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    AVFilterChannelLayouts *layouts;
+    AVFilterFormats *formats;
+    static const enum AVSampleFormat sample_fmts[] = {
+        AV_SAMPLE_FMT_DBLP,
+        AV_SAMPLE_FMT_NONE
+    };
+
+    layouts = ff_all_channel_layouts();
+    if (!layouts)
+        return AVERROR(ENOMEM);
+    ff_set_common_channel_layouts(ctx, layouts);
+
+    formats = ff_make_format_list(sample_fmts);
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_set_common_formats(ctx, formats);
+
+    formats = ff_all_samplerates();
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_set_common_samplerates(ctx, formats);
+
+    return 0;
+}
+
+static void count_items(char *item_str, int *nb_items)
+{
+    char *p;
+
+    *nb_items = 1;
+    for (p = item_str; *p; p++) {
+        if (*p == ' ')
+            (*nb_items)++;
+    }
+
+}
+
+static void update_volume(ChanParam *cp, double in)
+{
+    double delta = in - cp->volume;
+
+    if (delta > 0.0)
+        cp->volume += delta * cp->attack;
+    else
+        cp->volume += delta * cp->decay;
+}
+
+static double get_volume(CompandContext *s, double in_lin)
+{
+    CompandSegment *cs;
+    double in_log, out_log;
+    int i;
+
+    if (in_lin < s->in_min_lin)
+        return s->out_min_lin;
+
+    in_log = log(in_lin);
+
+    for (i = 1;; i++)
+        if (in_log <= s->segments[i + 1].x)
+            break;
+
+    cs = &s->segments[i];
+    in_log -= cs->x;
+    out_log = cs->y + in_log * (cs->a * in_log + cs->b);
+
+    return exp(out_log);
+}
+
+static int compand_nodelay(AVFilterContext *ctx, AVFrame *frame)
+{
+    CompandContext *s = ctx->priv;
+    AVFilterLink *inlink = ctx->inputs[0];
+    const int channels = inlink->channels;
+    const int nb_samples = frame->nb_samples;
+    AVFrame *out_frame;
+    int chan, i;
+
+    if (av_frame_is_writable(frame)) {
+        out_frame = frame;
+    } else {
+        out_frame = ff_get_audio_buffer(inlink, nb_samples);
+        if (!out_frame)
+            return AVERROR(ENOMEM);
+        av_frame_copy_props(out_frame, frame);
+    }
+
+    for (chan = 0; chan < channels; chan++) {
+        const double *src = (double *)frame->data[chan];
+        double *dst = (double *)out_frame->data[chan];
+        ChanParam *cp = &s->channels[chan];
+
+        for (i = 0; i < nb_samples; i++) {
+            update_volume(cp, fabs(src[i]));
+
+            dst[i] = av_clipd(src[i] * get_volume(s, cp->volume), -1, 1);
+        }
+    }
+
+    if (frame != out_frame)
+        av_frame_free(&frame);
+
+    return ff_filter_frame(ctx->outputs[0], out_frame);
+}
+
+#define MOD(a, b) (((a) >= (b)) ? (a) - (b) : (a))
+
+static int compand_delay(AVFilterContext *ctx, AVFrame *frame)
+{
+    CompandContext *s = ctx->priv;
+    AVFilterLink *inlink = ctx->inputs[0];
+    const int channels = inlink->channels;
+    const int nb_samples = frame->nb_samples;
+    int chan, i, dindex, oindex, count;
+    AVFrame *out_frame = NULL;
+
+    for (chan = 0; chan < channels; chan++) {
+        const double *src = (double *)frame->data[chan];
+        double *dbuf = (double *)s->delayptrs[chan];
+        ChanParam *cp = &s->channels[chan];
+        double *dst;
+
+        count  = s->delay_count;
+        dindex = s->delay_index;
+        for (i = 0, oindex = 0; i < nb_samples; i++) {
+            const double in = src[i];
+            update_volume(cp, fabs(in));
+
+            if (count >= s->delay_samples) {
+                if (!out_frame) {
+                    out_frame = ff_get_audio_buffer(inlink, nb_samples - i);
+                    if (!out_frame)
+                        return AVERROR(ENOMEM);
+                    av_frame_copy_props(out_frame, frame);
+                    out_frame->pts = s->pts;
+                    s->pts += av_rescale_q(nb_samples - i, (AVRational){1, inlink->sample_rate}, inlink->time_base);
+                }
+
+                dst = (double *)out_frame->data[chan];
+                dst[oindex++] = av_clipd(dbuf[dindex] * get_volume(s, cp->volume), -1, 1);
+            } else {
+                count++;
+            }
+
+            dbuf[dindex] = in;
+            dindex = MOD(dindex + 1, s->delay_samples);
+        }
+    }
+
+    s->delay_count = count;
+    s->delay_index = dindex;
+
+    av_frame_free(&frame);
+    return out_frame ? ff_filter_frame(ctx->outputs[0], out_frame) : 0;
+}
+
+static int compand_drain(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    CompandContext *s = ctx->priv;
+    const int channels = outlink->channels;
+    int chan, i, dindex;
+    AVFrame *frame = NULL;
+
+    frame = ff_get_audio_buffer(outlink, FFMIN(2048, s->delay_count));
+    if (!frame)
+        return AVERROR(ENOMEM);
+    frame->pts = s->pts;
+    s->pts += av_rescale_q(frame->nb_samples, (AVRational){1, outlink->sample_rate}, outlink->time_base);
+
+    for (chan = 0; chan < channels; chan++) {
+        double *dbuf = (double *)s->delayptrs[chan];
+        double *dst = (double *)frame->data[chan];
+        ChanParam *cp = &s->channels[chan];
+
+        dindex = s->delay_index;
+        for (i = 0; i < frame->nb_samples; i++) {
+            dst[i] = av_clipd(dbuf[dindex] * get_volume(s, cp->volume), -1, 1);
+            dindex = MOD(dindex + 1, s->delay_samples);
+        }
+    }
+    s->delay_count -= frame->nb_samples;
+    s->delay_index = dindex;
+
+    return ff_filter_frame(outlink, frame);
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    CompandContext *s = ctx->priv;
+    const int sample_rate = outlink->sample_rate;
+    double radius = s->curve_dB * M_LN10 / 20;
+    int nb_attacks, nb_decays, nb_points;
+    char *p, *saveptr = NULL;
+    int new_nb_items, num;
+    int i;
+
+    count_items(s->attacks, &nb_attacks);
+    count_items(s->decays, &nb_decays);
+    count_items(s->points, &nb_points);
+
+    if ((nb_attacks > outlink->channels) || (nb_decays > outlink->channels)) {
+        av_log(ctx, AV_LOG_ERROR, "Number of attacks/decays bigger than number of channels.\n");
+        return AVERROR(EINVAL);
+    }
+
+    uninit(ctx);
+
+    s->channels = av_mallocz_array(outlink->channels, sizeof(*s->channels));
+    s->segments = av_mallocz_array((nb_points + 4) * 2, sizeof(*s->segments));
+
+    if (!s->channels || !s->segments)
+        return AVERROR(ENOMEM);
+
+    p = s->attacks;
+    for (i = 0, new_nb_items = 0; i < nb_attacks; i++) {
+        char *tstr = av_strtok(p, " ", &saveptr);
+        p = NULL;
+        new_nb_items += sscanf(tstr, "%lf", &s->channels[i].attack) == 1;
+        if (s->channels[i].attack < 0)
+            return AVERROR(EINVAL);
+    }
+    nb_attacks = new_nb_items;
+
+    p = s->decays;
+    for (i = 0, new_nb_items = 0; i < nb_decays; i++) {
+        char *tstr = av_strtok(p, " ", &saveptr);
+        p = NULL;
+        new_nb_items += sscanf(tstr, "%lf", &s->channels[i].decay) == 1;
+        if (s->channels[i].decay < 0)
+            return AVERROR(EINVAL);
+    }
+    nb_decays = new_nb_items;
+
+    if (nb_attacks != nb_decays) {
+        av_log(ctx, AV_LOG_ERROR, "Number of attacks %d differs from number of decays %d.\n", nb_attacks, nb_decays);
+        return AVERROR(EINVAL);
+    }
+
+#define S(x) s->segments[2 * ((x) + 1)]
+    p = s->points;
+    for (i = 0, new_nb_items = 0; i < nb_points; i++) {
+        char *tstr = av_strtok(p, " ", &saveptr);
+        p = NULL;
+        if (sscanf(tstr, "%lf/%lf", &S(i).x, &S(i).y) != 2) {
+            av_log(ctx, AV_LOG_ERROR, "Invalid and/or missing input/output value.\n");
+            return AVERROR(EINVAL);
+        }
+        if (i && S(i - 1).x > S(i).x) {
+            av_log(ctx, AV_LOG_ERROR, "Transfer function input values must be increasing.\n");
+            return AVERROR(EINVAL);
+        }
+        S(i).y -= S(i).x;
+        av_log(ctx, AV_LOG_DEBUG, "%d: x=%f y=%f\n", i, S(i).x, S(i).y);
+        new_nb_items++;
+    }
+    num = new_nb_items;
+
+    /* Add 0,0 if necessary */
+    if (num == 0 || S(num - 1).x)
+        num++;
+
+#undef S
+#define S(x) s->segments[2 * (x)]
+    /* Add a tail off segment at the start */
+    S(0).x = S(1).x - 2 * s->curve_dB;
+    S(0).y = S(1).y;
+    num++;
+
+    /* Join adjacent colinear segments */
+    for (i = 2; i < num; i++) {
+        double g1 = (S(i - 1).y - S(i - 2).y) * (S(i - 0).x - S(i - 1).x);
+        double g2 = (S(i - 0).y - S(i - 1).y) * (S(i - 1).x - S(i - 2).x);
+        int j;
+
+        if (fabs(g1 - g2))
+            continue;
+        num--;
+        for (j = --i; j < num; j++)
+            S(j) = S(j + 1);
+    }
+
+    for (i = 0; !i || s->segments[i - 2].x; i += 2) {
+        s->segments[i].y += s->gain_dB;
+        s->segments[i].x *= M_LN10 / 20;
+        s->segments[i].y *= M_LN10 / 20;
+    }
+
+#define L(x) s->segments[i - (x)]
+    for (i = 4; s->segments[i - 2].x; i += 2) {
+        double x, y, cx, cy, in1, in2, out1, out2, theta, len, r;
+
+        L(4).a = 0;
+        L(4).b = (L(2).y - L(4).y) / (L(2).x - L(4).x);
+
+        L(2).a = 0;
+        L(2).b = (L(0).y - L(2).y) / (L(0).x - L(2).x);
+
+        theta = atan2(L(2).y - L(4).y, L(2).x - L(4).x);
+        len = sqrt(pow(L(2).x - L(4).x, 2.) + pow(L(2).y - L(4).y, 2.));
+        r = FFMIN(radius, len);
+        L(3).x = L(2).x - r * cos(theta);
+        L(3).y = L(2).y - r * sin(theta);
+
+        theta = atan2(L(0).y - L(2).y, L(0).x - L(2).x);
+        len = sqrt(pow(L(0).x - L(2).x, 2.) + pow(L(0).y - L(2).y, 2.));
+        r = FFMIN(radius, len / 2);
+        x = L(2).x + r * cos(theta);
+        y = L(2).y + r * sin(theta);
+
+        cx = (L(3).x + L(2).x + x) / 3;
+        cy = (L(3).y + L(2).y + y) / 3;
+
+        L(2).x = x;
+        L(2).y = y;
+
+        in1 = cx - L(3).x;
+        out1 = cy - L(3).y;
+        in2 = L(2).x - L(3).x;
+        out2 = L(2).y - L(3).y;
+        L(3).a = (out2 / in2 - out1 / in1) / (in2-in1);
+        L(3).b = out1 / in1 - L(3).a * in1;
+    }
+    L(3).x = 0;
+    L(3).y = L(2).y;
+
+    s->in_min_lin  = exp(s->segments[1].x);
+    s->out_min_lin = exp(s->segments[1].y);
+
+    for (i = 0; i < outlink->channels; i++) {
+        ChanParam *cp = &s->channels[i];
+
+        if (cp->attack > 1.0 / sample_rate)
+            cp->attack = 1.0 - exp(-1.0 / (sample_rate * cp->attack));
+        else
+            cp->attack = 1.0;
+        if (cp->decay > 1.0 / sample_rate)
+            cp->decay = 1.0 - exp(-1.0 / (sample_rate * cp->decay));
+        else
+            cp->decay = 1.0;
+        cp->volume = pow(10.0, s->initial_volume / 20);
+    }
+
+    s->delay_samples = s->delay * sample_rate;
+    if (s->delay_samples > 0) {
+        int ret;
+        if ((ret = av_samples_alloc_array_and_samples(&s->delayptrs, NULL,
+                                                      outlink->channels,
+                                                      s->delay_samples,
+                                                      outlink->format, 0)) < 0)
+            return ret;
+        s->compand = compand_delay;
+        outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP;
+    } else {
+        s->compand = compand_nodelay;
+    }
+    return 0;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
+{
+    AVFilterContext *ctx = inlink->dst;
+    CompandContext *s = ctx->priv;
+
+    return s->compand(ctx, frame);
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    CompandContext *s = ctx->priv;
+    int ret;
+
+    ret = ff_request_frame(ctx->inputs[0]);
+
+    if (ret == AVERROR_EOF && !ctx->is_disabled && s->delay_count)
+        ret = compand_drain(outlink);
+
+    return ret;
+}
+
+static const AVFilterPad compand_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_AUDIO,
+        .filter_frame = filter_frame,
+    },
+    { NULL },
+};
+
+static const AVFilterPad compand_outputs[] = {
+    {
+        .name          = "default",
+        .request_frame = request_frame,
+        .config_props  = config_output,
+        .type          = AVMEDIA_TYPE_AUDIO,
+    },
+    { NULL },
+};
+
+AVFilter avfilter_af_compand = {
+    .name          = "compand",
+    .description   = NULL_IF_CONFIG_SMALL("Compress or expand audio dynamic range."),
+    .query_formats = query_formats,
+    .priv_size     = sizeof(CompandContext),
+    .priv_class    = &compand_class,
+    .init          = init,
+    .uninit        = uninit,
+    .inputs        = compand_inputs,
+    .outputs       = compand_outputs,
+};
diff --git a/libavfilter/af_earwax.c b/libavfilter/af_earwax.c
index 189243a..3db4659 100644
--- a/libavfilter/af_earwax.c
+++ b/libavfilter/af_earwax.c
@@ -114,6 +114,7 @@
     AVFilterLink *outlink = inlink->dst->outputs[0];
     int16_t *taps, *endin, *in, *out;
     AVFrame *outsamples = ff_get_audio_buffer(inlink, insamples->nb_samples);
+    int len;
 
     if (!outsamples) {
         av_frame_free(&insamples);
@@ -125,16 +126,20 @@
     out   = (int16_t *)outsamples->data[0];
     in    = (int16_t *)insamples ->data[0];
 
+    len = FFMIN(NUMTAPS, 2*insamples->nb_samples);
     // copy part of new input and process with saved input
-    memcpy(taps+NUMTAPS, in, NUMTAPS * sizeof(*taps));
-    out   = scalarproduct(taps, taps + NUMTAPS, out);
+    memcpy(taps+NUMTAPS, in, len * sizeof(*taps));
+    out   = scalarproduct(taps, taps + len, out);
 
     // process current input
-    endin = in + insamples->nb_samples * 2 - NUMTAPS;
-    scalarproduct(in, endin, out);
+    if (2*insamples->nb_samples >= NUMTAPS ){
+        endin = in + insamples->nb_samples * 2 - NUMTAPS;
+        scalarproduct(in, endin, out);
 
-    // save part of input for next round
-    memcpy(taps, endin, NUMTAPS * sizeof(*taps));
+        // save part of input for next round
+        memcpy(taps, endin, NUMTAPS * sizeof(*taps));
+    } else
+        memmove(taps, taps + 2*insamples->nb_samples, NUMTAPS * sizeof(*taps));
 
     av_frame_free(&insamples);
     return ff_filter_frame(outlink, outsamples);
diff --git a/libavfilter/af_join.c b/libavfilter/af_join.c
index cea448b..11978bd 100644
--- a/libavfilter/af_join.c
+++ b/libavfilter/af_join.c
@@ -77,12 +77,7 @@
     { NULL },
 };
 
-static const AVClass join_class = {
-    .class_name = "join filter",
-    .item_name  = av_default_item_name,
-    .option     = join_options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
+AVFILTER_DEFINE_CLASS(join);
 
 static int filter_frame(AVFilterLink *link, AVFrame *frame)
 {
@@ -187,7 +182,7 @@
     return 0;
 }
 
-static int join_init(AVFilterContext *ctx)
+static av_cold int join_init(AVFilterContext *ctx)
 {
     JoinContext *s = ctx->priv;
     int ret, i;
@@ -235,7 +230,7 @@
     return ret;
 }
 
-static void join_uninit(AVFilterContext *ctx)
+static av_cold void join_uninit(AVFilterContext *ctx)
 {
     JoinContext *s = ctx->priv;
     int i;
diff --git a/libavfilter/af_silencedetect.c b/libavfilter/af_silencedetect.c
index eb4718b..0ae3c24 100644
--- a/libavfilter/af_silencedetect.c
+++ b/libavfilter/af_silencedetect.c
@@ -25,7 +25,6 @@
 
 #include <float.h> /* DBL_MAX */
 
-#include "libavutil/channel_layout.h"
 #include "libavutil/opt.h"
 #include "libavutil/timestamp.h"
 #include "audio.h"
@@ -64,7 +63,7 @@
 {
     int i;
     SilenceDetectContext *silence = inlink->dst->priv;
-    const int nb_channels           = av_get_channel_layout_nb_channels(inlink->channel_layout);
+    const int nb_channels           = inlink->channels;
     const int srate                 = inlink->sample_rate;
     const int nb_samples            = insamples->nb_samples     * nb_channels;
     const int64_t nb_samples_notify = srate * silence->duration * nb_channels;
diff --git a/libavfilter/af_volume.c b/libavfilter/af_volume.c
index a55e1a3..a2ac1e2 100644
--- a/libavfilter/af_volume.c
+++ b/libavfilter/af_volume.c
@@ -165,7 +165,7 @@
         smp_dst[i] = av_clipl_int32((((int64_t)smp_src[i] * volume + 128) >> 8));
 }
 
-static void volume_init(VolumeContext *vol)
+static av_cold void volume_init(VolumeContext *vol)
 {
     vol->samples_align = 1;
 
@@ -296,5 +296,5 @@
     .init           = init,
     .inputs         = avfilter_af_volume_inputs,
     .outputs        = avfilter_af_volume_outputs,
-    .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/af_volumedetect.c b/libavfilter/af_volumedetect.c
index 79d992e..f00836f 100644
--- a/libavfilter/af_volumedetect.c
+++ b/libavfilter/af_volumedetect.c
@@ -126,7 +126,7 @@
     }
 }
 
-static void uninit(AVFilterContext *ctx)
+static av_cold void uninit(AVFilterContext *ctx)
 {
     print_stats(ctx);
 }
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 2fc8b48..bcebcfc 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -48,6 +48,7 @@
 #if FF_API_ACONVERT_FILTER
     REGISTER_FILTER(ACONVERT,       aconvert,       af);
 #endif
+    REGISTER_FILTER(AECHO,          aecho,          af);
     REGISTER_FILTER(AFADE,          afade,          af);
     REGISTER_FILTER(AFORMAT,        aformat,        af);
     REGISTER_FILTER(AINTERLEAVE,    ainterleave,    af);
@@ -67,15 +68,19 @@
     REGISTER_FILTER(ASETTB,         asettb,         af);
     REGISTER_FILTER(ASHOWINFO,      ashowinfo,      af);
     REGISTER_FILTER(ASPLIT,         asplit,         af);
+    REGISTER_FILTER(ASTATS,         astats,         af);
     REGISTER_FILTER(ASTREAMSYNC,    astreamsync,    af);
     REGISTER_FILTER(ASYNCTS,        asyncts,        af);
     REGISTER_FILTER(ATEMPO,         atempo,         af);
+    REGISTER_FILTER(ATRIM,          atrim,          af);
+    REGISTER_FILTER(AZMQ,           azmq,           af);
     REGISTER_FILTER(BANDPASS,       bandpass,       af);
     REGISTER_FILTER(BANDREJECT,     bandreject,     af);
     REGISTER_FILTER(BASS,           bass,           af);
     REGISTER_FILTER(BIQUAD,         biquad,         af);
     REGISTER_FILTER(CHANNELMAP,     channelmap,     af);
     REGISTER_FILTER(CHANNELSPLIT,   channelsplit,   af);
+    REGISTER_FILTER(COMPAND,        compand,        af);
     REGISTER_FILTER(EARWAX,         earwax,         af);
     REGISTER_FILTER(EBUR128,        ebur128,        af);
     REGISTER_FILTER(EQUALIZER,      equalizer,      af);
@@ -111,12 +116,15 @@
     REGISTER_FILTER(CROP,           crop,           vf);
     REGISTER_FILTER(CROPDETECT,     cropdetect,     vf);
     REGISTER_FILTER(CURVES,         curves,         vf);
+    REGISTER_FILTER(DCTDNOIZ,       dctdnoiz,       vf);
     REGISTER_FILTER(DECIMATE,       decimate,       vf);
     REGISTER_FILTER(DELOGO,         delogo,         vf);
     REGISTER_FILTER(DESHAKE,        deshake,        vf);
     REGISTER_FILTER(DRAWBOX,        drawbox,        vf);
+    REGISTER_FILTER(DRAWGRID,       drawgrid,       vf);
     REGISTER_FILTER(DRAWTEXT,       drawtext,       vf);
     REGISTER_FILTER(EDGEDETECT,     edgedetect,     vf);
+    REGISTER_FILTER(EXTRACTPLANES,  extractplanes,  vf);
     REGISTER_FILTER(FADE,           fade,           vf);
     REGISTER_FILTER(FIELD,          field,          vf);
     REGISTER_FILTER(FIELDMATCH,     fieldmatch,     vf);
@@ -127,6 +135,7 @@
     REGISTER_FILTER(FREI0R,         frei0r,         vf);
     REGISTER_FILTER(GEQ,            geq,            vf);
     REGISTER_FILTER(GRADFUN,        gradfun,        vf);
+    REGISTER_FILTER(HALDCLUT,       haldclut,       vf);
     REGISTER_FILTER(HFLIP,          hflip,          vf);
     REGISTER_FILTER(HISTEQ,         histeq,         vf);
     REGISTER_FILTER(HISTOGRAM,      histogram,      vf);
@@ -137,9 +146,11 @@
     REGISTER_FILTER(INTERLACE,      interlace,      vf);
     REGISTER_FILTER(INTERLEAVE,     interleave,     vf);
     REGISTER_FILTER(KERNDEINT,      kerndeint,      vf);
+    REGISTER_FILTER(LUT3D,          lut3d,          vf);
     REGISTER_FILTER(LUT,            lut,            vf);
     REGISTER_FILTER(LUTRGB,         lutrgb,         vf);
     REGISTER_FILTER(LUTYUV,         lutyuv,         vf);
+    REGISTER_FILTER(MCDEINT,        mcdeint,        vf);
     REGISTER_FILTER(MP,             mp,             vf);
     REGISTER_FILTER(MPDECIMATE,     mpdecimate,     vf);
     REGISTER_FILTER(NEGATE,         negate,         vf);
@@ -148,11 +159,16 @@
     REGISTER_FILTER(NULL,           null,           vf);
     REGISTER_FILTER(OCV,            ocv,            vf);
     REGISTER_FILTER(OVERLAY,        overlay,        vf);
+    REGISTER_FILTER(OWDENOISE,      owdenoise,      vf);
     REGISTER_FILTER(PAD,            pad,            vf);
     REGISTER_FILTER(PERMS,          perms,          vf);
+    REGISTER_FILTER(PERSPECTIVE,    perspective,    vf);
     REGISTER_FILTER(PIXDESCTEST,    pixdesctest,    vf);
     REGISTER_FILTER(PP,             pp,             vf);
+    REGISTER_FILTER(PSNR,           psnr,           vf);
     REGISTER_FILTER(REMOVELOGO,     removelogo,     vf);
+    REGISTER_FILTER(ROTATE,         rotate,         vf);
+    REGISTER_FILTER(SAB,            sab,            vf);
     REGISTER_FILTER(SCALE,          scale,          vf);
     REGISTER_FILTER(SELECT,         select,         vf);
     REGISTER_FILTER(SENDCMD,        sendcmd,        vf);
@@ -165,6 +181,7 @@
     REGISTER_FILTER(SHOWINFO,       showinfo,       vf);
     REGISTER_FILTER(SMARTBLUR,      smartblur,      vf);
     REGISTER_FILTER(SPLIT,          split,          vf);
+    REGISTER_FILTER(SPP,            spp,            vf);
     REGISTER_FILTER(STEREO3D,       stereo3d,       vf);
     REGISTER_FILTER(SUBTITLES,      subtitles,      vf);
     REGISTER_FILTER(SUPER2XSAI,     super2xsai,     vf);
@@ -174,15 +191,19 @@
     REGISTER_FILTER(TILE,           tile,           vf);
     REGISTER_FILTER(TINTERLACE,     tinterlace,     vf);
     REGISTER_FILTER(TRANSPOSE,      transpose,      vf);
+    REGISTER_FILTER(TRIM,           trim,           vf);
     REGISTER_FILTER(UNSHARP,        unsharp,        vf);
     REGISTER_FILTER(VFLIP,          vflip,          vf);
     REGISTER_FILTER(VIDSTABDETECT,  vidstabdetect,  vf);
     REGISTER_FILTER(VIDSTABTRANSFORM, vidstabtransform, vf);
+    REGISTER_FILTER(VIGNETTE,       vignette,       vf);
     REGISTER_FILTER(YADIF,          yadif,          vf);
+    REGISTER_FILTER(ZMQ,            zmq,            vf);
 
     REGISTER_FILTER(CELLAUTO,       cellauto,       vsrc);
     REGISTER_FILTER(COLOR,          color,          vsrc);
     REGISTER_FILTER(FREI0R,         frei0r_src,     vsrc);
+    REGISTER_FILTER(HALDCLUTSRC,    haldclutsrc,    vsrc);
     REGISTER_FILTER(LIFE,           life,           vsrc);
     REGISTER_FILTER(MANDELBROT,     mandelbrot,     vsrc);
     REGISTER_FILTER(MPTESTSRC,      mptestsrc,      vsrc);
@@ -195,6 +216,7 @@
     REGISTER_FILTER(NULLSINK,       nullsink,       vsink);
 
     /* multimedia filters */
+    REGISTER_FILTER(AVECTORSCOPE,   avectorscope,   avf);
     REGISTER_FILTER(CONCAT,         concat,         avf);
     REGISTER_FILTER(SHOWSPECTRUM,   showspectrum,   avf);
     REGISTER_FILTER(SHOWWAVES,      showwaves,      avf);
diff --git a/libavfilter/asrc_aevalsrc.c b/libavfilter/asrc_aevalsrc.c
index 6e338ad..ebeb616 100644
--- a/libavfilter/asrc_aevalsrc.c
+++ b/libavfilter/asrc_aevalsrc.c
@@ -55,11 +55,10 @@
     char *chlayout_str;
     int nb_channels;
     int64_t pts;
-    AVExpr *expr[8];
+    AVExpr **expr;
     char *exprs;
     int nb_samples;             ///< number of samples per requested frame
-    char *duration_str;         ///< total duration of the generated audio
-    double duration;
+    int64_t duration;
     uint64_t n;
     double var_values[VAR_VARS_NB];
 } EvalContext;
@@ -73,8 +72,8 @@
     { "n",           "set the number of samples per requested frame", OFFSET(nb_samples),      AV_OPT_TYPE_INT,    {.i64 = 1024},    0,        INT_MAX, FLAGS },
     { "sample_rate", "set the sample rate",                           OFFSET(sample_rate_str), AV_OPT_TYPE_STRING, {.str = "44100"}, CHAR_MIN, CHAR_MAX, FLAGS },
     { "s",           "set the sample rate",                           OFFSET(sample_rate_str), AV_OPT_TYPE_STRING, {.str = "44100"}, CHAR_MIN, CHAR_MAX, FLAGS },
-    { "duration",    "set audio duration", OFFSET(duration_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
-    { "d",           "set audio duration", OFFSET(duration_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+    { "duration",    "set audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },
+    { "d",           "set audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },
     { "channel_layout", "set channel layout", OFFSET(chlayout_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
     { "c",              "set channel layout", OFFSET(chlayout_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
 {NULL},
@@ -87,7 +86,7 @@
     EvalContext *eval = ctx->priv;
     char *args1 = av_strdup(eval->exprs);
     char *expr, *buf;
-    int ret, i;
+    int ret;
 
     if (!args1) {
         av_log(ctx, AV_LOG_ERROR, "Channels expressions list is empty\n");
@@ -97,15 +96,16 @@
 
     /* parse expressions */
     buf = args1;
-    i = 0;
-    while (i < FF_ARRAY_ELEMS(eval->expr) && (expr = av_strtok(buf, "|", &buf))) {
-        ret = av_expr_parse(&eval->expr[i], expr, var_names,
+    while (expr = av_strtok(buf, "|", &buf)) {
+        if (!av_dynarray2_add((void **)&eval->expr, &eval->nb_channels, sizeof(*eval->expr), NULL)) {
+            ret = AVERROR(ENOMEM);
+            goto end;
+        }
+        ret = av_expr_parse(&eval->expr[eval->nb_channels - 1], expr, var_names,
                             NULL, NULL, NULL, NULL, 0, ctx);
         if (ret < 0)
             goto end;
-        i++;
     }
-    eval->nb_channels = i;
 
     if (eval->chlayout_str) {
         int n;
@@ -125,7 +125,7 @@
     } else {
         /* guess channel layout from nb expressions/channels */
         eval->chlayout = av_get_default_channel_layout(eval->nb_channels);
-        if (!eval->chlayout) {
+        if (!eval->chlayout && eval->nb_channels <= 0) {
             av_log(ctx, AV_LOG_ERROR, "Invalid number of channels '%d' provided\n",
                    eval->nb_channels);
             ret = AVERROR(EINVAL);
@@ -135,16 +135,6 @@
 
     if ((ret = ff_parse_sample_rate(&eval->sample_rate, eval->sample_rate_str, ctx)))
         goto end;
-
-    eval->duration = -1;
-    if (eval->duration_str) {
-        int64_t us = -1;
-        if ((ret = av_parse_time(&us, eval->duration_str, 1)) < 0) {
-            av_log(ctx, AV_LOG_ERROR, "Invalid duration: '%s'\n", eval->duration_str);
-            goto end;
-        }
-        eval->duration = (double)us / 1000000;
-    }
     eval->n = 0;
 
 end:
@@ -152,18 +142,16 @@
     return ret;
 }
 
-static void uninit(AVFilterContext *ctx)
+static av_cold void uninit(AVFilterContext *ctx)
 {
     EvalContext *eval = ctx->priv;
     int i;
 
-    for (i = 0; i < 8; i++) {
+    for (i = 0; i < eval->nb_channels; i++) {
         av_expr_free(eval->expr[i]);
         eval->expr[i] = NULL;
     }
-    av_freep(&eval->chlayout_str);
-    av_freep(&eval->duration_str);
-    av_freep(&eval->sample_rate_str);
+    av_freep(&eval->expr);
 }
 
 static int config_props(AVFilterLink *outlink)
@@ -179,7 +167,7 @@
     av_get_channel_layout_string(buf, sizeof(buf), 0, eval->chlayout);
 
     av_log(outlink->src, AV_LOG_VERBOSE,
-           "sample_rate:%d chlayout:%s duration:%f\n",
+           "sample_rate:%d chlayout:%s duration:%"PRId64"\n",
            eval->sample_rate, buf, eval->duration);
 
     return 0;
@@ -189,7 +177,7 @@
 {
     EvalContext *eval = ctx->priv;
     static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_DBLP, AV_SAMPLE_FMT_NONE };
-    int64_t chlayouts[] = { eval->chlayout, -1 };
+    int64_t chlayouts[] = { eval->chlayout ? eval->chlayout : FF_COUNT2LAYOUT(eval->nb_channels) , -1 };
     int sample_rates[] = { eval->sample_rate, -1 };
 
     ff_set_common_formats (ctx, ff_make_format_list(sample_fmts));
@@ -204,7 +192,7 @@
     EvalContext *eval = outlink->src->priv;
     AVFrame *samplesref;
     int i, j;
-    double t = eval->n * (double)1/eval->sample_rate;
+    int64_t t = av_rescale(eval->n, AV_TIME_BASE, eval->sample_rate);
 
     if (eval->duration >= 0 && t >= eval->duration)
         return AVERROR_EOF;
diff --git a/libavfilter/audio.c b/libavfilter/audio.c
index 1075217..315c273 100644
--- a/libavfilter/audio.c
+++ b/libavfilter/audio.c
@@ -42,43 +42,29 @@
 {
     AVFrame *frame = av_frame_alloc();
     int channels = link->channels;
-    int buf_size, ret;
+    int ret;
 
     av_assert0(channels == av_get_channel_layout_nb_channels(link->channel_layout) || !av_get_channel_layout_nb_channels(link->channel_layout));
 
     if (!frame)
         return NULL;
 
-    buf_size = av_samples_get_buffer_size(NULL, channels, nb_samples,
-                                          link->format, 0);
-    if (buf_size < 0)
-        goto fail;
-
-    frame->buf[0] = av_buffer_alloc(buf_size);
-    if (!frame->buf[0])
-        goto fail;
-
-    frame->nb_samples = nb_samples;
-    ret = avcodec_fill_audio_frame(frame, channels, link->format,
-                                   frame->buf[0]->data, buf_size, 0);
-    if (ret < 0)
-        goto fail;
-
-    av_samples_set_silence(frame->extended_data, 0, nb_samples, channels,
-                           link->format);
-
     frame->nb_samples     = nb_samples;
     frame->format         = link->format;
     av_frame_set_channels(frame, link->channels);
     frame->channel_layout = link->channel_layout;
     frame->sample_rate    = link->sample_rate;
+    ret = av_frame_get_buffer(frame, 0);
+    if (ret < 0) {
+        av_frame_free(&frame);
+        return NULL;
+    }
+
+    av_samples_set_silence(frame->extended_data, 0, nb_samples, channels,
+                           link->format);
+
 
     return frame;
-
-fail:
-    av_buffer_unref(&frame->buf[0]);
-    av_frame_free(&frame);
-    return NULL;
 }
 
 AVFrame *ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
diff --git a/libavfilter/avf_avectorscope.c b/libavfilter/avf_avectorscope.c
new file mode 100644
index 0000000..f5c7e31
--- /dev/null
+++ b/libavfilter/avf_avectorscope.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2013 Paul B Mahol
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * audio to video multimedia vector scope filter
+ */
+
+#include "libavutil/avassert.h"
+#include "libavutil/channel_layout.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "audio.h"
+#include "video.h"
+#include "internal.h"
+
+enum VectorScopeMode {
+    LISSAJOUS,
+    LISSAJOUS_XY,
+    MODE_NB,
+};
+
+typedef struct AudioVectorScopeContext {
+    const AVClass *class;
+    AVFrame *outpicref;
+    int w, h;
+    int hw, hh;
+    enum VectorScopeMode mode;
+    int contrast[3];
+    int fade[3];
+    double zoom;
+    AVRational frame_rate;
+} AudioVectorScopeContext;
+
+#define OFFSET(x) offsetof(AudioVectorScopeContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+
+static const AVOption avectorscope_options[] = {
+    { "mode", "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=LISSAJOUS}, 0, MODE_NB-1, FLAGS, "mode" },
+    { "m",    "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=LISSAJOUS}, 0, MODE_NB-1, FLAGS, "mode" },
+    { "lissajous",    "", 0, AV_OPT_TYPE_CONST, {.i64=LISSAJOUS},    0, 0, FLAGS, "mode" },
+    { "lissajous_xy", "", 0, AV_OPT_TYPE_CONST, {.i64=LISSAJOUS_XY}, 0, 0, FLAGS, "mode" },
+    { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str="25"}, 0, 0, FLAGS },
+    { "r",    "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str="25"}, 0, 0, FLAGS },
+    { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str="400x400"}, 0, 0, FLAGS },
+    { "s",    "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str="400x400"}, 0, 0, FLAGS },
+    { "rc", "set red contrast",   OFFSET(contrast[0]), AV_OPT_TYPE_INT, {.i64=40}, 0, 255, FLAGS },
+    { "gc", "set green contrast", OFFSET(contrast[1]), AV_OPT_TYPE_INT, {.i64=160}, 0, 255, FLAGS },
+    { "bc", "set blue contrast",  OFFSET(contrast[2]), AV_OPT_TYPE_INT, {.i64=80}, 0, 255, FLAGS },
+    { "rf", "set red fade",       OFFSET(fade[0]), AV_OPT_TYPE_INT, {.i64=15}, 0, 255, FLAGS },
+    { "gf", "set green fade",     OFFSET(fade[1]), AV_OPT_TYPE_INT, {.i64=10}, 0, 255, FLAGS },
+    { "bf", "set blue fade",      OFFSET(fade[2]), AV_OPT_TYPE_INT, {.i64=5}, 0, 255, FLAGS },
+    { "zoom", "set zoom factor",  OFFSET(zoom), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 1, 10, FLAGS },
+    {NULL},
+};
+
+AVFILTER_DEFINE_CLASS(avectorscope);
+
+static void draw_dot(AudioVectorScopeContext *p, unsigned x, unsigned y)
+{
+    const int linesize = p->outpicref->linesize[0];
+    uint8_t *dst;
+
+    if (p->zoom > 1) {
+        if (y >= p->h || x >= p->w)
+            return;
+    } else {
+        y = FFMIN(y, p->h - 1);
+        x = FFMIN(x, p->w - 1);
+    }
+
+    dst = &p->outpicref->data[0][y * linesize + x * 4];
+    dst[0] = FFMIN(dst[0] + p->contrast[0], 255);
+    dst[1] = FFMIN(dst[1] + p->contrast[1], 255);
+    dst[2] = FFMIN(dst[2] + p->contrast[2], 255);
+}
+
+static void fade(AudioVectorScopeContext *p)
+{
+    const int linesize = p->outpicref->linesize[0];
+    int i, j;
+
+    if (p->fade[0] || p->fade[1] || p->fade[2]) {
+        uint8_t *d = p->outpicref->data[0];
+        for (i = 0; i < p->h; i++) {
+            for (j = 0; j < p->w*4; j+=4) {
+                d[j+0] = FFMAX(d[j+0] - p->fade[0], 0);
+                d[j+1] = FFMAX(d[j+1] - p->fade[1], 0);
+                d[j+2] = FFMAX(d[j+2] - p->fade[2], 0);
+            }
+            d += linesize;
+        }
+    }
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    AVFilterFormats *formats = NULL;
+    AVFilterChannelLayouts *layout = NULL;
+    AVFilterLink *inlink = ctx->inputs[0];
+    AVFilterLink *outlink = ctx->outputs[0];
+    static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE };
+    static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_RGBA, AV_PIX_FMT_NONE };
+
+    formats = ff_make_format_list(sample_fmts);
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_formats_ref(formats, &inlink->out_formats);
+
+    ff_add_channel_layout(&layout, AV_CH_LAYOUT_STEREO);
+    ff_channel_layouts_ref(layout, &inlink->out_channel_layouts);
+
+    formats = ff_all_samplerates();
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_formats_ref(formats, &inlink->out_samplerates);
+
+    formats = ff_make_format_list(pix_fmts);
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_formats_ref(formats, &outlink->in_formats);
+
+    return 0;
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->dst;
+    AudioVectorScopeContext *p = ctx->priv;
+    int nb_samples;
+
+    nb_samples = FFMAX(1024, ((double)inlink->sample_rate / av_q2d(p->frame_rate)) + 0.5);
+    inlink->partial_buf_size =
+    inlink->min_samples =
+    inlink->max_samples = nb_samples;
+
+    return 0;
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+    AudioVectorScopeContext *p = outlink->src->priv;
+
+    outlink->w = p->w;
+    outlink->h = p->h;
+    outlink->sample_aspect_ratio = (AVRational){1,1};
+    outlink->frame_rate = p->frame_rate;
+
+    p->hw = p->w / 2;
+    p->hh = p->h / 2;
+
+    return 0;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
+{
+    AVFilterContext *ctx = inlink->dst;
+    AVFilterLink *outlink = ctx->outputs[0];
+    AudioVectorScopeContext *p = ctx->priv;
+    const int hw = p->hw;
+    const int hh = p->hh;
+    unsigned x, y;
+    const double zoom = p->zoom;
+    int i;
+
+    if (!p->outpicref || p->outpicref->width  != outlink->w ||
+                         p->outpicref->height != outlink->h) {
+        av_frame_free(&p->outpicref);
+        p->outpicref = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+        if (!p->outpicref)
+            av_frame_free(&insamples);
+            return AVERROR(ENOMEM);
+
+        for (i = 0; i < outlink->h; i++)
+            memset(p->outpicref->data[0] + i * p->outpicref->linesize[0], 0, outlink->w * 4);
+    }
+    p->outpicref->pts = insamples->pts;
+
+    fade(p);
+
+    switch (insamples->format) {
+    case AV_SAMPLE_FMT_S16:
+        for (i = 0; i < insamples->nb_samples; i++) {
+            int16_t *src = (int16_t *)insamples->data[0] + i * 2;
+
+            if (p->mode == LISSAJOUS) {
+                x = ((src[1] - src[0]) * zoom / (float)(UINT16_MAX) + 1) * hw;
+                y = (1.0 - (src[0] + src[1]) * zoom / (float)UINT16_MAX) * hh;
+            } else {
+                x = (src[1] * zoom / (float)INT16_MAX + 1) * hw;
+                y = (src[0] * zoom / (float)INT16_MAX + 1) * hh;
+            }
+
+            draw_dot(p, x, y);
+        }
+        break;
+    case AV_SAMPLE_FMT_FLT:
+        for (i = 0; i < insamples->nb_samples; i++) {
+            float *src = (float *)insamples->data[0] + i * 2;
+
+            if (p->mode == LISSAJOUS) {
+                x = ((src[1] - src[0]) * zoom / 2 + 1) * hw;
+                y = (1.0 - (src[0] + src[1]) * zoom / 2) * hh;
+            } else {
+                x = (src[1] * zoom + 1) * hw;
+                y = (src[0] * zoom + 1) * hh;
+            }
+
+            draw_dot(p, x, y);
+        }
+        break;
+    }
+
+    av_frame_free(&insamples);
+
+    return ff_filter_frame(outlink, av_frame_clone(p->outpicref));
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    AudioVectorScopeContext *p = ctx->priv;
+
+    av_frame_free(&p->outpicref);
+}
+
+static const AVFilterPad audiovectorscope_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_AUDIO,
+        .config_props = config_input,
+        .filter_frame = filter_frame,
+    },
+    { NULL }
+};
+
+static const AVFilterPad audiovectorscope_outputs[] = {
+    {
+        .name          = "default",
+        .type          = AVMEDIA_TYPE_VIDEO,
+        .config_props  = config_output,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_avf_avectorscope = {
+    .name          = "avectorscope",
+    .description   = NULL_IF_CONFIG_SMALL("Display audio vector scope."),
+    .uninit        = uninit,
+    .query_formats = query_formats,
+    .priv_size     = sizeof(AudioVectorScopeContext),
+    .inputs        = audiovectorscope_inputs,
+    .outputs       = audiovectorscope_outputs,
+    .priv_class    = &avectorscope_class,
+};
diff --git a/libavfilter/avf_concat.c b/libavfilter/avf_concat.c
index 04812aa..a69c9cb 100644
--- a/libavfilter/avf_concat.c
+++ b/libavfilter/avf_concat.c
@@ -68,7 +68,7 @@
       AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, A|F},
     { "unsafe", "enable unsafe mode",
       OFFSET(unsafe),
-      AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, A|A|F},
+      AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V|A|F},
     { 0 }
 };
 
@@ -134,10 +134,13 @@
     outlink->format              = inlink->format;
     for (seg = 1; seg < cat->nb_segments; seg++) {
         inlink = ctx->inputs[in_no += ctx->nb_outputs];
+        if (!outlink->sample_aspect_ratio.num)
+            outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
         /* possible enhancement: unsafe mode, do not check */
         if (outlink->w                       != inlink->w                       ||
             outlink->h                       != inlink->h                       ||
-            outlink->sample_aspect_ratio.num != inlink->sample_aspect_ratio.num ||
+            outlink->sample_aspect_ratio.num != inlink->sample_aspect_ratio.num &&
+                                                inlink->sample_aspect_ratio.num ||
             outlink->sample_aspect_ratio.den != inlink->sample_aspect_ratio.den) {
             av_log(ctx, AV_LOG_ERROR, "Input link %s parameters "
                    "(size %dx%d, SAR %d:%d) do not match the corresponding "
diff --git a/libavfilter/avf_showspectrum.c b/libavfilter/avf_showspectrum.c
index 058f22c..7cd75df 100644
--- a/libavfilter/avf_showspectrum.c
+++ b/libavfilter/avf_showspectrum.c
@@ -211,9 +211,11 @@
         if (!outpicref)
             return AVERROR(ENOMEM);
         outlink->sample_aspect_ratio = (AVRational){1,1};
-        memset(outpicref->data[0],   0, outlink->h * outpicref->linesize[0]);
-        memset(outpicref->data[1], 128, outlink->h * outpicref->linesize[1]);
-        memset(outpicref->data[2], 128, outlink->h * outpicref->linesize[2]);
+        for (i = 0; i < outlink->h; i++) {
+            memset(outpicref->data[0] + i * outpicref->linesize[0],   0, outlink->w);
+            memset(outpicref->data[1] + i * outpicref->linesize[1], 128, outlink->w);
+            memset(outpicref->data[2] + i * outpicref->linesize[2], 128, outlink->w);
+        }
     }
 
     if (showspectrum->xpos >= outlink->w)
diff --git a/libavfilter/avf_showwaves.c b/libavfilter/avf_showwaves.c
index 5e89146..52cd60f 100644
--- a/libavfilter/avf_showwaves.c
+++ b/libavfilter/avf_showwaves.c
@@ -169,7 +169,7 @@
     AVFrame *outpicref = showwaves->outpicref;
     int linesize = outpicref ? outpicref->linesize[0] : 0;
     int16_t *p = (int16_t *)insamples->data[0];
-    int nb_channels = av_get_channel_layout_nb_channels(insamples->channel_layout);
+    int nb_channels = inlink->channels;
     int i, j, k, h, ret = 0;
     const int n = showwaves->n;
     const int x = 255 / (nb_channels * n); /* multiplication factor, pre-computed to avoid in-loop divisions */
@@ -188,7 +188,8 @@
                                           (AVRational){ 1, inlink->sample_rate },
                                           outlink->time_base);
             linesize = outpicref->linesize[0];
-            memset(outpicref->data[0], 0, showwaves->h*linesize);
+            for (j = 0; j < outlink->h; j++)
+                memset(outpicref->data[0] + j * linesize, 0, outlink->w);
         }
         for (j = 0; j < nb_channels; j++) {
             h = showwaves->h/2 - av_rescale(*p++, showwaves->h/2, MAX_INT16);
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 06d92b2..7f69f86 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -19,12 +19,14 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/atomic.h"
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
 #include "libavutil/eval.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/internal.h"
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/rational.h"
@@ -66,7 +68,8 @@
     ff_tlog(ctx, "]%s", end ? "\n" : "");
 }
 
-unsigned avfilter_version(void) {
+unsigned avfilter_version(void)
+{
     av_assert0(LIBAVFILTER_VERSION_MICRO >= 100);
     return LIBAVFILTER_VERSION_INT;
 }
@@ -101,13 +104,13 @@
 
     *pads  = av_realloc(*pads,  sizeof(AVFilterPad)   * (*count + 1));
     *links = av_realloc(*links, sizeof(AVFilterLink*) * (*count + 1));
-    memmove(*pads +idx+1, *pads +idx, sizeof(AVFilterPad)   * (*count-idx));
-    memmove(*links+idx+1, *links+idx, sizeof(AVFilterLink*) * (*count-idx));
-    memcpy(*pads+idx, newpad, sizeof(AVFilterPad));
+    memmove(*pads  + idx + 1, *pads  + idx, sizeof(AVFilterPad)   * (*count - idx));
+    memmove(*links + idx + 1, *links + idx, sizeof(AVFilterLink*) * (*count - idx));
+    memcpy(*pads + idx, newpad, sizeof(AVFilterPad));
     (*links)[idx] = NULL;
 
     (*count)++;
-    for (i = idx+1; i < *count; i++)
+    for (i = idx + 1; i < *count; i++)
         if (*links[i])
             (*(unsigned *)((uint8_t *) *links[i] + padidx_off))++;
 }
@@ -129,8 +132,11 @@
         return AVERROR(EINVAL);
     }
 
-    src->outputs[srcpad] =
-    dst-> inputs[dstpad] = link = av_mallocz(sizeof(AVFilterLink));
+    link = av_mallocz(sizeof(*link));
+    if (!link)
+        return AVERROR(ENOMEM);
+
+    src->outputs[srcpad] = dst->inputs[dstpad] = link;
 
     link->src     = src;
     link->dst     = dst;
@@ -181,19 +187,18 @@
     }
 
     /* re-hookup the link to the new destination filter we inserted */
-    link->dst = filt;
-    link->dstpad = &filt->input_pads[filt_srcpad_idx];
+    link->dst                     = filt;
+    link->dstpad                  = &filt->input_pads[filt_srcpad_idx];
     filt->inputs[filt_srcpad_idx] = link;
 
     /* if any information on supported media formats already exists on the
      * link, we need to preserve that */
     if (link->out_formats)
         ff_formats_changeref(&link->out_formats,
-                                   &filt->outputs[filt_dstpad_idx]->out_formats);
-
+                             &filt->outputs[filt_dstpad_idx]->out_formats);
     if (link->out_samplerates)
         ff_formats_changeref(&link->out_samplerates,
-                                   &filt->outputs[filt_dstpad_idx]->out_samplerates);
+                             &filt->outputs[filt_dstpad_idx]->out_samplerates);
     if (link->out_channel_layouts)
         ff_channel_layouts_changeref(&link->out_channel_layouts,
                                      &filt->outputs[filt_dstpad_idx]->out_channel_layouts);
@@ -436,14 +441,14 @@
 
 AVFilter *avfilter_get_by_name(const char *name)
 {
-    AVFilter *f = NULL;
+    const AVFilter *f = NULL;
 
     if (!name)
         return NULL;
 
     while ((f = avfilter_next(f)))
         if (!strcmp(f->name, name))
-            return f;
+            return (AVFilter *)f;
 
     return NULL;
 }
@@ -453,17 +458,20 @@
     AVFilter **f = &first_filter;
     int i;
 
+    /* the filter must select generic or internal exclusively */
+    av_assert0((filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE) != AVFILTER_FLAG_SUPPORT_TIMELINE);
+
     for(i=0; filter->inputs && filter->inputs[i].name; i++) {
         const AVFilterPad *input = &filter->inputs[i];
         av_assert0(     !input->filter_frame
                     || (!input->start_frame && !input->end_frame));
     }
 
-    while (*f)
-        f = &(*f)->next;
-    *f = filter;
     filter->next = NULL;
 
+    while(avpriv_atomic_ptr_cas((void * volatile *)f, NULL, filter))
+        f = &(*f)->next;
+
     return 0;
 }
 
@@ -490,7 +498,8 @@
     if (!pads)
         return 0;
 
-    for(count = 0; pads->name; count ++) pads ++;
+    for (count = 0; pads->name; count++)
+        pads++;
     return count;
 }
 
@@ -510,7 +519,7 @@
 
 static const AVClass *filter_child_class_next(const AVClass *prev)
 {
-    AVFilter *f = NULL;
+    const AVFilter *f = NULL;
 
     /* find the filter that corresponds to prev */
     while (prev && (f = avfilter_next(f)))
@@ -531,9 +540,12 @@
 
 #define OFFSET(x) offsetof(AVFilterContext, x)
 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM
-static const AVOption filters_common_options[] = {
+static const AVOption avfilter_options[] = {
+    { "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS,
+        { .i64 = AVFILTER_THREAD_SLICE }, 0, INT_MAX, FLAGS, "thread_type" },
+        { "slice", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVFILTER_THREAD_SLICE }, .unit = "thread_type" },
     { "enable", "set enable expression", OFFSET(enable_str), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
-    { NULL }
+    { NULL },
 };
 
 static const AVClass avfilter_class = {
@@ -542,10 +554,23 @@
     .version    = LIBAVUTIL_VERSION_INT,
     .category   = AV_CLASS_CATEGORY_FILTER,
     .child_next = filter_child_next,
-    .option     = filters_common_options,
     .child_class_next = filter_child_class_next,
+    .option           = avfilter_options,
 };
 
+static int default_execute(AVFilterContext *ctx, action_func *func, void *arg,
+                           int *ret, int nb_jobs)
+{
+    int i;
+
+    for (i = 0; i < nb_jobs; i++) {
+        int r = func(ctx, arg, i, nb_jobs);
+        if (ret)
+            ret[i] = r;
+    }
+    return 0;
+}
+
 AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name)
 {
     AVFilterContext *ret;
@@ -566,11 +591,17 @@
             goto err;
     }
 
+    av_opt_set_defaults(ret);
     if (filter->priv_class) {
         *(const AVClass**)ret->priv = filter->priv_class;
         av_opt_set_defaults(ret->priv);
     }
 
+    ret->internal = av_mallocz(sizeof(*ret->internal));
+    if (!ret->internal)
+        goto err;
+    ret->internal->execute = default_execute;
+
     ret->nb_inputs = avfilter_pad_count(filter->inputs);
     if (ret->nb_inputs ) {
         ret->input_pads   = av_malloc(sizeof(AVFilterPad) * ret->nb_inputs);
@@ -593,8 +624,10 @@
             goto err;
     }
 #if FF_API_FOO_COUNT
+FF_DISABLE_DEPRECATION_WARNINGS
     ret->output_count = ret->nb_outputs;
     ret->input_count  = ret->nb_inputs;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
     return ret;
@@ -607,6 +640,7 @@
     av_freep(&ret->output_pads);
     ret->nb_outputs = 0;
     av_freep(&ret->priv);
+    av_freep(&ret->internal);
     av_free(ret);
     return NULL;
 }
@@ -619,10 +653,28 @@
 }
 #endif
 
+static void free_link(AVFilterLink *link)
+{
+    if (!link)
+        return;
+
+    if (link->src)
+        link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
+    if (link->dst)
+        link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
+
+    ff_formats_unref(&link->in_formats);
+    ff_formats_unref(&link->out_formats);
+    ff_formats_unref(&link->in_samplerates);
+    ff_formats_unref(&link->out_samplerates);
+    ff_channel_layouts_unref(&link->in_channel_layouts);
+    ff_channel_layouts_unref(&link->out_channel_layouts);
+    avfilter_link_free(&link);
+}
+
 void avfilter_free(AVFilterContext *filter)
 {
     int i;
-    AVFilterLink *link;
 
     if (!filter)
         return;
@@ -634,30 +686,10 @@
         filter->filter->uninit(filter);
 
     for (i = 0; i < filter->nb_inputs; i++) {
-        if ((link = filter->inputs[i])) {
-            if (link->src)
-                link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
-            ff_formats_unref(&link->in_formats);
-            ff_formats_unref(&link->out_formats);
-            ff_formats_unref(&link->in_samplerates);
-            ff_formats_unref(&link->out_samplerates);
-            ff_channel_layouts_unref(&link->in_channel_layouts);
-            ff_channel_layouts_unref(&link->out_channel_layouts);
-        }
-        avfilter_link_free(&link);
+        free_link(filter->inputs[i]);
     }
     for (i = 0; i < filter->nb_outputs; i++) {
-        if ((link = filter->outputs[i])) {
-            if (link->dst)
-                link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
-            ff_formats_unref(&link->in_formats);
-            ff_formats_unref(&link->out_formats);
-            ff_formats_unref(&link->in_samplerates);
-            ff_formats_unref(&link->out_samplerates);
-            ff_channel_layouts_unref(&link->in_channel_layouts);
-            ff_channel_layouts_unref(&link->out_channel_layouts);
-        }
-        avfilter_link_free(&link);
+        free_link(filter->outputs[i]);
     }
 
     if (filter->filter->priv_class)
@@ -676,6 +708,7 @@
     av_expr_free(filter->enable);
     filter->enable = NULL;
     av_freep(&filter->var_values);
+    av_freep(&filter->internal);
     av_free(filter);
 }
 
@@ -688,8 +721,6 @@
     const char *key;
     int offset= -1;
 
-    av_opt_set_defaults(ctx);
-
     if (!args)
         return 0;
 
@@ -728,8 +759,11 @@
 
         if (av_opt_find(ctx, key, NULL, 0, 0)) {
             ret = av_opt_set(ctx, key, value, 0);
-            if (ret < 0)
+            if (ret < 0) {
+                av_free(value);
+                av_free(parsed_key);
                 return ret;
+            }
         } else {
         av_dict_set(options, key, value, 0);
         if ((ret = av_opt_set(ctx->priv, key, value, 0)) < 0) {
@@ -767,6 +801,21 @@
 {
     int ret = 0;
 
+    ret = av_opt_set_dict(ctx, options);
+    if (ret < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Error applying generic filter options.\n");
+        return ret;
+    }
+
+    if (ctx->filter->flags & AVFILTER_FLAG_SLICE_THREADS &&
+        ctx->thread_type & ctx->graph->thread_type & AVFILTER_THREAD_SLICE &&
+        ctx->graph->internal->thread_execute) {
+        ctx->thread_type       = AVFILTER_THREAD_SLICE;
+        ctx->internal->execute = ctx->graph->internal->thread_execute;
+    } else {
+        ctx->thread_type = 0;
+    }
+
     if (ctx->filter->priv_class) {
         ret = av_opt_set_dict(ctx->priv, options);
         if (ret < 0) {
@@ -789,7 +838,7 @@
 {
     AVDictionary *options = NULL;
     AVDictionaryEntry *e;
-    int ret=0;
+    int ret = 0;
 
     if (args && *args) {
         if (!filter->filter->priv_class) {
@@ -993,9 +1042,11 @@
         dstctx->var_values[VAR_N] = link->frame_count;
         dstctx->var_values[VAR_T] = pts == AV_NOPTS_VALUE ? NAN : pts * av_q2d(link->time_base);
         dstctx->var_values[VAR_POS] = pos == -1 ? NAN : pos;
-        if (!av_expr_eval(dstctx->enable, dstctx->var_values, NULL))
-            filter_frame = dst->passthrough_filter_frame ? dst->passthrough_filter_frame
-                                                         : default_filter_frame;
+
+        dstctx->is_disabled = !av_expr_eval(dstctx->enable, dstctx->var_values, NULL);
+        if (dstctx->is_disabled &&
+            (dstctx->filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC))
+            filter_frame = default_filter_frame;
     }
     ret = filter_frame(link, out);
     link->frame_count++;
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index e7e979e..b8d7cc3 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -25,16 +25,17 @@
 /**
  * @file
  * @ingroup lavfi
- * external API header
+ * Main libavfilter public API header
  */
 
 /**
- * @defgroup lavfi Libavfilter
+ * @defgroup lavfi Libavfilter - graph-based frame editing library
  * @{
  */
 
 #include <stddef.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/avutil.h"
 #include "libavutil/dict.h"
 #include "libavutil/frame.h"
@@ -385,19 +386,6 @@
     int needs_fifo;
 
     int needs_writable;
-
-    /**
-     * Passthrough filtering callback.
-     *
-     * If a filter supports timeline editing (in case
-     * AVFILTER_FLAG_SUPPORT_TIMELINE is enabled) then it can implement a
-     * custom passthrough callback to update its local context (for example to
-     * keep a frame reference, or simply send the filter to a custom outlink).
-     * The filter must not do any change to the frame in this callback.
-     *
-     * Input pads only.
-     */
-    int (*passthrough_filter_frame)(AVFilterLink *link, AVFrame *frame);
 };
 #endif
 
@@ -442,31 +430,74 @@
  */
 #define AVFILTER_FLAG_DYNAMIC_OUTPUTS       (1 << 1)
 /**
+ * The filter supports multithreading by splitting frames into multiple parts
+ * and processing them concurrently.
+ */
+#define AVFILTER_FLAG_SLICE_THREADS         (1 << 2)
+/**
  * Some filters support a generic "enable" expression option that can be used
  * to enable or disable a filter in the timeline. Filters supporting this
- * option have this flag set.
+ * option have this flag set. When the enable expression is false, the default
+ * no-op filter_frame() function is called in place of the filter_frame()
+ * callback defined on each input pad, thus the frame is passed unchanged to
+ * the next filters.
  */
-#define AVFILTER_FLAG_SUPPORT_TIMELINE      (1 << 16)
+#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC  (1 << 16)
+/**
+ * Same as AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, except that the filter will
+ * have its filter_frame() callback(s) called as usual even when the enable
+ * expression is false. The filter will disable filtering within the
+ * filter_frame() callback(s) itself, for example executing code depending on
+ * the AVFilterContext->is_disabled value.
+ */
+#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL (1 << 17)
+/**
+ * Handy mask to test whether the filter supports or no the timeline feature
+ * (internally or generically).
+ */
+#define AVFILTER_FLAG_SUPPORT_TIMELINE (AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL)
 
 /**
  * Filter definition. This defines the pads a filter contains, and all the
  * callback functions used to interact with the filter.
  */
 typedef struct AVFilter {
-    const char *name;         ///< filter name
+    /**
+     * Filter name. Must be non-NULL and unique among filters.
+     */
+    const char *name;
 
     /**
-     * A description for the filter. You should use the
-     * NULL_IF_CONFIG_SMALL() macro to define it.
+     * A description of the filter. May be NULL.
+     *
+     * You should use the NULL_IF_CONFIG_SMALL() macro to define it.
      */
     const char *description;
 
-    const AVFilterPad *inputs;  ///< NULL terminated list of inputs. NULL if none
-    const AVFilterPad *outputs; ///< NULL terminated list of outputs. NULL if none
+    /**
+     * List of inputs, terminated by a zeroed element.
+     *
+     * NULL if there are no (static) inputs. Instances of filters with
+     * AVFILTER_FLAG_DYNAMIC_INPUTS set may have more inputs than present in
+     * this list.
+     */
+    const AVFilterPad *inputs;
+    /**
+     * List of outputs, terminated by a zeroed element.
+     *
+     * NULL if there are no (static) outputs. Instances of filters with
+     * AVFILTER_FLAG_DYNAMIC_OUTPUTS set may have more outputs than present in
+     * this list.
+     */
+    const AVFilterPad *outputs;
 
     /**
-     * A class for the private data, used to access filter private
-     * AVOptions.
+     * A class for the private data, used to declare filter private AVOptions.
+     * This field is NULL for filters that do not declare any options.
+     *
+     * If this field is non-NULL, the first member of the filter private data
+     * must be a pointer to AVClass, which will be set by libavfilter generic
+     * code to this class.
      */
     const AVClass *priv_class;
 
@@ -484,29 +515,71 @@
      */
 
     /**
-     * Filter initialization function. Called when all the options have been
-     * set.
+     * Filter initialization function.
+     *
+     * This callback will be called only once during the filter lifetime, after
+     * all the options have been set, but before links between filters are
+     * established and format negotiation is done.
+     *
+     * Basic filter initialization should be done here. Filters with dynamic
+     * inputs and/or outputs should create those inputs/outputs here based on
+     * provided options. No more changes to this filter's inputs/outputs can be
+     * done after this callback.
+     *
+     * This callback must not assume that the filter links exist or frame
+     * parameters are known.
+     *
+     * @ref AVFilter.uninit "uninit" is guaranteed to be called even if
+     * initialization fails, so this callback does not have to clean up on
+     * failure.
+     *
+     * @return 0 on success, a negative AVERROR on failure
      */
     int (*init)(AVFilterContext *ctx);
 
     /**
-     * Should be set instead of init by the filters that want to pass a
-     * dictionary of AVOptions to nested contexts that are allocated in
-     * init.
+     * Should be set instead of @ref AVFilter.init "init" by the filters that
+     * want to pass a dictionary of AVOptions to nested contexts that are
+     * allocated during init.
+     *
+     * On return, the options dict should be freed and replaced with one that
+     * contains all the options which could not be processed by this filter (or
+     * with NULL if all the options were processed).
+     *
+     * Otherwise the semantics is the same as for @ref AVFilter.init "init".
      */
     int (*init_dict)(AVFilterContext *ctx, AVDictionary **options);
 
     /**
-     * Filter uninitialization function. Should deallocate any memory held
-     * by the filter, release any buffer references, etc. This does not need
-     * to deallocate the AVFilterContext->priv memory itself.
+     * Filter uninitialization function.
+     *
+     * Called only once right before the filter is freed. Should deallocate any
+     * memory held by the filter, release any buffer references, etc. It does
+     * not need to deallocate the AVFilterContext.priv memory itself.
+     *
+     * This callback may be called even if @ref AVFilter.init "init" was not
+     * called or failed, so it must be prepared to handle such a situation.
      */
     void (*uninit)(AVFilterContext *ctx);
 
     /**
-     * Queries formats/layouts supported by the filter and its pads, and sets
-     * the in_formats/in_chlayouts for links connected to its output pads,
-     * and out_formats/out_chlayouts for links connected to its input pads.
+     * Query formats supported by the filter on its inputs and outputs.
+     *
+     * This callback is called after the filter is initialized (so the inputs
+     * and outputs are fixed), shortly before the format negotiation. This
+     * callback may be called more than once.
+     *
+     * This callback must set AVFilterLink.out_formats on every input link and
+     * AVFilterLink.in_formats on every output link to a list of pixel/sample
+     * formats that the filter supports on that link. For audio links, this
+     * filter must also set @ref AVFilterLink.in_samplerates "in_samplerates" /
+     * @ref AVFilterLink.out_samplerates "out_samplerates" and
+     * @ref AVFilterLink.in_channel_layouts "in_channel_layouts" /
+     * @ref AVFilterLink.out_channel_layouts "out_channel_layouts" analogously.
+     *
+     * This callback may be NULL for filters with one input, in which case
+     * libavfilter assumes that it supports all input formats and preserves
+     * them on output.
      *
      * @return zero on success, a negative value corresponding to an
      * AVERROR code otherwise
@@ -515,6 +588,10 @@
 
     int priv_size;      ///< size of private data to allocate for the filter
 
+    /**
+     * Used by the filter registration system. Must not be touched by any other
+     * code.
+     */
     struct AVFilter *next;
 
     /**
@@ -539,6 +616,13 @@
     int (*init_opaque)(AVFilterContext *ctx, void *opaque);
 } AVFilter;
 
+/**
+ * Process multiple parts of the frame concurrently.
+ */
+#define AVFILTER_THREAD_SLICE (1 << 0)
+
+typedef struct AVFilterInternal AVFilterInternal;
+
 /** An instance of a filter */
 struct AVFilterContext {
     const AVClass *av_class;        ///< needed for av_log() and filters common options
@@ -550,14 +634,14 @@
     AVFilterPad   *input_pads;      ///< array of input pads
     AVFilterLink **inputs;          ///< array of pointers to input links
 #if FF_API_FOO_COUNT
-    unsigned input_count;           ///< @deprecated use nb_inputs
+    attribute_deprecated unsigned input_count; ///< @deprecated use nb_inputs
 #endif
     unsigned    nb_inputs;          ///< number of input pads
 
     AVFilterPad   *output_pads;     ///< array of output pads
     AVFilterLink **outputs;         ///< array of pointers to output links
 #if FF_API_FOO_COUNT
-    unsigned output_count;          ///< @deprecated use nb_outputs
+    attribute_deprecated unsigned output_count; ///< @deprecated use nb_outputs
 #endif
     unsigned    nb_outputs;         ///< number of output pads
 
@@ -565,11 +649,35 @@
 
     struct AVFilterGraph *graph;    ///< filtergraph this filter belongs to
 
+    /**
+     * Type of multithreading being allowed/used. A combination of
+     * AVFILTER_THREAD_* flags.
+     *
+     * May be set by the caller before initializing the filter to forbid some
+     * or all kinds of multithreading for this filter. The default is allowing
+     * everything.
+     *
+     * When the filter is initialized, this field is combined using bit AND with
+     * AVFilterGraph.thread_type to get the final mask used for determining
+     * allowed threading types. I.e. a threading type needs to be set in both
+     * to be allowed.
+     *
+     * After the filter is initialzed, libavfilter sets this field to the
+     * threading type that is actually used (0 for no multithreading).
+     */
+    int thread_type;
+
+    /**
+     * An opaque struct for libavfilter internal use.
+     */
+    AVFilterInternal *internal;
+
     struct AVFilterCommand *command_queue;
 
     char *enable_str;               ///< enable expression string
     void *enable;                   ///< parsed expression (AVExpr*)
     double *var_values;             ///< variable values for the enable expression
+    int is_disabled;                ///< the enabled state from the last expression evaluation
 };
 
 /**
@@ -1016,6 +1124,8 @@
  */
 const AVClass *avfilter_get_class(void);
 
+typedef struct AVFilterGraphInternal AVFilterGraphInternal;
+
 typedef struct AVFilterGraph {
     const AVClass *av_class;
 #if FF_API_FOO_COUNT
@@ -1032,6 +1142,33 @@
 #if FF_API_FOO_COUNT
     unsigned nb_filters;
 #endif
+
+    /**
+     * Type of multithreading allowed for filters in this graph. A combination
+     * of AVFILTER_THREAD_* flags.
+     *
+     * May be set by the caller at any point, the setting will apply to all
+     * filters initialized after that. The default is allowing everything.
+     *
+     * When a filter in this graph is initialized, this field is combined using
+     * bit AND with AVFilterContext.thread_type to get the final mask used for
+     * determining allowed threading types. I.e. a threading type needs to be
+     * set in both to be allowed.
+     */
+    int thread_type;
+
+    /**
+     * Maximum number of threads used by filters in this graph. May be set by
+     * the caller before adding any filters to the filtergraph. Zero (the
+     * default) means that the number of threads is determined automatically.
+     */
+    int nb_threads;
+
+    /**
+     * Opaque object for libavfilter internal use.
+     */
+    AVFilterGraphInternal *internal;
+
     char *aresample_swr_opts; ///< swr options to use for the auto-inserted aresample filters, Access ONLY through AVOptions
 
     /**
@@ -1105,7 +1242,7 @@
  * @return a negative AVERROR error code in case of failure, a non
  * negative value otherwise
  */
-int avfilter_graph_create_filter(AVFilterContext **filt_ctx, AVFilter *filt,
+int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt,
                                  const char *name, const char *args, void *opaque,
                                  AVFilterGraph *graph_ctx);
 
@@ -1175,6 +1312,49 @@
  */
 void avfilter_inout_free(AVFilterInOut **inout);
 
+#if AV_HAVE_INCOMPATIBLE_LIBAV_ABI || !FF_API_OLD_GRAPH_PARSE
+/**
+ * Add a graph described by a string to a graph.
+ *
+ * @note The caller must provide the lists of inputs and outputs,
+ * which therefore must be known before calling the function.
+ *
+ * @note The inputs parameter describes inputs of the already existing
+ * part of the graph; i.e. from the point of view of the newly created
+ * part, they are outputs. Similarly the outputs parameter describes
+ * outputs of the already existing filters, which are provided as
+ * inputs to the parsed filters.
+ *
+ * @param graph   the filter graph where to link the parsed grap context
+ * @param filters string to be parsed
+ * @param inputs  linked list to the inputs of the graph
+ * @param outputs linked list to the outputs of the graph
+ * @return zero on success, a negative AVERROR code on error
+ */
+int avfilter_graph_parse(AVFilterGraph *graph, const char *filters,
+                         AVFilterInOut *inputs, AVFilterInOut *outputs,
+                         void *log_ctx);
+#else
+/**
+ * Add a graph described by a string to a graph.
+ *
+ * @param graph   the filter graph where to link the parsed graph context
+ * @param filters string to be parsed
+ * @param inputs  pointer to a linked list to the inputs of the graph, may be NULL.
+ *                If non-NULL, *inputs is updated to contain the list of open inputs
+ *                after the parsing, should be freed with avfilter_inout_free().
+ * @param outputs pointer to a linked list to the outputs of the graph, may be NULL.
+ *                If non-NULL, *outputs is updated to contain the list of open outputs
+ *                after the parsing, should be freed with avfilter_inout_free().
+ * @return non negative on success, a negative AVERROR code on error
+ * @deprecated Use avfilter_graph_parse_ptr() instead.
+ */
+attribute_deprecated
+int avfilter_graph_parse(AVFilterGraph *graph, const char *filters,
+                         AVFilterInOut **inputs, AVFilterInOut **outputs,
+                         void *log_ctx);
+#endif
+
 /**
  * Add a graph described by a string to a graph.
  *
@@ -1188,9 +1368,9 @@
  *                after the parsing, should be freed with avfilter_inout_free().
  * @return non negative on success, a negative AVERROR code on error
  */
-int avfilter_graph_parse(AVFilterGraph *graph, const char *filters,
-                         AVFilterInOut **inputs, AVFilterInOut **outputs,
-                         void *log_ctx);
+int avfilter_graph_parse_ptr(AVFilterGraph *graph, const char *filters,
+                             AVFilterInOut **inputs, AVFilterInOut **outputs,
+                             void *log_ctx);
 
 /**
  * Add a graph described by a string to a graph.
@@ -1205,21 +1385,13 @@
  *                     caller using avfilter_inout_free().
  * @return zero on success, a negative AVERROR code on error
  *
- * @note the difference between avfilter_graph_parse2() and
- * avfilter_graph_parse() is that in avfilter_graph_parse(), the caller provides
- * the lists of inputs and outputs, which therefore must be known before calling
- * the function. On the other hand, avfilter_graph_parse2() \em returns the
- * inputs and outputs that are left unlinked after parsing the graph and the
- * caller then deals with them. Another difference is that in
- * avfilter_graph_parse(), the inputs parameter describes inputs of the
- * <em>already existing</em> part of the graph; i.e. from the point of view of
- * the newly created part, they are outputs. Similarly the outputs parameter
- * describes outputs of the already existing filters, which are provided as
- * inputs to the parsed filters.
- * avfilter_graph_parse2() takes the opposite approach -- it makes no reference
- * whatsoever to already existing parts of the graph and the inputs parameter
- * will on return contain inputs of the newly parsed part of the graph.
- * Analogously the outputs parameter will contain outputs of the newly created
+ * @note This function returns the inputs and outputs that are left
+ * unlinked after parsing the graph and the caller then deals with
+ * them.
+ * @note This function makes no reference whatsoever to already
+ * existing parts of the graph and the inputs parameter will on return
+ * contain inputs of the newly parsed part of the graph.  Analogously
+ * the outputs parameter will contain outputs of the newly created
  * filters.
  */
 int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters,
@@ -1234,7 +1406,7 @@
  *               "all" sends to all filters
  *               otherwise it can be a filter or filter instance name
  *               which will send the command to all matching filters.
- * @param cmd    the command to sent, for handling simplicity all commands must be alphanumeric only
+ * @param cmd    the command to send, for handling simplicity all commands must be alphanumeric only
  * @param arg    the argument for the command
  * @param res    a buffer with size res_size where the filter(s) can return a response.
  *
@@ -1294,4 +1466,5 @@
 /**
  * @}
  */
+
 #endif /* AVFILTER_AVFILTER_H */
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index 582a870..fb78a87 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -20,42 +20,75 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config.h"
+
 #include <string.h>
 
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/bprint.h"
 #include "libavutil/channel_layout.h"
+#include "libavutil/internal.h"
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "libavcodec/avcodec.h" // avcodec_find_best_pix_fmt_of_2()
+
 #include "avfilter.h"
 #include "formats.h"
 #include "internal.h"
+#include "thread.h"
 
-#define OFFSET(x) offsetof(AVFilterGraph,x)
-
-static const AVOption options[]={
-{"scale_sws_opts"       , "default scale filter options"        , OFFSET(scale_sws_opts)        ,  AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, 0 },
-{"aresample_swr_opts"   , "default aresample filter options"    , OFFSET(aresample_swr_opts)    ,  AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, 0 },
-{0}
+#define OFFSET(x) offsetof(AVFilterGraph, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+static const AVOption filtergraph_options[] = {
+    { "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS,
+        { .i64 = AVFILTER_THREAD_SLICE }, 0, INT_MAX, FLAGS, "thread_type" },
+        { "slice", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVFILTER_THREAD_SLICE }, .flags = FLAGS, .unit = "thread_type" },
+    { "threads",     "Maximum number of threads", OFFSET(nb_threads),
+        AV_OPT_TYPE_INT,   { .i64 = 0 }, 0, INT_MAX, FLAGS },
+    {"scale_sws_opts"       , "default scale filter options"        , OFFSET(scale_sws_opts)        ,
+        AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+    {"aresample_swr_opts"   , "default aresample filter options"    , OFFSET(aresample_swr_opts)    ,
+        AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+    { NULL },
 };
 
-
 static const AVClass filtergraph_class = {
     .class_name = "AVFilterGraph",
     .item_name  = av_default_item_name,
-    .option     = options,
     .version    = LIBAVUTIL_VERSION_INT,
+    .option     = filtergraph_options,
     .category   = AV_CLASS_CATEGORY_FILTER,
 };
 
+#if !HAVE_THREADS
+void ff_graph_thread_free(AVFilterGraph *graph)
+{
+}
+
+int ff_graph_thread_init(AVFilterGraph *graph)
+{
+    graph->thread_type = 0;
+    graph->nb_threads  = 1;
+    return 0;
+}
+#endif
+
 AVFilterGraph *avfilter_graph_alloc(void)
 {
     AVFilterGraph *ret = av_mallocz(sizeof(*ret));
     if (!ret)
         return NULL;
+
+    ret->internal = av_mallocz(sizeof(*ret->internal));
+    if (!ret->internal) {
+        av_freep(&ret);
+        return NULL;
+    }
+
     ret->av_class = &filtergraph_class;
+    av_opt_set_defaults(ret);
+
     return ret;
 }
 
@@ -80,11 +113,15 @@
     while ((*graph)->nb_filters)
         avfilter_free((*graph)->filters[0]);
 
+    ff_graph_thread_free(*graph);
+
     av_freep(&(*graph)->sink_links);
+
     av_freep(&(*graph)->scale_sws_opts);
     av_freep(&(*graph)->aresample_swr_opts);
     av_freep(&(*graph)->resample_lavr_opts);
     av_freep(&(*graph)->filters);
+    av_freep(&(*graph)->internal);
     av_freep(graph);
 }
 
@@ -100,7 +137,9 @@
     graph->filters[graph->nb_filters++] = filter;
 
 #if FF_API_FOO_COUNT
+FF_DISABLE_DEPRECATION_WARNINGS
     graph->filter_count_unused = graph->nb_filters;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
     filter->graph = graph;
@@ -109,7 +148,7 @@
 }
 #endif
 
-int avfilter_graph_create_filter(AVFilterContext **filt_ctx, AVFilter *filt,
+int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt,
                                  const char *name, const char *args, void *opaque,
                                  AVFilterGraph *graph_ctx)
 {
@@ -143,6 +182,14 @@
 {
     AVFilterContext **filters, *s;
 
+    if (graph->thread_type && !graph->internal->thread) {
+        int ret = ff_graph_thread_init(graph);
+        if (ret < 0) {
+            av_log(graph, AV_LOG_ERROR, "Error initializing threading.\n");
+            return NULL;
+        }
+    }
+
     s = ff_filter_alloc(filter, name);
     if (!s)
         return NULL;
@@ -157,7 +204,9 @@
     graph->filters[graph->nb_filters++] = s;
 
 #if FF_API_FOO_COUNT
+FF_DISABLE_DEPRECATION_WARNINGS
     graph->filter_count_unused = graph->nb_filters;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
     s->graph = graph;
@@ -316,12 +365,66 @@
     return 1;
 }
 
+static AVFilterFormats *clone_filter_formats(AVFilterFormats *arg)
+{
+    AVFilterFormats *a = av_memdup(arg, sizeof(*arg));
+    if (a) {
+        a->refcount = 0;
+        a->refs     = NULL;
+        a->formats  = av_memdup(a->formats, sizeof(*a->formats) * a->nb_formats);
+        if (!a->formats && arg->formats)
+            av_freep(&a);
+    }
+    return a;
+}
+
+static int can_merge_formats(AVFilterFormats *a_arg,
+                             AVFilterFormats *b_arg,
+                             enum AVMediaType type,
+                             int is_sample_rate)
+{
+    AVFilterFormats *a, *b, *ret;
+    if (a_arg == b_arg)
+        return 1;
+    a = clone_filter_formats(a_arg);
+    b = clone_filter_formats(b_arg);
+    if (is_sample_rate) {
+        ret = ff_merge_samplerates(a, b);
+    } else {
+        ret = ff_merge_formats(a, b, type);
+    }
+    if (ret) {
+        av_freep(&ret->formats);
+        av_freep(&ret->refs);
+        av_freep(&ret);
+        return 1;
+    } else {
+        av_freep(&a->formats);
+        av_freep(&b->formats);
+        av_freep(&a);
+        av_freep(&b);
+        return 0;
+    }
+}
+
+/**
+ * Perform one round of query_formats() and merging formats lists on the
+ * filter graph.
+ * @return  >=0 if all links formats lists could be queried and merged;
+ *          AVERROR(EAGAIN) some progress was made in the queries or merging
+ *          and a later call may succeed;
+ *          AVERROR(EIO) (may be changed) plus a log message if no progress
+ *          was made and the negotiation is stuck;
+ *          a negative error code if some other error happened
+ */
 static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
 {
     int i, j, ret;
     int scaler_count = 0, resampler_count = 0;
-    int count_queried = 0, count_merged = 0, count_already_merged = 0,
-        count_delayed = 0;
+    int count_queried = 0;        /* successful calls to query_formats() */
+    int count_merged = 0;         /* successful merge of formats lists */
+    int count_already_merged = 0; /* lists already merged */
+    int count_delayed = 0;        /* lists that need to be merged later */
 
     for (i = 0; i < graph->nb_filters; i++) {
         AVFilterContext *f = graph->filters[i];
@@ -333,7 +436,8 @@
             ret = ff_default_query_formats(f);
         if (ret < 0 && ret != AVERROR(EAGAIN))
             return ret;
-        count_queried++;
+        /* note: EAGAIN could indicate a partial success, not counted yet */
+        count_queried += ret >= 0;
     }
 
     /* go through and merge as many format lists as possible */
@@ -347,20 +451,30 @@
             if (!link)
                 continue;
 
+            if (link->in_formats != link->out_formats
+                && link->in_formats && link->out_formats)
+                if (!can_merge_formats(link->in_formats, link->out_formats,
+                                      link->type, 0))
+                    convert_needed = 1;
+            if (link->type == AVMEDIA_TYPE_AUDIO) {
+                if (link->in_samplerates != link->out_samplerates
+                    && link->in_samplerates && link->out_samplerates)
+                    if (!can_merge_formats(link->in_samplerates,
+                                           link->out_samplerates,
+                                           0, 1))
+                        convert_needed = 1;
+            }
+
 #define MERGE_DISPATCH(field, statement)                                     \
             if (!(link->in_ ## field && link->out_ ## field)) {              \
                 count_delayed++;                                             \
             } else if (link->in_ ## field == link->out_ ## field) {          \
                 count_already_merged++;                                      \
-            } else {                                                         \
+            } else if (!convert_needed) {                                    \
                 count_merged++;                                              \
                 statement                                                    \
             }
-            MERGE_DISPATCH(formats,
-                if (!ff_merge_formats(link->in_formats, link->out_formats,
-                                      link->type))
-                    convert_needed = 1;
-            )
+
             if (link->type == AVMEDIA_TYPE_AUDIO) {
                 MERGE_DISPATCH(channel_layouts,
                     if (!ff_merge_channel_layouts(link->in_channel_layouts,
@@ -373,6 +487,11 @@
                         convert_needed = 1;
                 )
             }
+            MERGE_DISPATCH(formats,
+                if (!ff_merge_formats(link->in_formats, link->out_formats,
+                                      link->type))
+                    convert_needed = 1;
+            )
 #undef MERGE_DISPATCH
 
             if (convert_needed) {
@@ -393,13 +512,9 @@
 
                     snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
                              scaler_count++);
-                    av_strlcpy(scale_args, "0:0", sizeof(scale_args));
-                    if (graph->scale_sws_opts) {
-                        av_strlcat(scale_args, ":", sizeof(scale_args));
-                        av_strlcat(scale_args, graph->scale_sws_opts, sizeof(scale_args));
-                    }
+
                     if ((ret = avfilter_graph_create_filter(&convert, filter,
-                                                            inst_name, scale_args, NULL,
+                                                            inst_name, graph->scale_sws_opts, NULL,
                                                             graph)) < 0)
                         return ret;
                     break;
@@ -463,6 +578,11 @@
     if (count_delayed) {
         AVBPrint bp;
 
+        /* if count_queried > 0, one filter at least did set its formats,
+           that will give additional information to its neighbour;
+           if count_merged > 0, one pair of formats lists at least was merged,
+           that will give additional information to all connected filters;
+           in both cases, progress was made and a new round must be done */
         if (count_queried || count_merged)
             return AVERROR(EAGAIN);
         av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
@@ -489,28 +609,28 @@
             int has_alpha= av_pix_fmt_desc_get(ref->format)->nb_components % 2 == 0;
             enum AVPixelFormat best= AV_PIX_FMT_NONE;
             int i;
-            for (i=0; i<link->in_formats->format_count; i++) {
+            for (i=0; i<link->in_formats->nb_formats; i++) {
                 enum AVPixelFormat p = link->in_formats->formats[i];
                 best= avcodec_find_best_pix_fmt_of_2(best, p, ref->format, has_alpha, NULL);
             }
             av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s alpha:%d\n",
-                   av_get_pix_fmt_name(best), link->in_formats->format_count,
+                   av_get_pix_fmt_name(best), link->in_formats->nb_formats,
                    av_get_pix_fmt_name(ref->format), has_alpha);
             link->in_formats->formats[0] = best;
         }
     }
 
-    link->in_formats->format_count = 1;
+    link->in_formats->nb_formats = 1;
     link->format = link->in_formats->formats[0];
 
     if (link->type == AVMEDIA_TYPE_AUDIO) {
-        if (!link->in_samplerates->format_count) {
+        if (!link->in_samplerates->nb_formats) {
             av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for"
                    " the link between filters %s and %s.\n", link->src->name,
                    link->dst->name);
             return AVERROR(EINVAL);
         }
-        link->in_samplerates->format_count = 1;
+        link->in_samplerates->nb_formats = 1;
         link->sample_rate = link->in_samplerates->formats[0];
 
         if (link->in_channel_layouts->all_layouts) {
@@ -558,6 +678,7 @@
                                                                        \
             if (!out_link->in_ ## list->nb) {                          \
                 add_format(&out_link->in_ ##list, fmt);                \
+                ret = 1;                                               \
                 break;                                                 \
             }                                                          \
                                                                        \
@@ -577,9 +698,9 @@
     int i, j, k, ret = 0;
 
     REDUCE_FORMATS(int,      AVFilterFormats,        formats,         formats,
-                   format_count, ff_add_format);
+                   nb_formats, ff_add_format);
     REDUCE_FORMATS(int,      AVFilterFormats,        samplerates,     formats,
-                   format_count, ff_add_format);
+                   nb_formats, ff_add_format);
 
     /* reduce channel layouts */
     for (i = 0; i < filter->nb_inputs; i++) {
@@ -642,7 +763,7 @@
         link = filter->inputs[i];
 
         if (link->type == AVMEDIA_TYPE_AUDIO &&
-            link->out_samplerates->format_count == 1)
+            link->out_samplerates->nb_formats== 1)
             break;
     }
     if (i == filter->nb_inputs)
@@ -655,10 +776,10 @@
         int best_idx, best_diff = INT_MAX;
 
         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
-            outlink->in_samplerates->format_count < 2)
+            outlink->in_samplerates->nb_formats < 2)
             continue;
 
-        for (j = 0; j < outlink->in_samplerates->format_count; j++) {
+        for (j = 0; j < outlink->in_samplerates->nb_formats; j++) {
             int diff = abs(sample_rate - outlink->in_samplerates->formats[j]);
 
             if (diff < best_diff) {
@@ -820,7 +941,7 @@
         link = filter->inputs[i];
 
         if (link->type == AVMEDIA_TYPE_AUDIO &&
-            link->out_formats->format_count == 1)
+            link->out_formats->nb_formats == 1)
             break;
     }
     if (i == filter->nb_inputs)
@@ -834,10 +955,10 @@
         int best_idx = -1, best_score = INT_MIN;
 
         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
-            outlink->in_formats->format_count < 2)
+            outlink->in_formats->nb_formats < 2)
             continue;
 
-        for (j = 0; j < outlink->in_formats->format_count; j++) {
+        for (j = 0; j < outlink->in_formats->nb_formats; j++) {
             int out_format = outlink->in_formats->formats[j];
             int out_bps    = av_get_bytes_per_sample(out_format);
             int score;
@@ -890,7 +1011,7 @@
             AVFilterContext *filter = graph->filters[i];
             if (filter->nb_inputs){
                 for (j = 0; j < filter->nb_inputs; j++){
-                    if(filter->inputs[j]->in_formats && filter->inputs[j]->in_formats->format_count == 1) {
+                    if(filter->inputs[j]->in_formats && filter->inputs[j]->in_formats->nb_formats == 1) {
                         if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
                             return ret;
                         change = 1;
@@ -899,7 +1020,7 @@
             }
             if (filter->nb_outputs){
                 for (j = 0; j < filter->nb_outputs; j++){
-                    if(filter->outputs[j]->in_formats && filter->outputs[j]->in_formats->format_count == 1) {
+                    if(filter->outputs[j]->in_formats && filter->outputs[j]->in_formats->nb_formats == 1) {
                         if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
                             return ret;
                         change = 1;
@@ -1063,24 +1184,24 @@
 {
     int i, r = AVERROR(ENOSYS);
 
-    if(!graph)
+    if (!graph)
         return r;
 
-    if((flags & AVFILTER_CMD_FLAG_ONE) && !(flags & AVFILTER_CMD_FLAG_FAST)) {
-        r=avfilter_graph_send_command(graph, target, cmd, arg, res, res_len, flags | AVFILTER_CMD_FLAG_FAST);
-        if(r != AVERROR(ENOSYS))
+    if ((flags & AVFILTER_CMD_FLAG_ONE) && !(flags & AVFILTER_CMD_FLAG_FAST)) {
+        r = avfilter_graph_send_command(graph, target, cmd, arg, res, res_len, flags | AVFILTER_CMD_FLAG_FAST);
+        if (r != AVERROR(ENOSYS))
             return r;
     }
 
-    if(res_len && res)
-        res[0]= 0;
+    if (res_len && res)
+        res[0] = 0;
 
     for (i = 0; i < graph->nb_filters; i++) {
         AVFilterContext *filter = graph->filters[i];
-        if(!strcmp(target, "all") || (filter->name && !strcmp(target, filter->name)) || !strcmp(target, filter->filter->name)){
+        if (!strcmp(target, "all") || (filter->name && !strcmp(target, filter->name)) || !strcmp(target, filter->filter->name)) {
             r = avfilter_process_command(filter, cmd, arg, res, res_len, flags);
-            if(r != AVERROR(ENOSYS)) {
-                if((flags & AVFILTER_CMD_FLAG_ONE) || r<0)
+            if (r != AVERROR(ENOSYS)) {
+                if ((flags & AVFILTER_CMD_FLAG_ONE) || r < 0)
                     return r;
             }
         }
diff --git a/libavfilter/buffer.c b/libavfilter/buffer.c
index 29fedc4..1bbfab8 100644
--- a/libavfilter/buffer.c
+++ b/libavfilter/buffer.c
@@ -30,7 +30,9 @@
 #include "internal.h"
 #include "audio.h"
 #include "avcodec.h"
+#include "version.h"
 
+#if FF_API_AVFILTERBUFFER
 void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
 {
     if (ptr->extended_data != ptr->data)
@@ -165,3 +167,4 @@
     av_dict_free(&dst->metadata);
     av_dict_copy(&dst->metadata, src->metadata, 0);
 }
+#endif /* FF_API_AVFILTERBUFFER */
diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c
index 234027d..6dca209 100644
--- a/libavfilter/buffersink.c
+++ b/libavfilter/buffersink.c
@@ -27,6 +27,7 @@
 #include "libavutil/avassert.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
+#include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
 
@@ -56,7 +57,7 @@
     int sample_rates_size;
 
     /* only used for compat API */
-    AVAudioFifo  *audio_fifo;    ///< FIFO for audio samples
+    AVAudioFifo *audio_fifo;     ///< FIFO for audio samples
     int64_t next_pts;            ///< interpolating audio pts
 } BufferSinkContext;
 
@@ -118,7 +119,7 @@
     return 0;
 }
 
-int av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame)
+int attribute_align_arg av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame)
 {
     return av_buffersink_get_frame_flags(ctx, frame, 0);
 }
@@ -173,10 +174,10 @@
     av_frame_free(&tmp);
 
     return 0;
-
 }
 
-int attribute_align_arg av_buffersink_get_samples(AVFilterContext *ctx, AVFrame *frame, int nb_samples)
+int attribute_align_arg av_buffersink_get_samples(AVFilterContext *ctx,
+                                                  AVFrame *frame, int nb_samples)
 {
     BufferSinkContext *s = ctx->priv;
     AVFilterLink   *link = ctx->inputs[0];
@@ -217,7 +218,6 @@
     }
 
     return ret;
-
 }
 
 AVBufferSinkParams *av_buffersink_params_alloc(void)
@@ -264,6 +264,7 @@
 }
 
 #if FF_API_AVFILTERBUFFER
+FF_DISABLE_DEPRECATION_WARNINGS
 static void compat_free_buffer(AVFilterBuffer *buf)
 {
     AVFrame *frame = buf->priv;
@@ -271,7 +272,8 @@
     av_free(buf);
 }
 
-static int attribute_align_arg compat_read(AVFilterContext *ctx, AVFilterBufferRef **pbuf, int nb_samples, int flags)
+static int compat_read(AVFilterContext *ctx,
+                       AVFilterBufferRef **pbuf, int nb_samples, int flags)
 {
     AVFilterBufferRef *buf;
     AVFrame *frame;
@@ -324,19 +326,19 @@
     return ret;
 }
 
-int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
+int attribute_align_arg av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
 {
     return compat_read(ctx, buf, 0, 0);
 }
 
-int av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **buf,
-                               int nb_samples)
+int attribute_align_arg av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **buf,
+                                                   int nb_samples)
 {
     return compat_read(ctx, buf, nb_samples, 0);
 }
 
-int av_buffersink_get_buffer_ref(AVFilterContext *ctx,
-                                  AVFilterBufferRef **bufref, int flags)
+int attribute_align_arg av_buffersink_get_buffer_ref(AVFilterContext *ctx,
+                                                     AVFilterBufferRef **bufref, int flags)
 {
     *bufref = NULL;
 
@@ -347,6 +349,7 @@
 
     return compat_read(ctx, bufref, 0, flags);
 }
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
 AVRational av_buffersink_get_frame_rate(AVFilterContext *ctx)
@@ -561,44 +564,44 @@
 
 static const AVFilterPad avfilter_vsink_buffer_inputs[] = {
     {
-        .name        = "default",
-        .type        = AVMEDIA_TYPE_VIDEO,
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
     { NULL }
 };
 
 AVFilter avfilter_vsink_buffer = {
-    .name      = "buffersink",
+    .name        = "buffersink",
     .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
-    .priv_size = sizeof(BufferSinkContext),
-    .priv_class = &buffersink_class,
+    .priv_size   = sizeof(BufferSinkContext),
+    .priv_class  = &buffersink_class,
     .init_opaque = vsink_init,
-    .uninit    = uninit,
+    .uninit      = uninit,
 
     .query_formats = vsink_query_formats,
-    .inputs    = avfilter_vsink_buffer_inputs,
-    .outputs   = NULL,
+    .inputs      = avfilter_vsink_buffer_inputs,
+    .outputs     = NULL,
 };
 
 static const AVFilterPad avfilter_asink_abuffer_inputs[] = {
     {
-        .name           = "default",
-        .type           = AVMEDIA_TYPE_AUDIO,
-        .filter_frame   = filter_frame,
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_AUDIO,
+        .filter_frame = filter_frame,
     },
     { NULL }
 };
 
 AVFilter avfilter_asink_abuffer = {
-    .name      = "abuffersink",
+    .name        = "abuffersink",
     .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
-    .priv_class = &abuffersink_class,
-    .priv_size = sizeof(BufferSinkContext),
+    .priv_class  = &abuffersink_class,
+    .priv_size   = sizeof(BufferSinkContext),
     .init_opaque = asink_init,
-    .uninit    = uninit,
+    .uninit      = uninit,
 
     .query_formats = asink_query_formats,
-    .inputs    = avfilter_asink_abuffer_inputs,
-    .outputs   = NULL,
+    .inputs      = avfilter_asink_abuffer_inputs,
+    .outputs     = NULL,
 };
diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c
index 5d834b5..b64f7fa 100644
--- a/libavfilter/buffersrc.c
+++ b/libavfilter/buffersrc.c
@@ -30,6 +30,7 @@
 #include "libavutil/fifo.h"
 #include "libavutil/frame.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/internal.h"
 #include "libavutil/opt.h"
 #include "libavutil/samplefmt.h"
 #include "audio.h"
@@ -51,7 +52,6 @@
     /* video only */
     int               w, h;
     enum AVPixelFormat  pix_fmt;
-    char               *pix_fmt_str;
     AVRational        pixel_aspect;
     char              *sws_param;
 
@@ -78,13 +78,13 @@
         return AVERROR(EINVAL);\
     }
 
-int av_buffersrc_write_frame(AVFilterContext *ctx, const AVFrame *frame)
+int attribute_align_arg av_buffersrc_write_frame(AVFilterContext *ctx, const AVFrame *frame)
 {
     return av_buffersrc_add_frame_flags(ctx, (AVFrame *)frame,
                                         AV_BUFFERSRC_FLAG_KEEP_REF);
 }
 
-int av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame)
+int attribute_align_arg av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame)
 {
     return av_buffersrc_add_frame_flags(ctx, frame, 0);
 }
@@ -92,7 +92,7 @@
 static int av_buffersrc_add_frame_internal(AVFilterContext *ctx,
                                            AVFrame *frame, int flags);
 
-int av_buffersrc_add_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags)
+int attribute_align_arg av_buffersrc_add_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags)
 {
     AVFrame *copy = NULL;
     int ret = 0;
@@ -116,8 +116,8 @@
     return ret;
 }
 
-static int attribute_align_arg av_buffersrc_add_frame_internal(AVFilterContext *ctx,
-                                                               AVFrame *frame, int flags)
+static int av_buffersrc_add_frame_internal(AVFilterContext *ctx,
+                                           AVFrame *frame, int flags)
 {
     BufferSourceContext *s = ctx->priv;
     AVFrame *copy;
@@ -174,6 +174,7 @@
 }
 
 #if FF_API_AVFILTERBUFFER
+FF_DISABLE_DEPRECATION_WARNINGS
 static void compat_free_buffer(void *opaque, uint8_t *data)
 {
     AVFilterBufferRef *buf = opaque;
@@ -284,6 +285,7 @@
 
     return ret;
 }
+FF_ENABLE_DEPRECATION_WARNINGS
 
 int av_buffersrc_buffer(AVFilterContext *ctx, AVFilterBufferRef *buf)
 {
diff --git a/libavfilter/deshake_opencl.c b/libavfilter/deshake_opencl.c
index 0f6dcc4..eea873e 100644
--- a/libavfilter/deshake_opencl.c
+++ b/libavfilter/deshake_opencl.c
@@ -27,64 +27,61 @@
 #include "libavutil/dict.h"
 #include "libavutil/pixdesc.h"
 #include "deshake_opencl.h"
+#include "libavutil/opencl_internal.h"
 
 #define MATRIX_SIZE 6
 #define PLANE_NUM 3
 
-#define TRANSFORM_OPENCL_CHECK(method, ...)                                                                  \
-    status = method(__VA_ARGS__);                                                                            \
-    if (status != CL_SUCCESS) {                                                                              \
-        av_log(ctx, AV_LOG_ERROR, "error %s %d\n", # method, status);                                        \
-        return AVERROR_EXTERNAL;                                                                             \
-    }
-
-#define TRANSFORM_OPENCL_SET_KERNEL_ARG(arg_ptr)                                                             \
-    status = clSetKernelArg((kernel),(arg_no++),(sizeof(arg_ptr)),(void*)(&(arg_ptr)));                      \
-    if (status != CL_SUCCESS) {                                                                              \
-        av_log(ctx, AV_LOG_ERROR, "cannot set kernel argument: %d\n", status );                              \
-        return AVERROR_EXTERNAL;                                                                             \
-    }
-
 int ff_opencl_transform(AVFilterContext *ctx,
                         int width, int height, int cw, int ch,
                         const float *matrix_y, const float *matrix_uv,
                         enum InterpolateMethod interpolate,
                         enum FillMethod fill, AVFrame *in, AVFrame *out)
 {
-    int arg_no, ret = 0;
+    int ret = 0;
     const size_t global_work_size = width * height + 2 * ch * cw;
-    cl_kernel kernel;
     cl_int status;
     DeshakeContext *deshake = ctx->priv;
+    FFOpenclParam opencl_param = {0};
+
+    opencl_param.ctx = ctx;
+    opencl_param.kernel = deshake->opencl_ctx.kernel_env.kernel;
     ret = av_opencl_buffer_write(deshake->opencl_ctx.cl_matrix_y, (uint8_t *)matrix_y, deshake->opencl_ctx.matrix_size * sizeof(cl_float));
     if (ret < 0)
         return ret;
     ret = av_opencl_buffer_write(deshake->opencl_ctx.cl_matrix_uv, (uint8_t *)matrix_uv, deshake->opencl_ctx.matrix_size * sizeof(cl_float));
     if (ret < 0)
         return ret;
-    kernel = deshake->opencl_ctx.kernel_env.kernel;
-    arg_no = 0;
 
     if ((unsigned int)interpolate > INTERPOLATE_BIQUADRATIC) {
         av_log(ctx, AV_LOG_ERROR, "Selected interpolate method is invalid\n");
         return AVERROR(EINVAL);
     }
-    TRANSFORM_OPENCL_SET_KERNEL_ARG(deshake->opencl_ctx.cl_inbuf);
-    TRANSFORM_OPENCL_SET_KERNEL_ARG(deshake->opencl_ctx.cl_outbuf);
-    TRANSFORM_OPENCL_SET_KERNEL_ARG(deshake->opencl_ctx.cl_matrix_y);
-    TRANSFORM_OPENCL_SET_KERNEL_ARG(deshake->opencl_ctx.cl_matrix_uv);
-    TRANSFORM_OPENCL_SET_KERNEL_ARG(interpolate);
-    TRANSFORM_OPENCL_SET_KERNEL_ARG(fill);
-    TRANSFORM_OPENCL_SET_KERNEL_ARG(in->linesize[0]);
-    TRANSFORM_OPENCL_SET_KERNEL_ARG(out->linesize[0]);
-    TRANSFORM_OPENCL_SET_KERNEL_ARG(in->linesize[1]);
-    TRANSFORM_OPENCL_SET_KERNEL_ARG(out->linesize[1]);
-    TRANSFORM_OPENCL_SET_KERNEL_ARG(height);
-    TRANSFORM_OPENCL_SET_KERNEL_ARG(width);
-    TRANSFORM_OPENCL_SET_KERNEL_ARG(ch);
-    TRANSFORM_OPENCL_SET_KERNEL_ARG(cw);
-    TRANSFORM_OPENCL_CHECK(clEnqueueNDRangeKernel, deshake->opencl_ctx.kernel_env.command_queue, deshake->opencl_ctx.kernel_env.kernel, 1, NULL,
-                           &global_work_size, NULL, 0, NULL, NULL);
+    ret = ff_opencl_set_parameter(&opencl_param,
+                                  FF_OPENCL_PARAM_INFO(deshake->opencl_ctx.cl_inbuf),
+                                  FF_OPENCL_PARAM_INFO(deshake->opencl_ctx.cl_outbuf),
+                                  FF_OPENCL_PARAM_INFO(deshake->opencl_ctx.cl_matrix_y),
+                                  FF_OPENCL_PARAM_INFO(deshake->opencl_ctx.cl_matrix_uv),
+                                  FF_OPENCL_PARAM_INFO(interpolate),
+                                  FF_OPENCL_PARAM_INFO(fill),
+                                  FF_OPENCL_PARAM_INFO(in->linesize[0]),
+                                  FF_OPENCL_PARAM_INFO(out->linesize[0]),
+                                  FF_OPENCL_PARAM_INFO(in->linesize[1]),
+                                  FF_OPENCL_PARAM_INFO(out->linesize[1]),
+                                  FF_OPENCL_PARAM_INFO(height),
+                                  FF_OPENCL_PARAM_INFO(width),
+                                  FF_OPENCL_PARAM_INFO(ch),
+                                  FF_OPENCL_PARAM_INFO(cw),
+                                  NULL);
+    if (ret < 0)
+        return ret;
+    status = clEnqueueNDRangeKernel(deshake->opencl_ctx.kernel_env.command_queue,
+                                    deshake->opencl_ctx.kernel_env.kernel, 1, NULL,
+                                    &global_work_size, NULL, 0, NULL, NULL);
+    if (status != CL_SUCCESS) {
+        av_log(ctx, AV_LOG_ERROR, "OpenCL run kernel error occurred: %s\n", av_opencl_errstr(status));
+        return AVERROR_EXTERNAL;
+    }
     clFinish(deshake->opencl_ctx.kernel_env.command_queue);
     ret = av_opencl_buffer_read_image(out->data, deshake->opencl_ctx.out_plane_size,
                                       deshake->opencl_ctx.plane_num, deshake->opencl_ctx.cl_outbuf,
@@ -138,7 +135,8 @@
     int ret = 0;
     AVFilterLink *link = ctx->inputs[0];
     DeshakeContext *deshake = ctx->priv;
-    int chroma_height = -((-link->h) >> av_pix_fmt_desc_get(link->format)->log2_chroma_h);
+    const int hshift = av_pix_fmt_desc_get(link->format)->log2_chroma_h;
+    int chroma_height = FF_CEIL_RSHIFT(link->h, hshift);
 
     if ((!deshake->opencl_ctx.cl_inbuf) || (!deshake->opencl_ctx.cl_outbuf)) {
         deshake->opencl_ctx.in_plane_size[0]  = (in->linesize[0] * in->height);
diff --git a/libavfilter/deshake_kernel.h b/libavfilter/deshake_opencl_kernel.h
similarity index 98%
rename from libavfilter/deshake_kernel.h
rename to libavfilter/deshake_opencl_kernel.h
index 1eb06fe..ca0bf83 100644
--- a/libavfilter/deshake_kernel.h
+++ b/libavfilter/deshake_opencl_kernel.h
@@ -19,8 +19,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#ifndef AVFILTER_DESHAKE_KERNEL_H
-#define AVFILTER_DESHAKE_KERNEL_H
+#ifndef AVFILTER_DESHAKE_OPENCL_KERNEL_H
+#define AVFILTER_DESHAKE_OPENCL_KERNEL_H
 
 #include "libavutil/opencl.h"
 
@@ -214,4 +214,4 @@
 }
 );
 
-#endif /* AVFILTER_DESHAKE_KERNEL_H */
+#endif /* AVFILTER_DESHAKE_OPENCL_KERNEL_H */
diff --git a/libavfilter/drawutils.c b/libavfilter/drawutils.c
index aebc000..a5064f8 100644
--- a/libavfilter/drawutils.c
+++ b/libavfilter/drawutils.c
@@ -37,12 +37,22 @@
     case AV_PIX_FMT_ARGB:  rgba_map[ALPHA] = 0; rgba_map[RED  ] = 1; rgba_map[GREEN] = 2; rgba_map[BLUE ] = 3; break;
     case AV_PIX_FMT_0BGR:
     case AV_PIX_FMT_ABGR:  rgba_map[ALPHA] = 0; rgba_map[BLUE ] = 1; rgba_map[GREEN] = 2; rgba_map[RED  ] = 3; break;
+    case AV_PIX_FMT_RGB48LE:
+    case AV_PIX_FMT_RGB48BE:
+    case AV_PIX_FMT_RGBA64BE:
+    case AV_PIX_FMT_RGBA64LE:
     case AV_PIX_FMT_RGB0:
     case AV_PIX_FMT_RGBA:
     case AV_PIX_FMT_RGB24: rgba_map[RED  ] = 0; rgba_map[GREEN] = 1; rgba_map[BLUE ] = 2; rgba_map[ALPHA] = 3; break;
+    case AV_PIX_FMT_BGR48LE:
+    case AV_PIX_FMT_BGR48BE:
+    case AV_PIX_FMT_BGRA64BE:
+    case AV_PIX_FMT_BGRA64LE:
     case AV_PIX_FMT_BGRA:
     case AV_PIX_FMT_BGR0:
     case AV_PIX_FMT_BGR24: rgba_map[BLUE ] = 0; rgba_map[GREEN] = 1; rgba_map[RED  ] = 2; rgba_map[ALPHA] = 3; break;
+    case AV_PIX_FMT_GBRAP:
+    case AV_PIX_FMT_GBRP:  rgba_map[GREEN] = 0; rgba_map[BLUE ] = 1; rgba_map[RED  ] = 2; rgba_map[ALPHA] = 3; break;
     default:                    /* unsupported */
         return AVERROR(EINVAL);
     }
@@ -83,7 +93,7 @@
             int hsub1 = (plane == 1 || plane == 2) ? hsub : 0;
 
             pixel_step[plane] = 1;
-            line_size = (w >> hsub1) * pixel_step[plane];
+            line_size = FF_CEIL_RSHIFT(w, hsub1) * pixel_step[plane];
             line[plane] = av_malloc(line_size);
             memset(line[plane], dst_color[plane], line_size);
         }
@@ -102,11 +112,13 @@
     for (plane = 0; plane < 4 && dst[plane]; plane++) {
         int hsub1 = plane == 1 || plane == 2 ? hsub : 0;
         int vsub1 = plane == 1 || plane == 2 ? vsub : 0;
+        int width  = FF_CEIL_RSHIFT(w, hsub1);
+        int height = FF_CEIL_RSHIFT(h, vsub1);
 
         p = dst[plane] + (y >> vsub1) * dst_linesize[plane];
-        for (i = 0; i < (h >> vsub1); i++) {
+        for (i = 0; i < height; i++) {
             memcpy(p + (x >> hsub1) * pixelstep[plane],
-                   src[plane], (w >> hsub1) * pixelstep[plane]);
+                   src[plane], width * pixelstep[plane]);
             p += dst_linesize[plane];
         }
     }
@@ -122,11 +134,13 @@
     for (plane = 0; plane < 4 && dst[plane]; plane++) {
         int hsub1 = plane == 1 || plane == 2 ? hsub : 0;
         int vsub1 = plane == 1 || plane == 2 ? vsub : 0;
+        int width  = FF_CEIL_RSHIFT(w, hsub1);
+        int height = FF_CEIL_RSHIFT(h, vsub1);
 
         p = dst[plane] + (y >> vsub1) * dst_linesize[plane];
-        for (i = 0; i < (h >> vsub1); i++) {
+        for (i = 0; i < height; i++) {
             memcpy(p + (x >> hsub1) * pixelstep[plane],
-                   src[plane] + src_linesize[plane]*(i+(y2>>vsub1)), (w >> hsub1) * pixelstep[plane]);
+                   src[plane] + src_linesize[plane]*(i+(y2>>vsub1)), width * pixelstep[plane]);
             p += dst_linesize[plane];
         }
     }
@@ -141,7 +155,7 @@
 
     if (!desc->name)
         return AVERROR(EINVAL);
-    if (desc->flags & ~(PIX_FMT_PLANAR | PIX_FMT_RGB | PIX_FMT_PSEUDOPAL | PIX_FMT_ALPHA))
+    if (desc->flags & ~(AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PSEUDOPAL | AV_PIX_FMT_FLAG_ALPHA))
         return AVERROR(ENOSYS);
     for (i = 0; i < desc->nb_components; i++) {
         c = &desc->comp[i];
@@ -166,10 +180,8 @@
     draw->format    = format;
     draw->nb_planes = nb_planes;
     memcpy(draw->pixelstep, pixelstep, sizeof(draw->pixelstep));
-    if (nb_planes >= 3 && !(desc->flags & PIX_FMT_RGB)) {
-        draw->hsub[1] = draw->hsub[2] = draw->hsub_max = desc->log2_chroma_w;
-        draw->vsub[1] = draw->vsub[2] = draw->vsub_max = desc->log2_chroma_h;
-    }
+    draw->hsub[1] = draw->hsub[2] = draw->hsub_max = desc->log2_chroma_w;
+    draw->vsub[1] = draw->vsub[2] = draw->vsub_max = desc->log2_chroma_h;
     for (i = 0; i < ((desc->nb_components - 1) | 1); i++)
         draw->comp_mask[desc->comp[i].plane] |=
             1 << (desc->comp[i].offset_plus1 - 1);
@@ -183,10 +195,15 @@
 
     if (rgba != color->rgba)
         memcpy(color->rgba, rgba, sizeof(color->rgba));
-    if ((draw->desc->flags & PIX_FMT_RGB) && draw->nb_planes == 1 &&
+    if ((draw->desc->flags & AV_PIX_FMT_FLAG_RGB) &&
         ff_fill_rgba_map(rgba_map, draw->format) >= 0) {
+        if (draw->nb_planes == 1) {
         for (i = 0; i < 4; i++)
             color->comp[0].u8[rgba_map[i]] = rgba[i];
+        } else {
+            for (i = 0; i < 4; i++)
+                color->comp[rgba_map[i]].u8[0] = rgba[i];
+        }
     } else if (draw->nb_planes == 3 || draw->nb_planes == 4) {
         /* assume YUV */
         color->comp[0].u8[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
@@ -223,8 +240,8 @@
     for (plane = 0; plane < draw->nb_planes; plane++) {
         p = pointer_at(draw, src, src_linesize, plane, src_x, src_y);
         q = pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y);
-        wp = (w >> draw->hsub[plane]) * draw->pixelstep[plane];
-        hp = (h >> draw->vsub[plane]);
+        wp = FF_CEIL_RSHIFT(w, draw->hsub[plane]) * draw->pixelstep[plane];
+        hp = FF_CEIL_RSHIFT(h, draw->vsub[plane]);
         for (y = 0; y < hp; y++) {
             memcpy(q, p, wp);
             p += src_linesize[plane];
@@ -242,8 +259,8 @@
 
     for (plane = 0; plane < draw->nb_planes; plane++) {
         p0 = pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y);
-        wp = (w >> draw->hsub[plane]);
-        hp = (h >> draw->vsub[plane]);
+        wp = FF_CEIL_RSHIFT(w, draw->hsub[plane]);
+        hp = FF_CEIL_RSHIFT(h, draw->vsub[plane]);
         if (!hp)
             return;
         p = p0;
diff --git a/libavfilter/dualinput.c b/libavfilter/dualinput.c
new file mode 100644
index 0000000..10e3652
--- /dev/null
+++ b/libavfilter/dualinput.c
@@ -0,0 +1,159 @@
+/*
+ * 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 MAIN  0
+#define SECOND 1
+
+#include "dualinput.h"
+#include "libavutil/timestamp.h"
+
+static int try_filter_frame(FFDualInputContext *s,
+                            AVFilterContext *ctx, AVFrame *mainpic)
+{
+    int ret;
+
+    /* Discard obsolete second frames: if there is a next second frame with pts
+     * before the main frame, we can drop the current second. */
+    while (1) {
+        AVFrame *next_overpic = ff_bufqueue_peek(&s->queue[SECOND], 0);
+        if (!next_overpic && s->second_eof && !s->repeatlast) {
+            av_frame_free(&s->second_frame);
+            break;
+        }
+        if (!next_overpic || av_compare_ts(next_overpic->pts, ctx->inputs[SECOND]->time_base,
+                                           mainpic->pts,      ctx->inputs[MAIN]->time_base) > 0)
+            break;
+        ff_bufqueue_get(&s->queue[SECOND]);
+        av_frame_free(&s->second_frame);
+        s->second_frame = next_overpic;
+    }
+
+    /* If there is no next frame and no EOF and the second frame is before
+     * the main frame, we can not know yet if it will be superseded. */
+    if (!s->queue[SECOND].available && !s->second_eof &&
+        (!s->second_frame || av_compare_ts(s->second_frame->pts, ctx->inputs[SECOND]->time_base,
+                                           mainpic->pts,         ctx->inputs[MAIN]->time_base) < 0))
+        return AVERROR(EAGAIN);
+
+    /* At this point, we know that the current second frame extends to the
+     * time of the main frame. */
+    av_dlog(ctx, "main_pts:%s main_pts_time:%s",
+            av_ts2str(mainpic->pts), av_ts2timestr(mainpic->pts, &ctx->inputs[MAIN]->time_base));
+    if (s->second_frame)
+        av_dlog(ctx, " second_pts:%s second_pts_time:%s",
+                av_ts2str(s->second_frame->pts), av_ts2timestr(s->second_frame->pts, &ctx->inputs[SECOND]->time_base));
+    av_dlog(ctx, "\n");
+
+    if (s->second_frame && !ctx->is_disabled)
+        mainpic = s->process(ctx, mainpic, s->second_frame);
+    ret = ff_filter_frame(ctx->outputs[0], mainpic);
+    av_assert1(ret != AVERROR(EAGAIN));
+    s->frame_requested = 0;
+    return ret;
+}
+
+static int try_filter_next_frame(FFDualInputContext *s, AVFilterContext *ctx)
+{
+    AVFrame *next_mainpic = ff_bufqueue_peek(&s->queue[MAIN], 0);
+    int ret;
+
+    if (!next_mainpic)
+        return AVERROR(EAGAIN);
+    if ((ret = try_filter_frame(s, ctx, next_mainpic)) == AVERROR(EAGAIN))
+        return ret;
+    ff_bufqueue_get(&s->queue[MAIN]);
+    return ret;
+}
+
+static int flush_frames(FFDualInputContext *s, AVFilterContext *ctx)
+{
+    int ret;
+
+    while (!(ret = try_filter_next_frame(s, ctx)));
+    return ret == AVERROR(EAGAIN) ? 0 : ret;
+}
+
+int ff_dualinput_filter_frame_main(FFDualInputContext *s,
+                                   AVFilterLink *inlink, AVFrame *in)
+{
+    AVFilterContext *ctx = inlink->dst;
+    int ret;
+
+    if ((ret = flush_frames(s, ctx)) < 0)
+        return ret;
+    if ((ret = try_filter_frame(s, ctx, in)) < 0) {
+        if (ret != AVERROR(EAGAIN))
+            return ret;
+        ff_bufqueue_add(ctx, &s->queue[MAIN], in);
+    }
+
+    if (!s->second_frame)
+        return 0;
+    flush_frames(s, ctx);
+
+    return 0;
+}
+
+int ff_dualinput_filter_frame_second(FFDualInputContext *s,
+                                     AVFilterLink *inlink, AVFrame *in)
+{
+    AVFilterContext *ctx = inlink->dst;
+    int ret;
+
+    if ((ret = flush_frames(s, ctx)) < 0)
+        return ret;
+    ff_bufqueue_add(ctx, &s->queue[SECOND], in);
+    ret = try_filter_next_frame(s, ctx);
+    return ret == AVERROR(EAGAIN) ? 0 : ret;
+}
+
+int ff_dualinput_request_frame(FFDualInputContext *s, AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    int input, ret;
+
+    if (!try_filter_next_frame(s, ctx))
+        return 0;
+    s->frame_requested = 1;
+    while (s->frame_requested) {
+        /* TODO if we had a frame duration, we could guess more accurately */
+        input = !s->second_eof && (s->queue[MAIN].available ||
+                                   s->queue[SECOND].available < 2) ?
+                SECOND : MAIN;
+        ret = ff_request_frame(ctx->inputs[input]);
+        /* EOF on main is reported immediately */
+        if (ret == AVERROR_EOF && input == SECOND) {
+            s->second_eof = 1;
+            if (s->shortest)
+                return ret;
+            if ((ret = try_filter_next_frame(s, ctx)) != AVERROR(EAGAIN))
+                return ret;
+            ret = 0; /* continue requesting frames on main */
+        }
+        if (ret < 0)
+            return ret;
+    }
+    return 0;
+}
+
+void ff_dualinput_uninit(FFDualInputContext *s)
+{
+    av_frame_free(&s->second_frame);
+    ff_bufqueue_discard_all(&s->queue[MAIN]);
+    ff_bufqueue_discard_all(&s->queue[SECOND]);
+}
diff --git a/libavfilter/dualinput.h b/libavfilter/dualinput.h
new file mode 100644
index 0000000..98d0544
--- /dev/null
+++ b/libavfilter/dualinput.h
@@ -0,0 +1,46 @@
+/*
+ * 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
+ */
+
+/**
+ * @file
+ * Double input streams helper for filters
+ */
+
+#ifndef AVFILTER_DUALINPUT_H
+#define AVFILTER_DUALINPUT_H
+
+#include <stdint.h>
+#include "bufferqueue.h"
+#include "internal.h"
+
+typedef struct {
+    uint8_t frame_requested;
+    uint8_t second_eof;
+    AVFrame *second_frame;
+    struct FFBufQueue queue[2];
+    AVFrame *(*process)(AVFilterContext *ctx, AVFrame *main, const AVFrame *second);
+    int shortest;               ///< terminate stream when the second input terminates
+    int repeatlast;             ///< repeat last second frame
+} FFDualInputContext;
+
+int ff_dualinput_filter_frame_main(FFDualInputContext *s, AVFilterLink *inlink, AVFrame *in);
+int ff_dualinput_filter_frame_second(FFDualInputContext *s, AVFilterLink *inlink, AVFrame *in);
+int ff_dualinput_request_frame(FFDualInputContext *s, AVFilterLink *outlink);
+void ff_dualinput_uninit(FFDualInputContext *s);
+
+#endif /* AVFILTER_DUALINPUT_H */
diff --git a/libavfilter/f_ebur128.c b/libavfilter/f_ebur128.c
index 88d37e8..99e12af 100644
--- a/libavfilter/f_ebur128.c
+++ b/libavfilter/f_ebur128.c
@@ -64,7 +64,7 @@
 #define HIST_SIZE  ((ABS_UP_THRES - ABS_THRES) * HIST_GRAIN + 1)
 
 /**
- * An histogram is an array of HIST_SIZE hist_entry storing all the energies
+ * A histogram is an array of HIST_SIZE hist_entry storing all the energies
  * recorded (with an accuracy of 1/HIST_GRAIN) of the loudnesses from ABS_THRES
  * (at 0) to ABS_UP_THRES (at HIST_SIZE-1).
  * This fixed-size system avoids the need of a list of energies growing
@@ -722,7 +722,7 @@
 
     /* set input and output audio formats
      * Note: ff_set_common_* functions are not used because they affect all the
-     * links, and thus break the video format negociation */
+     * links, and thus break the video format negotiation */
     formats = ff_make_format_list(sample_fmts);
     if (!formats)
         return AVERROR(ENOMEM);
diff --git a/libavfilter/f_interleave.c b/libavfilter/f_interleave.c
index 04d7677..33cb8cd 100644
--- a/libavfilter/f_interleave.c
+++ b/libavfilter/f_interleave.c
@@ -135,7 +135,7 @@
     return 0;
 }
 
-static void uninit(AVFilterContext *ctx)
+static av_cold void uninit(AVFilterContext *ctx)
 {
     InterleaveContext *interleave = ctx->priv;
     int i;
diff --git a/libavfilter/f_select.c b/libavfilter/f_select.c
index b0df507..07a64f3 100644
--- a/libavfilter/f_select.c
+++ b/libavfilter/f_select.c
@@ -59,6 +59,13 @@
     "SI",
     "SP",
     "BI",
+    "PICT_TYPE_I",
+    "PICT_TYPE_P",
+    "PICT_TYPE_B",
+    "PICT_TYPE_S",
+    "PICT_TYPE_SI",
+    "PICT_TYPE_SP",
+    "PICT_TYPE_BI",
 
     "interlace_type",    ///< the frame interlace type
     "PROGRESSIVE",
@@ -95,6 +102,13 @@
     VAR_PREV_SELECTED_T,
 
     VAR_PICT_TYPE,
+    VAR_I,
+    VAR_P,
+    VAR_B,
+    VAR_S,
+    VAR_SI,
+    VAR_SP,
+    VAR_BI,
     VAR_PICT_TYPE_I,
     VAR_PICT_TYPE_P,
     VAR_PICT_TYPE_B,
@@ -200,11 +214,18 @@
     select->var_values[VAR_START_PTS]         = NAN;
     select->var_values[VAR_START_T]           = NAN;
 
+    select->var_values[VAR_I]  = AV_PICTURE_TYPE_I;
+    select->var_values[VAR_P]  = AV_PICTURE_TYPE_P;
+    select->var_values[VAR_B]  = AV_PICTURE_TYPE_B;
+    select->var_values[VAR_SI] = AV_PICTURE_TYPE_SI;
+    select->var_values[VAR_SP] = AV_PICTURE_TYPE_SP;
+    select->var_values[VAR_BI] = AV_PICTURE_TYPE_BI;
     select->var_values[VAR_PICT_TYPE_I]  = AV_PICTURE_TYPE_I;
     select->var_values[VAR_PICT_TYPE_P]  = AV_PICTURE_TYPE_P;
     select->var_values[VAR_PICT_TYPE_B]  = AV_PICTURE_TYPE_B;
     select->var_values[VAR_PICT_TYPE_SI] = AV_PICTURE_TYPE_SI;
     select->var_values[VAR_PICT_TYPE_SP] = AV_PICTURE_TYPE_SP;
+    select->var_values[VAR_PICT_TYPE_BI] = AV_PICTURE_TYPE_BI;
 
     select->var_values[VAR_INTERLACE_TYPE_P] = INTERLACE_TYPE_P;
     select->var_values[VAR_INTERLACE_TYPE_T] = INTERLACE_TYPE_T;
diff --git a/libavfilter/f_sendcmd.c b/libavfilter/f_sendcmd.c
index 319d503..bb8a178 100644
--- a/libavfilter/f_sendcmd.c
+++ b/libavfilter/f_sendcmd.c
@@ -39,7 +39,7 @@
 
 static inline char *make_command_flags_str(AVBPrint *pbuf, int flags)
 {
-    const char *flag_strings[] = { "enter", "leave" };
+    static const char * const flag_strings[] = { "enter", "leave" };
     int i, is_first = 1;
 
     av_bprint_init(pbuf, 0, AV_BPRINT_SIZE_AUTOMATIC);
@@ -422,7 +422,7 @@
     return 0;
 }
 
-static void av_cold uninit(AVFilterContext *ctx)
+static av_cold void uninit(AVFilterContext *ctx)
 {
     SendCmdContext *sendcmd = ctx->priv;
     int i, j;
diff --git a/libavfilter/f_zmq.c b/libavfilter/f_zmq.c
new file mode 100644
index 0000000..547e1a3
--- /dev/null
+++ b/libavfilter/f_zmq.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 2013 Stefano Sabatini
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * receive commands through libzeromq and broker them to filters
+ */
+
+#include <zmq.h>
+#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
+#include "libavutil/opt.h"
+#include "avfilter.h"
+#include "internal.h"
+#include "avfiltergraph.h"
+#include "audio.h"
+#include "video.h"
+
+typedef struct {
+    const AVClass *class;
+    void *zmq;
+    void *responder;
+    char *bind_address;
+    int command_count;
+} ZMQContext;
+
+#define OFFSET(x) offsetof(ZMQContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "bind_address", "set bind address", OFFSET(bind_address), AV_OPT_TYPE_STRING, {.str = "tcp://*:5555"}, 0, 0, FLAGS },
+    { "b",            "set bind address", OFFSET(bind_address), AV_OPT_TYPE_STRING, {.str = "tcp://*:5555"}, 0, 0, FLAGS },
+    { NULL }
+};
+
+static av_cold int init(AVFilterContext *ctx)
+{
+    ZMQContext *zmq = ctx->priv;
+
+    zmq->zmq = zmq_ctx_new();
+    if (!zmq->zmq) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Could not create ZMQ context: %s\n", zmq_strerror(errno));
+        return AVERROR_EXTERNAL;
+    }
+
+    zmq->responder = zmq_socket(zmq->zmq, ZMQ_REP);
+    if (!zmq->responder) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Could not create ZMQ socket: %s\n", zmq_strerror(errno));
+        return AVERROR_EXTERNAL;
+    }
+
+    if (zmq_bind(zmq->responder, zmq->bind_address) == -1) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Could not bind ZMQ socket to address '%s': %s\n",
+               zmq->bind_address, zmq_strerror(errno));
+        return AVERROR_EXTERNAL;
+    }
+
+    zmq->command_count = -1;
+    return 0;
+}
+
+static void av_cold uninit(AVFilterContext *ctx)
+{
+    ZMQContext *zmq = ctx->priv;
+
+    zmq_close(zmq->responder);
+    zmq_ctx_destroy(zmq->zmq);
+}
+
+typedef struct {
+    char *target, *command, *arg;
+} Command;
+
+#define SPACES " \f\t\n\r"
+
+static int parse_command(Command *cmd, const char *command_str, void *log_ctx)
+{
+    const char **buf = &command_str;
+
+    cmd->target = av_get_token(buf, SPACES);
+    if (!cmd->target || !cmd->target[0]) {
+        av_log(log_ctx, AV_LOG_ERROR,
+               "No target specified in command '%s'\n", command_str);
+        return AVERROR(EINVAL);
+    }
+
+    cmd->command = av_get_token(buf, SPACES);
+    if (!cmd->command || !cmd->command[0]) {
+        av_log(log_ctx, AV_LOG_ERROR,
+               "No command specified in command '%s'\n", command_str);
+        return AVERROR(EINVAL);
+    }
+
+    cmd->arg = av_get_token(buf, SPACES);
+    return 0;
+}
+
+static int recv_msg(AVFilterContext *ctx, char **buf, int *buf_size)
+{
+    ZMQContext *zmq = ctx->priv;
+    zmq_msg_t msg;
+    int ret = 0;
+
+    if (zmq_msg_init(&msg) == -1) {
+        av_log(ctx, AV_LOG_WARNING,
+               "Could not initialize receive message: %s\n", zmq_strerror(errno));
+        return AVERROR_EXTERNAL;
+    }
+
+    if (zmq_msg_recv(&msg, zmq->responder, ZMQ_DONTWAIT) == -1) {
+        if (errno != EAGAIN)
+            av_log(ctx, AV_LOG_WARNING,
+                   "Could not receive message: %s\n", zmq_strerror(errno));
+        ret = AVERROR_EXTERNAL;
+        goto end;
+    }
+
+    *buf_size = zmq_msg_size(&msg) + 1;
+    *buf = av_malloc(*buf_size);
+    if (!*buf) {
+        ret = AVERROR(ENOMEM);
+        goto end;
+    }
+    memcpy(*buf, zmq_msg_data(&msg), *buf_size);
+    (*buf)[*buf_size-1] = 0;
+
+end:
+    zmq_msg_close(&msg);
+    return ret;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *ref)
+{
+    AVFilterContext *ctx = inlink->dst;
+    ZMQContext *zmq = ctx->priv;
+
+    while (1) {
+        char cmd_buf[1024];
+        char *recv_buf, *send_buf;
+        int recv_buf_size;
+        Command cmd = {0};
+        int ret;
+
+        /* receive command */
+        if (recv_msg(ctx, &recv_buf, &recv_buf_size) < 0)
+            break;
+        zmq->command_count++;
+
+        /* parse command */
+        if (parse_command(&cmd, recv_buf, ctx) < 0) {
+            av_log(ctx, AV_LOG_ERROR, "Could not parse command #%d\n", zmq->command_count);
+            goto end;
+        }
+
+        /* process command */
+        av_log(ctx, AV_LOG_VERBOSE,
+               "Processing command #%d target:%s command:%s arg:%s\n",
+               zmq->command_count, cmd.target, cmd.command, cmd.arg);
+        ret = avfilter_graph_send_command(inlink->graph,
+                                          cmd.target, cmd.command, cmd.arg,
+                                          cmd_buf, sizeof(cmd_buf),
+                                          AVFILTER_CMD_FLAG_ONE);
+        send_buf = av_asprintf("%d %s%s%s",
+                               -ret, av_err2str(ret), cmd_buf[0] ? "\n" : "", cmd_buf);
+        if (!send_buf) {
+            ret = AVERROR(ENOMEM);
+            goto end;
+        }
+        av_log(ctx, AV_LOG_VERBOSE,
+               "Sending command reply for command #%d:\n%s\n",
+               zmq->command_count, send_buf);
+        if (zmq_send(zmq->responder, send_buf, strlen(send_buf), 0) == -1)
+            av_log(ctx, AV_LOG_ERROR, "Failed to send reply for command #%d: %s\n",
+                   zmq->command_count, zmq_strerror(ret));
+
+    end:
+        av_freep(&send_buf);
+        av_freep(&recv_buf);
+        recv_buf_size = 0;
+        av_freep(&cmd.target);
+        av_freep(&cmd.command);
+        av_freep(&cmd.arg);
+    }
+
+    return ff_filter_frame(ctx->outputs[0], ref);
+}
+
+#if CONFIG_ZMQ_FILTER
+
+#define zmq_options options
+AVFILTER_DEFINE_CLASS(zmq);
+
+static const AVFilterPad zmq_inputs[] = {
+    {
+        .name             = "default",
+        .type             = AVMEDIA_TYPE_VIDEO,
+        .filter_frame     = filter_frame,
+    },
+    { NULL }
+};
+
+static const AVFilterPad zmq_outputs[] = {
+    {
+        .name = "default",
+        .type = AVMEDIA_TYPE_VIDEO,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_zmq = {
+    .name        = "zmq",
+    .description = NULL_IF_CONFIG_SMALL("Receive commands through ZMQ and broker them to filters."),
+    .init        = init,
+    .uninit      = uninit,
+    .priv_size   = sizeof(ZMQContext),
+    .inputs      = zmq_inputs,
+    .outputs     = zmq_outputs,
+    .priv_class  = &zmq_class,
+};
+
+#endif
+
+#if CONFIG_AZMQ_FILTER
+
+#define azmq_options options
+AVFILTER_DEFINE_CLASS(azmq);
+
+static const AVFilterPad azmq_inputs[] = {
+    {
+        .name             = "default",
+        .type             = AVMEDIA_TYPE_AUDIO,
+        .get_audio_buffer = ff_null_get_audio_buffer,
+        .filter_frame     = filter_frame,
+    },
+    { NULL }
+};
+
+static const AVFilterPad azmq_outputs[] = {
+    {
+        .name = "default",
+        .type = AVMEDIA_TYPE_AUDIO,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_af_azmq = {
+    .name        = "azmq",
+    .description = NULL_IF_CONFIG_SMALL("Receive commands through ZMQ and broker them to filters."),
+    .init        = init,
+    .uninit      = uninit,
+    .priv_size   = sizeof(ZMQContext),
+    .inputs      = azmq_inputs,
+    .outputs     = azmq_outputs,
+    .priv_class  = &azmq_class,
+};
+
+#endif
diff --git a/libavfilter/fifo.c b/libavfilter/fifo.c
index b06720e..c6beaf6 100644
--- a/libavfilter/fifo.c
+++ b/libavfilter/fifo.c
@@ -147,10 +147,14 @@
 {
     AVFilterLink *link = ctx->outputs[0];
     FifoContext *s = ctx->priv;
-    AVFrame *head = s->root.next->frame;
+    AVFrame *head = s->root.next ? s->root.next->frame : NULL;
     AVFrame *out;
     int ret;
 
+    /* if head is NULL then we're flushing the remaining samples in out */
+    if (!head && !s->out)
+        return AVERROR_EOF;
+
     if (!s->out &&
         head->nb_samples >= link->request_samples &&
         calc_ptr_alignment(head) >= 32) {
@@ -197,6 +201,7 @@
                     break;
                 } else if (ret < 0)
                     return ret;
+                av_assert0(s->root.next); // If ff_request_frame() succeeded then we should have a frame
             }
             head = s->root.next->frame;
 
@@ -227,8 +232,11 @@
     int ret = 0;
 
     if (!fifo->root.next) {
-        if ((ret = ff_request_frame(outlink->src->inputs[0])) < 0)
+        if ((ret = ff_request_frame(outlink->src->inputs[0])) < 0) {
+            if (ret == AVERROR_EOF && outlink->request_samples)
+                return return_audio_frame(outlink->src);
             return ret;
+        }
         av_assert0(fifo->root.next);
     }
 
diff --git a/libavfilter/filtfmts.c b/libavfilter/filtfmts.c
index 61b002d..6d4da68 100644
--- a/libavfilter/filtfmts.c
+++ b/libavfilter/filtfmts.c
@@ -35,7 +35,7 @@
         if (filter_ctx->inout##puts[i]->type == AVMEDIA_TYPE_VIDEO) {   \
             AVFilterFormats *fmts =                                     \
                 filter_ctx->inout##puts[i]->outin##_formats;            \
-            for (j = 0; j < fmts->format_count; j++)                    \
+            for (j = 0; j < fmts->nb_formats; j++)                    \
                 if(av_get_pix_fmt_name(fmts->formats[j]))               \
                 printf(#INOUT "PUT[%d] %s: fmt:%s\n",                   \
                        i, filter_ctx->filter->inout##puts[i].name,      \
@@ -45,7 +45,7 @@
             AVFilterChannelLayouts *layouts;                            \
                                                                         \
             fmts = filter_ctx->inout##puts[i]->outin##_formats;         \
-            for (j = 0; j < fmts->format_count; j++)                    \
+            for (j = 0; j < fmts->nb_formats; j++)                    \
                 printf(#INOUT "PUT[%d] %s: fmt:%s\n",                   \
                        i, filter_ctx->filter->inout##puts[i].name,      \
                        av_get_sample_fmt_name(fmts->formats[j]));       \
@@ -69,6 +69,7 @@
 {
     AVFilter *filter;
     AVFilterContext *filter_ctx;
+    AVFilterGraph *graph_ctx;
     const char *filter_name;
     const char *filter_args = NULL;
     int i;
@@ -84,6 +85,11 @@
     if (argc > 2)
         filter_args = argv[2];
 
+    /* allocate graph */
+    graph_ctx = avfilter_graph_alloc();
+    if (!graph_ctx)
+        return 1;
+
     avfilter_register_all();
 
     /* get a corresponding filter and open it */
@@ -92,7 +98,8 @@
         return 1;
     }
 
-    if (avfilter_open(&filter_ctx, filter, NULL) < 0) {
+    /* open filter and add it to the graph */
+    if (!(filter_ctx = avfilter_graph_alloc_filter(graph_ctx, filter, filter_name))) {
         fprintf(stderr, "Impossible to open filter with name '%s'\n",
                 filter_name);
         return 1;
@@ -123,6 +130,7 @@
     print_formats(filter_ctx);
 
     avfilter_free(filter_ctx);
+    avfilter_graph_free(&graph_ctx);
     fflush(stdout);
     return 0;
 }
diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index ea24627..d51bf3c 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -108,14 +108,14 @@
        To avoid that, pretend that there are no common formats to force the
        insertion of a conversion filter. */
     if (type == AVMEDIA_TYPE_VIDEO)
-        for (i = 0; i < a->format_count; i++)
-            for (j = 0; j < b->format_count; j++) {
+        for (i = 0; i < a->nb_formats; i++)
+            for (j = 0; j < b->nb_formats; j++) {
                 const AVPixFmtDescriptor *adesc = av_pix_fmt_desc_get(a->formats[i]);
                 const AVPixFmtDescriptor *bdesc = av_pix_fmt_desc_get(b->formats[j]);
-                alpha2 |= adesc->flags & bdesc->flags & PIX_FMT_ALPHA;
+                alpha2 |= adesc->flags & bdesc->flags & AV_PIX_FMT_FLAG_ALPHA;
                 chroma2|= adesc->nb_components > 1 && bdesc->nb_components > 1;
                 if (a->formats[i] == b->formats[j]) {
-                    alpha1 |= adesc->flags & PIX_FMT_ALPHA;
+                    alpha1 |= adesc->flags & AV_PIX_FMT_FLAG_ALPHA;
                     chroma1|= adesc->nb_components > 1;
                 }
             }
@@ -124,7 +124,7 @@
     if (alpha2 > alpha1 || chroma2 > chroma1)
         return NULL;
 
-    MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail);
+    MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail);
 
     return ret;
 fail:
@@ -143,9 +143,9 @@
 
     if (a == b) return a;
 
-    if (a->format_count && b->format_count) {
-        MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail);
-    } else if (a->format_count) {
+    if (a->nb_formats && b->nb_formats) {
+        MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail);
+    } else if (a->nb_formats) {
         MERGE_REF(a, b, formats, AVFilterFormats, fail);
         ret = a;
     } else {
@@ -274,20 +274,6 @@
     }                                                                   \
 }
 
-int *ff_copy_int_list(const int * const list)
-{
-    int *ret = NULL;
-    COPY_INT_LIST(ret, list, int);
-    return ret;
-}
-
-int64_t *ff_copy_int64_list(const int64_t * const list)
-{
-    int64_t *ret = NULL;
-    COPY_INT_LIST(ret, list, int64_t);
-    return ret;
-}
-
 #define MAKE_FORMAT_LIST(type, field, count_field)                      \
     type *formats;                                                      \
     int count = 0;                                                      \
@@ -307,7 +293,7 @@
 
 AVFilterFormats *ff_make_format_list(const int *fmts)
 {
-    MAKE_FORMAT_LIST(AVFilterFormats, formats, format_count);
+    MAKE_FORMAT_LIST(AVFilterFormats, formats, nb_formats);
     while (count--)
         formats->formats[count] = fmts[count];
 
@@ -343,7 +329,7 @@
 
 int ff_add_format(AVFilterFormats **avff, int64_t fmt)
 {
-    ADD_FORMAT(avff, fmt, int, formats, format_count);
+    ADD_FORMAT(avff, fmt, int, formats, nb_formats);
     return 0;
 }
 
@@ -364,7 +350,7 @@
     for (fmt = 0; fmt < num_formats; fmt++) {
         const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
         if ((type != AVMEDIA_TYPE_VIDEO) ||
-            (type == AVMEDIA_TYPE_VIDEO && !(desc->flags & PIX_FMT_HWACCEL)))
+            (type == AVMEDIA_TYPE_VIDEO && !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)))
             ff_add_format(&ret, fmt);
     }
 
diff --git a/libavfilter/formats.h b/libavfilter/formats.h
index c06f6df..468eac8 100644
--- a/libavfilter/formats.h
+++ b/libavfilter/formats.h
@@ -62,7 +62,7 @@
  * pointer to each of the pointers to itself.
  */
 struct AVFilterFormats {
-    unsigned format_count;      ///< number of formats
+    unsigned nb_formats;        ///< number of formats
     int *formats;               ///< list of media formats
 
     unsigned refcount;          ///< number of references to this list
diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c
index 3718d09..e14c4ec 100644
--- a/libavfilter/graphparser.c
+++ b/libavfilter/graphparser.c
@@ -96,7 +96,7 @@
 {
     AVFilter *filt;
     char inst_name[30];
-    char tmp_args[256];
+    char *tmp_args = NULL;
     int ret;
 
     snprintf(inst_name, sizeof(inst_name), "Parsed_%s_%d", filt_name, index);
@@ -118,19 +118,24 @@
 
     if (!strcmp(filt_name, "scale") && args && !strstr(args, "flags") &&
         ctx->scale_sws_opts) {
-        snprintf(tmp_args, sizeof(tmp_args), "%s:%s",
+        tmp_args = av_asprintf("%s:%s",
                  args, ctx->scale_sws_opts);
+        if (!tmp_args)
+            return AVERROR(ENOMEM);
         args = tmp_args;
     }
 
     ret = avfilter_init_str(*filt_ctx, args);
     if (ret < 0) {
         av_log(log_ctx, AV_LOG_ERROR,
-               "Error initializing filter '%s' with args '%s'\n", filt_name, args);
-        return ret;
+               "Error initializing filter '%s'", filt_name);
+        if (args)
+            av_log(log_ctx, AV_LOG_ERROR, " with args '%s'", args);
+        av_log(log_ctx, AV_LOG_ERROR, "\n");
     }
 
-    return 0;
+    av_free(tmp_args);
+    return ret;
 }
 
 /**
@@ -444,14 +449,12 @@
     return ret;
 }
 
+#if HAVE_INCOMPATIBLE_LIBAV_ABI || !FF_API_OLD_GRAPH_PARSE
 int avfilter_graph_parse(AVFilterGraph *graph, const char *filters,
-                         AVFilterInOut **open_inputs_ptr, AVFilterInOut **open_outputs_ptr,
-                         void *log_ctx)
+                         AVFilterInOut *open_inputs,
+                         AVFilterInOut *open_outputs, void *log_ctx)
 {
-#if 0
     int ret;
-    AVFilterInOut *open_inputs  = open_inputs_ptr  ? *open_inputs_ptr  : NULL;
-    AVFilterInOut *open_outputs = open_outputs_ptr ? *open_outputs_ptr : NULL;
     AVFilterInOut *cur, *match, *inputs = NULL, *outputs = NULL;
 
     if ((ret = avfilter_graph_parse2(graph, filters, &inputs, &outputs)) < 0)
@@ -505,14 +508,22 @@
     }
     avfilter_inout_free(&inputs);
     avfilter_inout_free(&outputs);
-    /* clear open_in/outputs only if not passed as parameters */
-    if (open_inputs_ptr) *open_inputs_ptr = open_inputs;
-    else avfilter_inout_free(&open_inputs);
-    if (open_outputs_ptr) *open_outputs_ptr = open_outputs;
-    else avfilter_inout_free(&open_outputs);
+    avfilter_inout_free(&open_inputs);
+    avfilter_inout_free(&open_outputs);
     return ret;
-}
 #else
+int avfilter_graph_parse(AVFilterGraph *graph, const char *filters,
+                         AVFilterInOut **inputs, AVFilterInOut **outputs,
+                         void *log_ctx)
+{
+    return avfilter_graph_parse_ptr(graph, filters, inputs, outputs, log_ctx);
+#endif
+}
+
+int avfilter_graph_parse_ptr(AVFilterGraph *graph, const char *filters,
+                         AVFilterInOut **open_inputs_ptr, AVFilterInOut **open_outputs_ptr,
+                         void *log_ctx)
+{
     int index = 0, ret = 0;
     char chr = 0;
 
@@ -592,5 +603,3 @@
     }
     return ret;
 }
-
-#endif
diff --git a/libavfilter/internal.h b/libavfilter/internal.h
index fbe9356..eede4f7 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -24,9 +24,12 @@
  * internal API functions
  */
 
+#include "libavutil/internal.h"
 #include "avfilter.h"
 #include "avfiltergraph.h"
 #include "formats.h"
+#include "thread.h"
+#include "version.h"
 #include "video.h"
 
 #define POOL_SIZE 32
@@ -141,24 +144,25 @@
 };
 #endif
 
+struct AVFilterGraphInternal {
+    void *thread;
+    int (*thread_execute)(AVFilterContext *ctx, action_func *func, void *arg,
+                          int *ret, int nb_jobs);
+};
+
+struct AVFilterInternal {
+    int (*execute)(AVFilterContext *ctx, action_func *func, void *arg,
+                   int *ret, int nb_jobs);
+};
+
+#if FF_API_AVFILTERBUFFER
 /** default handler for freeing audio/video buffer when there are no references left */
 void ff_avfilter_default_free_buffer(AVFilterBuffer *buf);
+#endif
 
 /** Tell is a format is contained in the provided list terminated by -1. */
 int ff_fmt_is_in(int fmt, const int *fmts);
 
-/**
- * Return a copy of a list of integers terminated by -1, or NULL in
- * case of copy failure.
- */
-int *ff_copy_int_list(const int * const list);
-
-/**
- * Return a copy of a list of 64-bit integers, or NULL in case of
- * copy failure.
- */
-int64_t *ff_copy_int64_list(const int64_t * const list);
-
 /* Functions to parse audio format arguments */
 
 /**
@@ -257,7 +261,9 @@
     ff_insert_pad(index, &f->nb_inputs, offsetof(AVFilterLink, dstpad),
                   &f->input_pads, &f->inputs, p);
 #if FF_API_FOO_COUNT
+FF_DISABLE_DEPRECATION_WARNINGS
     f->input_count = f->nb_inputs;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 }
 
@@ -268,7 +274,9 @@
     ff_insert_pad(index, &f->nb_outputs, offsetof(AVFilterLink, srcpad),
                   &f->output_pads, &f->outputs, p);
 #if FF_API_FOO_COUNT
+FF_DISABLE_DEPRECATION_WARNINGS
     f->output_count = f->nb_outputs;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 }
 
diff --git a/libavfilter/libmpcodecs/vf_mcdeint.c b/libavfilter/libmpcodecs/vf_mcdeint.c
deleted file mode 100644
index b9ffaf2..0000000
--- a/libavfilter/libmpcodecs/vf_mcdeint.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-
-/*
-Known Issues:
-* The motion estimation is somewhat at the mercy of the input, if the input
-  frames are created purely based on spatial interpolation then for example
-  a thin black line or another random and not interpolateable pattern
-  will cause problems
-  Note: completly ignoring the "unavailable" lines during motion estimation
-  didnt look any better, so the most obvious solution would be to improve
-  tfields or penalize problematic motion vectors ...
-
-* If non iterative ME is used then snow currently ignores the OBMC window
-  and as a result sometimes creates artifacts
-
-* only past frames are used, we should ideally use future frames too, something
-  like filtering the whole movie in forward and then backward direction seems
-  like a interresting idea but the current filter framework is FAR from
-  supporting such things
-
-* combining the motion compensated image with the input image also isnt
-  as trivial as it seems, simple blindly taking even lines from one and
-  odd ones from the other doesnt work at all as ME/MC sometimes simple
-  has nothing in the previous frames which matches the current, the current
-  algo has been found by trial and error and almost certainly can be
-  improved ...
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-#include <math.h>
-
-#include "mp_msg.h"
-#include "cpudetect.h"
-
-#include "libavutil/common.h"
-#include "libavutil/internal.h"
-#include "libavutil/intreadwrite.h"
-#include "libavcodec/avcodec.h"
-#include "libavcodec/dsputil.h"
-
-#undef fprintf
-#undef free
-#undef malloc
-
-#include "img_format.h"
-#include "mp_image.h"
-#include "vf.h"
-#include "av_helpers.h"
-
-#define MIN(a,b) ((a) > (b) ? (b) : (a))
-#define MAX(a,b) ((a) < (b) ? (b) : (a))
-#define ABS(a) ((a) > 0 ? (a) : (-(a)))
-
-//===========================================================================//
-
-struct vf_priv_s {
-    int mode;
-    int qp;
-    int parity;
-#if 0
-    int temp_stride[3];
-    uint8_t *src[3];
-    int16_t *temp[3];
-#endif
-    int outbuf_size;
-    uint8_t *outbuf;
-    AVCodecContext *avctx_enc;
-    AVFrame *frame;
-    AVFrame *frame_dec;
-};
-
-static void filter(struct vf_priv_s *p, uint8_t *dst[3], uint8_t *src[3], int dst_stride[3], int src_stride[3], int width, int height){
-    int x, y, i;
-
-    for(i=0; i<3; i++){
-        p->frame->data[i]= src[i];
-        p->frame->linesize[i]= src_stride[i];
-    }
-
-    p->avctx_enc->me_cmp=
-    p->avctx_enc->me_sub_cmp= FF_CMP_SAD /*| (p->parity ? FF_CMP_ODD : FF_CMP_EVEN)*/;
-    p->frame->quality= p->qp*FF_QP2LAMBDA;
-    avcodec_encode_video(p->avctx_enc, p->outbuf, p->outbuf_size, p->frame);
-    p->frame_dec = p->avctx_enc->coded_frame;
-
-    for(i=0; i<3; i++){
-        int is_chroma= !!i;
-        int w= width >>is_chroma;
-        int h= height>>is_chroma;
-        int fils= p->frame_dec->linesize[i];
-        int srcs= src_stride[i];
-
-        for(y=0; y<h; y++){
-            if((y ^ p->parity) & 1){
-                for(x=0; x<w; x++){
-                    if((x-2)+(y-1)*w>=0 && (x+2)+(y+1)*w<w*h){ //FIXME either alloc larger images or optimize this
-                        uint8_t *filp= &p->frame_dec->data[i][x + y*fils];
-                        uint8_t *srcp= &src[i][x + y*srcs];
-                        int diff0= filp[-fils] - srcp[-srcs];
-                        int diff1= filp[+fils] - srcp[+srcs];
-                        int spatial_score= ABS(srcp[-srcs-1] - srcp[+srcs-1])
-                                          +ABS(srcp[-srcs  ] - srcp[+srcs  ])
-                                          +ABS(srcp[-srcs+1] - srcp[+srcs+1]) - 1;
-                        int temp= filp[0];
-
-#define CHECK(j)\
-    {   int score= ABS(srcp[-srcs-1+(j)] - srcp[+srcs-1-(j)])\
-                 + ABS(srcp[-srcs  +(j)] - srcp[+srcs  -(j)])\
-                 + ABS(srcp[-srcs+1+(j)] - srcp[+srcs+1-(j)]);\
-        if(score < spatial_score){\
-            spatial_score= score;\
-            diff0= filp[-fils+(j)] - srcp[-srcs+(j)];\
-            diff1= filp[+fils-(j)] - srcp[+srcs-(j)];
-
-                        CHECK(-1) CHECK(-2) }} }}
-                        CHECK( 1) CHECK( 2) }} }}
-#if 0
-                        if((diff0 ^ diff1) > 0){
-                            int mindiff= ABS(diff0) > ABS(diff1) ? diff1 : diff0;
-                            temp-= mindiff;
-                        }
-#elif 1
-                        if(diff0 + diff1 > 0)
-                            temp-= (diff0 + diff1 - ABS( ABS(diff0) - ABS(diff1) )/2)/2;
-                        else
-                            temp-= (diff0 + diff1 + ABS( ABS(diff0) - ABS(diff1) )/2)/2;
-#else
-                        temp-= (diff0 + diff1)/2;
-#endif
-#if 1
-                        filp[0]=
-                        dst[i][x + y*dst_stride[i]]= temp > 255U ? ~(temp>>31) : temp;
-#else
-                        dst[i][x + y*dst_stride[i]]= filp[0];
-                        filp[0]= temp > 255U ? ~(temp>>31) : temp;
-#endif
-                    }else
-                        dst[i][x + y*dst_stride[i]]= p->frame_dec->data[i][x + y*fils];
-                }
-            }
-        }
-        for(y=0; y<h; y++){
-            if(!((y ^ p->parity) & 1)){
-                for(x=0; x<w; x++){
-#if 1
-                    p->frame_dec->data[i][x + y*fils]=
-                    dst[i][x + y*dst_stride[i]]= src[i][x + y*srcs];
-#else
-                    dst[i][x + y*dst_stride[i]]= p->frame_dec->data[i][x + y*fils];
-                    p->frame_dec->data[i][x + y*fils]= src[i][x + y*srcs];
-#endif
-                }
-            }
-        }
-    }
-    p->parity ^= 1;
-
-}
-
-static int config(struct vf_instance *vf,
-        int width, int height, int d_width, int d_height,
-        unsigned int flags, unsigned int outfmt){
-        int i;
-        AVCodec *enc= avcodec_find_encoder(AV_CODEC_ID_SNOW);
-
-        for(i=0; i<3; i++){
-            AVCodecContext *avctx_enc;
-            AVDictionary *opts = NULL;
-#if 0
-            int is_chroma= !!i;
-            int w= ((width  + 31) & (~31))>>is_chroma;
-            int h= ((height + 31) & (~31))>>is_chroma;
-
-            vf->priv->temp_stride[i]= w;
-            vf->priv->temp[i]= malloc(vf->priv->temp_stride[i]*h*sizeof(int16_t));
-            vf->priv->src [i]= malloc(vf->priv->temp_stride[i]*h*sizeof(uint8_t));
-#endif
-            avctx_enc=
-            vf->priv->avctx_enc= avcodec_alloc_context3(enc);
-            avctx_enc->width = width;
-            avctx_enc->height = height;
-            avctx_enc->time_base= (AVRational){1,25};  // meaningless
-            avctx_enc->gop_size = 300;
-            avctx_enc->max_b_frames= 0;
-            avctx_enc->pix_fmt = AV_PIX_FMT_YUV420P;
-            avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
-            avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
-            avctx_enc->global_quality= 1;
-            av_dict_set(&opts, "memc_only", "1", 0);
-            avctx_enc->me_cmp=
-            avctx_enc->me_sub_cmp= FF_CMP_SAD; //SSE;
-            avctx_enc->mb_cmp= FF_CMP_SSE;
-
-            switch(vf->priv->mode){
-            case 3:
-                avctx_enc->refs= 3;
-            case 2:
-                avctx_enc->me_method= ME_ITER;
-            case 1:
-                avctx_enc->flags |= CODEC_FLAG_4MV;
-                avctx_enc->dia_size=2;
-//                avctx_enc->mb_decision = MB_DECISION_RD;
-            case 0:
-                avctx_enc->flags |= CODEC_FLAG_QPEL;
-            }
-
-            avcodec_open2(avctx_enc, enc, &opts);
-            av_dict_free(&opts);
-
-        }
-        vf->priv->frame= avcodec_alloc_frame();
-
-        vf->priv->outbuf_size= width*height*10;
-        vf->priv->outbuf= malloc(vf->priv->outbuf_size);
-
-        return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
-}
-
-static void get_image(struct vf_instance *vf, mp_image_t *mpi){
-    if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change
-return; //caused problems, dunno why
-    // ok, we can do pp in-place (or pp disabled):
-    vf->dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
-        mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height);
-    mpi->planes[0]=vf->dmpi->planes[0];
-    mpi->stride[0]=vf->dmpi->stride[0];
-    mpi->width=vf->dmpi->width;
-    if(mpi->flags&MP_IMGFLAG_PLANAR){
-        mpi->planes[1]=vf->dmpi->planes[1];
-        mpi->planes[2]=vf->dmpi->planes[2];
-        mpi->stride[1]=vf->dmpi->stride[1];
-        mpi->stride[2]=vf->dmpi->stride[2];
-    }
-    mpi->flags|=MP_IMGFLAG_DIRECT;
-}
-
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
-    mp_image_t *dmpi;
-
-    if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
-        // no DR, so get a new image! hope we'll get DR buffer:
-        dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
-            MP_IMGTYPE_TEMP,
-            MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
-            mpi->width,mpi->height);
-        ff_vf_clone_mpi_attributes(dmpi, mpi);
-    }else{
-        dmpi=vf->dmpi;
-    }
-
-    filter(vf->priv, dmpi->planes, mpi->planes, dmpi->stride, mpi->stride, mpi->w, mpi->h);
-
-    return ff_vf_next_put_image(vf,dmpi, pts);
-}
-
-static void uninit(struct vf_instance *vf){
-    if(!vf->priv) return;
-
-#if 0
-    for(i=0; i<3; i++){
-        free(vf->priv->temp[i]);
-        vf->priv->temp[i]= NULL;
-        free(vf->priv->src[i]);
-        vf->priv->src[i]= NULL;
-    }
-#endif
-    if (vf->priv->avctx_enc) {
-    avcodec_close(vf->priv->avctx_enc);
-    av_freep(&vf->priv->avctx_enc);
-    }
-
-    free(vf->priv->outbuf);
-    free(vf->priv);
-    vf->priv=NULL;
-}
-
-//===========================================================================//
-static int query_format(struct vf_instance *vf, unsigned int fmt){
-    switch(fmt){
-        case IMGFMT_YV12:
-        case IMGFMT_I420:
-        case IMGFMT_IYUV:
-        case IMGFMT_Y800:
-        case IMGFMT_Y8:
-            return ff_vf_next_query_format(vf,fmt);
-    }
-    return 0;
-}
-
-static int vf_open(vf_instance_t *vf, char *args){
-
-    vf->config=config;
-    vf->put_image=put_image;
-    vf->get_image=get_image;
-    vf->query_format=query_format;
-    vf->uninit=uninit;
-    vf->priv=malloc(sizeof(struct vf_priv_s));
-    memset(vf->priv, 0, sizeof(struct vf_priv_s));
-
-    ff_init_avcodec();
-
-    vf->priv->mode=0;
-    vf->priv->parity= -1;
-    vf->priv->qp=1;
-
-    if (args) sscanf(args, "%d:%d:%d", &vf->priv->mode, &vf->priv->parity, &vf->priv->qp);
-
-    return 1;
-}
-
-const vf_info_t ff_vf_info_mcdeint = {
-    "motion compensating deinterlacer",
-    "mcdeint",
-    "Michael Niedermayer",
-    "",
-    vf_open,
-    NULL
-};
diff --git a/libavfilter/libmpcodecs/vf_ow.c b/libavfilter/libmpcodecs/vf_ow.c
deleted file mode 100644
index 69b07ef..0000000
--- a/libavfilter/libmpcodecs/vf_ow.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Copyright (C) 2007 Michael Niedermayer <michaelni@gmx.at>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-/**
- * @todo try to change to int
- * @todo try lifting based implementation
- * @todo optimize optimize optimize
- * @todo hard tresholding
- * @todo use QP to decide filter strength
- * @todo wavelet normalization / least squares optimal signal vs. noise thresholds
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <math.h>
-
-#include "mp_msg.h"
-#include "img_format.h"
-#include "mp_image.h"
-#include "vf.h"
-
-//===========================================================================//
-static const uint8_t  __attribute__((aligned(8))) dither[8][8]={
-{  0,  48,  12,  60,   3,  51,  15,  63, },
-{ 32,  16,  44,  28,  35,  19,  47,  31, },
-{  8,  56,   4,  52,  11,  59,   7,  55, },
-{ 40,  24,  36,  20,  43,  27,  39,  23, },
-{  2,  50,  14,  62,   1,  49,  13,  61, },
-{ 34,  18,  46,  30,  33,  17,  45,  29, },
-{ 10,  58,   6,  54,   9,  57,   5,  53, },
-{ 42,  26,  38,  22,  41,  25,  37,  21, },
-};
-//FIXME the above is duplicated in many filters
-
-struct vf_priv_s {
-    float strength[2];
-    float delta;
-    int mode;
-    int depth;
-    float *plane[16][4];
-    int stride;
-};
-
-#define S 1.41421356237 //sqrt(2)
-
-static const double coeff[2][5]={
-    {
-         0.6029490182363579  *S,
-         0.2668641184428723  *S,
-        -0.07822326652898785 *S,
-        -0.01686411844287495 *S,
-         0.02674875741080976 *S
-    },{
-         1.115087052456994   /S,
-        -0.5912717631142470  /S,
-        -0.05754352622849957 /S,
-         0.09127176311424948 /S
-    }
-};
-
-static const double icoeff[2][5]={
-    {
-         1.115087052456994   /S,
-         0.5912717631142470  /S,
-        -0.05754352622849957 /S,
-        -0.09127176311424948 /S
-    },{
-         0.6029490182363579  *S,
-        -0.2668641184428723  *S,
-        -0.07822326652898785 *S,
-         0.01686411844287495 *S,
-         0.02674875741080976 *S
-    }
-};
-#undef S
-
-static inline int mirror(int x, int w){
-    while((unsigned)x > (unsigned)w){
-        x=-x;
-        if(x<0) x+= 2*w;
-    }
-    return x;
-}
-
-static inline void decompose(float *dstL, float *dstH, float *src, int stride, int w){
-    int x, i;
-    for(x=0; x<w; x++){
-        double sumL= src[x*stride] * coeff[0][0];
-        double sumH= src[x*stride] * coeff[1][0];
-        for(i=1; i<=4; i++){
-            double s= (src[mirror(x-i, w-1)*stride] + src[mirror(x+i, w-1)*stride]);
-
-            sumL+= coeff[0][i]*s;
-            sumH+= coeff[1][i]*s;
-        }
-        dstL[x*stride]= sumL;
-        dstH[x*stride]= sumH;
-    }
-}
-
-static inline void compose(float *dst, float *srcL, float *srcH, int stride, int w){
-    int x, i;
-    for(x=0; x<w; x++){
-        double sumL= srcL[x*stride] * icoeff[0][0];
-        double sumH= srcH[x*stride] * icoeff[1][0];
-        for(i=1; i<=4; i++){
-            int x0= mirror(x-i, w-1)*stride;
-            int x1= mirror(x+i, w-1)*stride;
-
-            sumL+= icoeff[0][i]*(srcL[x0] + srcL[x1]);
-            sumH+= icoeff[1][i]*(srcH[x0] + srcH[x1]);
-        }
-        dst[x*stride]= (sumL + sumH)*0.5;
-    }
-}
-
-static inline void decompose2D(float *dstL, float *dstH, float *src, int xstride, int ystride, int step, int w, int h){
-    int y, x;
-    for(y=0; y<h; y++)
-        for(x=0; x<step; x++)
-            decompose(dstL + ystride*y + xstride*x, dstH + ystride*y + xstride*x, src + ystride*y + xstride*x, step*xstride, (w-x+step-1)/step);
-}
-
-static inline void compose2D(float *dst, float *srcL, float *srcH, int xstride, int ystride, int step, int w, int h){
-    int y, x;
-    for(y=0; y<h; y++)
-        for(x=0; x<step; x++)
-            compose(dst + ystride*y + xstride*x, srcL + ystride*y + xstride*x, srcH + ystride*y + xstride*x, step*xstride, (w-x+step-1)/step);
-}
-
-static void decompose2D2(float *dst[4], float *src, float *temp[2], int stride, int step, int w, int h){
-    decompose2D(temp[0], temp[1], src    , 1, stride, step  , w, h);
-    decompose2D( dst[0],  dst[1], temp[0], stride, 1, step  , h, w);
-    decompose2D( dst[2],  dst[3], temp[1], stride, 1, step  , h, w);
-}
-
-static void compose2D2(float *dst, float *src[4], float *temp[2], int stride, int step, int w, int h){
-    compose2D(temp[0],  src[0],  src[1], stride, 1, step  , h, w);
-    compose2D(temp[1],  src[2],  src[3], stride, 1, step  , h, w);
-    compose2D(dst    , temp[0], temp[1], 1, stride, step  , w, h);
-}
-
-static void filter(struct vf_priv_s *p, uint8_t *dst, uint8_t *src, int dst_stride, int src_stride, int width, int height, int is_luma){
-    int x,y, i, j;
-//    double sum=0;
-    double s= p->strength[!is_luma];
-    int depth= p->depth;
-
-    while(1<<depth > width || 1<<depth > height)
-        depth--;
-
-    for(y=0; y<height; y++)
-        for(x=0; x<width; x++)
-            p->plane[0][0][x + y*p->stride]= src[x + y*src_stride];
-
-    for(i=0; i<depth; i++){
-        decompose2D2(p->plane[i+1], p->plane[i][0], p->plane[0]+1,p->stride, 1<<i, width, height);
-    }
-    for(i=0; i<depth; i++){
-        for(j=1; j<4; j++){
-            for(y=0; y<height; y++){
-                for(x=0; x<width; x++){
-                    double v= p->plane[i+1][j][x + y*p->stride];
-                    if     (v> s) v-=s;
-                    else if(v<-s) v+=s;
-                    else          v =0;
-                    p->plane[i+1][j][x + y*p->stride]= v;
-                }
-            }
-        }
-    }
-    for(i=depth-1; i>=0; i--){
-        compose2D2(p->plane[i][0], p->plane[i+1], p->plane[0]+1, p->stride, 1<<i, width, height);
-    }
-
-    for(y=0; y<height; y++)
-        for(x=0; x<width; x++){
-            i= p->plane[0][0][x + y*p->stride] + dither[x&7][y&7]*(1.0/64) + 1.0/128; //yes the rounding is insane but optimal :)
-//            double e= i - src[x + y*src_stride];
-//            sum += e*e;
-            if((unsigned)i > 255U) i= ~(i>>31);
-            dst[x + y*dst_stride]= i;
-        }
-
-//    printf("%f\n", sum/height/width);
-}
-
-static int config(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){
-    int h= (height+15)&(~15);
-    int i,j;
-
-    vf->priv->stride= (width+15)&(~15);
-    for(j=0; j<4; j++){
-        for(i=0; i<=vf->priv->depth; i++)
-            vf->priv->plane[i][j]= malloc(vf->priv->stride*h*sizeof(vf->priv->plane[0][0][0]));
-    }
-
-    return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
-}
-
-static void get_image(struct vf_instance *vf, mp_image_t *mpi){
-    if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change
-    // ok, we can do pp in-place (or pp disabled):
-    vf->dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
-        mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height);
-    mpi->planes[0]=vf->dmpi->planes[0];
-    mpi->stride[0]=vf->dmpi->stride[0];
-    mpi->width=vf->dmpi->width;
-    if(mpi->flags&MP_IMGFLAG_PLANAR){
-        mpi->planes[1]=vf->dmpi->planes[1];
-        mpi->planes[2]=vf->dmpi->planes[2];
-        mpi->stride[1]=vf->dmpi->stride[1];
-        mpi->stride[2]=vf->dmpi->stride[2];
-    }
-    mpi->flags|=MP_IMGFLAG_DIRECT;
-}
-
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
-    mp_image_t *dmpi;
-
-    if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
-        // no DR, so get a new image! hope we'll get DR buffer:
-        dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
-            MP_IMGTYPE_TEMP,
-            MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
-            mpi->width,mpi->height);
-        ff_vf_clone_mpi_attributes(dmpi, mpi);
-    }else{
-        dmpi=vf->dmpi;
-    }
-
-    filter(vf->priv, dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h, 1);
-    filter(vf->priv, dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, 0);
-    filter(vf->priv, dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, 0);
-
-    return ff_vf_next_put_image(vf,dmpi, pts);
-}
-
-static void uninit(struct vf_instance *vf){
-    int i,j;
-    if(!vf->priv) return;
-
-    for(j=0; j<4; j++){
-        for(i=0; i<16; i++){
-            free(vf->priv->plane[i][j]);
-            vf->priv->plane[i][j]= NULL;
-        }
-    }
-
-    free(vf->priv);
-    vf->priv=NULL;
-}
-
-//===========================================================================//
-static int query_format(struct vf_instance *vf, unsigned int fmt){
-    switch(fmt){
-        case IMGFMT_YVU9:
-        case IMGFMT_IF09:
-        case IMGFMT_YV12:
-        case IMGFMT_I420:
-        case IMGFMT_IYUV:
-        case IMGFMT_CLPL:
-        case IMGFMT_Y800:
-        case IMGFMT_Y8:
-        case IMGFMT_444P:
-        case IMGFMT_422P:
-        case IMGFMT_411P:
-            return ff_vf_next_query_format(vf,fmt);
-    }
-    return 0;
-}
-
-
-static int vf_open(vf_instance_t *vf, char *args){
-    vf->config=config;
-    vf->put_image=put_image;
-    vf->get_image=get_image;
-    vf->query_format=query_format;
-    vf->uninit=uninit;
-    vf->priv=malloc(sizeof(struct vf_priv_s));
-    memset(vf->priv, 0, sizeof(struct vf_priv_s));
-
-    vf->priv->depth= 8;
-    vf->priv->strength[0]= 1.0;
-    vf->priv->strength[1]= 1.0;
-    vf->priv->delta= 1.0;
-
-    if (args) sscanf(args, "%d:%f:%f:%d:%f", &vf->priv->depth,
-                     &vf->priv->strength[0],
-                     &vf->priv->strength[1],
-                     &vf->priv->mode,
-                     &vf->priv->delta);
-
-    return 1;
-}
-
-const vf_info_t ff_vf_info_ow = {
-    "overcomplete wavelet denoiser",
-    "ow",
-    "Michael Niedermayer",
-    "",
-    vf_open,
-    NULL
-};
diff --git a/libavfilter/libmpcodecs/vf_perspective.c b/libavfilter/libmpcodecs/vf_perspective.c
deleted file mode 100644
index aed5c4d..0000000
--- a/libavfilter/libmpcodecs/vf_perspective.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (C) 2002 Michael Niedermayer <michaelni@gmx.at>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-#include <assert.h>
-#include <math.h>
-
-#include "config.h"
-#include "mp_msg.h"
-
-#if HAVE_MALLOC_H
-#include <malloc.h>
-#endif
-
-#include "libavutil/mem.h"
-
-#include "img_format.h"
-#include "mp_image.h"
-#include "vf.h"
-
-#define SUB_PIXEL_BITS 8
-#define SUB_PIXELS (1<<SUB_PIXEL_BITS)
-#define COEFF_BITS 11
-
-//===========================================================================//
-
-struct vf_priv_s {
-    double ref[4][2];
-    int32_t coeff[1<<SUB_PIXEL_BITS][4];
-    int32_t (*pv)[2];
-    int pvStride;
-    int cubic;
-};
-
-
-/***************************************************************************/
-
-static void initPv(struct vf_priv_s *priv, int W, int H){
-    double a,b,c,d,e,f,g,h,D;
-    double (*ref)[2]= priv->ref;
-    int x,y;
-
-    g= (  (ref[0][0] - ref[1][0] - ref[2][0] + ref[3][0])*(ref[2][1] - ref[3][1])
-        - (ref[0][1] - ref[1][1] - ref[2][1] + ref[3][1])*(ref[2][0] - ref[3][0]))*H;
-    h= (  (ref[0][1] - ref[1][1] - ref[2][1] + ref[3][1])*(ref[1][0] - ref[3][0])
-        - (ref[0][0] - ref[1][0] - ref[2][0] + ref[3][0])*(ref[1][1] - ref[3][1]))*W;
-    D=   (ref[1][0] - ref[3][0])*(ref[2][1] - ref[3][1])
-       - (ref[2][0] - ref[3][0])*(ref[1][1] - ref[3][1]);
-
-    a= D*(ref[1][0] - ref[0][0])*H + g*ref[1][0];
-    b= D*(ref[2][0] - ref[0][0])*W + h*ref[2][0];
-    c= D*ref[0][0]*W*H;
-    d= D*(ref[1][1] - ref[0][1])*H + g*ref[1][1];
-    e= D*(ref[2][1] - ref[0][1])*W + h*ref[2][1];
-    f= D*ref[0][1]*W*H;
-
-    for(y=0; y<H; y++){
-        for(x=0; x<W; x++){
-            int u, v;
-
-            u= (int)floor( SUB_PIXELS*(a*x + b*y + c)/(g*x + h*y + D*W*H) + 0.5);
-            v= (int)floor( SUB_PIXELS*(d*x + e*y + f)/(g*x + h*y + D*W*H) + 0.5);
-
-            priv->pv[x + y*W][0]= u;
-            priv->pv[x + y*W][1]= v;
-        }
-    }
-}
-
-static double getCoeff(double d){
-    double A= -0.60;
-    double coeff;
-
-    d= fabs(d);
-
-    // Equation is from VirtualDub
-    if(d<1.0)
-        coeff = (1.0 - (A+3.0)*d*d + (A+2.0)*d*d*d);
-    else if(d<2.0)
-        coeff = (-4.0*A + 8.0*A*d - 5.0*A*d*d + A*d*d*d);
-    else
-        coeff=0.0;
-
-    return coeff;
-}
-
-static int config(struct vf_instance *vf,
-    int width, int height, int d_width, int d_height,
-    unsigned int flags, unsigned int outfmt){
-    int i, j;
-
-    vf->priv->pvStride= width;
-    vf->priv->pv= av_malloc(width*height*2*sizeof(int32_t));
-    initPv(vf->priv, width, height);
-
-    for(i=0; i<SUB_PIXELS; i++){
-        double d= i/(double)SUB_PIXELS;
-        double temp[4];
-        double sum=0;
-
-        for(j=0; j<4; j++)
-            temp[j]= getCoeff(j - d - 1);
-
-        for(j=0; j<4; j++)
-            sum+= temp[j];
-
-        for(j=0; j<4; j++)
-            vf->priv->coeff[i][j]= (int)floor((1<<COEFF_BITS)*temp[j]/sum + 0.5);
-    }
-
-    return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
-}
-
-static void uninit(struct vf_instance *vf){
-    if(!vf->priv) return;
-
-    av_free(vf->priv->pv);
-    vf->priv->pv= NULL;
-
-    free(vf->priv);
-    vf->priv=NULL;
-}
-
-static inline void resampleCubic(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, int srcStride, struct vf_priv_s *privParam, int xShift, int yShift){
-    int x, y;
-    struct vf_priv_s priv= *privParam;
-
-    for(y=0; y<h; y++){
-        for(x=0; x<w; x++){
-            int u, v, subU, subV, sum, sx, sy;
-
-            sx= x << xShift;
-            sy= y << yShift;
-            u= priv.pv[sx + sy*priv.pvStride][0]>>xShift;
-            v= priv.pv[sx + sy*priv.pvStride][1]>>yShift;
-            subU= u & (SUB_PIXELS-1);
-            subV= v & (SUB_PIXELS-1);
-            u >>= SUB_PIXEL_BITS;
-            v >>= SUB_PIXEL_BITS;
-
-            if(u>0 && v>0 && u<w-2 && v<h-2){
-                const int index= u + v*srcStride;
-                const int a= priv.coeff[subU][0];
-                const int b= priv.coeff[subU][1];
-                const int c= priv.coeff[subU][2];
-                const int d= priv.coeff[subU][3];
-
-                sum=
-                 priv.coeff[subV][0]*(  a*src[index - 1 - srcStride] + b*src[index - 0 - srcStride]
-                                      + c*src[index + 1 - srcStride] + d*src[index + 2 - srcStride])
-                +priv.coeff[subV][1]*(  a*src[index - 1            ] + b*src[index - 0            ]
-                                      + c*src[index + 1            ] + d*src[index + 2            ])
-                +priv.coeff[subV][2]*(  a*src[index - 1 + srcStride] + b*src[index - 0 + srcStride]
-                                      + c*src[index + 1 + srcStride] + d*src[index + 2 + srcStride])
-                +priv.coeff[subV][3]*(  a*src[index - 1+2*srcStride] + b*src[index - 0+2*srcStride]
-                                      + c*src[index + 1+2*srcStride] + d*src[index + 2+2*srcStride]);
-            }else{
-                int dx, dy;
-                sum=0;
-
-                for(dy=0; dy<4; dy++){
-                    int iy= v + dy - 1;
-                    if     (iy< 0) iy=0;
-                    else if(iy>=h) iy=h-1;
-                    for(dx=0; dx<4; dx++){
-                        int ix= u + dx - 1;
-                        if     (ix< 0) ix=0;
-                        else if(ix>=w) ix=w-1;
-
-                        sum+=  priv.coeff[subU][dx]*priv.coeff[subV][dy]
-                              *src[ ix + iy*srcStride];
-                    }
-                }
-            }
-            sum= (sum + (1<<(COEFF_BITS*2-1)) ) >> (COEFF_BITS*2);
-            if(sum&~255){
-                if(sum<0) sum=0;
-                else      sum=255;
-            }
-            dst[ x + y*dstStride]= sum;
-        }
-    }
-}
-
-static inline void resampleLinear(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, int srcStride,
-                  struct vf_priv_s *privParam, int xShift, int yShift){
-    int x, y;
-    struct vf_priv_s priv= *privParam;
-
-    for(y=0; y<h; y++){
-        for(x=0; x<w; x++){
-            int u, v, subU, subV, sum, sx, sy, index, subUI, subVI;
-
-            sx= x << xShift;
-            sy= y << yShift;
-            u= priv.pv[sx + sy*priv.pvStride][0]>>xShift;
-            v= priv.pv[sx + sy*priv.pvStride][1]>>yShift;
-            subU= u & (SUB_PIXELS-1);
-            subV= v & (SUB_PIXELS-1);
-            u >>= SUB_PIXEL_BITS;
-            v >>= SUB_PIXEL_BITS;
-            index= u + v*srcStride;
-            subUI= SUB_PIXELS - subU;
-            subVI= SUB_PIXELS - subV;
-
-            if((unsigned)u < (unsigned)(w - 1)){
-                if((unsigned)v < (unsigned)(h - 1)){
-                    sum= subVI*(subUI*src[index          ] + subU*src[index          +1])
-                        +subV *(subUI*src[index+srcStride] + subU*src[index+srcStride+1]);
-                    sum= (sum + (1<<(SUB_PIXEL_BITS*2-1)) ) >> (SUB_PIXEL_BITS*2);
-                }else{
-                    if(v<0) v= 0;
-                    else    v= h-1;
-                    index= u + v*srcStride;
-                    sum= subUI*src[index] + subU*src[index+1];
-                    sum= (sum + (1<<(SUB_PIXEL_BITS-1)) ) >> SUB_PIXEL_BITS;
-                }
-            }else{
-                if((unsigned)v < (unsigned)(h - 1)){
-                    if(u<0) u= 0;
-                    else    u= w-1;
-                    index= u + v*srcStride;
-                    sum= subVI*src[index] + subV*src[index+srcStride];
-                    sum= (sum + (1<<(SUB_PIXEL_BITS-1)) ) >> SUB_PIXEL_BITS;
-                }else{
-                    if(u<0) u= 0;
-                    else    u= w-1;
-                    if(v<0) v= 0;
-                    else    v= h-1;
-                    index= u + v*srcStride;
-                    sum= src[index];
-                }
-            }
-            if(sum&~255){
-                if(sum<0) sum=0;
-                else      sum=255;
-            }
-            dst[ x + y*dstStride]= sum;
-        }
-    }
-}
-
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
-    int cw= mpi->w >> mpi->chroma_x_shift;
-    int ch= mpi->h >> mpi->chroma_y_shift;
-
-    mp_image_t *dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
-        MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
-        mpi->w,mpi->h);
-
-    assert(mpi->flags&MP_IMGFLAG_PLANAR);
-
-    if(vf->priv->cubic){
-        resampleCubic(dmpi->planes[0], mpi->planes[0], mpi->w,mpi->h, dmpi->stride[0], mpi->stride[0],
-                vf->priv, 0, 0);
-        resampleCubic(dmpi->planes[1], mpi->planes[1], cw    , ch   , dmpi->stride[1], mpi->stride[1],
-                vf->priv, mpi->chroma_x_shift, mpi->chroma_y_shift);
-        resampleCubic(dmpi->planes[2], mpi->planes[2], cw    , ch   , dmpi->stride[2], mpi->stride[2],
-                vf->priv, mpi->chroma_x_shift, mpi->chroma_y_shift);
-    }else{
-        resampleLinear(dmpi->planes[0], mpi->planes[0], mpi->w,mpi->h, dmpi->stride[0], mpi->stride[0],
-                vf->priv, 0, 0);
-        resampleLinear(dmpi->planes[1], mpi->planes[1], cw    , ch   , dmpi->stride[1], mpi->stride[1],
-                vf->priv, mpi->chroma_x_shift, mpi->chroma_y_shift);
-        resampleLinear(dmpi->planes[2], mpi->planes[2], cw    , ch   , dmpi->stride[2], mpi->stride[2],
-                vf->priv, mpi->chroma_x_shift, mpi->chroma_y_shift);
-    }
-
-    return ff_vf_next_put_image(vf,dmpi, pts);
-}
-
-//===========================================================================//
-
-static int query_format(struct vf_instance *vf, unsigned int fmt){
-    switch(fmt)
-    {
-    case IMGFMT_YV12:
-    case IMGFMT_I420:
-    case IMGFMT_IYUV:
-    case IMGFMT_YVU9:
-    case IMGFMT_444P:
-    case IMGFMT_422P:
-    case IMGFMT_411P:
-        return ff_vf_next_query_format(vf, fmt);
-    }
-    return 0;
-}
-
-static int vf_open(vf_instance_t *vf, char *args){
-    int e;
-
-    vf->config=config;
-    vf->put_image=put_image;
-//  vf->get_image=get_image;
-    vf->query_format=query_format;
-    vf->uninit=uninit;
-    vf->priv=malloc(sizeof(struct vf_priv_s));
-    memset(vf->priv, 0, sizeof(struct vf_priv_s));
-
-    if(args==NULL) return 0;
-
-    e=sscanf(args, "%lf:%lf:%lf:%lf:%lf:%lf:%lf:%lf:%d",
-        &vf->priv->ref[0][0], &vf->priv->ref[0][1],
-        &vf->priv->ref[1][0], &vf->priv->ref[1][1],
-        &vf->priv->ref[2][0], &vf->priv->ref[2][1],
-        &vf->priv->ref[3][0], &vf->priv->ref[3][1],
-        &vf->priv->cubic
-        );
-
-    if(e!=9)
-        return 0;
-
-    return 1;
-}
-
-const vf_info_t ff_vf_info_perspective = {
-    "perspective correcture",
-    "perspective",
-    "Michael Niedermayer",
-    "",
-    vf_open,
-    NULL
-};
-
-//===========================================================================//
diff --git a/libavfilter/libmpcodecs/vf_sab.c b/libavfilter/libmpcodecs/vf_sab.c
deleted file mode 100644
index 2928a85..0000000
--- a/libavfilter/libmpcodecs/vf_sab.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright (C) 2002 Michael Niedermayer <michaelni@gmx.at>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-#include <assert.h>
-
-#include "config.h"
-#include "mp_msg.h"
-
-#if HAVE_MALLOC_H
-#include <malloc.h>
-#endif
-
-#include "libavutil/avutil.h"
-#include "libavutil/mem.h"
-#include "img_format.h"
-#include "mp_image.h"
-#include "vf.h"
-#include "libswscale/swscale.h"
-#include "vf_scale.h"
-
-
-//===========================================================================//
-
-typedef struct FilterParam{
-    float radius;
-    float preFilterRadius;
-    float strength;
-    float quality;
-    struct SwsContext *preFilterContext;
-    uint8_t *preFilterBuf;
-    int preFilterStride;
-    int distWidth;
-    int distStride;
-    int *distCoeff;
-    int colorDiffCoeff[512];
-}FilterParam;
-
-struct vf_priv_s {
-    FilterParam luma;
-    FilterParam chroma;
-};
-
-
-/***************************************************************************/
-
-//FIXME stupid code duplication
-static void getSubSampleFactors(int *h, int *v, int format){
-    switch(format){
-    default:
-        assert(0);
-    case IMGFMT_YV12:
-    case IMGFMT_I420:
-        *h=1;
-        *v=1;
-        break;
-    case IMGFMT_YVU9:
-        *h=2;
-        *v=2;
-        break;
-    case IMGFMT_444P:
-        *h=0;
-        *v=0;
-        break;
-    case IMGFMT_422P:
-        *h=1;
-        *v=0;
-        break;
-    case IMGFMT_411P:
-        *h=2;
-        *v=0;
-        break;
-    }
-}
-
-static int allocStuff(FilterParam *f, int width, int height){
-    int stride= (width+7)&~7;
-    SwsVector *vec;
-    SwsFilter swsF;
-    int i,x,y;
-    f->preFilterBuf= av_malloc(stride*height);
-    f->preFilterStride= stride;
-
-    vec = sws_getGaussianVec(f->preFilterRadius, f->quality);
-    swsF.lumH= swsF.lumV= vec;
-    swsF.chrH= swsF.chrV= NULL;
-    f->preFilterContext= sws_getContext(
-        width, height, AV_PIX_FMT_GRAY8, width, height, AV_PIX_FMT_GRAY8, SWS_POINT, &swsF, NULL, NULL);
-
-    sws_freeVec(vec);
-    vec = sws_getGaussianVec(f->strength, 5.0);
-    for(i=0; i<512; i++){
-        double d;
-        int index= i-256 + vec->length/2;
-
-        if(index<0 || index>=vec->length)     d= 0.0;
-        else                    d= vec->coeff[index];
-
-        f->colorDiffCoeff[i]= (int)(d/vec->coeff[vec->length/2]*(1<<12) + 0.5);
-    }
-    sws_freeVec(vec);
-    vec = sws_getGaussianVec(f->radius, f->quality);
-    f->distWidth= vec->length;
-    f->distStride= (vec->length+7)&~7;
-    f->distCoeff= av_malloc(f->distWidth*f->distStride*sizeof(int32_t));
-
-    for(y=0; y<vec->length; y++){
-        for(x=0; x<vec->length; x++){
-            double d= vec->coeff[x] * vec->coeff[y];
-
-            f->distCoeff[x + y*f->distStride]= (int)(d*(1<<10) + 0.5);
-//            if(y==vec->length/2)
-//                printf("%6d ", f->distCoeff[x + y*f->distStride]);
-        }
-    }
-    sws_freeVec(vec);
-
-    return 0;
-}
-
-static int config(struct vf_instance *vf,
-    int width, int height, int d_width, int d_height,
-    unsigned int flags, unsigned int outfmt){
-
-    int sw, sh;
-//__asm__ volatile("emms\n\t");
-    allocStuff(&vf->priv->luma, width, height);
-
-    getSubSampleFactors(&sw, &sh, outfmt);
-    allocStuff(&vf->priv->chroma, width>>sw, height>>sh);
-
-    return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
-}
-
-static void freeBuffers(FilterParam *f){
-    if(f->preFilterContext) sws_freeContext(f->preFilterContext);
-    f->preFilterContext=NULL;
-
-    av_free(f->preFilterBuf);
-    f->preFilterBuf=NULL;
-
-    av_free(f->distCoeff);
-    f->distCoeff=NULL;
-}
-
-static void uninit(struct vf_instance *vf){
-    if(!vf->priv) return;
-
-    freeBuffers(&vf->priv->luma);
-    freeBuffers(&vf->priv->chroma);
-
-    free(vf->priv);
-    vf->priv=NULL;
-}
-
-static inline void blur(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, int srcStride, FilterParam *fp){
-    int x, y;
-    FilterParam f= *fp;
-    const int radius= f.distWidth/2;
-    const uint8_t* const srcArray[MP_MAX_PLANES] = {src};
-    uint8_t *dstArray[MP_MAX_PLANES]= {f.preFilterBuf};
-    int srcStrideArray[MP_MAX_PLANES]= {srcStride};
-    int dstStrideArray[MP_MAX_PLANES]= {f.preFilterStride};
-
-//    f.preFilterContext->swScale(f.preFilterContext, srcArray, srcStrideArray, 0, h, dstArray, dstStrideArray);
-    sws_scale(f.preFilterContext, srcArray, srcStrideArray, 0, h, dstArray, dstStrideArray);
-
-    for(y=0; y<h; y++){
-        for(x=0; x<w; x++){
-            int sum=0;
-            int div=0;
-            int dy;
-            const int preVal= f.preFilterBuf[x + y*f.preFilterStride];
-#if 0
-            const int srcVal= src[x + y*srcStride];
-if((x/32)&1){
-    dst[x + y*dstStride]= srcVal;
-    if(y%32==0) dst[x + y*dstStride]= 0;
-    continue;
-}
-#endif
-            if(x >= radius && x < w - radius){
-                for(dy=0; dy<radius*2+1; dy++){
-                    int dx;
-                    int iy= y+dy - radius;
-                    if     (iy<0)  iy=  -iy;
-                    else if(iy>=h) iy= h+h-iy-1;
-
-                    for(dx=0; dx<radius*2+1; dx++){
-                        const int ix= x+dx - radius;
-                        int factor;
-
-                        factor= f.colorDiffCoeff[256+preVal - f.preFilterBuf[ix + iy*f.preFilterStride] ]
-                            *f.distCoeff[dx + dy*f.distStride];
-                        sum+= src[ix + iy*srcStride] *factor;
-                        div+= factor;
-                    }
-                }
-            }else{
-                for(dy=0; dy<radius*2+1; dy++){
-                    int dx;
-                    int iy= y+dy - radius;
-                    if     (iy<0)  iy=  -iy;
-                    else if(iy>=h) iy= h+h-iy-1;
-
-                    for(dx=0; dx<radius*2+1; dx++){
-                        int ix= x+dx - radius;
-                        int factor;
-                        if     (ix<0)  ix=  -ix;
-                        else if(ix>=w) ix= w+w-ix-1;
-
-                        factor= f.colorDiffCoeff[256+preVal - f.preFilterBuf[ix + iy*f.preFilterStride] ]
-                            *f.distCoeff[dx + dy*f.distStride];
-                        sum+= src[ix + iy*srcStride] *factor;
-                        div+= factor;
-                    }
-                }
-            }
-            dst[x + y*dstStride]= (sum + div/2)/div;
-        }
-    }
-}
-
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
-    int cw= mpi->w >> mpi->chroma_x_shift;
-    int ch= mpi->h >> mpi->chroma_y_shift;
-
-    mp_image_t *dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
-        MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
-        mpi->w,mpi->h);
-
-    assert(mpi->flags&MP_IMGFLAG_PLANAR);
-
-    blur(dmpi->planes[0], mpi->planes[0], mpi->w,mpi->h, dmpi->stride[0], mpi->stride[0], &vf->priv->luma);
-    blur(dmpi->planes[1], mpi->planes[1], cw    , ch   , dmpi->stride[1], mpi->stride[1], &vf->priv->chroma);
-    blur(dmpi->planes[2], mpi->planes[2], cw    , ch   , dmpi->stride[2], mpi->stride[2], &vf->priv->chroma);
-
-    return ff_vf_next_put_image(vf,dmpi, pts);
-}
-
-//===========================================================================//
-
-static int query_format(struct vf_instance *vf, unsigned int fmt){
-    switch(fmt)
-    {
-    case IMGFMT_YV12:
-    case IMGFMT_I420:
-    case IMGFMT_IYUV:
-    case IMGFMT_YVU9:
-    case IMGFMT_444P:
-    case IMGFMT_422P:
-    case IMGFMT_411P:
-        return ff_vf_next_query_format(vf, fmt);
-    }
-    return 0;
-}
-
-static int vf_open(vf_instance_t *vf, char *args){
-    int e;
-
-    vf->config=config;
-    vf->put_image=put_image;
-//    vf->get_image=get_image;
-    vf->query_format=query_format;
-    vf->uninit=uninit;
-    vf->priv=malloc(sizeof(struct vf_priv_s));
-    memset(vf->priv, 0, sizeof(struct vf_priv_s));
-
-    if(args==NULL) return 0;
-
-    e=sscanf(args, "%f:%f:%f:%f:%f:%f",
-        &vf->priv->luma.radius,
-        &vf->priv->luma.preFilterRadius,
-        &vf->priv->luma.strength,
-        &vf->priv->chroma.radius,
-        &vf->priv->chroma.preFilterRadius,
-        &vf->priv->chroma.strength
-        );
-
-    vf->priv->luma.quality = vf->priv->chroma.quality= 3.0;
-
-    if(e==3){
-        vf->priv->chroma.radius= vf->priv->luma.radius;
-        vf->priv->chroma.preFilterRadius = vf->priv->luma.preFilterRadius;
-        vf->priv->chroma.strength= vf->priv->luma.strength;
-    }else if(e!=6)
-        return 0;
-
-//    if(vf->priv->luma.radius < 0) return 0;
-//    if(vf->priv->chroma.radius < 0) return 0;
-
-    return 1;
-}
-
-const vf_info_t ff_vf_info_sab = {
-    "shape adaptive blur",
-    "sab",
-    "Michael Niedermayer",
-    "",
-    vf_open,
-    NULL
-};
-
-//===========================================================================//
diff --git a/libavfilter/libmpcodecs/vf_spp.c b/libavfilter/libmpcodecs/vf_spp.c
deleted file mode 100644
index 75ede23..0000000
--- a/libavfilter/libmpcodecs/vf_spp.c
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * Copyright (C) 2003 Michael Niedermayer <michaelni@gmx.at>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-/*
- * This implementation is based on an algorithm described in
- * "Aria Nosratinia Embedded Post-Processing for
- * Enhancement of Compressed Images (1999)"
- * (http://citeseer.nj.nec.com/nosratinia99embedded.html)
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-#include <math.h>
-
-#include "config.h"
-
-#include "mp_msg.h"
-#include "cpudetect.h"
-
-#include "libavutil/common.h"
-#include "libavutil/internal.h"
-#include "libavutil/intreadwrite.h"
-#include "libavcodec/avcodec.h"
-#include "libavcodec/dsputil.h"
-
-#undef fprintf
-#undef free
-#undef malloc
-
-#include "img_format.h"
-#include "mp_image.h"
-#include "vf.h"
-#include "av_helpers.h"
-#include "libvo/fastmemcpy.h"
-
-#define XMIN(a,b) ((a) < (b) ? (a) : (b))
-
-//===========================================================================//
-static const uint8_t  __attribute__((aligned(8))) dither[8][8]={
-{  0,  48,  12,  60,   3,  51,  15,  63, },
-{ 32,  16,  44,  28,  35,  19,  47,  31, },
-{  8,  56,   4,  52,  11,  59,   7,  55, },
-{ 40,  24,  36,  20,  43,  27,  39,  23, },
-{  2,  50,  14,  62,   1,  49,  13,  61, },
-{ 34,  18,  46,  30,  33,  17,  45,  29, },
-{ 10,  58,   6,  54,   9,  57,   5,  53, },
-{ 42,  26,  38,  22,  41,  25,  37,  21, },
-};
-
-static const uint8_t offset[127][2]= {
-{0,0},
-{0,0}, {4,4},
-{0,0}, {2,2}, {6,4}, {4,6},
-{0,0}, {5,1}, {2,2}, {7,3}, {4,4}, {1,5}, {6,6}, {3,7},
-
-{0,0}, {4,0}, {1,1}, {5,1}, {3,2}, {7,2}, {2,3}, {6,3},
-{0,4}, {4,4}, {1,5}, {5,5}, {3,6}, {7,6}, {2,7}, {6,7},
-
-{0,0}, {0,2}, {0,4}, {0,6}, {1,1}, {1,3}, {1,5}, {1,7},
-{2,0}, {2,2}, {2,4}, {2,6}, {3,1}, {3,3}, {3,5}, {3,7},
-{4,0}, {4,2}, {4,4}, {4,6}, {5,1}, {5,3}, {5,5}, {5,7},
-{6,0}, {6,2}, {6,4}, {6,6}, {7,1}, {7,3}, {7,5}, {7,7},
-
-{0,0}, {4,4}, {0,4}, {4,0}, {2,2}, {6,6}, {2,6}, {6,2},
-{0,2}, {4,6}, {0,6}, {4,2}, {2,0}, {6,4}, {2,4}, {6,0},
-{1,1}, {5,5}, {1,5}, {5,1}, {3,3}, {7,7}, {3,7}, {7,3},
-{1,3}, {5,7}, {1,7}, {5,3}, {3,1}, {7,5}, {3,5}, {7,1},
-{0,1}, {4,5}, {0,5}, {4,1}, {2,3}, {6,7}, {2,7}, {6,3},
-{0,3}, {4,7}, {0,7}, {4,3}, {2,1}, {6,5}, {2,5}, {6,1},
-{1,0}, {5,4}, {1,4}, {5,0}, {3,2}, {7,6}, {3,6}, {7,2},
-{1,2}, {5,6}, {1,6}, {5,2}, {3,0}, {7,4}, {3,4}, {7,0},
-};
-
-struct vf_priv_s {
-        int log2_count;
-        int qp;
-        int mode;
-        int mpeg2;
-        int temp_stride;
-        uint8_t *src;
-        int16_t *temp;
-        AVCodecContext *avctx;
-        DSPContext dsp;
-        char *non_b_qp;
-};
-
-#define SHIFT 22
-
-static void hardthresh_c(int16_t dst[64], int16_t src[64], int qp, uint8_t *permutation){
-        int i;
-        int bias= 0; //FIXME
-        unsigned int threshold1, threshold2;
-
-        threshold1= qp*((1<<4) - bias) - 1;
-        threshold2= (threshold1<<1);
-
-        memset(dst, 0, 64*sizeof(int16_t));
-        dst[0]= (src[0] + 4)>>3;
-
-        for(i=1; i<64; i++){
-                int level= src[i];
-                if(((unsigned)(level+threshold1))>threshold2){
-                        const int j= permutation[i];
-                        dst[j]= (level + 4)>>3;
-                }
-        }
-}
-
-static void softthresh_c(int16_t dst[64], int16_t src[64], int qp, uint8_t *permutation){
-        int i;
-        int bias= 0; //FIXME
-        unsigned int threshold1, threshold2;
-
-        threshold1= qp*((1<<4) - bias) - 1;
-        threshold2= (threshold1<<1);
-
-        memset(dst, 0, 64*sizeof(int16_t));
-        dst[0]= (src[0] + 4)>>3;
-
-        for(i=1; i<64; i++){
-                int level= src[i];
-                if(((unsigned)(level+threshold1))>threshold2){
-                        const int j= permutation[i];
-                        if(level>0)
-                                dst[j]= (level - threshold1 + 4)>>3;
-                        else
-                                dst[j]= (level + threshold1 + 4)>>3;
-                }
-        }
-}
-
-#if HAVE_MMX
-static void hardthresh_mmx(int16_t dst[64], int16_t src[64], int qp, uint8_t *permutation){
-        int bias= 0; //FIXME
-        unsigned int threshold1;
-
-        threshold1= qp*((1<<4) - bias) - 1;
-
-        __asm__ volatile(
-#define REQUANT_CORE(dst0, dst1, dst2, dst3, src0, src1, src2, src3) \
-                "movq " #src0 ", %%mm0        \n\t"\
-                "movq " #src1 ", %%mm1        \n\t"\
-                "movq " #src2 ", %%mm2        \n\t"\
-                "movq " #src3 ", %%mm3        \n\t"\
-                "psubw %%mm4, %%mm0        \n\t"\
-                "psubw %%mm4, %%mm1        \n\t"\
-                "psubw %%mm4, %%mm2        \n\t"\
-                "psubw %%mm4, %%mm3        \n\t"\
-                "paddusw %%mm5, %%mm0        \n\t"\
-                "paddusw %%mm5, %%mm1        \n\t"\
-                "paddusw %%mm5, %%mm2        \n\t"\
-                "paddusw %%mm5, %%mm3        \n\t"\
-                "paddw %%mm6, %%mm0        \n\t"\
-                "paddw %%mm6, %%mm1        \n\t"\
-                "paddw %%mm6, %%mm2        \n\t"\
-                "paddw %%mm6, %%mm3        \n\t"\
-                "psubusw %%mm6, %%mm0        \n\t"\
-                "psubusw %%mm6, %%mm1        \n\t"\
-                "psubusw %%mm6, %%mm2        \n\t"\
-                "psubusw %%mm6, %%mm3        \n\t"\
-                "psraw $3, %%mm0        \n\t"\
-                "psraw $3, %%mm1        \n\t"\
-                "psraw $3, %%mm2        \n\t"\
-                "psraw $3, %%mm3        \n\t"\
-\
-                "movq %%mm0, %%mm7        \n\t"\
-                "punpcklwd %%mm2, %%mm0        \n\t" /*A*/\
-                "punpckhwd %%mm2, %%mm7        \n\t" /*C*/\
-                "movq %%mm1, %%mm2        \n\t"\
-                "punpcklwd %%mm3, %%mm1        \n\t" /*B*/\
-                "punpckhwd %%mm3, %%mm2        \n\t" /*D*/\
-                "movq %%mm0, %%mm3        \n\t"\
-                "punpcklwd %%mm1, %%mm0        \n\t" /*A*/\
-                "punpckhwd %%mm7, %%mm3        \n\t" /*C*/\
-                "punpcklwd %%mm2, %%mm7        \n\t" /*B*/\
-                "punpckhwd %%mm2, %%mm1        \n\t" /*D*/\
-\
-                "movq %%mm0, " #dst0 "        \n\t"\
-                "movq %%mm7, " #dst1 "        \n\t"\
-                "movq %%mm3, " #dst2 "        \n\t"\
-                "movq %%mm1, " #dst3 "        \n\t"
-
-                "movd %2, %%mm4                \n\t"
-                "movd %3, %%mm5                \n\t"
-                "movd %4, %%mm6                \n\t"
-                "packssdw %%mm4, %%mm4        \n\t"
-                "packssdw %%mm5, %%mm5        \n\t"
-                "packssdw %%mm6, %%mm6        \n\t"
-                "packssdw %%mm4, %%mm4        \n\t"
-                "packssdw %%mm5, %%mm5        \n\t"
-                "packssdw %%mm6, %%mm6        \n\t"
-                REQUANT_CORE(  (%1),  8(%1), 16(%1), 24(%1),  (%0), 8(%0), 64(%0), 72(%0))
-                REQUANT_CORE(32(%1), 40(%1), 48(%1), 56(%1),16(%0),24(%0), 48(%0), 56(%0))
-                REQUANT_CORE(64(%1), 72(%1), 80(%1), 88(%1),32(%0),40(%0), 96(%0),104(%0))
-                REQUANT_CORE(96(%1),104(%1),112(%1),120(%1),80(%0),88(%0),112(%0),120(%0))
-                : : "r" (src), "r" (dst), "g" (threshold1+1), "g" (threshold1+5), "g" (threshold1-4) //FIXME maybe more accurate then needed?
-        );
-        dst[0]= (src[0] + 4)>>3;
-}
-
-static void softthresh_mmx(int16_t dst[64], int16_t src[64], int qp, uint8_t *permutation){
-        int bias= 0; //FIXME
-        unsigned int threshold1;
-
-        threshold1= qp*((1<<4) - bias) - 1;
-
-        __asm__ volatile(
-#undef REQUANT_CORE
-#define REQUANT_CORE(dst0, dst1, dst2, dst3, src0, src1, src2, src3) \
-                "movq " #src0 ", %%mm0        \n\t"\
-                "movq " #src1 ", %%mm1        \n\t"\
-                "pxor %%mm6, %%mm6        \n\t"\
-                "pxor %%mm7, %%mm7        \n\t"\
-                "pcmpgtw %%mm0, %%mm6        \n\t"\
-                "pcmpgtw %%mm1, %%mm7        \n\t"\
-                "pxor %%mm6, %%mm0        \n\t"\
-                "pxor %%mm7, %%mm1        \n\t"\
-                "psubusw %%mm4, %%mm0        \n\t"\
-                "psubusw %%mm4, %%mm1        \n\t"\
-                "pxor %%mm6, %%mm0        \n\t"\
-                "pxor %%mm7, %%mm1        \n\t"\
-                "movq " #src2 ", %%mm2        \n\t"\
-                "movq " #src3 ", %%mm3        \n\t"\
-                "pxor %%mm6, %%mm6        \n\t"\
-                "pxor %%mm7, %%mm7        \n\t"\
-                "pcmpgtw %%mm2, %%mm6        \n\t"\
-                "pcmpgtw %%mm3, %%mm7        \n\t"\
-                "pxor %%mm6, %%mm2        \n\t"\
-                "pxor %%mm7, %%mm3        \n\t"\
-                "psubusw %%mm4, %%mm2        \n\t"\
-                "psubusw %%mm4, %%mm3        \n\t"\
-                "pxor %%mm6, %%mm2        \n\t"\
-                "pxor %%mm7, %%mm3        \n\t"\
-\
-                "paddsw %%mm5, %%mm0        \n\t"\
-                "paddsw %%mm5, %%mm1        \n\t"\
-                "paddsw %%mm5, %%mm2        \n\t"\
-                "paddsw %%mm5, %%mm3        \n\t"\
-                "psraw $3, %%mm0        \n\t"\
-                "psraw $3, %%mm1        \n\t"\
-                "psraw $3, %%mm2        \n\t"\
-                "psraw $3, %%mm3        \n\t"\
-\
-                "movq %%mm0, %%mm7        \n\t"\
-                "punpcklwd %%mm2, %%mm0        \n\t" /*A*/\
-                "punpckhwd %%mm2, %%mm7        \n\t" /*C*/\
-                "movq %%mm1, %%mm2        \n\t"\
-                "punpcklwd %%mm3, %%mm1        \n\t" /*B*/\
-                "punpckhwd %%mm3, %%mm2        \n\t" /*D*/\
-                "movq %%mm0, %%mm3        \n\t"\
-                "punpcklwd %%mm1, %%mm0        \n\t" /*A*/\
-                "punpckhwd %%mm7, %%mm3        \n\t" /*C*/\
-                "punpcklwd %%mm2, %%mm7        \n\t" /*B*/\
-                "punpckhwd %%mm2, %%mm1        \n\t" /*D*/\
-\
-                "movq %%mm0, " #dst0 "        \n\t"\
-                "movq %%mm7, " #dst1 "        \n\t"\
-                "movq %%mm3, " #dst2 "        \n\t"\
-                "movq %%mm1, " #dst3 "        \n\t"
-
-                "movd %2, %%mm4                \n\t"
-                "movd %3, %%mm5                \n\t"
-                "packssdw %%mm4, %%mm4        \n\t"
-                "packssdw %%mm5, %%mm5        \n\t"
-                "packssdw %%mm4, %%mm4        \n\t"
-                "packssdw %%mm5, %%mm5        \n\t"
-                REQUANT_CORE(  (%1),  8(%1), 16(%1), 24(%1),  (%0), 8(%0), 64(%0), 72(%0))
-                REQUANT_CORE(32(%1), 40(%1), 48(%1), 56(%1),16(%0),24(%0), 48(%0), 56(%0))
-                REQUANT_CORE(64(%1), 72(%1), 80(%1), 88(%1),32(%0),40(%0), 96(%0),104(%0))
-                REQUANT_CORE(96(%1),104(%1),112(%1),120(%1),80(%0),88(%0),112(%0),120(%0))
-                : : "r" (src), "r" (dst), "g" (threshold1), "rm" (4) //FIXME maybe more accurate then needed?
-        );
-
-        dst[0]= (src[0] + 4)>>3;
-}
-#endif
-
-static inline void add_block(int16_t *dst, int stride, int16_t block[64]){
-        int y;
-
-        for(y=0; y<8; y++){
-                *(uint32_t*)&dst[0 + y*stride]+= *(uint32_t*)&block[0 + y*8];
-                *(uint32_t*)&dst[2 + y*stride]+= *(uint32_t*)&block[2 + y*8];
-                *(uint32_t*)&dst[4 + y*stride]+= *(uint32_t*)&block[4 + y*8];
-                *(uint32_t*)&dst[6 + y*stride]+= *(uint32_t*)&block[6 + y*8];
-        }
-}
-
-static void store_slice_c(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale){
-        int y, x;
-
-#define STORE(pos) \
-        temp= ((src[x + y*src_stride + pos]<<log2_scale) + d[pos])>>6;\
-        if(temp & 0x100) temp= ~(temp>>31);\
-        dst[x + y*dst_stride + pos]= temp;
-
-        for(y=0; y<height; y++){
-                const uint8_t *d= dither[y];
-                for(x=0; x<width; x+=8){
-                        int temp;
-                        STORE(0);
-                        STORE(1);
-                        STORE(2);
-                        STORE(3);
-                        STORE(4);
-                        STORE(5);
-                        STORE(6);
-                        STORE(7);
-                }
-        }
-}
-
-#if HAVE_MMX
-static void store_slice_mmx(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale){
-        int y;
-
-        for(y=0; y<height; y++){
-                uint8_t *dst1= dst;
-                int16_t *src1= src;
-                __asm__ volatile(
-                        "movq (%3), %%mm3        \n\t"
-                        "movq (%3), %%mm4        \n\t"
-                        "movd %4, %%mm2                \n\t"
-                        "pxor %%mm0, %%mm0        \n\t"
-                        "punpcklbw %%mm0, %%mm3        \n\t"
-                        "punpckhbw %%mm0, %%mm4        \n\t"
-                        "psraw %%mm2, %%mm3        \n\t"
-                        "psraw %%mm2, %%mm4        \n\t"
-                        "movd %5, %%mm2                \n\t"
-                        "1:                        \n\t"
-                        "movq (%0), %%mm0        \n\t"
-                        "movq 8(%0), %%mm1        \n\t"
-                        "paddw %%mm3, %%mm0        \n\t"
-                        "paddw %%mm4, %%mm1        \n\t"
-                        "psraw %%mm2, %%mm0        \n\t"
-                        "psraw %%mm2, %%mm1        \n\t"
-                        "packuswb %%mm1, %%mm0        \n\t"
-                        "movq %%mm0, (%1)         \n\t"
-                        "add $16, %0                \n\t"
-                        "add $8, %1                \n\t"
-                        "cmp %2, %1                \n\t"
-                        " jb 1b                        \n\t"
-                        : "+r" (src1), "+r"(dst1)
-                        : "r"(dst + width), "r"(dither[y]), "g"(log2_scale), "g"(6-log2_scale)
-                );
-                src += src_stride;
-                dst += dst_stride;
-        }
-//        if(width != mmxw)
-//                store_slice_c(dst + mmxw, src + mmxw, dst_stride, src_stride, width - mmxw, log2_scale);
-}
-#endif
-
-static void (*store_slice)(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale)= store_slice_c;
-
-static void (*requantize)(int16_t dst[64], int16_t src[64], int qp, uint8_t *permutation)= hardthresh_c;
-
-static void filter(struct vf_priv_s *p, uint8_t *dst, uint8_t *src, int dst_stride, int src_stride, int width, int height, uint8_t *qp_store, int qp_stride, int is_luma){
-        int x, y, i;
-        const int count= 1<<p->log2_count;
-        const int stride= is_luma ? p->temp_stride : ((width+16+15)&(~15));
-        uint64_t __attribute__((aligned(16))) block_align[32];
-        int16_t *block = (int16_t *)block_align;
-        int16_t *block2= (int16_t *)(block_align+16);
-
-        if (!src || !dst) return; // HACK avoid crash for Y8 colourspace
-        for(y=0; y<height; y++){
-                int index= 8 + 8*stride + y*stride;
-                fast_memcpy(p->src + index, src + y*src_stride, width);
-                for(x=0; x<8; x++){
-                        p->src[index         - x - 1]= p->src[index +         x    ];
-                        p->src[index + width + x    ]= p->src[index + width - x - 1];
-                }
-        }
-        for(y=0; y<8; y++){
-                fast_memcpy(p->src + (      7-y)*stride, p->src + (      y+8)*stride, stride);
-                fast_memcpy(p->src + (height+8+y)*stride, p->src + (height-y+7)*stride, stride);
-        }
-        //FIXME (try edge emu)
-
-        for(y=0; y<height+8; y+=8){
-                memset(p->temp + (8+y)*stride, 0, 8*stride*sizeof(int16_t));
-                for(x=0; x<width+8; x+=8){
-                        const int qps= 3 + is_luma;
-                        int qp;
-
-                        if(p->qp)
-                                qp= p->qp;
-                        else{
-                                qp= qp_store[ (XMIN(x, width-1)>>qps) + (XMIN(y, height-1)>>qps) * qp_stride];
-                                qp = FFMAX(1, norm_qscale(qp, p->mpeg2));
-                        }
-                        for(i=0; i<count; i++){
-                                const int x1= x + offset[i+count-1][0];
-                                const int y1= y + offset[i+count-1][1];
-                                const int index= x1 + y1*stride;
-                                p->dsp.get_pixels(block, p->src + index, stride);
-                                p->dsp.fdct(block);
-                                requantize(block2, block, qp, p->dsp.idct_permutation);
-                                p->dsp.idct(block2);
-                                add_block(p->temp + index, stride, block2);
-                        }
-                }
-                if(y)
-                        store_slice(dst + (y-8)*dst_stride, p->temp + 8 + y*stride, dst_stride, stride, width, XMIN(8, height+8-y), 6-p->log2_count);
-        }
-#if 0
-        for(y=0; y<height; y++){
-                for(x=0; x<width; x++){
-                        if((((x>>6) ^ (y>>6)) & 1) == 0)
-                                dst[x + y*dst_stride]= p->src[8 + 8*stride  + x + y*stride];
-                        if((x&63) == 0 || (y&63)==0)
-                                dst[x + y*dst_stride] += 128;
-                }
-        }
-#endif
-        //FIXME reorder for better caching
-}
-
-static int config(struct vf_instance *vf,
-        int width, int height, int d_width, int d_height,
-        unsigned int flags, unsigned int outfmt){
-        int h= (height+16+15)&(~15);
-
-        vf->priv->temp_stride= (width+16+15)&(~15);
-        vf->priv->temp= malloc(vf->priv->temp_stride*h*sizeof(int16_t));
-        vf->priv->src = malloc(vf->priv->temp_stride*h*sizeof(uint8_t));
-
-        return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
-}
-
-static void get_image(struct vf_instance *vf, mp_image_t *mpi){
-    if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change
-    // ok, we can do pp in-place (or pp disabled):
-    vf->dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
-        mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height);
-    mpi->planes[0]=vf->dmpi->planes[0];
-    mpi->stride[0]=vf->dmpi->stride[0];
-    mpi->width=vf->dmpi->width;
-    if(mpi->flags&MP_IMGFLAG_PLANAR){
-        mpi->planes[1]=vf->dmpi->planes[1];
-        mpi->planes[2]=vf->dmpi->planes[2];
-        mpi->stride[1]=vf->dmpi->stride[1];
-        mpi->stride[2]=vf->dmpi->stride[2];
-    }
-    mpi->flags|=MP_IMGFLAG_DIRECT;
-}
-
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
-        mp_image_t *dmpi;
-
-        if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
-                // no DR, so get a new image! hope we'll get DR buffer:
-                dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
-                    MP_IMGTYPE_TEMP,
-                    MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
-                    mpi->width,mpi->height);
-                ff_vf_clone_mpi_attributes(dmpi, mpi);
-        }else{
-           dmpi=vf->dmpi;
-        }
-
-        vf->priv->mpeg2= mpi->qscale_type;
-        if(mpi->pict_type != 3 && mpi->qscale && !vf->priv->qp){
-            int w = mpi->qstride;
-            int h = (mpi->h + 15) >> 4;
-            if (!w) {
-                w = (mpi->w + 15) >> 4;
-                h = 1;
-            }
-            if(!vf->priv->non_b_qp)
-                vf->priv->non_b_qp= malloc(w*h);
-            fast_memcpy(vf->priv->non_b_qp, mpi->qscale, w*h);
-        }
-        if(vf->priv->log2_count || !(mpi->flags&MP_IMGFLAG_DIRECT)){
-            char *qp_tab= vf->priv->non_b_qp;
-            if((vf->priv->mode&4) || !qp_tab)
-                qp_tab= mpi->qscale;
-
-            if(qp_tab || vf->priv->qp){
-                filter(vf->priv, dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h, qp_tab, mpi->qstride, 1);
-                filter(vf->priv, dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, qp_tab, mpi->qstride, 0);
-                filter(vf->priv, dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, qp_tab, mpi->qstride, 0);
-            }else{
-                memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0], mpi->stride[0]);
-                memcpy_pic(dmpi->planes[1], mpi->planes[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[1], mpi->stride[1]);
-                memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[2], mpi->stride[2]);
-            }
-        }
-
-#if HAVE_MMX
-        if(ff_gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t");
-#endif
-#if HAVE_MMX2
-        if(ff_gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
-#endif
-
-        return ff_vf_next_put_image(vf,dmpi, pts);
-}
-
-static void uninit(struct vf_instance *vf){
-        if(!vf->priv) return;
-
-        free(vf->priv->temp);
-        vf->priv->temp= NULL;
-        free(vf->priv->src);
-        vf->priv->src= NULL;
-        free(vf->priv->avctx);
-        vf->priv->avctx= NULL;
-        free(vf->priv->non_b_qp);
-        vf->priv->non_b_qp= NULL;
-
-        free(vf->priv);
-        vf->priv=NULL;
-}
-
-//===========================================================================//
-static int query_format(struct vf_instance *vf, unsigned int fmt){
-    switch(fmt){
-        case IMGFMT_YVU9:
-        case IMGFMT_IF09:
-        case IMGFMT_YV12:
-        case IMGFMT_I420:
-        case IMGFMT_IYUV:
-        case IMGFMT_CLPL:
-        case IMGFMT_Y800:
-        case IMGFMT_Y8:
-        case IMGFMT_444P:
-        case IMGFMT_422P:
-        case IMGFMT_411P:
-            return ff_vf_next_query_format(vf,fmt);
-    }
-    return 0;
-}
-
-static int control(struct vf_instance *vf, int request, void* data){
-    switch(request){
-    case VFCTRL_QUERY_MAX_PP_LEVEL:
-        return 6;
-    case VFCTRL_SET_PP_LEVEL:
-        vf->priv->log2_count= *((unsigned int*)data);
-        return CONTROL_TRUE;
-    }
-    return ff_vf_next_control(vf,request,data);
-}
-
-static int vf_open(vf_instance_t *vf, char *args){
-
-    int log2c=-1;
-
-    vf->config=config;
-    vf->put_image=put_image;
-    vf->get_image=get_image;
-    vf->query_format=query_format;
-    vf->uninit=uninit;
-    vf->control= control;
-    vf->priv=malloc(sizeof(struct vf_priv_s));
-    memset(vf->priv, 0, sizeof(struct vf_priv_s));
-
-    ff_init_avcodec();
-
-    vf->priv->avctx= avcodec_alloc_context3(NULL);
-    ff_dsputil_init(&vf->priv->dsp, vf->priv->avctx);
-
-    vf->priv->log2_count= 3;
-
-    if (args) sscanf(args, "%d:%d:%d", &log2c, &vf->priv->qp, &vf->priv->mode);
-
-    if( log2c >=0 && log2c <=6 )
-        vf->priv->log2_count = log2c;
-
-    if(vf->priv->qp < 0)
-        vf->priv->qp = 0;
-
-    switch(vf->priv->mode&3){
-        default:
-        case 0: requantize= hardthresh_c; break;
-        case 1: requantize= softthresh_c; break;
-    }
-
-#if HAVE_MMX
-    if(ff_gCpuCaps.hasMMX){
-        store_slice= store_slice_mmx;
-        switch(vf->priv->mode&3){
-            case 0: requantize= hardthresh_mmx; break;
-            case 1: requantize= softthresh_mmx; break;
-        }
-    }
-#endif
-
-    return 1;
-}
-
-const vf_info_t ff_vf_info_spp = {
-    "simple postprocess",
-    "spp",
-    "Michael Niedermayer",
-    "",
-    vf_open,
-    NULL
-};
diff --git a/libavfilter/libmpcodecs/vf_tinterlace.c b/libavfilter/libmpcodecs/vf_tinterlace.c
deleted file mode 100644
index 6c7dbab..0000000
--- a/libavfilter/libmpcodecs/vf_tinterlace.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2003 Michael Zucchi <notzed@ximian.com>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "config.h"
-#include "mp_msg.h"
-
-#include "img_format.h"
-#include "mp_image.h"
-#include "vf.h"
-
-#include "libvo/fastmemcpy.h"
-
-struct vf_priv_s {
-    int mode;
-    int frame;
-    mp_image_t *dmpi;
-};
-
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
-{
-    int ret = 0;
-    mp_image_t *dmpi;
-
-    switch (vf->priv->mode) {
-    case 0:
-        dmpi = vf->priv->dmpi;
-        if (dmpi == NULL) {
-            dmpi = ff_vf_get_image(vf->next, mpi->imgfmt,
-                        MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
-                        MP_IMGFLAG_PRESERVE,
-                        mpi->width, mpi->height*2);
-
-            vf->priv->dmpi = dmpi;
-
-            memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h,
-                   dmpi->stride[0]*2, mpi->stride[0]);
-            if (mpi->flags & MP_IMGFLAG_PLANAR) {
-                memcpy_pic(dmpi->planes[1], mpi->planes[1],
-                       mpi->chroma_width, mpi->chroma_height,
-                       dmpi->stride[1]*2, mpi->stride[1]);
-                memcpy_pic(dmpi->planes[2], mpi->planes[2],
-                       mpi->chroma_width, mpi->chroma_height,
-                       dmpi->stride[2]*2, mpi->stride[2]);
-            }
-        } else {
-            vf->priv->dmpi = NULL;
-
-            memcpy_pic(dmpi->planes[0]+dmpi->stride[0], mpi->planes[0], mpi->w, mpi->h,
-                   dmpi->stride[0]*2, mpi->stride[0]);
-            if (mpi->flags & MP_IMGFLAG_PLANAR) {
-                memcpy_pic(dmpi->planes[1]+dmpi->stride[1], mpi->planes[1],
-                       mpi->chroma_width, mpi->chroma_height,
-                       dmpi->stride[1]*2, mpi->stride[1]);
-                memcpy_pic(dmpi->planes[2]+dmpi->stride[2], mpi->planes[2],
-                       mpi->chroma_width, mpi->chroma_height,
-                       dmpi->stride[2]*2, mpi->stride[2]);
-            }
-            ret = ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
-        }
-        break;
-    case 1:
-        if (vf->priv->frame & 1)
-            ret = ff_vf_next_put_image(vf, mpi, MP_NOPTS_VALUE);
-        break;
-    case 2:
-        if ((vf->priv->frame & 1) == 0)
-            ret = ff_vf_next_put_image(vf, mpi, MP_NOPTS_VALUE);
-        break;
-    case 3:
-        dmpi = ff_vf_get_image(vf->next, mpi->imgfmt,
-                    MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
-                    mpi->width, mpi->height*2);
-        /* fixme, just clear alternate lines */
-        ff_vf_mpi_clear(dmpi, 0, 0, dmpi->w, dmpi->h);
-        if ((vf->priv->frame & 1) == 0) {
-            memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h,
-                   dmpi->stride[0]*2, mpi->stride[0]);
-            if (mpi->flags & MP_IMGFLAG_PLANAR) {
-                memcpy_pic(dmpi->planes[1], mpi->planes[1],
-                       mpi->chroma_width, mpi->chroma_height,
-                       dmpi->stride[1]*2, mpi->stride[1]);
-                memcpy_pic(dmpi->planes[2], mpi->planes[2],
-                       mpi->chroma_width, mpi->chroma_height,
-                       dmpi->stride[2]*2, mpi->stride[2]);
-            }
-        } else {
-            memcpy_pic(dmpi->planes[0]+dmpi->stride[0], mpi->planes[0], mpi->w, mpi->h,
-                   dmpi->stride[0]*2, mpi->stride[0]);
-            if (mpi->flags & MP_IMGFLAG_PLANAR) {
-                memcpy_pic(dmpi->planes[1]+dmpi->stride[1], mpi->planes[1],
-                       mpi->chroma_width, mpi->chroma_height,
-                       dmpi->stride[1]*2, mpi->stride[1]);
-                memcpy_pic(dmpi->planes[2]+dmpi->stride[2], mpi->planes[2],
-                       mpi->chroma_width, mpi->chroma_height,
-                       dmpi->stride[2]*2, mpi->stride[2]);
-            }
-        }
-        ret = ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
-        break;
-    case 4:
-        // Interleave even lines (only) from Frame 'i' with odd
-        // lines (only) from Frame 'i+1', halving the Frame
-        // rate and preserving image height.
-
-        dmpi = vf->priv->dmpi;
-
-        // @@ Need help:  Should I set dmpi->fields to indicate
-        // that the (new) frame will be interlaced!?  E.g. ...
-        // dmpi->fields |= MP_IMGFIELD_INTERLACED;
-        // dmpi->fields |= MP_IMGFIELD_TOP_FIRST;
-        // etc.
-
-        if (dmpi == NULL) {
-            dmpi = ff_vf_get_image(vf->next, mpi->imgfmt,
-                        MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
-                        MP_IMGFLAG_PRESERVE,
-                        mpi->width, mpi->height);
-
-            vf->priv->dmpi = dmpi;
-
-            my_memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h/2,
-                      dmpi->stride[0]*2, mpi->stride[0]*2);
-            if (mpi->flags & MP_IMGFLAG_PLANAR) {
-                my_memcpy_pic(dmpi->planes[1], mpi->planes[1],
-                          mpi->chroma_width, mpi->chroma_height/2,
-                          dmpi->stride[1]*2, mpi->stride[1]*2);
-                my_memcpy_pic(dmpi->planes[2], mpi->planes[2],
-                          mpi->chroma_width, mpi->chroma_height/2,
-                          dmpi->stride[2]*2, mpi->stride[2]*2);
-            }
-        } else {
-            vf->priv->dmpi = NULL;
-
-            my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0],
-                      mpi->planes[0]+mpi->stride[0],
-                      mpi->w, mpi->h/2,
-                      dmpi->stride[0]*2, mpi->stride[0]*2);
-            if (mpi->flags & MP_IMGFLAG_PLANAR) {
-                my_memcpy_pic(dmpi->planes[1]+dmpi->stride[1],
-                          mpi->planes[1]+mpi->stride[1],
-                          mpi->chroma_width, mpi->chroma_height/2,
-                          dmpi->stride[1]*2, mpi->stride[1]*2);
-                my_memcpy_pic(dmpi->planes[2]+dmpi->stride[2],
-                          mpi->planes[2]+mpi->stride[2],
-                          mpi->chroma_width, mpi->chroma_height/2,
-                          dmpi->stride[2]*2, mpi->stride[2]*2);
-            }
-            ret = ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
-        }
-        break;
-    }
-
-    vf->priv->frame++;
-
-    return ret;
-}
-
-static int query_format(struct vf_instance *vf, unsigned int fmt)
-{
-    /* FIXME - figure out which other formats work */
-    switch (fmt) {
-    case IMGFMT_YV12:
-    case IMGFMT_IYUV:
-    case IMGFMT_I420:
-        return ff_vf_next_query_format(vf, fmt);
-    }
-    return 0;
-}
-
-static int config(struct vf_instance *vf,
-    int width, int height, int d_width, int d_height,
-    unsigned int flags, unsigned int outfmt)
-{
-    switch (vf->priv->mode) {
-    case 0:
-    case 3:
-        return ff_vf_next_config(vf,width,height*2,d_width,d_height*2,flags,outfmt);
-    case 1:            /* odd frames */
-    case 2:            /* even frames */
-    case 4:            /* alternate frame (height-preserving) interlacing */
-        return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
-    }
-    return 0;
-}
-
-static void uninit(struct vf_instance *vf)
-{
-    free(vf->priv);
-}
-
-static int vf_open(vf_instance_t *vf, char *args)
-{
-    struct vf_priv_s *p;
-    vf->config = config;
-    vf->put_image = put_image;
-    vf->query_format = query_format;
-    vf->uninit = uninit;
-    vf->default_reqs = VFCAP_ACCEPT_STRIDE;
-    vf->priv = p = calloc(1, sizeof(struct vf_priv_s));
-    p->mode = 0;
-    if (args)
-      sscanf(args, "%d", &p->mode);
-    p->frame = 0;
-    return 1;
-}
-
-const vf_info_t ff_vf_info_tinterlace = {
-    "temporal field interlacing",
-    "tinterlace",
-    "Michael Zucchi",
-    "",
-    vf_open,
-    NULL
-};
diff --git a/libavfilter/opencl_allkernels.c b/libavfilter/opencl_allkernels.c
index 021eec2..6d80fa8 100644
--- a/libavfilter/opencl_allkernels.c
+++ b/libavfilter/opencl_allkernels.c
@@ -21,7 +21,8 @@
 #include "opencl_allkernels.h"
 #if CONFIG_OPENCL
 #include "libavutil/opencl.h"
-#include "deshake_kernel.h"
+#include "deshake_opencl_kernel.h"
+#include "unsharp_opencl_kernel.h"
 #endif
 
 #define OPENCL_REGISTER_KERNEL_CODE(X, x)                                              \
@@ -35,5 +36,6 @@
 {
  #if CONFIG_OPENCL
    OPENCL_REGISTER_KERNEL_CODE(DESHAKE,     deshake);
+   OPENCL_REGISTER_KERNEL_CODE(UNSHARP,     unsharp);
  #endif
 }
diff --git a/libavfilter/pthread.c b/libavfilter/pthread.c
new file mode 100644
index 0000000..ab29662
--- /dev/null
+++ b/libavfilter/pthread.c
@@ -0,0 +1,230 @@
+/*
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * Libavfilter multithreading support
+ */
+
+#include "config.h"
+
+#include "libavutil/common.h"
+#include "libavutil/cpu.h"
+#include "libavutil/mem.h"
+
+#include "avfilter.h"
+#include "internal.h"
+#include "thread.h"
+
+#if HAVE_PTHREADS
+#include <pthread.h>
+#elif HAVE_OS2THREADS
+#include "compat/os2threads.h"
+#elif HAVE_W32THREADS
+#include "compat/w32pthreads.h"
+#endif
+
+typedef struct ThreadContext {
+    AVFilterGraph *graph;
+
+    int nb_threads;
+    pthread_t *workers;
+    action_func *func;
+
+    /* per-execute perameters */
+    AVFilterContext *ctx;
+    void *arg;
+    int   *rets;
+    int nb_rets;
+    int nb_jobs;
+
+    pthread_cond_t last_job_cond;
+    pthread_cond_t current_job_cond;
+    pthread_mutex_t current_job_lock;
+    int current_job;
+    int done;
+} ThreadContext;
+
+static void* attribute_align_arg worker(void *v)
+{
+    ThreadContext *c = v;
+    int our_job      = c->nb_jobs;
+    int nb_threads   = c->nb_threads;
+    int self_id;
+
+    pthread_mutex_lock(&c->current_job_lock);
+    self_id = c->current_job++;
+    for (;;) {
+        while (our_job >= c->nb_jobs) {
+            if (c->current_job == nb_threads + c->nb_jobs)
+                pthread_cond_signal(&c->last_job_cond);
+
+            pthread_cond_wait(&c->current_job_cond, &c->current_job_lock);
+            our_job = self_id;
+
+            if (c->done) {
+                pthread_mutex_unlock(&c->current_job_lock);
+                return NULL;
+            }
+        }
+        pthread_mutex_unlock(&c->current_job_lock);
+
+        c->rets[our_job % c->nb_rets] = c->func(c->ctx, c->arg, our_job, c->nb_jobs);
+
+        pthread_mutex_lock(&c->current_job_lock);
+        our_job = c->current_job++;
+    }
+}
+
+static void slice_thread_uninit(ThreadContext *c)
+{
+    int i;
+
+    pthread_mutex_lock(&c->current_job_lock);
+    c->done = 1;
+    pthread_cond_broadcast(&c->current_job_cond);
+    pthread_mutex_unlock(&c->current_job_lock);
+
+    for (i = 0; i < c->nb_threads; i++)
+         pthread_join(c->workers[i], NULL);
+
+    pthread_mutex_destroy(&c->current_job_lock);
+    pthread_cond_destroy(&c->current_job_cond);
+    pthread_cond_destroy(&c->last_job_cond);
+    av_freep(&c->workers);
+}
+
+static void slice_thread_park_workers(ThreadContext *c)
+{
+    pthread_cond_wait(&c->last_job_cond, &c->current_job_lock);
+    pthread_mutex_unlock(&c->current_job_lock);
+}
+
+static int thread_execute(AVFilterContext *ctx, action_func *func,
+                          void *arg, int *ret, int nb_jobs)
+{
+    ThreadContext *c = ctx->graph->internal->thread;
+    int dummy_ret;
+
+    if (nb_jobs <= 0)
+        return 0;
+
+    pthread_mutex_lock(&c->current_job_lock);
+
+    c->current_job = c->nb_threads;
+    c->nb_jobs     = nb_jobs;
+    c->ctx         = ctx;
+    c->arg         = arg;
+    c->func        = func;
+    if (ret) {
+        c->rets    = ret;
+        c->nb_rets = nb_jobs;
+    } else {
+        c->rets    = &dummy_ret;
+        c->nb_rets = 1;
+    }
+    pthread_cond_broadcast(&c->current_job_cond);
+
+    slice_thread_park_workers(c);
+
+    return 0;
+}
+
+static int thread_init_internal(ThreadContext *c, int nb_threads)
+{
+    int i, ret;
+
+    if (!nb_threads) {
+        int nb_cpus = av_cpu_count();
+        // use number of cores + 1 as thread count if there is more than one
+        if (nb_cpus > 1)
+            nb_threads = nb_cpus + 1;
+        else
+            nb_threads = 1;
+    }
+
+    if (nb_threads <= 1)
+        return 1;
+
+    c->nb_threads = nb_threads;
+    c->workers = av_mallocz(sizeof(*c->workers) * nb_threads);
+    if (!c->workers)
+        return AVERROR(ENOMEM);
+
+    c->current_job = 0;
+    c->nb_jobs     = 0;
+    c->done        = 0;
+
+    pthread_cond_init(&c->current_job_cond, NULL);
+    pthread_cond_init(&c->last_job_cond,    NULL);
+
+    pthread_mutex_init(&c->current_job_lock, NULL);
+    pthread_mutex_lock(&c->current_job_lock);
+    for (i = 0; i < nb_threads; i++) {
+        ret = pthread_create(&c->workers[i], NULL, worker, c);
+        if (ret) {
+           pthread_mutex_unlock(&c->current_job_lock);
+           c->nb_threads = i;
+           slice_thread_uninit(c);
+           return AVERROR(ret);
+        }
+    }
+
+    slice_thread_park_workers(c);
+
+    return c->nb_threads;
+}
+
+int ff_graph_thread_init(AVFilterGraph *graph)
+{
+    int ret;
+
+#if HAVE_W32THREADS
+    w32thread_init();
+#endif
+
+    if (graph->nb_threads == 1) {
+        graph->thread_type = 0;
+        return 0;
+    }
+
+    graph->internal->thread = av_mallocz(sizeof(ThreadContext));
+    if (!graph->internal->thread)
+        return AVERROR(ENOMEM);
+
+    ret = thread_init_internal(graph->internal->thread, graph->nb_threads);
+    if (ret <= 1) {
+        av_freep(&graph->internal->thread);
+        graph->thread_type = 0;
+        graph->nb_threads  = 1;
+        return (ret < 0) ? ret : 0;
+    }
+    graph->nb_threads = ret;
+
+    graph->internal->thread_execute = thread_execute;
+
+    return 0;
+}
+
+void ff_graph_thread_free(AVFilterGraph *graph)
+{
+    if (graph->internal->thread)
+        slice_thread_uninit(graph->internal->thread);
+    av_freep(&graph->internal->thread);
+}
diff --git a/libavfilter/f_setpts.c b/libavfilter/setpts.c
similarity index 83%
rename from libavfilter/f_setpts.c
rename to libavfilter/setpts.c
index c0fd422..3dd4e6a 100644
--- a/libavfilter/f_setpts.c
+++ b/libavfilter/setpts.c
@@ -29,15 +29,15 @@
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
 #include "libavutil/time.h"
+#include "audio.h"
 #include "avfilter.h"
 #include "internal.h"
-#include "audio.h"
 #include "video.h"
 
 static const char *const var_names[] = {
     "FRAME_RATE",  ///< defined only for constant frame-rate video
     "INTERLACED",  ///< tell if the current frame is interlaced
-    "N",           ///< frame number (starting at zero)
+    "N",           ///< frame / sample number (starting at zero)
     "NB_CONSUMED_SAMPLES", ///< number of samples consumed by the filter (only audio)
     "NB_SAMPLES",  ///< number of samples in the current frame (only audio)
     "POS",         ///< original position in the file of the frame
@@ -53,6 +53,8 @@
     "TB",          ///< timebase
     "RTCTIME",     ///< wallclock (RTC) time in micro seconds
     "RTCSTART",    ///< wallclock (RTC) time at the start of the movie in micro seconds
+    "S",           //   Number of samples in the current frame
+    "SR",          //   Audio sample rate
     NULL
 };
 
@@ -75,6 +77,8 @@
     VAR_TB,
     VAR_RTCTIME,
     VAR_RTCSTART,
+    VAR_S,
+    VAR_SR,
     VAR_VARS_NB
 };
 
@@ -97,10 +101,14 @@
         return ret;
     }
 
-    setpts->var_values[VAR_N          ] = 0.0;
-    setpts->var_values[VAR_PREV_INPTS ] = setpts->var_values[VAR_PREV_INT ] = NAN;
-    setpts->var_values[VAR_PREV_OUTPTS] = setpts->var_values[VAR_PREV_OUTT] = NAN;
-    setpts->var_values[VAR_STARTPTS   ] = setpts->var_values[VAR_STARTT   ] = NAN;
+    setpts->var_values[VAR_N]           = 0.0;
+    setpts->var_values[VAR_S]           = 0.0;
+    setpts->var_values[VAR_PREV_INPTS]  = NAN;
+    setpts->var_values[VAR_PREV_INT]    = NAN;
+    setpts->var_values[VAR_PREV_OUTPTS] = NAN;
+    setpts->var_values[VAR_PREV_OUTT]   = NAN;
+    setpts->var_values[VAR_STARTPTS]    = NAN;
+    setpts->var_values[VAR_STARTT]      = NAN;
     return 0;
 }
 
@@ -113,6 +121,7 @@
     setpts->var_values[VAR_TB] = av_q2d(inlink->time_base);
     setpts->var_values[VAR_RTCSTART] = av_gettime();
 
+    setpts->var_values[VAR_SR] =
     setpts->var_values[VAR_SAMPLE_RATE] =
         setpts->type == AVMEDIA_TYPE_AUDIO ? inlink->sample_rate : NAN;
 
@@ -156,17 +165,15 @@
     setpts->var_values[VAR_POS       ] = av_frame_get_pkt_pos(frame) == -1 ? NAN : av_frame_get_pkt_pos(frame);
     setpts->var_values[VAR_RTCTIME   ] = av_gettime();
 
-    switch (inlink->type) {
-    case AVMEDIA_TYPE_VIDEO:
+    if (inlink->type == AVMEDIA_TYPE_VIDEO) {
         setpts->var_values[VAR_INTERLACED] = frame->interlaced_frame;
-        break;
-
-    case AVMEDIA_TYPE_AUDIO:
+    } else if (inlink->type == AVMEDIA_TYPE_AUDIO) {
+        setpts->var_values[VAR_S] = frame->nb_samples;
         setpts->var_values[VAR_NB_SAMPLES] = frame->nb_samples;
-        break;
     }
 
     d = av_expr_eval(setpts->expr, setpts->var_values, NULL);
+    frame->pts = D2TS(d);
 
     av_log(inlink->dst, AV_LOG_DEBUG,
            "N:%"PRId64" PTS:%s T:%f POS:%s",
@@ -187,13 +194,16 @@
     }
     av_log(inlink->dst, AV_LOG_DEBUG, " -> PTS:%s T:%f\n", d2istr(d), TS2T(d, inlink->time_base));
 
-    frame->pts = D2TS(d);
+    if (inlink->type == AVMEDIA_TYPE_VIDEO) {
+        setpts->var_values[VAR_N] += 1.0;
+    } else {
+        setpts->var_values[VAR_N] += frame->nb_samples;
+    }
 
     setpts->var_values[VAR_PREV_INPTS ] = TS2D(in_pts);
     setpts->var_values[VAR_PREV_INT   ] = TS2T(in_pts, inlink->time_base);
     setpts->var_values[VAR_PREV_OUTPTS] = TS2D(frame->pts);
     setpts->var_values[VAR_PREV_OUTT]   = TS2T(frame->pts, inlink->time_base);
-    setpts->var_values[VAR_N] += 1.0;
     if (setpts->type == AVMEDIA_TYPE_AUDIO) {
         setpts->var_values[VAR_NB_CONSUMED_SAMPLES] += frame->nb_samples;
     }
@@ -207,68 +217,16 @@
     setpts->expr = NULL;
 }
 
-#if CONFIG_ASETPTS_FILTER
-
 #define OFFSET(x) offsetof(SetPTSContext, x)
-#define AFLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
-static const AVOption aoptions[] = {
-    { "expr", "Expression determining the frame timestamp", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "PTS" }, .flags = AFLAGS },
-    { NULL },
-};
-
-static const AVClass asetpts_class = {
-    .class_name = "asetpts",
-    .item_name  = av_default_item_name,
-    .option     = aoptions,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
-
-static const AVFilterPad avfilter_af_asetpts_inputs[] = {
-    {
-        .name             = "default",
-        .type             = AVMEDIA_TYPE_AUDIO,
-        .get_audio_buffer = ff_null_get_audio_buffer,
-        .config_props     = config_input,
-        .filter_frame     = filter_frame,
-    },
-    { NULL }
-};
-
-static const AVFilterPad avfilter_af_asetpts_outputs[] = {
-    {
-        .name = "default",
-        .type = AVMEDIA_TYPE_AUDIO,
-    },
-    { NULL }
-};
-
-AVFilter avfilter_af_asetpts = {
-    .name      = "asetpts",
-    .description = NULL_IF_CONFIG_SMALL("Set PTS for the output audio frame."),
-    .init      = init,
-    .uninit    = uninit,
-    .priv_size = sizeof(SetPTSContext),
-    .priv_class= &asetpts_class,
-    .inputs    = avfilter_af_asetpts_inputs,
-    .outputs   = avfilter_af_asetpts_outputs,
-};
-#endif /* CONFIG_ASETPTS_FILTER */
-
-#if CONFIG_SETPTS_FILTER
-
-#define OFFSET(x) offsetof(SetPTSContext, x)
-#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
 static const AVOption options[] = {
     { "expr", "Expression determining the frame timestamp", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "PTS" }, .flags = FLAGS },
     { NULL },
 };
 
-static const AVClass setpts_class = {
-    .class_name = "setpts",
-    .item_name  = av_default_item_name,
-    .option     = options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
+#if CONFIG_SETPTS_FILTER
+#define setpts_options options
+AVFILTER_DEFINE_CLASS(setpts);
 
 static const AVFilterPad avfilter_vf_setpts_inputs[] = {
     {
@@ -302,3 +260,39 @@
     .outputs   = avfilter_vf_setpts_outputs,
 };
 #endif /* CONFIG_SETPTS_FILTER */
+
+#if CONFIG_ASETPTS_FILTER
+
+#define asetpts_options options
+AVFILTER_DEFINE_CLASS(asetpts);
+
+static const AVFilterPad asetpts_inputs[] = {
+    {
+        .name             = "default",
+        .type             = AVMEDIA_TYPE_AUDIO,
+        .get_audio_buffer = ff_null_get_audio_buffer,
+        .config_props     = config_input,
+        .filter_frame     = filter_frame,
+    },
+    { NULL }
+};
+
+static const AVFilterPad asetpts_outputs[] = {
+    {
+        .name = "default",
+        .type = AVMEDIA_TYPE_AUDIO,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_af_asetpts = {
+    .name        = "asetpts",
+    .description = NULL_IF_CONFIG_SMALL("Set PTS for the output audio frame."),
+    .init        = init,
+    .uninit      = uninit,
+    .priv_size   = sizeof(SetPTSContext),
+    .priv_class  = &asetpts_class,
+    .inputs      = asetpts_inputs,
+    .outputs     = asetpts_outputs,
+};
+#endif /* CONFIG_ASETPTS_FILTER */
diff --git a/libavfilter/split.c b/libavfilter/split.c
index 251ea2e..f3fe233 100644
--- a/libavfilter/split.c
+++ b/libavfilter/split.c
@@ -25,6 +25,7 @@
 
 #include <stdio.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/internal.h"
 #include "libavutil/mem.h"
 #include "libavutil/opt.h"
@@ -39,7 +40,7 @@
     int nb_outputs;
 } SplitContext;
 
-static int split_init(AVFilterContext *ctx)
+static av_cold int split_init(AVFilterContext *ctx)
 {
     SplitContext *s = ctx->priv;
     int i;
@@ -58,7 +59,7 @@
     return 0;
 }
 
-static void split_uninit(AVFilterContext *ctx)
+static av_cold void split_uninit(AVFilterContext *ctx)
 {
     int i;
 
@@ -115,7 +116,7 @@
 
 AVFilter avfilter_vf_split = {
     .name      = "split",
-    .description = NULL_IF_CONFIG_SMALL("Pass on the input video to N outputs."),
+    .description = NULL_IF_CONFIG_SMALL("Pass on the input to N video outputs."),
 
     .priv_size  = sizeof(SplitContext),
     .priv_class = &split_class,
diff --git a/libavfilter/src_movie.c b/libavfilter/src_movie.c
index 7dc4d20..dfb4289 100644
--- a/libavfilter/src_movie.c
+++ b/libavfilter/src_movie.c
@@ -27,9 +27,9 @@
  * @todo support a PTS correction mechanism
  */
 
-/* #define DEBUG */
-
 #include <float.h>
+
+#include "libavutil/attributes.h"
 #include "libavutil/avstring.h"
 #include "libavutil/avassert.h"
 #include "libavutil/opt.h"
@@ -92,13 +92,13 @@
 static AVStream *find_stream(void *log, AVFormatContext *avf, const char *spec)
 {
     int i, ret, already = 0, stream_id = -1;
-    char type_char, dummy;
+    char type_char[2], dummy;
     AVStream *found = NULL;
     enum AVMediaType type;
 
-    ret = sscanf(spec, "d%[av]%d%c", &type_char, &stream_id, &dummy);
+    ret = sscanf(spec, "d%1[av]%d%c", type_char, &stream_id, &dummy);
     if (ret >= 1 && ret <= 2) {
-        type = type_char == 'v' ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
+        type = type_char[0] == 'v' ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
         ret = av_find_best_stream(avf, type, stream_id, -1, NULL, 0);
         if (ret < 0) {
             av_log(log, AV_LOG_ERROR, "No %s stream with index '%d' found\n",
@@ -197,7 +197,7 @@
     char name[16];
     AVStream *st;
 
-    if (!*movie->file_name) {
+    if (!movie->file_name) {
         av_log(ctx, AV_LOG_ERROR, "No filename provided!\n");
         return AVERROR(EINVAL);
     }
@@ -322,7 +322,6 @@
         if (movie->st[i].st)
             avcodec_close(movie->st[i].st->codec);
     }
-    av_freep(&movie->file_name);
     av_freep(&movie->st);
     av_freep(&movie->out_index);
     av_frame_free(&movie->frame);
@@ -515,9 +514,12 @@
     if (ret < 0) {
         av_log(ctx, AV_LOG_WARNING, "Decode error: %s\n", av_err2str(ret));
         av_frame_free(&movie->frame);
+        av_free_packet(&movie->pkt0);
+        movie->pkt.size = 0;
+        movie->pkt.data = NULL;
         return 0;
     }
-    if (!ret)
+    if (!ret || st->st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
         ret = pkt->size;
 
     pkt->data += ret;
@@ -563,17 +565,12 @@
 
 AVFILTER_DEFINE_CLASS(movie);
 
-static av_cold int movie_init(AVFilterContext *ctx)
-{
-    return movie_common_init(ctx);
-}
-
 AVFilter avfilter_avsrc_movie = {
     .name          = "movie",
     .description   = NULL_IF_CONFIG_SMALL("Read from a movie source."),
     .priv_size     = sizeof(MovieContext),
     .priv_class    = &movie_class,
-    .init          = movie_init,
+    .init          = movie_common_init,
     .uninit        = movie_uninit,
     .query_formats = movie_query_formats,
 
@@ -589,16 +586,11 @@
 #define amovie_options movie_options
 AVFILTER_DEFINE_CLASS(amovie);
 
-static av_cold int amovie_init(AVFilterContext *ctx)
-{
-    return movie_common_init(ctx);
-}
-
 AVFilter avfilter_avsrc_amovie = {
     .name          = "amovie",
     .description   = NULL_IF_CONFIG_SMALL("Read audio from a movie source."),
     .priv_size     = sizeof(MovieContext),
-    .init          = amovie_init,
+    .init          = movie_common_init,
     .uninit        = movie_uninit,
     .query_formats = movie_query_formats,
 
diff --git a/libavfilter/thread.h b/libavfilter/thread.h
new file mode 100644
index 0000000..0dc3aaa
--- /dev/null
+++ b/libavfilter/thread.h
@@ -0,0 +1,31 @@
+/*
+ *
+ * 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
+ */
+
+#ifndef AVFILTER_THREAD_H
+#define AVFILTER_THREAD_H
+
+#include "avfilter.h"
+
+typedef int (action_func)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
+
+int ff_graph_thread_init(AVFilterGraph *graph);
+
+void ff_graph_thread_free(AVFilterGraph *graph);
+
+#endif /* AVFILTER_THREAD_H */
diff --git a/libavfilter/trim.c b/libavfilter/trim.c
new file mode 100644
index 0000000..e9f2b20
--- /dev/null
+++ b/libavfilter/trim.c
@@ -0,0 +1,400 @@
+/*
+ * 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
+ */
+
+#include <float.h>
+#include <math.h>
+
+#include "config.h"
+
+#include "libavutil/avassert.h"
+#include "libavutil/channel_layout.h"
+#include "libavutil/common.h"
+#include "libavutil/log.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "libavutil/samplefmt.h"
+
+#include "audio.h"
+#include "avfilter.h"
+#include "internal.h"
+
+typedef struct TrimContext {
+    const AVClass *class;
+
+    /*
+     * AVOptions
+     */
+    int64_t duration;
+    int64_t start_time, end_time;
+    int64_t start_frame, end_frame;
+
+    double duration_dbl;
+    double start_time_dbl, end_time_dbl;
+    /*
+     * in the link timebase for video,
+     * in 1/samplerate for audio
+     */
+    int64_t start_pts, end_pts;
+    int64_t start_sample, end_sample;
+
+    /*
+     * number of video frames that arrived on this filter so far
+     */
+    int64_t nb_frames;
+    /*
+     * number of audio samples that arrived on this filter so far
+     */
+    int64_t nb_samples;
+    /*
+     * timestamp of the first frame in the output, in the timebase units
+     */
+    int64_t first_pts;
+    /*
+     * duration in the timebase units
+     */
+    int64_t duration_tb;
+
+    int64_t next_pts;
+
+    int eof;
+} TrimContext;
+
+static int init(AVFilterContext *ctx)
+{
+    TrimContext *s = ctx->priv;
+
+    s->first_pts = AV_NOPTS_VALUE;
+
+    return 0;
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->dst;
+    TrimContext       *s = ctx->priv;
+    AVRational tb = (inlink->type == AVMEDIA_TYPE_VIDEO) ?
+                     inlink->time_base : (AVRational){ 1, inlink->sample_rate };
+
+    if (s->start_time_dbl != DBL_MAX)
+        s->start_time = s->start_time_dbl * 1e6;
+    if (s->end_time_dbl != DBL_MAX)
+        s->end_time = s->end_time_dbl * 1e6;
+    if (s->duration_dbl != 0)
+        s->duration = s->duration_dbl * 1e6;
+
+    if (s->start_time != INT64_MAX) {
+        int64_t start_pts = av_rescale_q(s->start_time, AV_TIME_BASE_Q, tb);
+        if (s->start_pts == AV_NOPTS_VALUE || start_pts < s->start_pts)
+            s->start_pts = start_pts;
+    }
+    if (s->end_time != INT64_MAX) {
+        int64_t end_pts = av_rescale_q(s->end_time, AV_TIME_BASE_Q, tb);
+        if (s->end_pts == AV_NOPTS_VALUE || end_pts > s->end_pts)
+            s->end_pts = end_pts;
+    }
+    if (s->duration)
+        s->duration_tb = av_rescale_q(s->duration, AV_TIME_BASE_Q, tb);
+
+    return 0;
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+    outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP;
+    return 0;
+}
+
+#define OFFSET(x) offsetof(TrimContext, x)
+#define COMMON_OPTS                                                                                                                                                         \
+    { "starti",      "Timestamp of the first frame that "                                                                                                        \
+        "should be passed",                                              OFFSET(start_time),  AV_OPT_TYPE_DURATION, { .i64 = INT64_MAX },    INT64_MIN, INT64_MAX, FLAGS }, \
+    { "endi",        "Timestamp of the first frame that "                                                                                                        \
+        "should be dropped again",                                       OFFSET(end_time),    AV_OPT_TYPE_DURATION, { .i64 = INT64_MAX },    INT64_MIN, INT64_MAX, FLAGS }, \
+    { "start_pts",   "Timestamp of the first frame that should be "                                                                                                         \
+       " passed",                                                        OFFSET(start_pts),   AV_OPT_TYPE_INT64,  { .i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, FLAGS }, \
+    { "end_pts",     "Timestamp of the first frame that should be "                                                                                                         \
+        "dropped again",                                                 OFFSET(end_pts),     AV_OPT_TYPE_INT64,  { .i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, FLAGS }, \
+    { "durationi",   "Maximum duration of the output",                   OFFSET(duration),    AV_OPT_TYPE_DURATION, { .i64 = 0 },                    0, INT64_MAX, FLAGS },
+
+#define COMPAT_OPTS \
+    { "start",       "Timestamp in seconds of the first frame that "                                                                                                        \
+        "should be passed",                                              OFFSET(start_time_dbl),AV_OPT_TYPE_DOUBLE, { .dbl = DBL_MAX },       -DBL_MAX, DBL_MAX,     FLAGS }, \
+    { "end",         "Timestamp in seconds of the first frame that "                                                                                                        \
+        "should be dropped again",                                       OFFSET(end_time_dbl),  AV_OPT_TYPE_DOUBLE, { .dbl = DBL_MAX },       -DBL_MAX, DBL_MAX,     FLAGS }, \
+    { "duration",    "Maximum duration of the output in seconds",        OFFSET(duration_dbl),  AV_OPT_TYPE_DOUBLE, { .dbl = 0 },                      0,   DBL_MAX, FLAGS },
+
+
+#if CONFIG_TRIM_FILTER
+static int trim_filter_frame(AVFilterLink *inlink, AVFrame *frame)
+{
+    AVFilterContext *ctx = inlink->dst;
+    TrimContext       *s = ctx->priv;
+    int drop;
+
+    /* drop everything if EOF has already been returned */
+    if (s->eof) {
+        av_frame_free(&frame);
+        return 0;
+    }
+
+    if (s->start_frame >= 0 || s->start_pts != AV_NOPTS_VALUE) {
+        drop = 1;
+        if (s->start_frame >= 0 && s->nb_frames >= s->start_frame)
+            drop = 0;
+        if (s->start_pts != AV_NOPTS_VALUE && frame->pts != AV_NOPTS_VALUE &&
+            frame->pts >= s->start_pts)
+            drop = 0;
+        if (drop)
+            goto drop;
+    }
+
+    if (s->first_pts == AV_NOPTS_VALUE && frame->pts != AV_NOPTS_VALUE)
+        s->first_pts = frame->pts;
+
+    if (s->end_frame != INT64_MAX || s->end_pts != AV_NOPTS_VALUE || s->duration_tb) {
+        drop = 1;
+
+        if (s->end_frame != INT64_MAX && s->nb_frames < s->end_frame)
+            drop = 0;
+        if (s->end_pts != AV_NOPTS_VALUE && frame->pts != AV_NOPTS_VALUE &&
+            frame->pts < s->end_pts)
+            drop = 0;
+        if (s->duration_tb && frame->pts != AV_NOPTS_VALUE &&
+            frame->pts - s->first_pts < s->duration_tb)
+            drop = 0;
+
+        if (drop) {
+            s->eof = inlink->closed = 1;
+            goto drop;
+        }
+    }
+
+    s->nb_frames++;
+
+    return ff_filter_frame(ctx->outputs[0], frame);
+
+drop:
+    s->nb_frames++;
+    av_frame_free(&frame);
+    return 0;
+}
+
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
+static const AVOption trim_options[] = {
+    COMMON_OPTS
+    { "start_frame", "Number of the first frame that should be passed "
+        "to the output",                                                 OFFSET(start_frame), AV_OPT_TYPE_INT64,  { .i64 = -1 },       -1, INT64_MAX, FLAGS },
+    { "end_frame",   "Number of the first frame that should be dropped "
+        "again",                                                         OFFSET(end_frame),   AV_OPT_TYPE_INT64,  { .i64 = INT64_MAX }, 0, INT64_MAX, FLAGS },
+    COMPAT_OPTS
+    { NULL },
+};
+#undef FLAGS
+
+AVFILTER_DEFINE_CLASS(trim);
+
+static const AVFilterPad trim_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = trim_filter_frame,
+        .config_props = config_input,
+    },
+    { NULL }
+};
+
+static const AVFilterPad trim_outputs[] = {
+    {
+        .name          = "default",
+        .type          = AVMEDIA_TYPE_VIDEO,
+        .config_props  = config_output,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_trim = {
+    .name        = "trim",
+    .description = NULL_IF_CONFIG_SMALL("Pick one continuous section from the input, drop the rest."),
+
+    .init        = init,
+
+    .priv_size   = sizeof(TrimContext),
+    .priv_class  = &trim_class,
+
+    .inputs      = trim_inputs,
+    .outputs     = trim_outputs,
+};
+#endif // CONFIG_TRIM_FILTER
+
+#if CONFIG_ATRIM_FILTER
+static int atrim_filter_frame(AVFilterLink *inlink, AVFrame *frame)
+{
+    AVFilterContext *ctx = inlink->dst;
+    TrimContext       *s = ctx->priv;
+    int64_t start_sample, end_sample = frame->nb_samples;
+    int64_t pts;
+    int drop;
+
+    /* drop everything if EOF has already been returned */
+    if (s->eof) {
+        av_frame_free(&frame);
+        return 0;
+    }
+
+    if (frame->pts != AV_NOPTS_VALUE)
+        pts = av_rescale_q(frame->pts, inlink->time_base,
+                           (AVRational){ 1, inlink->sample_rate });
+    else
+        pts = s->next_pts;
+    s->next_pts = pts + frame->nb_samples;
+
+    /* check if at least a part of the frame is after the start time */
+    if (s->start_sample < 0 && s->start_pts == AV_NOPTS_VALUE) {
+        start_sample = 0;
+    } else {
+        drop = 1;
+        start_sample = frame->nb_samples;
+
+        if (s->start_sample >= 0 &&
+            s->nb_samples + frame->nb_samples > s->start_sample) {
+            drop         = 0;
+            start_sample = FFMIN(start_sample, s->start_sample - s->nb_samples);
+        }
+
+        if (s->start_pts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE &&
+            pts + frame->nb_samples > s->start_pts) {
+            drop = 0;
+            start_sample = FFMIN(start_sample, s->start_pts - pts);
+        }
+
+        if (drop)
+            goto drop;
+    }
+
+    if (s->first_pts == AV_NOPTS_VALUE)
+        s->first_pts = pts + start_sample;
+
+    /* check if at least a part of the frame is before the end time */
+    if (s->end_sample == INT64_MAX && s->end_pts == AV_NOPTS_VALUE && !s->duration_tb) {
+        end_sample = frame->nb_samples;
+    } else {
+        drop       = 1;
+        end_sample = 0;
+
+        if (s->end_sample != INT64_MAX &&
+            s->nb_samples < s->end_sample) {
+            drop       = 0;
+            end_sample = FFMAX(end_sample, s->end_sample - s->nb_samples);
+        }
+
+        if (s->end_pts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE &&
+            pts < s->end_pts) {
+            drop       = 0;
+            end_sample = FFMAX(end_sample, s->end_pts - pts);
+        }
+
+        if (s->duration_tb && pts - s->first_pts < s->duration_tb) {
+            drop       = 0;
+            end_sample = FFMAX(end_sample, s->first_pts + s->duration_tb - pts);
+        }
+
+        if (drop) {
+            s->eof = inlink->closed = 1;
+            goto drop;
+        }
+    }
+
+    s->nb_samples += frame->nb_samples;
+    start_sample   = FFMAX(0, start_sample);
+    end_sample     = FFMIN(frame->nb_samples, end_sample);
+    av_assert0(start_sample < end_sample || (start_sample == end_sample && !frame->nb_samples));
+
+    if (start_sample) {
+        AVFrame *out = ff_get_audio_buffer(ctx->outputs[0], end_sample - start_sample);
+        if (!out) {
+            av_frame_free(&frame);
+            return AVERROR(ENOMEM);
+        }
+
+        av_frame_copy_props(out, frame);
+        av_samples_copy(out->extended_data, frame->extended_data, 0, start_sample,
+                        out->nb_samples, inlink->channels,
+                        frame->format);
+        if (out->pts != AV_NOPTS_VALUE)
+            out->pts += av_rescale_q(start_sample, (AVRational){ 1, out->sample_rate },
+                                     inlink->time_base);
+
+        av_frame_free(&frame);
+        frame = out;
+    } else
+        frame->nb_samples = end_sample;
+
+    return ff_filter_frame(ctx->outputs[0], frame);
+
+drop:
+    s->nb_samples += frame->nb_samples;
+    av_frame_free(&frame);
+    return 0;
+}
+
+#define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
+static const AVOption atrim_options[] = {
+    COMMON_OPTS
+    { "start_sample", "Number of the first audio sample that should be "
+        "passed to the output",                                          OFFSET(start_sample), AV_OPT_TYPE_INT64,  { .i64 = -1 },       -1, INT64_MAX, FLAGS },
+    { "end_sample",   "Number of the first audio sample that should be "
+        "dropped again",                                                 OFFSET(end_sample),   AV_OPT_TYPE_INT64,  { .i64 = INT64_MAX }, 0, INT64_MAX, FLAGS },
+    COMPAT_OPTS
+    { NULL },
+};
+#undef FLAGS
+
+AVFILTER_DEFINE_CLASS(atrim);
+
+static const AVFilterPad atrim_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_AUDIO,
+        .filter_frame = atrim_filter_frame,
+        .config_props = config_input,
+    },
+    { NULL }
+};
+
+static const AVFilterPad atrim_outputs[] = {
+    {
+        .name          = "default",
+        .type          = AVMEDIA_TYPE_AUDIO,
+        .config_props  = config_output,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_af_atrim = {
+    .name        = "atrim",
+    .description = NULL_IF_CONFIG_SMALL("Pick one continuous section from the input, drop the rest."),
+
+    .init        = init,
+
+    .priv_size   = sizeof(TrimContext),
+    .priv_class  = &atrim_class,
+
+    .inputs      = atrim_inputs,
+    .outputs     = atrim_outputs,
+};
+#endif // CONFIG_ATRIM_FILTER
diff --git a/libavfilter/unsharp.h b/libavfilter/unsharp.h
new file mode 100644
index 0000000..c225929
--- /dev/null
+++ b/libavfilter/unsharp.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2013 Wei Gao <weigao@multicorewareinc.com>
+ *
+ * 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
+ */
+
+#ifndef AVFILTER_UNSHARP_H
+#define AVFILTER_UNSHARP_H
+
+#include "config.h"
+#include "avfilter.h"
+#if CONFIG_OPENCL
+#include "libavutil/opencl.h"
+#endif
+
+#define MIN_MATRIX_SIZE 3
+#define MAX_MATRIX_SIZE 63
+
+#if CONFIG_OPENCL
+
+typedef struct {
+    cl_mem cl_luma_mask;
+    cl_mem cl_chroma_mask;
+    int in_plane_size[8];
+    int out_plane_size[8];
+    int plane_num;
+    cl_mem cl_inbuf;
+    size_t cl_inbuf_size;
+    cl_mem cl_outbuf;
+    size_t cl_outbuf_size;
+    AVOpenCLKernelEnv kernel_env;
+} UnsharpOpenclContext;
+
+#endif
+
+typedef struct UnsharpFilterParam {
+    int msize_x;                             ///< matrix width
+    int msize_y;                             ///< matrix height
+    int amount;                              ///< effect amount
+    int steps_x;                             ///< horizontal step count
+    int steps_y;                             ///< vertical step count
+    int scalebits;                           ///< bits to shift pixel
+    int32_t halfscale;                       ///< amount to add to pixel
+    uint32_t *sc[MAX_MATRIX_SIZE - 1];       ///< finite state machine storage
+} UnsharpFilterParam;
+
+typedef struct {
+    const AVClass *class;
+    int lmsize_x, lmsize_y, cmsize_x, cmsize_y;
+    float lamount, camount;
+    UnsharpFilterParam luma;   ///< luma parameters (width, height, amount)
+    UnsharpFilterParam chroma; ///< chroma parameters (width, height, amount)
+    int hsub, vsub;
+    int opencl;
+#if CONFIG_OPENCL
+    UnsharpOpenclContext opencl_ctx;
+#endif
+    int (* apply_unsharp)(AVFilterContext *ctx, AVFrame *in, AVFrame *out);
+} UnsharpContext;
+
+#endif /* AVFILTER_UNSHARP_H */
diff --git a/libavfilter/unsharp_opencl.c b/libavfilter/unsharp_opencl.c
new file mode 100644
index 0000000..b373b66
--- /dev/null
+++ b/libavfilter/unsharp_opencl.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2013 Wei Gao <weigao@multicorewareinc.com>
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * unsharp input video
+ */
+
+#include "unsharp_opencl.h"
+#include "libavutil/common.h"
+#include "libavutil/opencl_internal.h"
+
+#define PLANE_NUM 3
+
+static inline void add_mask_counter(uint32_t *dst, uint32_t *counter1, uint32_t *counter2, int len)
+{
+    int i;
+    for (i = 0; i < len; i++) {
+        dst[i] = counter1[i] + counter2[i];
+    }
+}
+
+static int compute_mask(int step, uint32_t *mask)
+{
+    int i, z, ret = 0;
+    int counter_size = sizeof(uint32_t) * (2 * step + 1);
+    uint32_t *temp1_counter, *temp2_counter, **counter;
+    temp1_counter = av_mallocz(counter_size);
+    if (!temp1_counter) {
+        ret = AVERROR(ENOMEM);
+        goto end;
+    }
+    temp2_counter = av_mallocz(counter_size);
+    if (!temp2_counter) {
+        ret = AVERROR(ENOMEM);
+        goto end;
+    }
+    counter = av_mallocz(sizeof(uint32_t *) * (2 * step + 1));
+    if (!counter) {
+        ret = AVERROR(ENOMEM);
+        goto end;
+    }
+    for (i = 0; i < 2 * step + 1; i++) {
+        counter[i] = av_mallocz(counter_size);
+        if (!counter[i]) {
+            ret = AVERROR(ENOMEM);
+            goto end;
+        }
+    }
+    for (i = 0; i < 2 * step + 1; i++) {
+        memset(temp1_counter, 0, counter_size);
+        temp1_counter[i] = 1;
+        for (z = 0; z < step * 2; z += 2) {
+            add_mask_counter(temp2_counter, counter[z], temp1_counter, step * 2);
+            memcpy(counter[z], temp1_counter, counter_size);
+            add_mask_counter(temp1_counter, counter[z + 1], temp2_counter, step * 2);
+            memcpy(counter[z + 1], temp2_counter, counter_size);
+        }
+    }
+    memcpy(mask, temp1_counter, counter_size);
+end:
+    av_freep(&temp1_counter);
+    av_freep(&temp2_counter);
+    for (i = 0; i < 2 * step + 1; i++) {
+        av_freep(&counter[i]);
+    }
+    av_freep(&counter);
+    return ret;
+}
+
+static int compute_mask_matrix(cl_mem cl_mask_matrix, int step_x, int step_y)
+{
+    int i, j, ret = 0;
+    uint32_t *mask_matrix, *mask_x, *mask_y;
+    size_t size_matrix = sizeof(uint32_t) * (2 * step_x + 1) * (2 * step_y + 1);
+    mask_x = av_mallocz(sizeof(uint32_t) * (2 * step_x + 1));
+    if (!mask_x) {
+        ret = AVERROR(ENOMEM);
+        goto end;
+    }
+    mask_y = av_mallocz(sizeof(uint32_t) * (2 * step_y + 1));
+    if (!mask_y) {
+        ret = AVERROR(ENOMEM);
+        goto end;
+    }
+    mask_matrix = av_mallocz(size_matrix);
+    if (!mask_matrix) {
+        ret = AVERROR(ENOMEM);
+        goto end;
+    }
+    ret = compute_mask(step_x, mask_x);
+    if (ret < 0)
+        goto end;
+    ret = compute_mask(step_y, mask_y);
+    if (ret < 0)
+        goto end;
+    for (j = 0; j < 2 * step_y + 1; j++) {
+        for (i = 0; i < 2 * step_x + 1; i++) {
+            mask_matrix[i + j * (2 * step_x + 1)] = mask_y[j] * mask_x[i];
+        }
+    }
+    ret = av_opencl_buffer_write(cl_mask_matrix, (uint8_t *)mask_matrix, size_matrix);
+end:
+    av_freep(&mask_x);
+    av_freep(&mask_y);
+    av_freep(&mask_matrix);
+    return ret;
+}
+
+static int generate_mask(AVFilterContext *ctx)
+{
+    UnsharpContext *unsharp = ctx->priv;
+    int i, ret = 0, step_x[2], step_y[2];
+    cl_mem mask_matrix[2];
+    mask_matrix[0] = unsharp->opencl_ctx.cl_luma_mask;
+    mask_matrix[1] = unsharp->opencl_ctx.cl_chroma_mask;
+    step_x[0] = unsharp->luma.steps_x;
+    step_x[1] = unsharp->chroma.steps_x;
+    step_y[0] = unsharp->luma.steps_y;
+    step_y[1] = unsharp->chroma.steps_y;
+    if (!mask_matrix[0] || !mask_matrix[1]) {
+        av_log(ctx, AV_LOG_ERROR, "Luma mask and chroma mask should not be NULL\n");
+        return AVERROR(EINVAL);
+    }
+    for (i = 0; i < 2; i++) {
+        ret = compute_mask_matrix(mask_matrix[i], step_x[i], step_y[i]);
+        if (ret < 0)
+            return ret;
+    }
+    return ret;
+}
+
+int ff_opencl_apply_unsharp(AVFilterContext *ctx, AVFrame *in, AVFrame *out)
+{
+    int ret;
+    AVFilterLink *link = ctx->inputs[0];
+    UnsharpContext *unsharp = ctx->priv;
+    cl_int status;
+    int cw = FF_CEIL_RSHIFT(link->w, unsharp->hsub);
+    int ch = FF_CEIL_RSHIFT(link->h, unsharp->vsub);
+    const size_t global_work_size = link->w * link->h + 2 * ch * cw;
+    FFOpenclParam opencl_param = {0};
+
+    opencl_param.ctx = ctx;
+    opencl_param.kernel = unsharp->opencl_ctx.kernel_env.kernel;
+    ret = ff_opencl_set_parameter(&opencl_param,
+                                  FF_OPENCL_PARAM_INFO(unsharp->opencl_ctx.cl_inbuf),
+                                  FF_OPENCL_PARAM_INFO(unsharp->opencl_ctx.cl_outbuf),
+                                  FF_OPENCL_PARAM_INFO(unsharp->opencl_ctx.cl_luma_mask),
+                                  FF_OPENCL_PARAM_INFO(unsharp->opencl_ctx.cl_chroma_mask),
+                                  FF_OPENCL_PARAM_INFO(unsharp->luma.amount),
+                                  FF_OPENCL_PARAM_INFO(unsharp->chroma.amount),
+                                  FF_OPENCL_PARAM_INFO(unsharp->luma.steps_x),
+                                  FF_OPENCL_PARAM_INFO(unsharp->luma.steps_y),
+                                  FF_OPENCL_PARAM_INFO(unsharp->chroma.steps_x),
+                                  FF_OPENCL_PARAM_INFO(unsharp->chroma.steps_y),
+                                  FF_OPENCL_PARAM_INFO(unsharp->luma.scalebits),
+                                  FF_OPENCL_PARAM_INFO(unsharp->chroma.scalebits),
+                                  FF_OPENCL_PARAM_INFO(unsharp->luma.halfscale),
+                                  FF_OPENCL_PARAM_INFO(unsharp->chroma.halfscale),
+                                  FF_OPENCL_PARAM_INFO(in->linesize[0]),
+                                  FF_OPENCL_PARAM_INFO(in->linesize[1]),
+                                  FF_OPENCL_PARAM_INFO(out->linesize[0]),
+                                  FF_OPENCL_PARAM_INFO(out->linesize[1]),
+                                  FF_OPENCL_PARAM_INFO(link->h),
+                                  FF_OPENCL_PARAM_INFO(link->w),
+                                  FF_OPENCL_PARAM_INFO(ch),
+                                  FF_OPENCL_PARAM_INFO(cw),
+                                  NULL);
+    if (ret < 0)
+        return ret;
+    status = clEnqueueNDRangeKernel(unsharp->opencl_ctx.kernel_env.command_queue,
+                                    unsharp->opencl_ctx.kernel_env.kernel, 1, NULL,
+                                    &global_work_size, NULL, 0, NULL, NULL);
+    if (status != CL_SUCCESS) {
+        av_log(ctx, AV_LOG_ERROR, "OpenCL run kernel error occurred: %s\n", av_opencl_errstr(status));
+        return AVERROR_EXTERNAL;
+    }
+    clFinish(unsharp->opencl_ctx.kernel_env.command_queue);
+    return av_opencl_buffer_read_image(out->data, unsharp->opencl_ctx.out_plane_size,
+                                       unsharp->opencl_ctx.plane_num, unsharp->opencl_ctx.cl_outbuf,
+                                       unsharp->opencl_ctx.cl_outbuf_size);
+}
+
+int ff_opencl_unsharp_init(AVFilterContext *ctx)
+{
+    int ret = 0;
+    UnsharpContext *unsharp = ctx->priv;
+    ret = av_opencl_init(NULL);
+    if (ret < 0)
+        return ret;
+    ret = av_opencl_buffer_create(&unsharp->opencl_ctx.cl_luma_mask,
+                                  sizeof(uint32_t) * (2 * unsharp->luma.steps_x + 1) * (2 * unsharp->luma.steps_y + 1),
+                                  CL_MEM_READ_ONLY, NULL);
+    if (ret < 0)
+        return ret;
+    ret = av_opencl_buffer_create(&unsharp->opencl_ctx.cl_chroma_mask,
+                                  sizeof(uint32_t) * (2 * unsharp->chroma.steps_x + 1) * (2 * unsharp->chroma.steps_y + 1),
+                                  CL_MEM_READ_ONLY, NULL);
+    if (ret < 0)
+        return ret;
+    ret = generate_mask(ctx);
+    if (ret < 0)
+        return ret;
+    unsharp->opencl_ctx.plane_num = PLANE_NUM;
+    if (!unsharp->opencl_ctx.kernel_env.kernel) {
+        ret = av_opencl_create_kernel(&unsharp->opencl_ctx.kernel_env, "unsharp");
+        if (ret < 0) {
+            av_log(ctx, AV_LOG_ERROR, "OpenCL failed to create kernel with name 'unsharp'\n");
+            return ret;
+        }
+    }
+    return ret;
+}
+
+void ff_opencl_unsharp_uninit(AVFilterContext *ctx)
+{
+    UnsharpContext *unsharp = ctx->priv;
+    av_opencl_buffer_release(&unsharp->opencl_ctx.cl_inbuf);
+    av_opencl_buffer_release(&unsharp->opencl_ctx.cl_outbuf);
+    av_opencl_buffer_release(&unsharp->opencl_ctx.cl_luma_mask);
+    av_opencl_buffer_release(&unsharp->opencl_ctx.cl_chroma_mask);
+    av_opencl_release_kernel(&unsharp->opencl_ctx.kernel_env);
+    av_opencl_uninit();
+}
+
+int ff_opencl_unsharp_process_inout_buf(AVFilterContext *ctx, AVFrame *in, AVFrame *out)
+{
+    int ret = 0;
+    AVFilterLink *link = ctx->inputs[0];
+    UnsharpContext *unsharp = ctx->priv;
+    int ch = FF_CEIL_RSHIFT(link->h, unsharp->vsub);
+
+    if ((!unsharp->opencl_ctx.cl_inbuf) || (!unsharp->opencl_ctx.cl_outbuf)) {
+        unsharp->opencl_ctx.in_plane_size[0]  = (in->linesize[0] * in->height);
+        unsharp->opencl_ctx.in_plane_size[1]  = (in->linesize[1] * ch);
+        unsharp->opencl_ctx.in_plane_size[2]  = (in->linesize[2] * ch);
+        unsharp->opencl_ctx.out_plane_size[0] = (out->linesize[0] * out->height);
+        unsharp->opencl_ctx.out_plane_size[1] = (out->linesize[1] * ch);
+        unsharp->opencl_ctx.out_plane_size[2] = (out->linesize[2] * ch);
+        unsharp->opencl_ctx.cl_inbuf_size  = unsharp->opencl_ctx.in_plane_size[0] +
+                                             unsharp->opencl_ctx.in_plane_size[1] +
+                                             unsharp->opencl_ctx.in_plane_size[2];
+        unsharp->opencl_ctx.cl_outbuf_size = unsharp->opencl_ctx.out_plane_size[0] +
+                                             unsharp->opencl_ctx.out_plane_size[1] +
+                                             unsharp->opencl_ctx.out_plane_size[2];
+        if (!unsharp->opencl_ctx.cl_inbuf) {
+            ret = av_opencl_buffer_create(&unsharp->opencl_ctx.cl_inbuf,
+                                          unsharp->opencl_ctx.cl_inbuf_size,
+                                          CL_MEM_READ_ONLY, NULL);
+            if (ret < 0)
+                return ret;
+        }
+        if (!unsharp->opencl_ctx.cl_outbuf) {
+            ret = av_opencl_buffer_create(&unsharp->opencl_ctx.cl_outbuf,
+                                          unsharp->opencl_ctx.cl_outbuf_size,
+                                          CL_MEM_READ_WRITE, NULL);
+            if (ret < 0)
+                return ret;
+        }
+    }
+    return av_opencl_buffer_write_image(unsharp->opencl_ctx.cl_inbuf,
+                                        unsharp->opencl_ctx.cl_inbuf_size,
+                                        0, in->data, unsharp->opencl_ctx.in_plane_size,
+                                        unsharp->opencl_ctx.plane_num);
+}
diff --git a/libavfilter/unsharp_opencl.h b/libavfilter/unsharp_opencl.h
new file mode 100644
index 0000000..3aefab6
--- /dev/null
+++ b/libavfilter/unsharp_opencl.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2013 Wei Gao <weigao@multicorewareinc.com>
+ *
+ * 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
+ */
+
+#ifndef AVFILTER_UNSHARP_OPENCL_H
+#define AVFILTER_UNSHARP_OPENCL_H
+
+#include "unsharp.h"
+
+int ff_opencl_unsharp_init(AVFilterContext *ctx);
+
+void ff_opencl_unsharp_uninit(AVFilterContext *ctx);
+
+int ff_opencl_unsharp_process_inout_buf(AVFilterContext *ctx, AVFrame *in, AVFrame *out);
+
+int ff_opencl_apply_unsharp(AVFilterContext *ctx, AVFrame *in, AVFrame *out);
+
+#endif /* AVFILTER_UNSHARP_OPENCL_H */
diff --git a/libavfilter/unsharp_opencl_kernel.h b/libavfilter/unsharp_opencl_kernel.h
new file mode 100644
index 0000000..0cc8e90
--- /dev/null
+++ b/libavfilter/unsharp_opencl_kernel.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2013 Wei Gao <weigao@multicorewareinc.com>
+ *
+ * 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
+ */
+
+#ifndef AVFILTER_UNSHARP_OPENCL_KERNEL_H
+#define AVFILTER_UNSHARP_OPENCL_KERNEL_H
+
+#include "libavutil/opencl.h"
+
+const char *ff_kernel_unsharp_opencl = AV_OPENCL_KERNEL(
+inline unsigned char clip_uint8(int a)
+{
+    if (a & (~0xFF))
+        return (-a)>>31;
+    else
+        return a;
+}
+
+kernel void unsharp(global  unsigned char *src,
+                    global  unsigned char *dst,
+                    const global  unsigned int *mask_lu,
+                    const global  unsigned int *mask_ch,
+                    int amount_lu,
+                    int amount_ch,
+                    int step_x_lu,
+                    int step_y_lu,
+                    int step_x_ch,
+                    int step_y_ch,
+                    int scalebits_lu,
+                    int scalebits_ch,
+                    int halfscale_lu,
+                    int halfscale_ch,
+                    int src_stride_lu,
+                    int src_stride_ch,
+                    int dst_stride_lu,
+                    int dst_stride_ch,
+                    int height,
+                    int width,
+                    int ch,
+                    int cw)
+{
+    global unsigned char *dst_y = dst;
+    global unsigned char *dst_u = dst_y + height * dst_stride_lu;
+    global unsigned char *dst_v = dst_u + ch * dst_stride_ch;
+
+    global unsigned char *src_y = src;
+    global unsigned char *src_u = src_y + height * src_stride_lu;
+    global unsigned char *src_v = src_u + ch * src_stride_ch;
+
+    global unsigned char *temp_dst;
+    global unsigned char *temp_src;
+    const global unsigned int *temp_mask;
+    int global_id = get_global_id(0);
+    int i, j, x, y, temp_src_stride, temp_dst_stride, temp_height, temp_width, temp_steps_x, temp_steps_y,
+        temp_amount, temp_scalebits, temp_halfscale, sum, idx_x, idx_y, temp, res;
+    if (global_id < width * height) {
+        y = global_id / width;
+        x = global_id % width;
+        temp_dst = dst_y;
+        temp_src = src_y;
+        temp_src_stride = src_stride_lu;
+        temp_dst_stride = dst_stride_lu;
+        temp_height = height;
+        temp_width = width;
+        temp_steps_x = step_x_lu;
+        temp_steps_y = step_y_lu;
+        temp_mask = mask_lu;
+        temp_amount = amount_lu;
+        temp_scalebits = scalebits_lu;
+        temp_halfscale = halfscale_lu;
+    } else if ((global_id >= width * height) && (global_id < width * height + ch * cw)) {
+        y = (global_id - width * height) / cw;
+        x = (global_id - width * height) % cw;
+        temp_dst = dst_u;
+        temp_src = src_u;
+        temp_src_stride = src_stride_ch;
+        temp_dst_stride = dst_stride_ch;
+        temp_height = ch;
+        temp_width = cw;
+        temp_steps_x = step_x_ch;
+        temp_steps_y = step_y_ch;
+        temp_mask = mask_ch;
+        temp_amount = amount_ch;
+        temp_scalebits = scalebits_ch;
+        temp_halfscale = halfscale_ch;
+    } else {
+        y = (global_id - width * height - ch * cw) / cw;
+        x = (global_id - width * height - ch * cw) % cw;
+        temp_dst = dst_v;
+        temp_src = src_v;
+        temp_src_stride = src_stride_ch;
+        temp_dst_stride = dst_stride_ch;
+        temp_height = ch;
+        temp_width = cw;
+        temp_steps_x = step_x_ch;
+        temp_steps_y = step_y_ch;
+        temp_mask = mask_ch;
+        temp_amount = amount_ch;
+        temp_scalebits = scalebits_ch;
+        temp_halfscale = halfscale_ch;
+    }
+    if (temp_amount) {
+        sum = 0;
+        for (j = 0; j <= 2 * temp_steps_y; j++) {
+            idx_y = (y - temp_steps_y + j) <= 0 ? 0 : (y - temp_steps_y + j) >= temp_height ? temp_height-1 : y - temp_steps_y + j;
+            for (i = 0; i <= 2 * temp_steps_x; i++) {
+                idx_x = (x - temp_steps_x + i) <= 0 ? 0 : (x - temp_steps_x + i) >= temp_width ? temp_width-1 : x - temp_steps_x + i;
+                sum += temp_mask[i + j * (2 * temp_steps_x + 1)] * temp_src[idx_x + idx_y * temp_src_stride];
+            }
+        }
+        temp = (int)temp_src[x + y * temp_src_stride];
+        res = temp + (((temp - (int)((sum + temp_halfscale) >> temp_scalebits)) * temp_amount) >> 16);
+        temp_dst[x + y * temp_dst_stride] = clip_uint8(res);
+    } else {
+        temp_dst[x + y * temp_dst_stride] = temp_src[x + y * temp_src_stride];
+    }
+}
+
+);
+
+#endif /* AVFILTER_UNSHARP_OPENCL_KERNEL_H */
diff --git a/libavfilter/version.h b/libavfilter/version.h
index 9e8e83a..20ff257 100644
--- a/libavfilter/version.h
+++ b/libavfilter/version.h
@@ -23,14 +23,15 @@
 
 /**
  * @file
+ * @ingroup lavfi
  * Libavfilter version macros
  */
 
 #include "libavutil/avutil.h"
 
 #define LIBAVFILTER_VERSION_MAJOR  3
-#define LIBAVFILTER_VERSION_MINOR  60
-#define LIBAVFILTER_VERSION_MICRO 101
+#define LIBAVFILTER_VERSION_MINOR  82
+#define LIBAVFILTER_VERSION_MICRO 102
 
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
                                                LIBAVFILTER_VERSION_MINOR, \
@@ -78,5 +79,8 @@
 #ifndef FF_API_OLD_FILTER_REGISTER
 #define FF_API_OLD_FILTER_REGISTER          (LIBAVFILTER_VERSION_MAJOR < 4)
 #endif
+#ifndef FF_API_OLD_GRAPH_PARSE
+#define FF_API_OLD_GRAPH_PARSE              (LIBAVFILTER_VERSION_MAJOR < 4)
+#endif
 
 #endif /* AVFILTER_VERSION_H */
diff --git a/libavfilter/vf_alphaextract.c b/libavfilter/vf_alphaextract.c
deleted file mode 100644
index 62ceecf..0000000
--- a/libavfilter/vf_alphaextract.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2012 Steven Robertson
- *
- * 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
- */
-
-/**
- * @file
- * simple channel-swapping filter to get at the alpha component
- */
-
-#include <string.h>
-
-#include "libavutil/pixfmt.h"
-#include "avfilter.h"
-#include "drawutils.h"
-#include "internal.h"
-#include "formats.h"
-#include "video.h"
-
-enum { Y, U, V, A };
-
-typedef struct {
-    int is_packed_rgb;
-    uint8_t rgba_map[4];
-} AlphaExtractContext;
-
-static int query_formats(AVFilterContext *ctx)
-{
-    static const enum AVPixelFormat in_fmts[] = {
-        AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P,
-        AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR,
-        AV_PIX_FMT_NONE
-    };
-    static const enum AVPixelFormat out_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE };
-    ff_formats_ref(ff_make_format_list(in_fmts), &ctx->inputs[0]->out_formats);
-    ff_formats_ref(ff_make_format_list(out_fmts), &ctx->outputs[0]->in_formats);
-    return 0;
-}
-
-static int config_input(AVFilterLink *inlink)
-{
-    AlphaExtractContext *extract = inlink->dst->priv;
-    extract->is_packed_rgb =
-        ff_fill_rgba_map(extract->rgba_map, inlink->format) >= 0;
-    return 0;
-}
-
-static int filter_frame(AVFilterLink *inlink, AVFrame *cur_buf)
-{
-    AlphaExtractContext *extract = inlink->dst->priv;
-    AVFilterLink *outlink = inlink->dst->outputs[0];
-    AVFrame *out_buf = ff_get_video_buffer(outlink, outlink->w, outlink->h);
-    int ret;
-
-    if (!out_buf) {
-        ret = AVERROR(ENOMEM);
-        goto end;
-    }
-    av_frame_copy_props(out_buf, cur_buf);
-
-    if (extract->is_packed_rgb) {
-        int x, y;
-        uint8_t *pcur, *pout;
-        for (y = 0; y < outlink->h; y++) {
-            pcur = cur_buf->data[0] + y * cur_buf->linesize[0] + extract->rgba_map[A];
-            pout = out_buf->data[0] + y * out_buf->linesize[0];
-            for (x = 0; x < outlink->w; x++) {
-                *pout = *pcur;
-                pout += 1;
-                pcur += 4;
-            }
-        }
-    } else {
-        const int linesize = abs(FFMIN(out_buf->linesize[Y], cur_buf->linesize[A]));
-        int y;
-        for (y = 0; y < outlink->h; y++) {
-            memcpy(out_buf->data[Y] + y * out_buf->linesize[Y],
-                   cur_buf->data[A] + y * cur_buf->linesize[A],
-                   linesize);
-        }
-    }
-
-    ret = ff_filter_frame(outlink, out_buf);
-
-end:
-    av_frame_free(&cur_buf);
-    return ret;
-}
-
-static const AVFilterPad alphaextract_inputs[] = {
-    {
-        .name         = "default",
-        .type         = AVMEDIA_TYPE_VIDEO,
-        .config_props = config_input,
-        .filter_frame = filter_frame,
-    },
-    { NULL }
-};
-
-static const AVFilterPad alphaextract_outputs[] = {
-    {
-        .name = "default",
-        .type = AVMEDIA_TYPE_VIDEO,
-    },
-    { NULL }
-};
-
-AVFilter avfilter_vf_alphaextract = {
-    .name           = "alphaextract",
-    .description    = NULL_IF_CONFIG_SMALL("Extract an alpha channel as a "
-                      "grayscale image component."),
-    .priv_size      = sizeof(AlphaExtractContext),
-    .query_formats  = query_formats,
-    .inputs         = alphaextract_inputs,
-    .outputs        = alphaextract_outputs,
-};
diff --git a/libavfilter/vf_aspect.c b/libavfilter/vf_aspect.c
index 25dde7f..22d6c70 100644
--- a/libavfilter/vf_aspect.c
+++ b/libavfilter/vf_aspect.c
@@ -37,7 +37,8 @@
 
 typedef struct {
     const AVClass *class;
-    AVRational aspect;
+    AVRational dar;
+    AVRational sar;
     int max;
 #if FF_API_OLD_FILTER_OPTS
     float aspect_den;
@@ -61,25 +62,26 @@
             av_log(ctx, AV_LOG_ERROR, "Unable to parse ratio numerator \"%s\"\n", s->ratio_str);
             return AVERROR(EINVAL);
         }
-        s->aspect = av_d2q(num / s->aspect_den, s->max);
+        s->sar = s->dar = av_d2q(num / s->aspect_den, s->max);
     } else
 #endif
     if (s->ratio_str) {
-        ret = av_parse_ratio(&s->aspect, s->ratio_str, s->max, 0, ctx);
-        if (ret < 0 || s->aspect.num < 0 || s->aspect.den <= 0) {
+        ret = av_parse_ratio(&s->sar, s->ratio_str, s->max, 0, ctx);
+        if (ret < 0 || s->sar.num < 0 || s->sar.den <= 0) {
             av_log(ctx, AV_LOG_ERROR,
                    "Invalid string '%s' for aspect ratio\n", s->ratio_str);
             return AVERROR(EINVAL);
         }
+        s->dar = s->sar;
     }
     return 0;
 }
 
 static int filter_frame(AVFilterLink *link, AVFrame *frame)
 {
-    AspectContext *aspect = link->dst->priv;
+    AspectContext *s = link->dst->priv;
 
-    frame->sample_aspect_ratio = aspect->aspect;
+    frame->sample_aspect_ratio = s->sar;
     return ff_filter_frame(link->dst->outputs[0], frame);
 }
 
@@ -99,15 +101,17 @@
 
 static int setdar_config_props(AVFilterLink *inlink)
 {
-    AspectContext *aspect = inlink->dst->priv;
-    AVRational dar = aspect->aspect, old_dar;
+    AspectContext *s = inlink->dst->priv;
+    AVRational dar;
+    AVRational old_dar;
     AVRational old_sar = inlink->sample_aspect_ratio;
 
-    if (aspect->aspect.num && aspect->aspect.den) {
-        av_reduce(&aspect->aspect.num, &aspect->aspect.den,
-                   aspect->aspect.num * inlink->h,
-                   aspect->aspect.den * inlink->w, INT_MAX);
-        inlink->sample_aspect_ratio = aspect->aspect;
+    if (s->dar.num && s->dar.den) {
+        av_reduce(&s->sar.num, &s->sar.den,
+                   s->dar.num * inlink->h,
+                   s->dar.den * inlink->w, INT_MAX);
+        inlink->sample_aspect_ratio = s->sar;
+        dar = s->dar;
     } else {
         inlink->sample_aspect_ratio = (AVRational){ 1, 1 };
         dar = (AVRational){ inlink->w, inlink->h };
@@ -171,14 +175,14 @@
 
 static int setsar_config_props(AVFilterLink *inlink)
 {
-    AspectContext *aspect = inlink->dst->priv;
+    AspectContext *s = inlink->dst->priv;
     AVRational old_sar = inlink->sample_aspect_ratio;
     AVRational old_dar, dar;
 
-    inlink->sample_aspect_ratio = aspect->aspect;
+    inlink->sample_aspect_ratio = s->sar;
 
     compute_dar(&old_dar, old_sar, inlink->w, inlink->h);
-    compute_dar(&dar, aspect->aspect, inlink->w, inlink->h);
+    compute_dar(&dar, s->sar, inlink->w, inlink->h);
     av_log(inlink->dst, AV_LOG_VERBOSE, "w:%d h:%d sar:%d/%d dar:%d/%d -> sar:%d/%d dar:%d/%d\n",
            inlink->w, inlink->h, old_sar.num, old_sar.den, old_dar.num, old_dar.den,
            inlink->sample_aspect_ratio.num, inlink->sample_aspect_ratio.den, dar.num, dar.den);
diff --git a/libavfilter/vf_bbox.c b/libavfilter/vf_bbox.c
index 6b4cdd0..a29627d 100644
--- a/libavfilter/vf_bbox.c
+++ b/libavfilter/vf_bbox.c
@@ -23,6 +23,7 @@
  * bounding box detection filter
  */
 
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/timestamp.h"
 #include "avfilter.h"
@@ -30,9 +31,20 @@
 #include "internal.h"
 
 typedef struct {
-    unsigned int frame;
+    const AVClass *class;
+    int min_val;
 } BBoxContext;
 
+#define OFFSET(x) offsetof(BBoxContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption bbox_options[] = {
+    { "min_val", "set minimum luminance value for bounding box", OFFSET(min_val), AV_OPT_TYPE_INT, { .i64 = 16 }, 0, 254, FLAGS },
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(bbox);
+
 static int query_formats(AVFilterContext *ctx)
 {
     static const enum AVPixelFormat pix_fmts[] = {
@@ -48,25 +60,39 @@
     return 0;
 }
 
+#define SET_META(key, value) \
+    snprintf(buf, sizeof(buf), "%d", value);  \
+    av_dict_set(metadata, key, buf, 0);
+
 static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
 {
     AVFilterContext *ctx = inlink->dst;
     BBoxContext *bbox = ctx->priv;
     FFBoundingBox box;
     int has_bbox, w, h;
+    char buf[32];
 
     has_bbox =
         ff_calculate_bounding_box(&box,
                                   frame->data[0], frame->linesize[0],
-                                  inlink->w, inlink->h, 16);
+                                  inlink->w, inlink->h, bbox->min_val);
     w = box.x2 - box.x1 + 1;
     h = box.y2 - box.y1 + 1;
 
     av_log(ctx, AV_LOG_INFO,
-           "n:%d pts:%s pts_time:%s", bbox->frame,
+           "n:%"PRId64" pts:%s pts_time:%s", inlink->frame_count,
            av_ts2str(frame->pts), av_ts2timestr(frame->pts, &inlink->time_base));
 
     if (has_bbox) {
+        AVDictionary **metadata = avpriv_frame_get_metadatap(frame);
+
+        SET_META("lavfi.bbox.x1", box.x1)
+        SET_META("lavfi.bbox.x2", box.x2)
+        SET_META("lavfi.bbox.y1", box.y1)
+        SET_META("lavfi.bbox.y2", box.y2)
+        SET_META("lavfi.bbox.w",  w)
+        SET_META("lavfi.bbox.h",  h)
+
         av_log(ctx, AV_LOG_INFO,
                " x1:%d x2:%d y1:%d y2:%d w:%d h:%d"
                " crop=%d:%d:%d:%d drawbox=%d:%d:%d:%d",
@@ -76,7 +102,6 @@
     }
     av_log(ctx, AV_LOG_INFO, "\n");
 
-    bbox->frame++;
     return ff_filter_frame(inlink->dst->outputs[0], frame);
 }
 
@@ -101,7 +126,9 @@
     .name          = "bbox",
     .description   = NULL_IF_CONFIG_SMALL("Compute bounding box for each frame."),
     .priv_size     = sizeof(BBoxContext),
+    .priv_class    = &bbox_class,
     .query_formats = query_formats,
     .inputs        = bbox_inputs,
     .outputs       = bbox_outputs,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_blackdetect.c b/libavfilter/vf_blackdetect.c
index ddbf082..c96ad40 100644
--- a/libavfilter/vf_blackdetect.c
+++ b/libavfilter/vf_blackdetect.c
@@ -62,7 +62,7 @@
 AVFILTER_DEFINE_CLASS(blackdetect);
 
 #define YUVJ_FORMATS \
-    AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P
+    AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P
 
 static enum AVPixelFormat yuvj_formats[] = {
     YUVJ_FORMATS, AV_PIX_FMT_NONE
@@ -71,8 +71,11 @@
 static int query_formats(AVFilterContext *ctx)
 {
     static const enum AVPixelFormat pix_fmts[] = {
-        AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NV12,
-        AV_PIX_FMT_NV21, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV411P,
+        AV_PIX_FMT_GRAY8,
+        AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P,
+        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P,
+        AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P,
+        AV_PIX_FMT_NV12, AV_PIX_FMT_NV21,
         YUVJ_FORMATS,
         AV_PIX_FMT_NONE
     };
diff --git a/libavfilter/vf_blackframe.c b/libavfilter/vf_blackframe.c
index 7b38fcb..b83e1f8 100644
--- a/libavfilter/vf_blackframe.c
+++ b/libavfilter/vf_blackframe.c
@@ -62,30 +62,30 @@
 static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
 {
     AVFilterContext *ctx = inlink->dst;
-    BlackFrameContext *blackframe = ctx->priv;
+    BlackFrameContext *s = ctx->priv;
     int x, i;
     int pblack = 0;
     uint8_t *p = frame->data[0];
 
     for (i = 0; i < frame->height; i++) {
         for (x = 0; x < inlink->w; x++)
-            blackframe->nblack += p[x] < blackframe->bthresh;
+            s->nblack += p[x] < s->bthresh;
         p += frame->linesize[0];
     }
 
     if (frame->key_frame)
-        blackframe->last_keyframe = blackframe->frame;
+        s->last_keyframe = s->frame;
 
-    pblack = blackframe->nblack * 100 / (inlink->w * inlink->h);
-    if (pblack >= blackframe->bamount)
+    pblack = s->nblack * 100 / (inlink->w * inlink->h);
+    if (pblack >= s->bamount)
         av_log(ctx, AV_LOG_INFO, "frame:%u pblack:%u pts:%"PRId64" t:%f "
                "type:%c last_keyframe:%d\n",
-               blackframe->frame, pblack, frame->pts,
+               s->frame, pblack, frame->pts,
                frame->pts == AV_NOPTS_VALUE ? -1 : frame->pts * av_q2d(inlink->time_base),
-               av_get_picture_type_char(frame->pict_type), blackframe->last_keyframe);
+               av_get_picture_type_char(frame->pict_type), s->last_keyframe);
 
-    blackframe->frame++;
-    blackframe->nblack = 0;
+    s->frame++;
+    s->nblack = 0;
     return ff_filter_frame(inlink->dst->outputs[0], frame);
 }
 
diff --git a/libavfilter/vf_blend.c b/libavfilter/vf_blend.c
index 93b68be..959fcad 100644
--- a/libavfilter/vf_blend.c
+++ b/libavfilter/vf_blend.c
@@ -26,6 +26,7 @@
 #include "bufferqueue.h"
 #include "formats.h"
 #include "internal.h"
+#include "dualinput.h"
 #include "video.h"
 
 #define TOP    0
@@ -65,22 +66,30 @@
 
 typedef struct FilterParams {
     enum BlendMode mode;
-    double values[VAR_VARS_NB];
     double opacity;
     AVExpr *e;
     char *expr_str;
     void (*blend)(const uint8_t *top, int top_linesize,
                   const uint8_t *bottom, int bottom_linesize,
                   uint8_t *dst, int dst_linesize,
-                  int width, int height, struct FilterParams *param);
+                  int width, int start, int end,
+                  struct FilterParams *param, double *values);
 } FilterParams;
 
+typedef struct ThreadData {
+    const AVFrame *top, *bottom;
+    AVFrame *dst;
+    AVFilterLink *inlink;
+    int plane;
+    int w, h;
+    FilterParams *param;
+} ThreadData;
+
 typedef struct {
     const AVClass *class;
-    struct FFBufQueue queue_top;
-    struct FFBufQueue queue_bottom;
+    FFDualInputContext dinput;
     int hsub, vsub;             ///< chroma subsampling values
-    int frame_requested;
+    int nb_planes;
     char *all_expr;
     enum BlendMode all_mode;
     double all_opacity;
@@ -131,6 +140,8 @@
     { "c2_opacity",  "set color component #2 opacity", OFFSET(params[2].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS },
     { "c3_opacity",  "set color component #3 opacity", OFFSET(params[3].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS },
     { "all_opacity", "set opacity for all color components", OFFSET(all_opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
+    { "shortest",    "force termination when the shortest input terminates", OFFSET(dinput.shortest), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS },
+    { "repeatlast",  "repeat last bottom frame", OFFSET(dinput.repeatlast), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS },
     { NULL },
 };
 
@@ -139,21 +150,23 @@
 static void blend_normal(const uint8_t *top, int top_linesize,
                          const uint8_t *bottom, int bottom_linesize,
                          uint8_t *dst, int dst_linesize,
-                         int width, int height, FilterParams *param)
+                         int width, int start, int end,
+                         FilterParams *param, double *values)
 {
-    av_image_copy_plane(dst, dst_linesize, top, top_linesize, width, height);
+    av_image_copy_plane(dst, dst_linesize, top, top_linesize, width, end - start);
 }
 
 #define DEFINE_BLEND(name, expr)                                      \
 static void blend_## name(const uint8_t *top, int top_linesize,       \
                           const uint8_t *bottom, int bottom_linesize, \
                           uint8_t *dst, int dst_linesize,             \
-                          int width, int height, FilterParams *param) \
+                          int width, int start, int end,              \
+                          FilterParams *param, double *values)        \
 {                                                                     \
     double opacity = param->opacity;                                  \
     int i, j;                                                         \
                                                                       \
-    for (i = 0; i < height; i++) {                                    \
+    for (i = start; i < end; i++) {                                   \
         for (j = 0; j < width; j++) {                                 \
             dst[j] = top[j] + ((expr) - top[j]) * opacity;            \
         }                                                             \
@@ -198,14 +211,13 @@
 static void blend_expr(const uint8_t *top, int top_linesize,
                        const uint8_t *bottom, int bottom_linesize,
                        uint8_t *dst, int dst_linesize,
-                       int width, int height,
-                       FilterParams *param)
+                       int width, int start, int end,
+                       FilterParams *param, double *values)
 {
     AVExpr *e = param->e;
-    double *values = param->values;
     int y, x;
 
-    for (y = 0; y < height; y++) {
+    for (y = start; y < end; y++) {
         values[VAR_Y] = y;
         for (x = 0; x < width; x++) {
             values[VAR_X]      = x;
@@ -219,6 +231,65 @@
     }
 }
 
+static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+    ThreadData *td = arg;
+    int slice_start = (td->h *  jobnr   ) / nb_jobs;
+    int slice_end   = (td->h * (jobnr+1)) / nb_jobs;
+    const uint8_t *top    = td->top->data[td->plane];
+    const uint8_t *bottom = td->bottom->data[td->plane];
+    uint8_t *dst    = td->dst->data[td->plane];
+    double values[VAR_VARS_NB];
+
+    values[VAR_N]  = td->inlink->frame_count;
+    values[VAR_T]  = td->dst->pts == AV_NOPTS_VALUE ? NAN : td->dst->pts * av_q2d(td->inlink->time_base);
+    values[VAR_W]  = td->w;
+    values[VAR_H]  = td->h;
+    values[VAR_SW] = td->w / (double)td->dst->width;
+    values[VAR_SH] = td->h / (double)td->dst->height;
+
+    td->param->blend(top + slice_start * td->top->linesize[td->plane],
+                     td->top->linesize[td->plane],
+                     bottom + slice_start * td->bottom->linesize[td->plane],
+                     td->bottom->linesize[td->plane],
+                     dst + slice_start * td->dst->linesize[td->plane],
+                     td->dst->linesize[td->plane],
+                     td->w, slice_start, slice_end, td->param, &values[0]);
+    return 0;
+}
+
+static AVFrame *blend_frame(AVFilterContext *ctx, AVFrame *top_buf,
+                            const AVFrame *bottom_buf)
+{
+    BlendContext *b = ctx->priv;
+    AVFilterLink *inlink = ctx->inputs[0];
+    AVFilterLink *outlink = ctx->outputs[0];
+    AVFrame *dst_buf;
+    int plane;
+
+    dst_buf = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+    if (!dst_buf)
+        return top_buf;
+    av_frame_copy_props(dst_buf, top_buf);
+
+    for (plane = 0; plane < b->nb_planes; plane++) {
+        int hsub = plane == 1 || plane == 2 ? b->hsub : 0;
+        int vsub = plane == 1 || plane == 2 ? b->vsub : 0;
+        int outw = FF_CEIL_RSHIFT(dst_buf->width,  hsub);
+        int outh = FF_CEIL_RSHIFT(dst_buf->height, vsub);
+        FilterParams *param = &b->params[plane];
+        ThreadData td = { .top = top_buf, .bottom = bottom_buf, .dst = dst_buf,
+                          .w = outw, .h = outh, .param = param, .plane = plane,
+                          .inlink = inlink };
+
+        ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(outh, ctx->graph->nb_threads));
+    }
+
+    av_frame_free(&top_buf);
+
+    return dst_buf;
+}
+
 static av_cold int init(AVFilterContext *ctx)
 {
     BlendContext *b = ctx->priv;
@@ -273,6 +344,7 @@
         }
     }
 
+    b->dinput.process = blend_frame;
     return 0;
 }
 
@@ -280,9 +352,9 @@
 {
     static const enum AVPixelFormat pix_fmts[] = {
         AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P,
-        AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ422P,AV_PIX_FMT_YUVJ420P,
-        AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV410P,
-        AV_PIX_FMT_GBRP, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE
+        AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ422P,AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ411P,
+        AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P,
+        AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE
     };
 
     ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
@@ -294,13 +366,15 @@
     AVFilterContext *ctx = outlink->src;
     AVFilterLink *toplink = ctx->inputs[TOP];
     AVFilterLink *bottomlink = ctx->inputs[BOTTOM];
+    BlendContext *b = ctx->priv;
+    const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(toplink->format);
 
     if (toplink->format != bottomlink->format) {
         av_log(ctx, AV_LOG_ERROR, "inputs must be of same pixel format\n");
         return AVERROR(EINVAL);
     }
-    if (toplink->w                        != bottomlink->w ||
-        toplink->h                        != bottomlink->h ||
+    if (toplink->w                       != bottomlink->w ||
+        toplink->h                       != bottomlink->h ||
         toplink->sample_aspect_ratio.num != bottomlink->sample_aspect_ratio.num ||
         toplink->sample_aspect_ratio.den != bottomlink->sample_aspect_ratio.den) {
         av_log(ctx, AV_LOG_ERROR, "First input link %s parameters "
@@ -316,20 +390,15 @@
     }
 
     outlink->w = toplink->w;
-    outlink->h = bottomlink->h;
+    outlink->h = toplink->h;
     outlink->time_base = toplink->time_base;
     outlink->sample_aspect_ratio = toplink->sample_aspect_ratio;
     outlink->frame_rate = toplink->frame_rate;
-    return 0;
-}
-
-static int config_input_top(AVFilterLink *inlink)
-{
-    BlendContext *b = inlink->dst->priv;
-    const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
 
     b->hsub = pix_desc->log2_chroma_w;
     b->vsub = pix_desc->log2_chroma_h;
+    b->nb_planes = av_pix_fmt_count_planes(toplink->format);
+
     return 0;
 }
 
@@ -338,107 +407,38 @@
     BlendContext *b = ctx->priv;
     int i;
 
-    ff_bufqueue_discard_all(&b->queue_top);
-    ff_bufqueue_discard_all(&b->queue_bottom);
-
+    ff_dualinput_uninit(&b->dinput);
     for (i = 0; i < FF_ARRAY_ELEMS(b->params); i++)
         av_expr_free(b->params[i].e);
 }
 
 static int request_frame(AVFilterLink *outlink)
 {
-    AVFilterContext *ctx = outlink->src;
-    BlendContext *b = ctx->priv;
-    int in, ret;
-
-    b->frame_requested = 1;
-    while (b->frame_requested) {
-        in = ff_bufqueue_peek(&b->queue_top, 0) ? BOTTOM : TOP;
-        ret = ff_request_frame(ctx->inputs[in]);
-        if (ret < 0)
-            return ret;
-    }
-    return 0;
+    BlendContext *b = outlink->src->priv;
+    return ff_dualinput_request_frame(&b->dinput, outlink);
 }
 
-static void blend_frame(AVFilterContext *ctx,
-                        AVFrame *top_buf,
-                        AVFrame *bottom_buf,
-                        AVFrame *dst_buf)
+static int filter_frame_top(AVFilterLink *inlink, AVFrame *buf)
 {
-    BlendContext *b = ctx->priv;
-    AVFilterLink *inlink = ctx->inputs[0];
-    FilterParams *param;
-    int plane;
-
-    for (plane = 0; dst_buf->data[plane]; plane++) {
-        int hsub = plane == 1 || plane == 2 ? b->hsub : 0;
-        int vsub = plane == 1 || plane == 2 ? b->vsub : 0;
-        int outw = dst_buf->width  >> hsub;
-        int outh = dst_buf->height >> vsub;
-        uint8_t *dst    = dst_buf->data[plane];
-        uint8_t *top    = top_buf->data[plane];
-        uint8_t *bottom = bottom_buf->data[plane];
-
-        param = &b->params[plane];
-        param->values[VAR_N]  = inlink->frame_count;
-        param->values[VAR_T]  = dst_buf->pts == AV_NOPTS_VALUE ? NAN : dst_buf->pts * av_q2d(inlink->time_base);
-        param->values[VAR_W]  = outw;
-        param->values[VAR_H]  = outh;
-        param->values[VAR_SW] = outw / dst_buf->width;
-        param->values[VAR_SH] = outh / dst_buf->height;
-        param->blend(top, top_buf->linesize[plane],
-                     bottom, bottom_buf->linesize[plane],
-                     dst, dst_buf->linesize[plane], outw, outh, param);
-    }
+    BlendContext *b = inlink->dst->priv;
+    return ff_dualinput_filter_frame_main(&b->dinput, inlink, buf);
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
+static int filter_frame_bottom(AVFilterLink *inlink, AVFrame *buf)
 {
-    AVFilterContext *ctx = inlink->dst;
-    AVFilterLink *outlink = ctx->outputs[0];
-    BlendContext *b = ctx->priv;
-
-    int ret = 0;
-    int is_bottom = (inlink == ctx->inputs[BOTTOM]);
-    struct FFBufQueue *queue =
-        (is_bottom ? &b->queue_bottom : &b->queue_top);
-    ff_bufqueue_add(ctx, queue, buf);
-
-    while (1) {
-        AVFrame *top_buf, *bottom_buf, *out_buf;
-
-        if (!ff_bufqueue_peek(&b->queue_top, 0) ||
-            !ff_bufqueue_peek(&b->queue_bottom, 0)) break;
-
-        top_buf = ff_bufqueue_get(&b->queue_top);
-        bottom_buf = ff_bufqueue_get(&b->queue_bottom);
-
-        out_buf = ff_get_video_buffer(outlink, outlink->w, outlink->h);
-        if (!out_buf) {
-            return AVERROR(ENOMEM);
-        }
-        av_frame_copy_props(out_buf, top_buf);
-
-        b->frame_requested = 0;
-        blend_frame(ctx, top_buf, bottom_buf, out_buf);
-        ret = ff_filter_frame(ctx->outputs[0], out_buf);
-        av_frame_free(&top_buf);
-        av_frame_free(&bottom_buf);
-    }
-    return ret;
+    BlendContext *b = inlink->dst->priv;
+    return ff_dualinput_filter_frame_second(&b->dinput, inlink, buf);
 }
 
 static const AVFilterPad blend_inputs[] = {
     {
         .name             = "top",
         .type             = AVMEDIA_TYPE_VIDEO,
-        .config_props     = config_input_top,
-        .filter_frame     = filter_frame,
+        .filter_frame     = filter_frame_top,
     },{
         .name             = "bottom",
         .type             = AVMEDIA_TYPE_VIDEO,
-        .filter_frame     = filter_frame,
+        .filter_frame     = filter_frame_bottom,
     },
     { NULL }
 };
@@ -463,4 +463,5 @@
     .inputs        = blend_inputs,
     .outputs       = blend_outputs,
     .priv_class    = &blend_class,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_boxblur.c b/libavfilter/vf_boxblur.c
index b010670..bf4c42e 100644
--- a/libavfilter/vf_boxblur.c
+++ b/libavfilter/vf_boxblur.c
@@ -80,39 +80,39 @@
 
 static av_cold int init(AVFilterContext *ctx)
 {
-    BoxBlurContext *boxblur = ctx->priv;
+    BoxBlurContext *s = ctx->priv;
 
-    if (!boxblur->luma_param.radius_expr) {
+    if (!s->luma_param.radius_expr) {
         av_log(ctx, AV_LOG_ERROR, "Luma radius expression is not set.\n");
         return AVERROR(EINVAL);
     }
 
     /* fill missing params */
-    if (!boxblur->chroma_param.radius_expr) {
-        boxblur->chroma_param.radius_expr = av_strdup(boxblur->luma_param.radius_expr);
-        if (!boxblur->chroma_param.radius_expr)
+    if (!s->chroma_param.radius_expr) {
+        s->chroma_param.radius_expr = av_strdup(s->luma_param.radius_expr);
+        if (!s->chroma_param.radius_expr)
             return AVERROR(ENOMEM);
     }
-    if (boxblur->chroma_param.power < 0)
-        boxblur->chroma_param.power = boxblur->luma_param.power;
+    if (s->chroma_param.power < 0)
+        s->chroma_param.power = s->luma_param.power;
 
-    if (!boxblur->alpha_param.radius_expr) {
-        boxblur->alpha_param.radius_expr = av_strdup(boxblur->luma_param.radius_expr);
-        if (!boxblur->alpha_param.radius_expr)
+    if (!s->alpha_param.radius_expr) {
+        s->alpha_param.radius_expr = av_strdup(s->luma_param.radius_expr);
+        if (!s->alpha_param.radius_expr)
             return AVERROR(ENOMEM);
     }
-    if (boxblur->alpha_param.power < 0)
-        boxblur->alpha_param.power = boxblur->luma_param.power;
+    if (s->alpha_param.power < 0)
+        s->alpha_param.power = s->luma_param.power;
 
     return 0;
 }
 
 static av_cold void uninit(AVFilterContext *ctx)
 {
-    BoxBlurContext *boxblur = ctx->priv;
+    BoxBlurContext *s = ctx->priv;
 
-    av_freep(&boxblur->temp[0]);
-    av_freep(&boxblur->temp[1]);
+    av_freep(&s->temp[0]);
+    av_freep(&s->temp[1]);
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -134,32 +134,32 @@
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
     AVFilterContext    *ctx = inlink->dst;
-    BoxBlurContext *boxblur = ctx->priv;
+    BoxBlurContext *s = ctx->priv;
     int w = inlink->w, h = inlink->h;
     int cw, ch;
     double var_values[VARS_NB], res;
     char *expr;
     int ret;
 
-    if (!(boxblur->temp[0] = av_malloc(FFMAX(w, h))) ||
-        !(boxblur->temp[1] = av_malloc(FFMAX(w, h))))
+    if (!(s->temp[0] = av_malloc(FFMAX(w, h))) ||
+        !(s->temp[1] = av_malloc(FFMAX(w, h))))
         return AVERROR(ENOMEM);
 
-    boxblur->hsub = desc->log2_chroma_w;
-    boxblur->vsub = desc->log2_chroma_h;
+    s->hsub = desc->log2_chroma_w;
+    s->vsub = desc->log2_chroma_h;
 
     var_values[VAR_W]       = inlink->w;
     var_values[VAR_H]       = inlink->h;
-    var_values[VAR_CW] = cw = w>>boxblur->hsub;
-    var_values[VAR_CH] = ch = h>>boxblur->vsub;
-    var_values[VAR_HSUB]    = 1<<boxblur->hsub;
-    var_values[VAR_VSUB]    = 1<<boxblur->vsub;
+    var_values[VAR_CW] = cw = w>>s->hsub;
+    var_values[VAR_CH] = ch = h>>s->vsub;
+    var_values[VAR_HSUB]    = 1<<s->hsub;
+    var_values[VAR_VSUB]    = 1<<s->vsub;
 
 #define EVAL_RADIUS_EXPR(comp)                                          \
-    expr = boxblur->comp##_param.radius_expr;                           \
+    expr = s->comp##_param.radius_expr;                                 \
     ret = av_expr_parse_and_eval(&res, expr, var_names, var_values,     \
                                  NULL, NULL, NULL, NULL, NULL, 0, ctx); \
-    boxblur->comp##_param.radius = res;                                 \
+    s->comp##_param.radius = res;                                       \
     if (ret < 0) {                                                      \
         av_log(NULL, AV_LOG_ERROR,                                      \
                "Error when evaluating " #comp " radius expression '%s'\n", expr); \
@@ -174,30 +174,30 @@
            "chroma_radius:%d chroma_power:%d "
            "alpha_radius:%d alpha_power:%d "
            "w:%d chroma_w:%d h:%d chroma_h:%d\n",
-           boxblur->luma_param  .radius, boxblur->luma_param  .power,
-           boxblur->chroma_param.radius, boxblur->chroma_param.power,
-           boxblur->alpha_param .radius, boxblur->alpha_param .power,
+           s->luma_param  .radius, s->luma_param  .power,
+           s->chroma_param.radius, s->chroma_param.power,
+           s->alpha_param .radius, s->alpha_param .power,
            w, cw, h, ch);
 
 #define CHECK_RADIUS_VAL(w_, h_, comp)                                  \
-    if (boxblur->comp##_param.radius < 0 ||                             \
-        2*boxblur->comp##_param.radius > FFMIN(w_, h_)) {               \
+    if (s->comp##_param.radius < 0 ||                                   \
+        2*s->comp##_param.radius > FFMIN(w_, h_)) {                     \
         av_log(ctx, AV_LOG_ERROR,                                       \
                "Invalid " #comp " radius value %d, must be >= 0 and <= %d\n", \
-               boxblur->comp##_param.radius, FFMIN(w_, h_)/2);          \
+               s->comp##_param.radius, FFMIN(w_, h_)/2);                \
         return AVERROR(EINVAL);                                         \
     }
     CHECK_RADIUS_VAL(w,  h,  luma);
     CHECK_RADIUS_VAL(cw, ch, chroma);
     CHECK_RADIUS_VAL(w,  h,  alpha);
 
-    boxblur->radius[Y] = boxblur->luma_param.radius;
-    boxblur->radius[U] = boxblur->radius[V] = boxblur->chroma_param.radius;
-    boxblur->radius[A] = boxblur->alpha_param.radius;
+    s->radius[Y] = s->luma_param.radius;
+    s->radius[U] = s->radius[V] = s->chroma_param.radius;
+    s->radius[A] = s->alpha_param.radius;
 
-    boxblur->power[Y] = boxblur->luma_param.power;
-    boxblur->power[U] = boxblur->power[V] = boxblur->chroma_param.power;
-    boxblur->power[A] = boxblur->alpha_param.power;
+    s->power[Y] = s->luma_param.power;
+    s->power[U] = s->power[V] = s->chroma_param.power;
+    s->power[A] = s->alpha_param.power;
 
     return 0;
 }
@@ -298,11 +298,11 @@
 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
     AVFilterContext *ctx = inlink->dst;
-    BoxBlurContext *boxblur = ctx->priv;
+    BoxBlurContext *s = ctx->priv;
     AVFilterLink *outlink = inlink->dst->outputs[0];
     AVFrame *out;
     int plane;
-    int cw = inlink->w >> boxblur->hsub, ch = in->height >> boxblur->vsub;
+    int cw = FF_CEIL_RSHIFT(inlink->w, s->hsub), ch = FF_CEIL_RSHIFT(in->height, s->vsub);
     int w[4] = { inlink->w, cw, cw, inlink->w };
     int h[4] = { in->height, ch, ch, in->height };
 
@@ -313,17 +313,17 @@
     }
     av_frame_copy_props(out, in);
 
-    for (plane = 0; in->data[plane] && plane < 4; plane++)
+    for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++)
         hblur(out->data[plane], out->linesize[plane],
               in ->data[plane], in ->linesize[plane],
-              w[plane], h[plane], boxblur->radius[plane], boxblur->power[plane],
-              boxblur->temp);
+              w[plane], h[plane], s->radius[plane], s->power[plane],
+              s->temp);
 
-    for (plane = 0; in->data[plane] && plane < 4; plane++)
+    for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++)
         vblur(out->data[plane], out->linesize[plane],
               out->data[plane], out->linesize[plane],
-              w[plane], h[plane], boxblur->radius[plane], boxblur->power[plane],
-              boxblur->temp);
+              w[plane], h[plane], s->radius[plane], s->power[plane],
+              s->temp);
 
     av_frame_free(&in);
 
@@ -383,5 +383,5 @@
 
     .inputs    = avfilter_vf_boxblur_inputs,
     .outputs   = avfilter_vf_boxblur_outputs,
-    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_colorbalance.c b/libavfilter/vf_colorbalance.c
index be0f4f4..ca6c781 100644
--- a/libavfilter/vf_colorbalance.c
+++ b/libavfilter/vf_colorbalance.c
@@ -185,20 +185,20 @@
 
 static const AVFilterPad colorbalance_inputs[] = {
     {
-        .name           = "default",
-        .type           = AVMEDIA_TYPE_VIDEO,
-        .filter_frame   = filter_frame,
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = filter_frame,
     },
     { NULL }
 };
 
 static const AVFilterPad colorbalance_outputs[] = {
-     {
-         .name         = "default",
-         .type         = AVMEDIA_TYPE_VIDEO,
-         .config_props = config_output,
-     },
-     { NULL }
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .config_props = config_output,
+    },
+    { NULL }
 };
 
 AVFilter avfilter_vf_colorbalance = {
@@ -209,4 +209,5 @@
     .query_formats = query_formats,
     .inputs        = colorbalance_inputs,
     .outputs       = colorbalance_outputs,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_colorchannelmixer.c b/libavfilter/vf_colorchannelmixer.c
index 963d415..9c0044d 100644
--- a/libavfilter/vf_colorchannelmixer.c
+++ b/libavfilter/vf_colorchannelmixer.c
@@ -91,27 +91,16 @@
     ColorChannelMixerContext *cm = ctx->priv;
     int i, j, size, *buffer;
 
+    ff_fill_rgba_map(cm->rgba_map, outlink->format);
+
     switch (outlink->format) {
     case AV_PIX_FMT_RGB48:
     case AV_PIX_FMT_BGR48:
     case AV_PIX_FMT_RGBA64:
     case AV_PIX_FMT_BGRA64:
-        if (outlink->format == AV_PIX_FMT_RGB48 ||
-            outlink->format == AV_PIX_FMT_RGBA64) {
-            cm->rgba_map[R] = 0;
-            cm->rgba_map[G] = 1;
-            cm->rgba_map[B] = 2;
-            cm->rgba_map[A] = 3;
-        } else {
-            cm->rgba_map[R] = 2;
-            cm->rgba_map[G] = 1;
-            cm->rgba_map[B] = 0;
-            cm->rgba_map[A] = 3;
-        }
         size = 65536;
         break;
     default:
-        ff_fill_rgba_map(cm->rgba_map, outlink->format);
         size = 256;
     }
 
@@ -124,25 +113,25 @@
             cm->lut[i][j] = buffer;
 
     for (i = 0; i < size; i++) {
-        cm->lut[R][R][i] = i * cm->rr;
-        cm->lut[R][G][i] = i * cm->rg;
-        cm->lut[R][B][i] = i * cm->rb;
-        cm->lut[R][A][i] = i * cm->ra;
+        cm->lut[R][R][i] = round(i * cm->rr);
+        cm->lut[R][G][i] = round(i * cm->rg);
+        cm->lut[R][B][i] = round(i * cm->rb);
+        cm->lut[R][A][i] = round(i * cm->ra);
 
-        cm->lut[G][R][i] = i * cm->gr;
-        cm->lut[G][G][i] = i * cm->gg;
-        cm->lut[G][B][i] = i * cm->gb;
-        cm->lut[G][A][i] = i * cm->ga;
+        cm->lut[G][R][i] = round(i * cm->gr);
+        cm->lut[G][G][i] = round(i * cm->gg);
+        cm->lut[G][B][i] = round(i * cm->gb);
+        cm->lut[G][A][i] = round(i * cm->ga);
 
-        cm->lut[B][R][i] = i * cm->br;
-        cm->lut[B][G][i] = i * cm->bg;
-        cm->lut[B][B][i] = i * cm->bb;
-        cm->lut[B][A][i] = i * cm->ba;
+        cm->lut[B][R][i] = round(i * cm->br);
+        cm->lut[B][G][i] = round(i * cm->bg);
+        cm->lut[B][B][i] = round(i * cm->bb);
+        cm->lut[B][A][i] = round(i * cm->ba);
 
-        cm->lut[A][R][i] = i * cm->ar;
-        cm->lut[A][G][i] = i * cm->ag;
-        cm->lut[A][B][i] = i * cm->ab;
-        cm->lut[A][A][i] = i * cm->aa;
+        cm->lut[A][R][i] = round(i * cm->ar);
+        cm->lut[A][G][i] = round(i * cm->ag);
+        cm->lut[A][B][i] = round(i * cm->ab);
+        cm->lut[A][A][i] = round(i * cm->aa);
     }
 
     return 0;
@@ -342,20 +331,20 @@
 
 static const AVFilterPad colorchannelmixer_inputs[] = {
     {
-        .name           = "default",
-        .type           = AVMEDIA_TYPE_VIDEO,
-        .filter_frame   = filter_frame,
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = filter_frame,
     },
     { NULL }
 };
 
 static const AVFilterPad colorchannelmixer_outputs[] = {
-     {
-         .name         = "default",
-         .type         = AVMEDIA_TYPE_VIDEO,
-         .config_props = config_output,
-     },
-     { NULL }
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .config_props = config_output,
+    },
+    { NULL }
 };
 
 AVFilter avfilter_vf_colorchannelmixer = {
@@ -367,4 +356,5 @@
     .query_formats = query_formats,
     .inputs        = colorchannelmixer_inputs,
     .outputs       = colorchannelmixer_outputs,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_colormatrix.c b/libavfilter/vf_colormatrix.c
index 8db5fcf..7db0bd8 100644
--- a/libavfilter/vf_colormatrix.c
+++ b/libavfilter/vf_colormatrix.c
@@ -385,5 +385,5 @@
     .inputs        = colormatrix_inputs,
     .outputs       = colormatrix_outputs,
     .priv_class    = &colormatrix_class,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_copy.c b/libavfilter/vf_copy.c
index df7ec31..b9859c4 100644
--- a/libavfilter/vf_copy.c
+++ b/libavfilter/vf_copy.c
@@ -37,7 +37,7 @@
         return AVERROR(ENOMEM);
     }
     av_frame_copy_props(out, in);
-    av_image_copy(out->data, out->linesize, in->data, in->linesize,
+    av_image_copy(out->data, out->linesize, (const uint8_t**) in->data, in->linesize,
                   in->format, in->width, in->height);
 
     av_frame_free(&in);
diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c
index 5d7dd2c..e112c23 100644
--- a/libavfilter/vf_crop.c
+++ b/libavfilter/vf_crop.c
@@ -23,8 +23,6 @@
  * video crop filter
  */
 
-/* #define DEBUG */
-
 #include <stdio.h>
 
 #include "avfilter.h"
@@ -94,43 +92,28 @@
 
 static int query_formats(AVFilterContext *ctx)
 {
-    static const enum AVPixelFormat pix_fmts[] = {
-        AV_PIX_FMT_RGB48BE,      AV_PIX_FMT_RGB48LE,
-        AV_PIX_FMT_BGR48BE,      AV_PIX_FMT_BGR48LE,
-        AV_PIX_FMT_ARGB,         AV_PIX_FMT_RGBA,
-        AV_PIX_FMT_ABGR,         AV_PIX_FMT_BGRA,
-        AV_PIX_FMT_RGB24,        AV_PIX_FMT_BGR24,
-        AV_PIX_FMT_RGB565BE,     AV_PIX_FMT_RGB565LE,
-        AV_PIX_FMT_RGB555BE,     AV_PIX_FMT_RGB555LE,
-        AV_PIX_FMT_BGR565BE,     AV_PIX_FMT_BGR565LE,
-        AV_PIX_FMT_BGR555BE,     AV_PIX_FMT_BGR555LE,
-        AV_PIX_FMT_GRAY16BE,     AV_PIX_FMT_GRAY16LE,
-        AV_PIX_FMT_YUV420P16LE,  AV_PIX_FMT_YUV420P16BE,
-        AV_PIX_FMT_YUV422P16LE,  AV_PIX_FMT_YUV422P16BE,
-        AV_PIX_FMT_YUV444P16LE,  AV_PIX_FMT_YUV444P16BE,
-        AV_PIX_FMT_YUV444P,      AV_PIX_FMT_YUV422P,
-        AV_PIX_FMT_YUV420P,      AV_PIX_FMT_YUV411P,
-        AV_PIX_FMT_YUV410P,      AV_PIX_FMT_YUV440P,
-        AV_PIX_FMT_YUVJ444P,     AV_PIX_FMT_YUVJ422P,
-        AV_PIX_FMT_YUVJ420P,     AV_PIX_FMT_YUVJ440P,
-        AV_PIX_FMT_YUVA420P,
-        AV_PIX_FMT_RGB8,         AV_PIX_FMT_BGR8,
-        AV_PIX_FMT_RGB4_BYTE,    AV_PIX_FMT_BGR4_BYTE,
-        AV_PIX_FMT_PAL8,         AV_PIX_FMT_GRAY8,
-        AV_PIX_FMT_NONE
-    };
+    AVFilterFormats *formats = NULL;
+    int fmt;
 
-    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    for (fmt = 0; fmt < AV_PIX_FMT_NB; fmt++) {
+        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
+        if (!(desc->flags & (AV_PIX_FMT_FLAG_HWACCEL | AV_PIX_FMT_FLAG_BITSTREAM)) &&
+            !((desc->log2_chroma_w || desc->log2_chroma_h) && !(desc->flags & AV_PIX_FMT_FLAG_PLANAR)))
+            ff_add_format(&formats, fmt);
+    }
 
+    ff_set_common_formats(ctx, formats);
     return 0;
 }
 
 static av_cold void uninit(AVFilterContext *ctx)
 {
-    CropContext *crop = ctx->priv;
+    CropContext *s = ctx->priv;
 
-    av_expr_free(crop->x_pexpr); crop->x_pexpr = NULL;
-    av_expr_free(crop->y_pexpr); crop->y_pexpr = NULL;
+    av_expr_free(s->x_pexpr);
+    s->x_pexpr = NULL;
+    av_expr_free(s->y_pexpr);
+    s->y_pexpr = NULL;
 }
 
 static inline int normalize_double(int *n, double d)
@@ -151,86 +134,93 @@
 static int config_input(AVFilterLink *link)
 {
     AVFilterContext *ctx = link->dst;
-    CropContext *crop = ctx->priv;
+    CropContext *s = ctx->priv;
     const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(link->format);
     int ret;
     const char *expr;
     double res;
 
-    crop->var_values[VAR_IN_W]  = crop->var_values[VAR_IW] = ctx->inputs[0]->w;
-    crop->var_values[VAR_IN_H]  = crop->var_values[VAR_IH] = ctx->inputs[0]->h;
-    crop->var_values[VAR_A]     = (float) link->w / link->h;
-    crop->var_values[VAR_SAR]   = link->sample_aspect_ratio.num ? av_q2d(link->sample_aspect_ratio) : 1;
-    crop->var_values[VAR_DAR]   = crop->var_values[VAR_A] * crop->var_values[VAR_SAR];
-    crop->var_values[VAR_HSUB]  = 1<<pix_desc->log2_chroma_w;
-    crop->var_values[VAR_VSUB]  = 1<<pix_desc->log2_chroma_h;
-    crop->var_values[VAR_X]     = NAN;
-    crop->var_values[VAR_Y]     = NAN;
-    crop->var_values[VAR_OUT_W] = crop->var_values[VAR_OW] = NAN;
-    crop->var_values[VAR_OUT_H] = crop->var_values[VAR_OH] = NAN;
-    crop->var_values[VAR_N]     = 0;
-    crop->var_values[VAR_T]     = NAN;
-    crop->var_values[VAR_POS]   = NAN;
+    s->var_values[VAR_IN_W]  = s->var_values[VAR_IW] = ctx->inputs[0]->w;
+    s->var_values[VAR_IN_H]  = s->var_values[VAR_IH] = ctx->inputs[0]->h;
+    s->var_values[VAR_A]     = (float) link->w / link->h;
+    s->var_values[VAR_SAR]   = link->sample_aspect_ratio.num ? av_q2d(link->sample_aspect_ratio) : 1;
+    s->var_values[VAR_DAR]   = s->var_values[VAR_A] * s->var_values[VAR_SAR];
+    s->var_values[VAR_HSUB]  = 1<<pix_desc->log2_chroma_w;
+    s->var_values[VAR_VSUB]  = 1<<pix_desc->log2_chroma_h;
+    s->var_values[VAR_X]     = NAN;
+    s->var_values[VAR_Y]     = NAN;
+    s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = NAN;
+    s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = NAN;
+    s->var_values[VAR_N]     = 0;
+    s->var_values[VAR_T]     = NAN;
+    s->var_values[VAR_POS]   = NAN;
 
-    av_image_fill_max_pixsteps(crop->max_step, NULL, pix_desc);
-    crop->hsub = pix_desc->log2_chroma_w;
-    crop->vsub = pix_desc->log2_chroma_h;
+    av_image_fill_max_pixsteps(s->max_step, NULL, pix_desc);
+    s->hsub = pix_desc->log2_chroma_w;
+    s->vsub = pix_desc->log2_chroma_h;
 
-    if ((ret = av_expr_parse_and_eval(&res, (expr = crop->w_expr),
-                                      var_names, crop->var_values,
-                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) goto fail_expr;
-    crop->var_values[VAR_OUT_W] = crop->var_values[VAR_OW] = res;
-    if ((ret = av_expr_parse_and_eval(&res, (expr = crop->h_expr),
-                                      var_names, crop->var_values,
-                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) goto fail_expr;
-    crop->var_values[VAR_OUT_H] = crop->var_values[VAR_OH] = res;
+    if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr),
+                                      var_names, s->var_values,
+                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
+        goto fail_expr;
+    s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = res;
+    if ((ret = av_expr_parse_and_eval(&res, (expr = s->h_expr),
+                                      var_names, s->var_values,
+                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
+        goto fail_expr;
+    s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = res;
     /* evaluate again ow as it may depend on oh */
-    if ((ret = av_expr_parse_and_eval(&res, (expr = crop->w_expr),
-                                      var_names, crop->var_values,
-                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) goto fail_expr;
-    crop->var_values[VAR_OUT_W] = crop->var_values[VAR_OW] = res;
-    if (normalize_double(&crop->w, crop->var_values[VAR_OUT_W]) < 0 ||
-        normalize_double(&crop->h, crop->var_values[VAR_OUT_H]) < 0) {
+    if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr),
+                                      var_names, s->var_values,
+                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
+        goto fail_expr;
+
+    s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = res;
+    if (normalize_double(&s->w, s->var_values[VAR_OUT_W]) < 0 ||
+        normalize_double(&s->h, s->var_values[VAR_OUT_H]) < 0) {
         av_log(ctx, AV_LOG_ERROR,
                "Too big value or invalid expression for out_w/ow or out_h/oh. "
                "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n",
-               crop->w_expr, crop->h_expr);
+               s->w_expr, s->h_expr);
         return AVERROR(EINVAL);
     }
-    crop->w &= ~((1 << crop->hsub) - 1);
-    crop->h &= ~((1 << crop->vsub) - 1);
+    s->w &= ~((1 << s->hsub) - 1);
+    s->h &= ~((1 << s->vsub) - 1);
 
-    if ((ret = av_expr_parse(&crop->x_pexpr, crop->x_expr, var_names,
+    av_expr_free(s->x_pexpr);
+    av_expr_free(s->y_pexpr);
+    s->x_pexpr = s->y_pexpr = NULL;
+    if ((ret = av_expr_parse(&s->x_pexpr, s->x_expr, var_names,
                              NULL, NULL, NULL, NULL, 0, ctx)) < 0 ||
-        (ret = av_expr_parse(&crop->y_pexpr, crop->y_expr, var_names,
+        (ret = av_expr_parse(&s->y_pexpr, s->y_expr, var_names,
                              NULL, NULL, NULL, NULL, 0, ctx)) < 0)
         return AVERROR(EINVAL);
 
-    if (crop->keep_aspect) {
+    if (s->keep_aspect) {
         AVRational dar = av_mul_q(link->sample_aspect_ratio,
                                   (AVRational){ link->w, link->h });
-        av_reduce(&crop->out_sar.num, &crop->out_sar.den,
-                  dar.num * crop->h, dar.den * crop->w, INT_MAX);
+        av_reduce(&s->out_sar.num, &s->out_sar.den,
+                  dar.num * s->h, dar.den * s->w, INT_MAX);
     } else
-        crop->out_sar = link->sample_aspect_ratio;
+        s->out_sar = link->sample_aspect_ratio;
 
     av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d sar:%d/%d -> w:%d h:%d sar:%d/%d\n",
            link->w, link->h, link->sample_aspect_ratio.num, link->sample_aspect_ratio.den,
-           crop->w, crop->h, crop->out_sar.num, crop->out_sar.den);
+           s->w, s->h, s->out_sar.num, s->out_sar.den);
 
-    if (crop->w <= 0 || crop->h <= 0 ||
-        crop->w > link->w || crop->h > link->h) {
+    if (s->w <= 0 || s->h <= 0 ||
+        s->w > link->w || s->h > link->h) {
         av_log(ctx, AV_LOG_ERROR,
                "Invalid too big or non positive size for width '%d' or height '%d'\n",
-               crop->w, crop->h);
+               s->w, s->h);
         return AVERROR(EINVAL);
     }
 
     /* set default, required in the case the first computed value for x/y is NAN */
-    crop->x = (link->w - crop->w) / 2;
-    crop->y = (link->h - crop->h) / 2;
-    crop->x &= ~((1 << crop->hsub) - 1);
-    crop->y &= ~((1 << crop->vsub) - 1);
+    s->x = (link->w - s->w) / 2;
+    s->y = (link->h - s->h) / 2;
+    s->x &= ~((1 << s->hsub) - 1);
+    s->y &= ~((1 << s->vsub) - 1);
     return 0;
 
 fail_expr:
@@ -240,11 +230,11 @@
 
 static int config_output(AVFilterLink *link)
 {
-    CropContext *crop = link->src->priv;
+    CropContext *s = link->src->priv;
 
-    link->w = crop->w;
-    link->h = crop->h;
-    link->sample_aspect_ratio = crop->out_sar;
+    link->w = s->w;
+    link->h = s->h;
+    link->sample_aspect_ratio = s->out_sar;
 
     return 0;
 }
@@ -252,52 +242,56 @@
 static int filter_frame(AVFilterLink *link, AVFrame *frame)
 {
     AVFilterContext *ctx = link->dst;
-    CropContext *crop = ctx->priv;
+    CropContext *s = ctx->priv;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
     int i;
 
-    frame->width  = crop->w;
-    frame->height = crop->h;
+    frame->width  = s->w;
+    frame->height = s->h;
 
-    crop->var_values[VAR_N] = link->frame_count;
-    crop->var_values[VAR_T] = frame->pts == AV_NOPTS_VALUE ?
+    s->var_values[VAR_N] = link->frame_count;
+    s->var_values[VAR_T] = frame->pts == AV_NOPTS_VALUE ?
         NAN : frame->pts * av_q2d(link->time_base);
-    crop->var_values[VAR_POS] = av_frame_get_pkt_pos(frame) == -1 ?
+    s->var_values[VAR_POS] = av_frame_get_pkt_pos(frame) == -1 ?
         NAN : av_frame_get_pkt_pos(frame);
-    crop->var_values[VAR_X] = av_expr_eval(crop->x_pexpr, crop->var_values, NULL);
-    crop->var_values[VAR_Y] = av_expr_eval(crop->y_pexpr, crop->var_values, NULL);
-    crop->var_values[VAR_X] = av_expr_eval(crop->x_pexpr, crop->var_values, NULL);
+    s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL);
+    s->var_values[VAR_Y] = av_expr_eval(s->y_pexpr, s->var_values, NULL);
+    s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL);
 
-    normalize_double(&crop->x, crop->var_values[VAR_X]);
-    normalize_double(&crop->y, crop->var_values[VAR_Y]);
+    normalize_double(&s->x, s->var_values[VAR_X]);
+    normalize_double(&s->y, s->var_values[VAR_Y]);
 
-    if (crop->x < 0) crop->x = 0;
-    if (crop->y < 0) crop->y = 0;
-    if ((unsigned)crop->x + (unsigned)crop->w > link->w) crop->x = link->w - crop->w;
-    if ((unsigned)crop->y + (unsigned)crop->h > link->h) crop->y = link->h - crop->h;
-    crop->x &= ~((1 << crop->hsub) - 1);
-    crop->y &= ~((1 << crop->vsub) - 1);
+    if (s->x < 0)
+        s->x = 0;
+    if (s->y < 0)
+        s->y = 0;
+    if ((unsigned)s->x + (unsigned)s->w > link->w)
+        s->x = link->w - s->w;
+    if ((unsigned)s->y + (unsigned)s->h > link->h)
+        s->y = link->h - s->h;
+    s->x &= ~((1 << s->hsub) - 1);
+    s->y &= ~((1 << s->vsub) - 1);
 
     av_dlog(ctx, "n:%d t:%f pos:%f x:%d y:%d x+w:%d y+h:%d\n",
-            (int)crop->var_values[VAR_N], crop->var_values[VAR_T], crop->var_values[VAR_POS],
-            crop->x, crop->y, crop->x+crop->w, crop->y+crop->h);
+            (int)s->var_values[VAR_N], s->var_values[VAR_T], s->var_values[VAR_POS],
+            s->x, s->y, s->x+s->w, s->y+s->h);
 
-    frame->data[0] += crop->y * frame->linesize[0];
-    frame->data[0] += crop->x * crop->max_step[0];
+    frame->data[0] += s->y * frame->linesize[0];
+    frame->data[0] += s->x * s->max_step[0];
 
-    if (!(desc->flags & PIX_FMT_PAL || desc->flags & PIX_FMT_PSEUDOPAL)) {
+    if (!(desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) {
         for (i = 1; i < 3; i ++) {
             if (frame->data[i]) {
-                frame->data[i] += (crop->y >> crop->vsub) * frame->linesize[i];
-                frame->data[i] += (crop->x * crop->max_step[i]) >> crop->hsub;
+                frame->data[i] += (s->y >> s->vsub) * frame->linesize[i];
+                frame->data[i] += (s->x * s->max_step[i]) >> s->hsub;
             }
         }
     }
 
     /* alpha plane */
     if (frame->data[3]) {
-        frame->data[3] += crop->y * frame->linesize[3];
-        frame->data[3] += crop->x * crop->max_step[3];
+        frame->data[3] += s->y * frame->linesize[3];
+        frame->data[3] += s->x * s->max_step[3];
     }
 
     return ff_filter_frame(link->dst->outputs[0], frame);
diff --git a/libavfilter/vf_cropdetect.c b/libavfilter/vf_cropdetect.c
index cb170d0..184b769 100644
--- a/libavfilter/vf_cropdetect.c
+++ b/libavfilter/vf_cropdetect.c
@@ -86,12 +86,12 @@
 
 static av_cold int init(AVFilterContext *ctx)
 {
-    CropDetectContext *cd = ctx->priv;
+    CropDetectContext *s = ctx->priv;
 
-    cd->frame_nb = -2;
+    s->frame_nb = -2;
 
     av_log(ctx, AV_LOG_VERBOSE, "limit:%d round:%d reset_count:%d\n",
-           cd->limit, cd->round, cd->reset_count);
+           s->limit, s->round, s->reset_count);
 
     return 0;
 }
@@ -99,91 +99,108 @@
 static int config_input(AVFilterLink *inlink)
 {
     AVFilterContext *ctx = inlink->dst;
-    CropDetectContext *cd = ctx->priv;
+    CropDetectContext *s = ctx->priv;
 
-    av_image_fill_max_pixsteps(cd->max_pixsteps, NULL,
+    av_image_fill_max_pixsteps(s->max_pixsteps, NULL,
                                av_pix_fmt_desc_get(inlink->format));
 
-    cd->x1 = inlink->w - 1;
-    cd->y1 = inlink->h - 1;
-    cd->x2 = 0;
-    cd->y2 = 0;
+    s->x1 = inlink->w - 1;
+    s->y1 = inlink->h - 1;
+    s->x2 = 0;
+    s->y2 = 0;
 
     return 0;
 }
 
+#define SET_META(key, value) \
+    snprintf(buf, sizeof(buf), "%d", value);  \
+    av_dict_set(metadata, key, buf, 0)
+
 static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
 {
     AVFilterContext *ctx = inlink->dst;
-    CropDetectContext *cd = ctx->priv;
-    int bpp = cd->max_pixsteps[0];
+    CropDetectContext *s = ctx->priv;
+    int bpp = s->max_pixsteps[0];
     int w, h, x, y, shrink_by;
+    AVDictionary **metadata;
+    char buf[32];
 
     // ignore first 2 frames - they may be empty
-    if (++cd->frame_nb > 0) {
+    if (++s->frame_nb > 0) {
+        metadata = avpriv_frame_get_metadatap(frame);
+
         // Reset the crop area every reset_count frames, if reset_count is > 0
-        if (cd->reset_count > 0 && cd->frame_nb > cd->reset_count) {
-            cd->x1 = frame->width  - 1;
-            cd->y1 = frame->height - 1;
-            cd->x2 = 0;
-            cd->y2 = 0;
-            cd->frame_nb = 1;
+        if (s->reset_count > 0 && s->frame_nb > s->reset_count) {
+            s->x1 = frame->width  - 1;
+            s->y1 = frame->height - 1;
+            s->x2 = 0;
+            s->y2 = 0;
+            s->frame_nb = 1;
         }
 
-        for (y = 0; y < cd->y1; y++) {
-            if (checkline(ctx, frame->data[0] + frame->linesize[0] * y, bpp, frame->width, bpp) > cd->limit) {
-                cd->y1 = y;
+        for (y = 0; y < s->y1; y++) {
+            if (checkline(ctx, frame->data[0] + frame->linesize[0] * y, bpp, frame->width, bpp) > s->limit) {
+                s->y1 = y;
                 break;
             }
         }
 
-        for (y = frame->height - 1; y > cd->y2; y--) {
-            if (checkline(ctx, frame->data[0] + frame->linesize[0] * y, bpp, frame->width, bpp) > cd->limit) {
-                cd->y2 = y;
+        for (y = frame->height - 1; y > s->y2; y--) {
+            if (checkline(ctx, frame->data[0] + frame->linesize[0] * y, bpp, frame->width, bpp) > s->limit) {
+                s->y2 = y;
                 break;
             }
         }
 
-        for (y = 0; y < cd->x1; y++) {
-            if (checkline(ctx, frame->data[0] + bpp*y, frame->linesize[0], frame->height, bpp) > cd->limit) {
-                cd->x1 = y;
+        for (y = 0; y < s->x1; y++) {
+            if (checkline(ctx, frame->data[0] + bpp*y, frame->linesize[0], frame->height, bpp) > s->limit) {
+                s->x1 = y;
                 break;
             }
         }
 
-        for (y = frame->width - 1; y > cd->x2; y--) {
-            if (checkline(ctx, frame->data[0] + bpp*y, frame->linesize[0], frame->height, bpp) > cd->limit) {
-                cd->x2 = y;
+        for (y = frame->width - 1; y > s->x2; y--) {
+            if (checkline(ctx, frame->data[0] + bpp*y, frame->linesize[0], frame->height, bpp) > s->limit) {
+                s->x2 = y;
                 break;
             }
         }
 
         // round x and y (up), important for yuv colorspaces
         // make sure they stay rounded!
-        x = (cd->x1+1) & ~1;
-        y = (cd->y1+1) & ~1;
+        x = (s->x1+1) & ~1;
+        y = (s->y1+1) & ~1;
 
-        w = cd->x2 - x + 1;
-        h = cd->y2 - y + 1;
+        w = s->x2 - x + 1;
+        h = s->y2 - y + 1;
 
         // w and h must be divisible by 2 as well because of yuv
         // colorspace problems.
-        if (cd->round <= 1)
-            cd->round = 16;
-        if (cd->round % 2)
-            cd->round *= 2;
+        if (s->round <= 1)
+            s->round = 16;
+        if (s->round % 2)
+            s->round *= 2;
 
-        shrink_by = w % cd->round;
+        shrink_by = w % s->round;
         w -= shrink_by;
         x += (shrink_by/2 + 1) & ~1;
 
-        shrink_by = h % cd->round;
+        shrink_by = h % s->round;
         h -= shrink_by;
         y += (shrink_by/2 + 1) & ~1;
 
+        SET_META("lavfi.cropdetect.x1", s->x1);
+        SET_META("lavfi.cropdetect.x2", s->x2);
+        SET_META("lavfi.cropdetect.y1", s->y1);
+        SET_META("lavfi.cropdetect.y2", s->y2);
+        SET_META("lavfi.cropdetect.w",  w);
+        SET_META("lavfi.cropdetect.h",  h);
+        SET_META("lavfi.cropdetect.x",  x);
+        SET_META("lavfi.cropdetect.y",  y);
+
         av_log(ctx, AV_LOG_INFO,
                "x1:%d x2:%d y1:%d y2:%d w:%d h:%d x:%d y:%d pts:%"PRId64" t:%f crop=%d:%d:%d:%d\n",
-               cd->x1, cd->x2, cd->y1, cd->y2, w, h, x, y, frame->pts,
+               s->x1, s->x2, s->y1, s->y2, w, h, x, y, frame->pts,
                frame->pts == AV_NOPTS_VALUE ? -1 : frame->pts * av_q2d(inlink->time_base),
                w, h, x, y);
     }
@@ -233,5 +250,5 @@
     .query_formats = query_formats,
     .inputs    = avfilter_vf_cropdetect_inputs,
     .outputs   = avfilter_vf_cropdetect_outputs,
-    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_curves.c b/libavfilter/vf_curves.c
index 626b4ea..6356cef 100644
--- a/libavfilter/vf_curves.c
+++ b/libavfilter/vf_curves.c
@@ -24,11 +24,18 @@
 #include "libavutil/file.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/avassert.h"
+#include "libavutil/pixdesc.h"
 #include "avfilter.h"
+#include "drawutils.h"
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
 
+#define R 0
+#define G 1
+#define B 2
+#define A 3
+
 struct keypoint {
     double x, y;
     struct keypoint *next;
@@ -58,6 +65,8 @@
     char *comp_points_str_all;
     uint8_t graph[NB_COMP + 1][256];
     char *psfile;
+    uint8_t rgba_map[4];
+    int step;
 } CurvesContext;
 
 #define OFFSET(x) offsetof(CurvesContext, x)
@@ -242,27 +251,27 @@
         point = point->next;
     }
 
-#define B 0 /* sub  diagonal (below main) */
-#define M 1 /* main diagonal (center) */
-#define A 2 /* sup  diagonal (above main) */
+#define BD 0 /* sub  diagonal (below main) */
+#define MD 1 /* main diagonal (center) */
+#define AD 2 /* sup  diagonal (above main) */
 
     /* left side of the polynomials into a tridiagonal matrix. */
-    matrix[0][M] = matrix[n - 1][M] = 1;
+    matrix[0][MD] = matrix[n - 1][MD] = 1;
     for (i = 1; i < n - 1; i++) {
-        matrix[i][B] = h[i-1];
-        matrix[i][M] = 2 * (h[i-1] + h[i]);
-        matrix[i][A] = h[i];
+        matrix[i][BD] = h[i-1];
+        matrix[i][MD] = 2 * (h[i-1] + h[i]);
+        matrix[i][AD] = h[i];
     }
 
     /* tridiagonal solving of the linear system */
     for (i = 1; i < n; i++) {
-        double den = matrix[i][M] - matrix[i][B] * matrix[i-1][A];
+        double den = matrix[i][MD] - matrix[i][BD] * matrix[i-1][AD];
         double k = den ? 1./den : 1.;
-        matrix[i][A] *= k;
-        r[i] = (r[i] - matrix[i][B] * r[i - 1]) * k;
+        matrix[i][AD] *= k;
+        r[i] = (r[i] - matrix[i][BD] * r[i - 1]) * k;
     }
     for (i = n - 2; i >= 0; i--)
-        r[i] = r[i] - matrix[i][A] * r[i + 1];
+        r[i] = r[i] - matrix[i][AD] * r[i + 1];
 
     /* compute the graph with x=[0..255] */
     i = 0;
@@ -441,20 +450,43 @@
 
 static int query_formats(AVFilterContext *ctx)
 {
-    static const enum AVPixelFormat pix_fmts[] = {AV_PIX_FMT_RGB24, AV_PIX_FMT_NONE};
+    static const enum AVPixelFormat pix_fmts[] = {
+        AV_PIX_FMT_RGB24,  AV_PIX_FMT_BGR24,
+        AV_PIX_FMT_RGBA,   AV_PIX_FMT_BGRA,
+        AV_PIX_FMT_ARGB,   AV_PIX_FMT_ABGR,
+        AV_PIX_FMT_0RGB,   AV_PIX_FMT_0BGR,
+        AV_PIX_FMT_RGB0,   AV_PIX_FMT_BGR0,
+        AV_PIX_FMT_NONE
+    };
     ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
     return 0;
 }
 
+static int config_input(AVFilterLink *inlink)
+{
+    CurvesContext *curves = inlink->dst->priv;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+
+    ff_fill_rgba_map(curves->rgba_map, inlink->format);
+    curves->step = av_get_padded_bits_per_pixel(desc) >> 3;
+
+    return 0;
+}
+
 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
-    int x, y, i, direct = 0;
+    int x, y, direct = 0;
     AVFilterContext *ctx = inlink->dst;
     CurvesContext *curves = ctx->priv;
-    AVFilterLink *outlink = inlink->dst->outputs[0];
+    AVFilterLink *outlink = ctx->outputs[0];
     AVFrame *out;
     uint8_t *dst;
     const uint8_t *src;
+    const int step = curves->step;
+    const uint8_t r = curves->rgba_map[R];
+    const uint8_t g = curves->rgba_map[G];
+    const uint8_t b = curves->rgba_map[B];
+    const uint8_t a = curves->rgba_map[A];
 
     if (av_frame_is_writable(in)) {
         direct = 1;
@@ -472,12 +504,13 @@
     src = in ->data[0];
 
     for (y = 0; y < inlink->h; y++) {
-        uint8_t *dstp = dst;
-        const uint8_t *srcp = src;
-
-        for (x = 0; x < inlink->w; x++)
-            for (i = 0; i < NB_COMP; i++, dstp++, srcp++)
-                *dstp = curves->graph[i][*srcp];
+        for (x = 0; x < inlink->w * step; x += step) {
+            dst[x + r] = curves->graph[R][src[x + r]];
+            dst[x + g] = curves->graph[G][src[x + g]];
+            dst[x + b] = curves->graph[B][src[x + b]];
+            if (!direct && step == 4)
+                dst[x + a] = src[x + a];
+        }
         dst += out->linesize[0];
         src += in ->linesize[0];
     }
@@ -493,16 +526,17 @@
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
+        .config_props = config_input,
     },
     { NULL }
 };
 
 static const AVFilterPad curves_outputs[] = {
-     {
-         .name = "default",
-         .type = AVMEDIA_TYPE_VIDEO,
-     },
-     { NULL }
+    {
+        .name = "default",
+        .type = AVMEDIA_TYPE_VIDEO,
+    },
+    { NULL }
 };
 
 AVFilter avfilter_vf_curves = {
@@ -514,5 +548,5 @@
     .inputs        = curves_inputs,
     .outputs       = curves_outputs,
     .priv_class    = &curves_class,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_dctdnoiz.c b/libavfilter/vf_dctdnoiz.c
new file mode 100644
index 0000000..92129ad
--- /dev/null
+++ b/libavfilter/vf_dctdnoiz.c
@@ -0,0 +1,433 @@
+/*
+ * Copyright (c) 2013 Clément Bœsch
+ *
+ * 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
+ */
+
+/**
+ * A simple, relatively efficient and extremely slow DCT image denoiser.
+ * @see http://www.ipol.im/pub/art/2011/ys-dct/
+ */
+
+#include "libavcodec/avfft.h"
+#include "libavutil/eval.h"
+#include "libavutil/opt.h"
+#include "drawutils.h"
+#include "internal.h"
+
+#define NBITS 4
+#define BSIZE (1<<(NBITS))
+
+static const char *const var_names[] = { "c", NULL };
+enum { VAR_C, VAR_VARS_NB };
+
+typedef struct {
+    const AVClass *class;
+
+    /* coefficient factor expression */
+    char *expr_str;
+    AVExpr *expr;
+    double var_values[VAR_VARS_NB];
+
+    int pr_width, pr_height;    // width and height to process
+    float sigma;                // used when no expression are st
+    float th;                   // threshold (3*sigma)
+    float color_dct[3][3];      // 3x3 DCT for color decorrelation
+    float *cbuf[2][3];          // two planar rgb color buffers
+    float *weights;             // dct coeff are cumulated with overlapping; these values are used for averaging
+    int p_linesize;             // line sizes for color and weights
+    int overlap;                // number of block overlapping pixels
+    int step;                   // block step increment (BSIZE - overlap)
+    DCTContext *dct, *idct;     // DCT and inverse DCT contexts
+    float *block, *tmp_block;   // two BSIZE x BSIZE block buffers
+} DCTdnoizContext;
+
+#define OFFSET(x) offsetof(DCTdnoizContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption dctdnoiz_options[] = {
+    { "sigma",   "set noise sigma constant",               OFFSET(sigma),    AV_OPT_TYPE_FLOAT,  {.dbl=0},            0, 999,          .flags = FLAGS },
+    { "s",       "set noise sigma constant",               OFFSET(sigma),    AV_OPT_TYPE_FLOAT,  {.dbl=0},            0, 999,          .flags = FLAGS },
+    { "overlap", "set number of block overlapping pixels", OFFSET(overlap),  AV_OPT_TYPE_INT,    {.i64=(1<<NBITS)-1}, 0, (1<<NBITS)-1, .flags = FLAGS },
+    { "expr",    "set coefficient factor expression",      OFFSET(expr_str), AV_OPT_TYPE_STRING, {.str=NULL},                          .flags = FLAGS },
+    { "e",       "set coefficient factor expression",      OFFSET(expr_str), AV_OPT_TYPE_STRING, {.str=NULL},                          .flags = FLAGS },
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(dctdnoiz);
+
+static float *dct_block(DCTdnoizContext *ctx, const float *src, int src_linesize)
+{
+    int x, y;
+    float *column;
+
+    for (y = 0; y < BSIZE; y++) {
+        float *line = ctx->block;
+
+        memcpy(line, src, BSIZE * sizeof(*line));
+        src += src_linesize;
+        av_dct_calc(ctx->dct, line);
+
+        column = ctx->tmp_block + y;
+        column[0] = line[0] * (1. / sqrt(BSIZE));
+        column += BSIZE;
+        for (x = 1; x < BSIZE; x++) {
+            *column = line[x] * sqrt(2. / BSIZE);
+            column += BSIZE;
+        }
+    }
+
+    column = ctx->tmp_block;
+    for (x = 0; x < BSIZE; x++) {
+        av_dct_calc(ctx->dct, column);
+        column[0] *= 1. / sqrt(BSIZE);
+        for (y = 1; y < BSIZE; y++)
+            column[y] *= sqrt(2. / BSIZE);
+        column += BSIZE;
+    }
+
+    for (y = 0; y < BSIZE; y++)
+        for (x = 0; x < BSIZE; x++)
+            ctx->block[y*BSIZE + x] = ctx->tmp_block[x*BSIZE + y];
+
+    return ctx->block;
+}
+
+static void idct_block(DCTdnoizContext *ctx, float *dst, int dst_linesize)
+{
+    int x, y;
+    float *block = ctx->block;
+    float *tmp = ctx->tmp_block;
+
+    for (y = 0; y < BSIZE; y++) {
+        block[0] *= sqrt(BSIZE);
+        for (x = 1; x < BSIZE; x++)
+            block[x] *= 1./sqrt(2. / BSIZE);
+        av_dct_calc(ctx->idct, block);
+        block += BSIZE;
+    }
+
+    block = ctx->block;
+    for (y = 0; y < BSIZE; y++) {
+        tmp[0] = block[y] * sqrt(BSIZE);
+        for (x = 1; x < BSIZE; x++)
+            tmp[x] = block[x*BSIZE + y] * (1./sqrt(2. / BSIZE));
+        av_dct_calc(ctx->idct, tmp);
+        for (x = 0; x < BSIZE; x++)
+            dst[x*dst_linesize + y] += tmp[x];
+    }
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->dst;
+    DCTdnoizContext *s = ctx->priv;
+    int i, x, y, bx, by, linesize, *iweights;
+    const float dct_3x3[3][3] = {
+        { 1./sqrt(3),  1./sqrt(3),  1./sqrt(3) },
+        { 1./sqrt(2),           0, -1./sqrt(2) },
+        { 1./sqrt(6), -2./sqrt(6),  1./sqrt(6) },
+    };
+    uint8_t rgba_map[4];
+
+    ff_fill_rgba_map(rgba_map, inlink->format);
+    for (y = 0; y < 3; y++)
+        for (x = 0; x < 3; x++)
+            s->color_dct[y][x] = dct_3x3[rgba_map[y]][rgba_map[x]];
+
+    s->pr_width  = inlink->w - (inlink->w - BSIZE) % s->step;
+    s->pr_height = inlink->h - (inlink->h - BSIZE) % s->step;
+    if (s->pr_width != inlink->w)
+        av_log(ctx, AV_LOG_WARNING, "The last %d horizontal pixels won't be denoised\n",
+               inlink->w - s->pr_width);
+    if (s->pr_height != inlink->h)
+        av_log(ctx, AV_LOG_WARNING, "The last %d vertical pixels won't be denoised\n",
+               inlink->h - s->pr_height);
+
+    s->p_linesize = linesize = FFALIGN(s->pr_width, 32);
+    for (i = 0; i < 2; i++) {
+        s->cbuf[i][0] = av_malloc(linesize * s->pr_height * sizeof(*s->cbuf[i][0]));
+        s->cbuf[i][1] = av_malloc(linesize * s->pr_height * sizeof(*s->cbuf[i][1]));
+        s->cbuf[i][2] = av_malloc(linesize * s->pr_height * sizeof(*s->cbuf[i][2]));
+        if (!s->cbuf[i][0] || !s->cbuf[i][1] || !s->cbuf[i][2])
+            return AVERROR(ENOMEM);
+    }
+
+    s->weights = av_malloc(s->pr_height * linesize * sizeof(*s->weights));
+    if (!s->weights)
+        return AVERROR(ENOMEM);
+    iweights = av_calloc(s->pr_height, linesize * sizeof(*iweights));
+    if (!iweights)
+        return AVERROR(ENOMEM);
+    for (y = 0; y < s->pr_height - BSIZE + 1; y += s->step)
+        for (x = 0; x < s->pr_width - BSIZE + 1; x += s->step)
+            for (by = 0; by < BSIZE; by++)
+                for (bx = 0; bx < BSIZE; bx++)
+                    iweights[(y + by)*linesize + x + bx]++;
+    for (y = 0; y < s->pr_height; y++)
+        for (x = 0; x < s->pr_width; x++)
+            s->weights[y*linesize + x] = 1. / iweights[y*linesize + x];
+    av_free(iweights);
+
+    return 0;
+}
+
+static av_cold int init(AVFilterContext *ctx)
+{
+    DCTdnoizContext *s = ctx->priv;
+
+    if (s->expr_str) {
+        int ret = av_expr_parse(&s->expr, s->expr_str, var_names,
+                                NULL, NULL, NULL, NULL, 0, ctx);
+        if (ret < 0)
+            return ret;
+    }
+
+    s->th   = s->sigma * 3.;
+    s->step = BSIZE - s->overlap;
+    s->dct  = av_dct_init(NBITS, DCT_II);
+    s->idct = av_dct_init(NBITS, DCT_III);
+    s->block     = av_malloc(BSIZE * BSIZE * sizeof(*s->block));
+    s->tmp_block = av_malloc(BSIZE * BSIZE * sizeof(*s->tmp_block));
+
+    if (!s->dct || !s->idct || !s->tmp_block || !s->block)
+        return AVERROR(ENOMEM);
+
+    return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat pix_fmts[] = {
+        AV_PIX_FMT_BGR24, AV_PIX_FMT_RGB24,
+        AV_PIX_FMT_NONE
+    };
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+static void color_decorrelation(float dct3ch[3][3], float **dst, int dst_linesize,
+                                const uint8_t *src, int src_linesize, int w, int h)
+{
+    int x, y;
+    float *dstp_r = dst[0];
+    float *dstp_g = dst[1];
+    float *dstp_b = dst[2];
+
+    for (y = 0; y < h; y++) {
+        const uint8_t *srcp = src;
+
+        for (x = 0; x < w; x++) {
+            dstp_r[x] = srcp[0] * dct3ch[0][0] + srcp[1] * dct3ch[0][1] + srcp[2] * dct3ch[0][2];
+            dstp_g[x] = srcp[0] * dct3ch[1][0] + srcp[1] * dct3ch[1][1] + srcp[2] * dct3ch[1][2];
+            dstp_b[x] = srcp[0] * dct3ch[2][0] + srcp[1] * dct3ch[2][1] + srcp[2] * dct3ch[2][2];
+            srcp += 3;
+        }
+        src += src_linesize;
+        dstp_r += dst_linesize;
+        dstp_g += dst_linesize;
+        dstp_b += dst_linesize;
+    }
+}
+
+static void color_correlation(float dct3ch[3][3], uint8_t *dst, int dst_linesize,
+                              float **src, int src_linesize, int w, int h)
+{
+    int x, y;
+    const float *src_r = src[0];
+    const float *src_g = src[1];
+    const float *src_b = src[2];
+
+    for (y = 0; y < h; y++) {
+        uint8_t *dstp = dst;
+
+        for (x = 0; x < w; x++) {
+            dstp[0] = av_clip_uint8(src_r[x] * dct3ch[0][0] + src_g[x] * dct3ch[1][0] + src_b[x] * dct3ch[2][0]);
+            dstp[1] = av_clip_uint8(src_r[x] * dct3ch[0][1] + src_g[x] * dct3ch[1][1] + src_b[x] * dct3ch[2][1]);
+            dstp[2] = av_clip_uint8(src_r[x] * dct3ch[0][2] + src_g[x] * dct3ch[1][2] + src_b[x] * dct3ch[2][2]);
+            dstp += 3;
+        }
+        dst += dst_linesize;
+        src_r += src_linesize;
+        src_g += src_linesize;
+        src_b += src_linesize;
+    }
+}
+
+static void filter_plane(AVFilterContext *ctx,
+                         float *dst, int dst_linesize,
+                         const float *src, int src_linesize,
+                         int w, int h)
+{
+    int x, y, bx, by;
+    DCTdnoizContext *s = ctx->priv;
+    float *dst0 = dst;
+    const float *weights = s->weights;
+
+    // reset block sums
+    memset(dst, 0, h * dst_linesize * sizeof(*dst));
+
+    // block dct sums
+    for (y = 0; y < h - BSIZE + 1; y += s->step) {
+        for (x = 0; x < w - BSIZE + 1; x += s->step) {
+            float *ftb = dct_block(s, src + x, src_linesize);
+
+            if (s->expr) {
+                for (by = 0; by < BSIZE; by++) {
+                    for (bx = 0; bx < BSIZE; bx++) {
+                        s->var_values[VAR_C] = FFABS(*ftb);
+                        *ftb++ *= av_expr_eval(s->expr, s->var_values, s);
+                    }
+                }
+            } else {
+                for (by = 0; by < BSIZE; by++) {
+                    for (bx = 0; bx < BSIZE; bx++) {
+                        if (FFABS(*ftb) < s->th)
+                            *ftb = 0;
+                        ftb++;
+                    }
+                }
+            }
+            idct_block(s, dst + x, dst_linesize);
+        }
+        src += s->step * src_linesize;
+        dst += s->step * dst_linesize;
+    }
+
+    // average blocks
+    dst = dst0;
+    for (y = 0; y < h; y++) {
+        for (x = 0; x < w; x++)
+            dst[x] *= weights[x];
+        dst += dst_linesize;
+        weights += dst_linesize;
+    }
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+{
+    AVFilterContext *ctx = inlink->dst;
+    DCTdnoizContext *s = ctx->priv;
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+    int direct, plane;
+    AVFrame *out;
+
+    if (av_frame_is_writable(in)) {
+        direct = 1;
+        out = in;
+    } else {
+        direct = 0;
+        out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+        if (!out) {
+            av_frame_free(&in);
+            return AVERROR(ENOMEM);
+        }
+        av_frame_copy_props(out, in);
+    }
+
+    color_decorrelation(s->color_dct, s->cbuf[0], s->p_linesize,
+                        in->data[0], in->linesize[0], s->pr_width, s->pr_height);
+    for (plane = 0; plane < 3; plane++)
+        filter_plane(ctx, s->cbuf[1][plane], s->p_linesize,
+                          s->cbuf[0][plane], s->p_linesize,
+                          s->pr_width, s->pr_height);
+    color_correlation(s->color_dct, out->data[0], out->linesize[0],
+                      s->cbuf[1], s->p_linesize, s->pr_width, s->pr_height);
+
+    if (!direct) {
+        int y;
+        uint8_t *dst = out->data[0];
+        const uint8_t *src = in->data[0];
+        const int dst_linesize = out->linesize[0];
+        const int src_linesize = in->linesize[0];
+        const int hpad = (inlink->w - s->pr_width) * 3;
+        const int vpad = (inlink->h - s->pr_height);
+
+        if (hpad) {
+            uint8_t       *dstp = dst + s->pr_width * 3;
+            const uint8_t *srcp = src + s->pr_width * 3;
+
+            for (y = 0; y < s->pr_height; y++) {
+                memcpy(dstp, srcp, hpad);
+                dstp += dst_linesize;
+                srcp += src_linesize;
+            }
+        }
+        if (vpad) {
+            uint8_t       *dstp = dst + s->pr_height * dst_linesize;
+            const uint8_t *srcp = src + s->pr_height * src_linesize;
+
+            for (y = 0; y < vpad; y++) {
+                memcpy(dstp, srcp, inlink->w * 3);
+                dstp += dst_linesize;
+                srcp += src_linesize;
+            }
+        }
+
+        av_frame_free(&in);
+    }
+
+    return ff_filter_frame(outlink, out);
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    int i;
+    DCTdnoizContext *s = ctx->priv;
+
+    av_dct_end(s->dct);
+    av_dct_end(s->idct);
+    av_free(s->block);
+    av_free(s->tmp_block);
+    av_free(s->weights);
+    for (i = 0; i < 2; i++) {
+        av_free(s->cbuf[i][0]);
+        av_free(s->cbuf[i][1]);
+        av_free(s->cbuf[i][2]);
+    }
+    av_expr_free(s->expr);
+}
+
+static const AVFilterPad dctdnoiz_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = filter_frame,
+        .config_props = config_input,
+    },
+    { NULL }
+};
+
+static const AVFilterPad dctdnoiz_outputs[] = {
+    {
+        .name = "default",
+        .type = AVMEDIA_TYPE_VIDEO,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_dctdnoiz = {
+    .name          = "dctdnoiz",
+    .description   = NULL_IF_CONFIG_SMALL("Denoise frames using 2D DCT."),
+    .priv_size     = sizeof(DCTdnoizContext),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+    .inputs        = dctdnoiz_inputs,
+    .outputs       = dctdnoiz_outputs,
+    .priv_class    = &dctdnoiz_class,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
+};
diff --git a/libavfilter/vf_decimate.c b/libavfilter/vf_decimate.c
index 9548531..8767d5f 100644
--- a/libavfilter/vf_decimate.c
+++ b/libavfilter/vf_decimate.c
@@ -92,8 +92,8 @@
         const int linesize2 = f2->linesize[plane];
         const uint8_t *f1p = f1->data[plane];
         const uint8_t *f2p = f2->data[plane];
-        int width    = plane ? f1->width  >> dm->hsub : f1->width;
-        int height   = plane ? f1->height >> dm->vsub : f1->height;
+        int width    = plane ? FF_CEIL_RSHIFT(f1->width,  dm->hsub) : f1->width;
+        int height   = plane ? FF_CEIL_RSHIFT(f1->height, dm->vsub) : f1->height;
         int hblockx  = dm->blockx / 2;
         int hblocky  = dm->blocky / 2;
 
diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c
index c747b02..971e986 100644
--- a/libavfilter/vf_delogo.c
+++ b/libavfilter/vf_delogo.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2002 Jindrich Makovicka <makovick@gmail.com>
  * Copyright (c) 2011 Stefano Sabatini
+ * Copyright (c) 2013 Jean Delvare <khali@linux-fr.org>
  *
  * This file is part of FFmpeg.
  *
@@ -22,7 +23,8 @@
 /**
  * @file
  * A very simple tv station logo remover
- * Ported from MPlayer libmpcodecs/vf_delogo.c.
+ * Originally imported from MPlayer libmpcodecs/vf_delogo.c,
+ * the algorithm was later improved.
  */
 
 #include "libavutil/common.h"
@@ -35,8 +37,8 @@
 #include "video.h"
 
 /**
- * Apply a simple delogo algorithm to the image in dst and put the
- * result in src.
+ * Apply a simple delogo algorithm to the image in src and put the
+ * result in dst.
  *
  * The algorithm is only applied to the region specified by the logo
  * parameters.
@@ -54,15 +56,16 @@
  */
 static void apply_delogo(uint8_t *dst, int dst_linesize,
                          uint8_t *src, int src_linesize,
-                         int w, int h,
+                         int w, int h, AVRational sar,
                          int logo_x, int logo_y, int logo_w, int logo_h,
-                         int band, int show, int direct)
+                         unsigned int band, int show, int direct)
 {
     int x, y;
-    int interp, dist;
+    uint64_t interp, weightl, weightr, weightt, weightb;
     uint8_t *xdst, *xsrc;
 
     uint8_t *topleft, *botleft, *topright;
+    unsigned int left_sample, right_sample;
     int xclipl, xclipr, yclipt, yclipb;
     int logo_x1, logo_x2, logo_y1, logo_y2;
 
@@ -87,32 +90,43 @@
     src += (logo_y1 + 1) * src_linesize;
 
     for (y = logo_y1+1; y < logo_y2-1; y++) {
+        left_sample = topleft[src_linesize*(y-logo_y1)]   +
+                      topleft[src_linesize*(y-logo_y1-1)] +
+                      topleft[src_linesize*(y-logo_y1+1)];
+        right_sample = topright[src_linesize*(y-logo_y1)]   +
+                       topright[src_linesize*(y-logo_y1-1)] +
+                       topright[src_linesize*(y-logo_y1+1)];
+
         for (x = logo_x1+1,
              xdst = dst+logo_x1+1,
              xsrc = src+logo_x1+1; x < logo_x2-1; x++, xdst++, xsrc++) {
+
+            /* Weighted interpolation based on relative distances, taking SAR into account */
+            weightl = (uint64_t)              (logo_x2-1-x) * (y-logo_y1) * (logo_y2-1-y) * sar.den;
+            weightr = (uint64_t)(x-logo_x1)                 * (y-logo_y1) * (logo_y2-1-y) * sar.den;
+            weightt = (uint64_t)(x-logo_x1) * (logo_x2-1-x)               * (logo_y2-1-y) * sar.num;
+            weightb = (uint64_t)(x-logo_x1) * (logo_x2-1-x) * (y-logo_y1)                 * sar.num;
+
             interp =
-                (topleft[src_linesize*(y-logo_y  -yclipt)]   +
-                 topleft[src_linesize*(y-logo_y-1-yclipt)]   +
-                 topleft[src_linesize*(y-logo_y+1-yclipt)])  * (logo_w-(x-logo_x))/logo_w
+                left_sample * weightl
                 +
-                (topright[src_linesize*(y-logo_y-yclipt)]    +
-                 topright[src_linesize*(y-logo_y-1-yclipt)]  +
-                 topright[src_linesize*(y-logo_y+1-yclipt)]) * (x-logo_x)/logo_w
+                right_sample * weightr
                 +
-                (topleft[x-logo_x-xclipl]    +
-                 topleft[x-logo_x-1-xclipl]  +
-                 topleft[x-logo_x+1-xclipl]) * (logo_h-(y-logo_y))/logo_h
+                (topleft[x-logo_x1]    +
+                 topleft[x-logo_x1-1]  +
+                 topleft[x-logo_x1+1]) * weightt
                 +
-                (botleft[x-logo_x-xclipl]    +
-                 botleft[x-logo_x-1-xclipl]  +
-                 botleft[x-logo_x+1-xclipl]) * (y-logo_y)/logo_h;
-            interp /= 6;
+                (botleft[x-logo_x1]    +
+                 botleft[x-logo_x1-1]  +
+                 botleft[x-logo_x1+1]) * weightb;
+            interp /= (weightl + weightr + weightt + weightb) * 3U;
 
             if (y >= logo_y+band && y < logo_y+logo_h-band &&
                 x >= logo_x+band && x < logo_x+logo_w-band) {
                 *xdst = interp;
             } else {
-                dist = 0;
+                unsigned dist = 0;
+
                 if      (x < logo_x+band)
                     dist = FFMAX(dist, logo_x-x+band);
                 else if (x >= logo_x+logo_w-band)
@@ -147,8 +161,8 @@
     { "y",    "set logo y position",       OFFSET(y),    AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS },
     { "w",    "set logo width",            OFFSET(w),    AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS },
     { "h",    "set logo height",           OFFSET(h),    AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS },
-    { "band", "set delogo area band size", OFFSET(band), AV_OPT_TYPE_INT, { .i64 =  4 }, -1, INT_MAX, FLAGS },
-    { "t",    "set delogo area band size", OFFSET(band), AV_OPT_TYPE_INT, { .i64 =  4 }, -1, INT_MAX, FLAGS },
+    { "band", "set delogo area band size", OFFSET(band), AV_OPT_TYPE_INT, { .i64 =  4 },  1, INT_MAX, FLAGS },
+    { "t",    "set delogo area band size", OFFSET(band), AV_OPT_TYPE_INT, { .i64 =  4 },  1, INT_MAX, FLAGS },
     { "show", "show delogo area",          OFFSET(show), AV_OPT_TYPE_INT, { .i64 =  0 },  0, 1,       FLAGS },
     { NULL },
 };
@@ -170,11 +184,11 @@
 
 static av_cold int init(AVFilterContext *ctx)
 {
-    DelogoContext *delogo = ctx->priv;
+    DelogoContext *s = ctx->priv;
 
 #define CHECK_UNSET_OPT(opt)                                            \
-    if (delogo->opt == -1) {                                            \
-        av_log(delogo, AV_LOG_ERROR, "Option %s was not set.\n", #opt); \
+    if (s->opt == -1) {                                            \
+        av_log(s, AV_LOG_ERROR, "Option %s was not set.\n", #opt); \
         return AVERROR(EINVAL);                                         \
     }
     CHECK_UNSET_OPT(x);
@@ -182,25 +196,20 @@
     CHECK_UNSET_OPT(w);
     CHECK_UNSET_OPT(h);
 
-    if (delogo->band < 0 || delogo->show) {
-        delogo->show = 1;
-        delogo->band = 4;
-    }
-
     av_log(ctx, AV_LOG_VERBOSE, "x:%d y:%d, w:%d h:%d band:%d show:%d\n",
-           delogo->x, delogo->y, delogo->w, delogo->h, delogo->band, delogo->show);
+           s->x, s->y, s->w, s->h, s->band, s->show);
 
-    delogo->w += delogo->band*2;
-    delogo->h += delogo->band*2;
-    delogo->x -= delogo->band;
-    delogo->y -= delogo->band;
+    s->w += s->band*2;
+    s->h += s->band*2;
+    s->x -= s->band;
+    s->y -= s->band;
 
     return 0;
 }
 
 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
-    DelogoContext *delogo = inlink->dst->priv;
+    DelogoContext *s = inlink->dst->priv;
     AVFilterLink *outlink = inlink->dst->outputs[0];
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
     AVFrame *out;
@@ -208,6 +217,7 @@
     int vsub0 = desc->log2_chroma_h;
     int direct = 0;
     int plane;
+    AVRational sar;
 
     if (av_frame_is_writable(in)) {
         direct = 1;
@@ -222,17 +232,26 @@
         av_frame_copy_props(out, in);
     }
 
-    for (plane = 0; plane < 4 && in->data[plane]; plane++) {
+    sar = in->sample_aspect_ratio;
+    /* Assume square pixels if SAR is unknown */
+    if (!sar.num)
+        sar.num = sar.den = 1;
+
+    for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) {
         int hsub = plane == 1 || plane == 2 ? hsub0 : 0;
         int vsub = plane == 1 || plane == 2 ? vsub0 : 0;
 
         apply_delogo(out->data[plane], out->linesize[plane],
                      in ->data[plane], in ->linesize[plane],
-                     inlink->w>>hsub, inlink->h>>vsub,
-                     delogo->x>>hsub, delogo->y>>vsub,
-                     delogo->w>>hsub, delogo->h>>vsub,
-                     delogo->band>>FFMIN(hsub, vsub),
-                     delogo->show, direct);
+                     FF_CEIL_RSHIFT(inlink->w, hsub),
+                     FF_CEIL_RSHIFT(inlink->h, vsub),
+                     sar, s->x>>hsub, s->y>>vsub,
+                     /* Up and left borders were rounded down, inject lost bits
+                      * into width and height to avoid error accumulation */
+                     FF_CEIL_RSHIFT(s->w + (s->x & ((1<<hsub)-1)), hsub),
+                     FF_CEIL_RSHIFT(s->h + (s->y & ((1<<vsub)-1)), vsub),
+                     s->band>>FFMIN(hsub, vsub),
+                     s->show, direct);
     }
 
     if (!direct)
@@ -269,5 +288,5 @@
 
     .inputs    = avfilter_vf_delogo_inputs,
     .outputs   = avfilter_vf_delogo_outputs,
-    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_deshake.c b/libavfilter/vf_deshake.c
index fd72132..4729c7e 100644
--- a/libavfilter/vf_deshake.c
+++ b/libavfilter/vf_deshake.c
@@ -355,6 +355,11 @@
     deshake->blocksize /= 2;
     deshake->blocksize = av_clip(deshake->blocksize, 4, 128);
 
+    if (deshake->rx % 16) {
+        av_log(ctx, AV_LOG_ERROR, "rx must be a multiple of 16\n");
+        return AVERROR_PATCHWELCOME;
+    }
+
     if (deshake->filename)
         deshake->fp = fopen(deshake->filename, "w");
     if (deshake->fp)
diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c
index c2ffbf3..7dff875 100644
--- a/libavfilter/vf_drawbox.c
+++ b/libavfilter/vf_drawbox.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2008 Affine Systems, Inc (Michael Sullivan, Bobby Impollonia)
+ * Copyright (c) 2013 Andrey Utkin <andrey.krieger.utkin gmail com>
  *
  * This file is part of FFmpeg.
  *
@@ -20,13 +21,14 @@
 
 /**
  * @file
- * Box drawing filter. Also a nice template for a filter that needs to
- * write in the input frame.
+ * Box and grid drawing filters. Also a nice template for a filter
+ * that needs to write in the input frame.
  */
 
 #include "libavutil/colorspace.h"
 #include "libavutil/common.h"
 #include "libavutil/opt.h"
+#include "libavutil/eval.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/parseutils.h"
 #include "avfilter.h"
@@ -34,32 +36,66 @@
 #include "internal.h"
 #include "video.h"
 
+static const char *const var_names[] = {
+    "dar",
+    "hsub", "vsub",
+    "in_h", "ih",      ///< height of the input video
+    "in_w", "iw",      ///< width  of the input video
+    "sar",
+    "x",
+    "y",
+    "h",              ///< height of the rendered box
+    "w",              ///< width  of the rendered box
+    "t",
+    NULL
+};
+
 enum { Y, U, V, A };
 
+enum var_name {
+    VAR_DAR,
+    VAR_HSUB, VAR_VSUB,
+    VAR_IN_H, VAR_IH,
+    VAR_IN_W, VAR_IW,
+    VAR_SAR,
+    VAR_X,
+    VAR_Y,
+    VAR_H,
+    VAR_W,
+    VAR_T,
+    VARS_NB
+};
+
 typedef struct {
     const AVClass *class;
-    int x, y, w, h, thickness;
+    int x, y, w, h;
+    int thickness;
     char *color_str;
     unsigned char yuv_color[4];
     int invert_color; ///< invert luma color
     int vsub, hsub;   ///< chroma subsampling
+    char *x_expr, *y_expr; ///< expression for x and y
+    char *w_expr, *h_expr; ///< expression for width and height
+    char *t_expr;          ///< expression for thickness
 } DrawBoxContext;
 
+static const int NUM_EXPR_EVALS = 5;
+
 static av_cold int init(AVFilterContext *ctx)
 {
-    DrawBoxContext *drawbox = ctx->priv;
+    DrawBoxContext *s = ctx->priv;
     uint8_t rgba_color[4];
 
-    if (!strcmp(drawbox->color_str, "invert"))
-        drawbox->invert_color = 1;
-    else if (av_parse_color(rgba_color, drawbox->color_str, -1, ctx) < 0)
+    if (!strcmp(s->color_str, "invert"))
+        s->invert_color = 1;
+    else if (av_parse_color(rgba_color, s->color_str, -1, ctx) < 0)
         return AVERROR(EINVAL);
 
-    if (!drawbox->invert_color) {
-        drawbox->yuv_color[Y] = RGB_TO_Y_CCIR(rgba_color[0], rgba_color[1], rgba_color[2]);
-        drawbox->yuv_color[U] = RGB_TO_U_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
-        drawbox->yuv_color[V] = RGB_TO_V_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
-        drawbox->yuv_color[A] = rgba_color[3];
+    if (!s->invert_color) {
+        s->yuv_color[Y] = RGB_TO_Y_CCIR(rgba_color[0], rgba_color[1], rgba_color[2]);
+        s->yuv_color[U] = RGB_TO_U_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
+        s->yuv_color[V] = RGB_TO_V_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
+        s->yuv_color[A] = rgba_color[3];
     }
 
     return 0;
@@ -81,49 +117,112 @@
 
 static int config_input(AVFilterLink *inlink)
 {
-    DrawBoxContext *drawbox = inlink->dst->priv;
+    AVFilterContext *ctx = inlink->dst;
+    DrawBoxContext *s = ctx->priv;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+    double var_values[VARS_NB], res;
+    char *expr;
+    int ret;
+    int i;
 
-    drawbox->hsub = desc->log2_chroma_w;
-    drawbox->vsub = desc->log2_chroma_h;
+    s->hsub = desc->log2_chroma_w;
+    s->vsub = desc->log2_chroma_h;
 
-    if (drawbox->w == 0) drawbox->w = inlink->w;
-    if (drawbox->h == 0) drawbox->h = inlink->h;
+    var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h;
+    var_values[VAR_IN_W] = var_values[VAR_IW] = inlink->w;
+    var_values[VAR_SAR]  = inlink->sample_aspect_ratio.num ? av_q2d(inlink->sample_aspect_ratio) : 1;
+    var_values[VAR_DAR]  = (double)inlink->w / inlink->h * var_values[VAR_SAR];
+    var_values[VAR_HSUB] = s->hsub;
+    var_values[VAR_VSUB] = s->vsub;
+    var_values[VAR_X] = NAN;
+    var_values[VAR_Y] = NAN;
+    var_values[VAR_H] = NAN;
+    var_values[VAR_W] = NAN;
+    var_values[VAR_T] = NAN;
 
-    av_log(inlink->dst, AV_LOG_VERBOSE, "x:%d y:%d w:%d h:%d color:0x%02X%02X%02X%02X\n",
-           drawbox->x, drawbox->y, drawbox->w, drawbox->h,
-           drawbox->yuv_color[Y], drawbox->yuv_color[U], drawbox->yuv_color[V], drawbox->yuv_color[A]);
+    for (i = 0; i <= NUM_EXPR_EVALS; i++) {
+        /* evaluate expressions, fail on last iteration */
+        if ((ret = av_expr_parse_and_eval(&res, (expr = s->x_expr),
+                                          var_names, var_values,
+                                          NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS)
+            goto fail;
+        s->x = var_values[VAR_X] = res;
+
+        if ((ret = av_expr_parse_and_eval(&res, (expr = s->y_expr),
+                                          var_names, var_values,
+                                          NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS)
+            goto fail;
+        s->y = var_values[VAR_Y] = res;
+
+        if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr),
+                                          var_names, var_values,
+                                          NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS)
+            goto fail;
+        s->w = var_values[VAR_W] = res;
+
+        if ((ret = av_expr_parse_and_eval(&res, (expr = s->h_expr),
+                                          var_names, var_values,
+                                          NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS)
+            goto fail;
+        s->h = var_values[VAR_H] = res;
+
+        if ((ret = av_expr_parse_and_eval(&res, (expr = s->t_expr),
+                                          var_names, var_values,
+                                          NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS)
+            goto fail;
+        s->thickness = var_values[VAR_T] = res;
+    }
+
+    /* if w or h are zero, use the input w/h */
+    s->w = (s->w > 0) ? s->w : inlink->w;
+    s->h = (s->h > 0) ? s->h : inlink->h;
+
+    /* sanity check width and height */
+    if (s->w <  0 || s->h <  0) {
+        av_log(ctx, AV_LOG_ERROR, "Size values less than 0 are not acceptable.\n");
+        return AVERROR(EINVAL);
+    }
+
+    av_log(ctx, AV_LOG_VERBOSE, "x:%d y:%d w:%d h:%d color:0x%02X%02X%02X%02X\n",
+           s->x, s->y, s->w, s->h,
+           s->yuv_color[Y], s->yuv_color[U], s->yuv_color[V], s->yuv_color[A]);
 
     return 0;
+
+fail:
+    av_log(ctx, AV_LOG_ERROR,
+           "Error when evaluating the expression '%s'.\n",
+           expr);
+    return ret;
 }
 
 static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
 {
-    DrawBoxContext *drawbox = inlink->dst->priv;
-    int plane, x, y, xb = drawbox->x, yb = drawbox->y;
+    DrawBoxContext *s = inlink->dst->priv;
+    int plane, x, y, xb = s->x, yb = s->y;
     unsigned char *row[4];
 
-    for (y = FFMAX(yb, 0); y < frame->height && y < (yb + drawbox->h); y++) {
+    for (y = FFMAX(yb, 0); y < frame->height && y < (yb + s->h); y++) {
         row[0] = frame->data[0] + y * frame->linesize[0];
 
         for (plane = 1; plane < 3; plane++)
             row[plane] = frame->data[plane] +
-                 frame->linesize[plane] * (y >> drawbox->vsub);
+                 frame->linesize[plane] * (y >> s->vsub);
 
-        if (drawbox->invert_color) {
-            for (x = FFMAX(xb, 0); x < xb + drawbox->w && x < frame->width; x++)
-                if ((y - yb < drawbox->thickness-1) || (yb + drawbox->h - y < drawbox->thickness) ||
-                    (x - xb < drawbox->thickness-1) || (xb + drawbox->w - x < drawbox->thickness))
+        if (s->invert_color) {
+            for (x = FFMAX(xb, 0); x < xb + s->w && x < frame->width; x++)
+                if ((y - yb < s->thickness) || (yb + s->h - 1 - y < s->thickness) ||
+                    (x - xb < s->thickness) || (xb + s->w - 1 - x < s->thickness))
                     row[0][x] = 0xff - row[0][x];
         } else {
-            for (x = FFMAX(xb, 0); x < xb + drawbox->w && x < frame->width; x++) {
-                double alpha = (double)drawbox->yuv_color[A] / 255;
+            for (x = FFMAX(xb, 0); x < xb + s->w && x < frame->width; x++) {
+                double alpha = (double)s->yuv_color[A] / 255;
 
-                if ((y - yb < drawbox->thickness-1) || (yb + drawbox->h - y < drawbox->thickness) ||
-                    (x - xb < drawbox->thickness-1) || (xb + drawbox->w - x < drawbox->thickness)) {
-                    row[0][x                 ] = (1 - alpha) * row[0][x                 ] + alpha * drawbox->yuv_color[Y];
-                    row[1][x >> drawbox->hsub] = (1 - alpha) * row[1][x >> drawbox->hsub] + alpha * drawbox->yuv_color[U];
-                    row[2][x >> drawbox->hsub] = (1 - alpha) * row[2][x >> drawbox->hsub] + alpha * drawbox->yuv_color[V];
+                if ((y - yb < s->thickness) || (yb + s->h - 1 - y < s->thickness) ||
+                    (x - xb < s->thickness) || (xb + s->w - 1 - x < s->thickness)) {
+                    row[0][x                 ] = (1 - alpha) * row[0][x                 ] + alpha * s->yuv_color[Y];
+                    row[1][x >> s->hsub] = (1 - alpha) * row[1][x >> s->hsub] + alpha * s->yuv_color[U];
+                    row[2][x >> s->hsub] = (1 - alpha) * row[2][x >> s->hsub] + alpha * s->yuv_color[V];
                 }
             }
         }
@@ -135,23 +234,25 @@
 #define OFFSET(x) offsetof(DrawBoxContext, x)
 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
 
+#if CONFIG_DRAWBOX_FILTER
+
 static const AVOption drawbox_options[] = {
-    { "x",      "Horizontal position of the left box edge", OFFSET(x),         AV_OPT_TYPE_INT,    { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS },
-    { "y",      "Vertical position of the top box edge",    OFFSET(y),         AV_OPT_TYPE_INT,    { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS },
-    { "width",  "Width of the box",                         OFFSET(w),         AV_OPT_TYPE_INT,    { .i64 = 0 }, 0,       INT_MAX, FLAGS },
-    { "w",      "Width of the box",                         OFFSET(w),         AV_OPT_TYPE_INT,    { .i64 = 0 }, 0,       INT_MAX, FLAGS },
-    { "height", "Height of the box",                        OFFSET(h),         AV_OPT_TYPE_INT,    { .i64 = 0 }, 0,       INT_MAX, FLAGS },
-    { "h",      "Height of the box",                        OFFSET(h),         AV_OPT_TYPE_INT,    { .i64 = 0 }, 0,       INT_MAX, FLAGS },
-    { "color",  "Color of the box",                         OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, CHAR_MIN, CHAR_MAX, .flags = FLAGS },
-    { "c",      "Color of the box",                         OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, CHAR_MIN, CHAR_MAX, .flags = FLAGS },
-    { "thickness",   "set the box maximum thickness",       OFFSET(thickness), AV_OPT_TYPE_INT, {.i64=4}, 0, INT_MAX, FLAGS },
-    { "t",           "set the box maximum thickness",       OFFSET(thickness), AV_OPT_TYPE_INT, {.i64=4}, 0, INT_MAX, FLAGS },
-    { NULL },
+    { "x",         "set horizontal position of the left box edge", OFFSET(x_expr),    AV_OPT_TYPE_STRING, { .str="0" },       CHAR_MIN, CHAR_MAX, FLAGS },
+    { "y",         "set vertical position of the top box edge",    OFFSET(y_expr),    AV_OPT_TYPE_STRING, { .str="0" },       CHAR_MIN, CHAR_MAX, FLAGS },
+    { "width",     "set width of the box",                         OFFSET(w_expr),    AV_OPT_TYPE_STRING, { .str="0" },       CHAR_MIN, CHAR_MAX, FLAGS },
+    { "w",         "set width of the box",                         OFFSET(w_expr),    AV_OPT_TYPE_STRING, { .str="0" },       CHAR_MIN, CHAR_MAX, FLAGS },
+    { "height",    "set height of the box",                        OFFSET(h_expr),    AV_OPT_TYPE_STRING, { .str="0" },       CHAR_MIN, CHAR_MAX, FLAGS },
+    { "h",         "set height of the box",                        OFFSET(h_expr),    AV_OPT_TYPE_STRING, { .str="0" },       CHAR_MIN, CHAR_MAX, FLAGS },
+    { "color",     "set color of the box",                         OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "c",         "set color of the box",                         OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "thickness", "set the box thickness",                        OFFSET(t_expr),    AV_OPT_TYPE_STRING, { .str="3" },       CHAR_MIN, CHAR_MAX, FLAGS },
+    { "t",         "set the box thickness",                        OFFSET(t_expr),    AV_OPT_TYPE_STRING, { .str="3" },       CHAR_MIN, CHAR_MAX, FLAGS },
+    { NULL }
 };
 
 AVFILTER_DEFINE_CLASS(drawbox);
 
-static const AVFilterPad avfilter_vf_drawbox_inputs[] = {
+static const AVFilterPad drawbox_inputs[] = {
     {
         .name             = "default",
         .type             = AVMEDIA_TYPE_VIDEO,
@@ -163,7 +264,7 @@
     { NULL }
 };
 
-static const AVFilterPad avfilter_vf_drawbox_outputs[] = {
+static const AVFilterPad drawbox_outputs[] = {
     {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
@@ -179,7 +280,115 @@
     .init      = init,
 
     .query_formats   = query_formats,
-    .inputs    = avfilter_vf_drawbox_inputs,
-    .outputs   = avfilter_vf_drawbox_outputs,
-    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .inputs    = drawbox_inputs,
+    .outputs   = drawbox_outputs,
+    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
+#endif /* CONFIG_DRAWBOX_FILTER */
+
+#if CONFIG_DRAWGRID_FILTER
+static av_pure av_always_inline int pixel_belongs_to_grid(DrawBoxContext *drawgrid, int x, int y)
+{
+    // x is horizontal (width) coord,
+    // y is vertical (height) coord
+    int x_modulo;
+    int y_modulo;
+
+    // Abstract from the offset
+    x -= drawgrid->x;
+    y -= drawgrid->y;
+
+    x_modulo = x % drawgrid->w;
+    y_modulo = y % drawgrid->h;
+
+    // If x or y got negative, fix values to preserve logics
+    if (x_modulo < 0)
+        x_modulo += drawgrid->w;
+    if (y_modulo < 0)
+        y_modulo += drawgrid->h;
+
+    return x_modulo < drawgrid->thickness  // Belongs to vertical line
+        || y_modulo < drawgrid->thickness;  // Belongs to horizontal line
+}
+
+static int drawgrid_filter_frame(AVFilterLink *inlink, AVFrame *frame)
+{
+    DrawBoxContext *drawgrid = inlink->dst->priv;
+    int plane, x, y;
+    uint8_t *row[4];
+
+    for (y = 0; y < frame->height; y++) {
+        row[0] = frame->data[0] + y * frame->linesize[0];
+
+        for (plane = 1; plane < 3; plane++)
+            row[plane] = frame->data[plane] +
+                 frame->linesize[plane] * (y >> drawgrid->vsub);
+
+        if (drawgrid->invert_color) {
+            for (x = 0; x < frame->width; x++)
+                if (pixel_belongs_to_grid(drawgrid, x, y))
+                    row[0][x] = 0xff - row[0][x];
+        } else {
+            for (x = 0; x < frame->width; x++) {
+                double alpha = (double)drawgrid->yuv_color[A] / 255;
+
+                if (pixel_belongs_to_grid(drawgrid, x, y)) {
+                    row[0][x                  ] = (1 - alpha) * row[0][x                  ] + alpha * drawgrid->yuv_color[Y];
+                    row[1][x >> drawgrid->hsub] = (1 - alpha) * row[1][x >> drawgrid->hsub] + alpha * drawgrid->yuv_color[U];
+                    row[2][x >> drawgrid->hsub] = (1 - alpha) * row[2][x >> drawgrid->hsub] + alpha * drawgrid->yuv_color[V];
+                }
+            }
+        }
+    }
+
+    return ff_filter_frame(inlink->dst->outputs[0], frame);
+}
+
+static const AVOption drawgrid_options[] = {
+    { "x",         "set horizontal offset",   OFFSET(x_expr),    AV_OPT_TYPE_STRING, { .str="0" },       CHAR_MIN, CHAR_MAX, FLAGS },
+    { "y",         "set vertical offset",     OFFSET(y_expr),    AV_OPT_TYPE_STRING, { .str="0" },       CHAR_MIN, CHAR_MAX, FLAGS },
+    { "width",     "set width of grid cell",  OFFSET(w_expr),    AV_OPT_TYPE_STRING, { .str="0" },       CHAR_MIN, CHAR_MAX, FLAGS },
+    { "w",         "set width of grid cell",  OFFSET(w_expr),    AV_OPT_TYPE_STRING, { .str="0" },       CHAR_MIN, CHAR_MAX, FLAGS },
+    { "height",    "set height of grid cell", OFFSET(h_expr),    AV_OPT_TYPE_STRING, { .str="0" },       CHAR_MIN, CHAR_MAX, FLAGS },
+    { "h",         "set height of grid cell", OFFSET(h_expr),    AV_OPT_TYPE_STRING, { .str="0" },       CHAR_MIN, CHAR_MAX, FLAGS },
+    { "color",     "set color of the grid",   OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "c",         "set color of the grid",   OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "thickness", "set grid line thickness", OFFSET(t_expr),    AV_OPT_TYPE_STRING, {.str="1"},         CHAR_MIN, CHAR_MAX, FLAGS },
+    { "t",         "set grid line thickness", OFFSET(t_expr),    AV_OPT_TYPE_STRING, {.str="1"},         CHAR_MIN, CHAR_MAX, FLAGS },
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(drawgrid);
+
+static const AVFilterPad drawgrid_inputs[] = {
+    {
+        .name           = "default",
+        .type           = AVMEDIA_TYPE_VIDEO,
+        .config_props   = config_input,
+        .filter_frame   = drawgrid_filter_frame,
+        .needs_writable = 1,
+    },
+    { NULL }
+};
+
+static const AVFilterPad drawgrid_outputs[] = {
+    {
+        .name = "default",
+        .type = AVMEDIA_TYPE_VIDEO,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_drawgrid = {
+    .name          = "drawgrid",
+    .description   = NULL_IF_CONFIG_SMALL("Draw a colored grid on the input video."),
+    .priv_size     = sizeof(DrawBoxContext),
+    .priv_class    = &drawgrid_class,
+    .init          = init,
+    .query_formats = query_formats,
+    .inputs        = drawgrid_inputs,
+    .outputs       = drawgrid_outputs,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
+};
+
+#endif  /* CONFIG_DRAWGRID_FILTER */
diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
index ef5bb03..69124a9 100644
--- a/libavfilter/vf_drawtext.c
+++ b/libavfilter/vf_drawtext.c
@@ -136,9 +136,6 @@
     int max_glyph_h;                ///< max glyph height
     int shadowx, shadowy;
     unsigned int fontsize;          ///< font size to use
-    char *fontcolor_string;         ///< font color as string
-    char *boxcolor_string;          ///< box color as string
-    char *shadowcolor_string;       ///< shadow color as string
 
     short int draw_box;             ///< draw box around text - true or false
     int use_kerning;                ///< font kerning is used - true/false
@@ -167,6 +164,8 @@
     AVTimecode  tc;                 ///< timecode context
     int tc24hmax;                   ///< 1 if timecode is wrapped to 24 hours, 0 otherwise
     int reload;                     ///< reload text file for each frame
+    int start_number;               ///< starting frame number for n/frame_num var
+    AVDictionary *metadata;
 } DrawTextContext;
 
 #define OFFSET(x) offsetof(DrawTextContext, x)
@@ -176,9 +175,9 @@
     {"fontfile",    "set font file",        OFFSET(fontfile),           AV_OPT_TYPE_STRING, {.str=NULL},  CHAR_MIN, CHAR_MAX, FLAGS},
     {"text",        "set text",             OFFSET(text),               AV_OPT_TYPE_STRING, {.str=NULL},  CHAR_MIN, CHAR_MAX, FLAGS},
     {"textfile",    "set text file",        OFFSET(textfile),           AV_OPT_TYPE_STRING, {.str=NULL},  CHAR_MIN, CHAR_MAX, FLAGS},
-    {"fontcolor",   "set foreground color", OFFSET(fontcolor_string),   AV_OPT_TYPE_STRING, {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS},
-    {"boxcolor",    "set box color",        OFFSET(boxcolor_string),    AV_OPT_TYPE_STRING, {.str="white"}, CHAR_MIN, CHAR_MAX, FLAGS},
-    {"shadowcolor", "set shadow color",     OFFSET(shadowcolor_string), AV_OPT_TYPE_STRING, {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS},
+    {"fontcolor",   "set foreground color", OFFSET(fontcolor.rgba),     AV_OPT_TYPE_COLOR,  {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS},
+    {"boxcolor",    "set box color",        OFFSET(boxcolor.rgba),      AV_OPT_TYPE_COLOR,  {.str="white"}, CHAR_MIN, CHAR_MAX, FLAGS},
+    {"shadowcolor", "set shadow color",     OFFSET(shadowcolor.rgba),   AV_OPT_TYPE_COLOR,  {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS},
     {"box",         "set box",              OFFSET(draw_box),           AV_OPT_TYPE_INT,    {.i64=0},     0,        1       , FLAGS},
     {"fontsize",    "set font size",        OFFSET(fontsize),           AV_OPT_TYPE_INT,    {.i64=0},     0,        INT_MAX , FLAGS},
     {"x",           "set x expression",     OFFSET(x_expr),             AV_OPT_TYPE_STRING, {.str="0"},   CHAR_MIN, CHAR_MAX, FLAGS},
@@ -201,6 +200,7 @@
     {"rate",            "set rate (timecode only)",         OFFSET(tc_rate),       AV_OPT_TYPE_RATIONAL, {.dbl=0},           0,  INT_MAX, FLAGS},
     {"reload",     "reload text file for each frame",                       OFFSET(reload),     AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS},
     {"fix_bounds", "if true, check and fix text coords to avoid clipping",  OFFSET(fix_bounds), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS},
+    {"start_number", "start frame number for n/frame_num variable", OFFSET(start_number), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS},
 
     /* FT_LOAD_* flags */
     { "ft_load_flags", "set font loading flags for libfreetype", OFFSET(ft_load_flags), AV_OPT_TYPE_FLAGS, { .i64 = FT_LOAD_DEFAULT | FT_LOAD_RENDER}, 0, INT_MAX, FLAGS, "ft_load_flags" },
@@ -260,13 +260,13 @@
  */
 static int load_glyph(AVFilterContext *ctx, Glyph **glyph_ptr, uint32_t code)
 {
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = ctx->priv;
     Glyph *glyph;
     struct AVTreeNode *node = NULL;
     int ret;
 
-    /* load glyph into dtext->face->glyph */
-    if (FT_Load_Char(dtext->face, code, dtext->ft_load_flags))
+    /* load glyph into s->face->glyph */
+    if (FT_Load_Char(s->face, code, s->ft_load_flags))
         return AVERROR(EINVAL);
 
     /* save glyph */
@@ -277,15 +277,15 @@
     }
     glyph->code  = code;
 
-    if (FT_Get_Glyph(dtext->face->glyph, glyph->glyph)) {
+    if (FT_Get_Glyph(s->face->glyph, glyph->glyph)) {
         ret = AVERROR(EINVAL);
         goto error;
     }
 
-    glyph->bitmap      = dtext->face->glyph->bitmap;
-    glyph->bitmap_left = dtext->face->glyph->bitmap_left;
-    glyph->bitmap_top  = dtext->face->glyph->bitmap_top;
-    glyph->advance     = dtext->face->glyph->advance.x >> 6;
+    glyph->bitmap      = s->face->glyph->bitmap;
+    glyph->bitmap_left = s->face->glyph->bitmap_left;
+    glyph->bitmap_top  = s->face->glyph->bitmap_top;
+    glyph->advance     = s->face->glyph->advance.x >> 6;
 
     /* measure text height to calculate text_height (or the maximum text height) */
     FT_Glyph_Get_CBox(*glyph->glyph, ft_glyph_bbox_pixels, &glyph->bbox);
@@ -295,7 +295,7 @@
         ret = AVERROR(ENOMEM);
         goto error;
     }
-    av_tree_insert(&dtext->glyphs, glyph, glyph_cmp, &node);
+    av_tree_insert(&s->glyphs, glyph, glyph_cmp, &node);
 
     if (glyph_ptr)
         *glyph_ptr = glyph;
@@ -312,10 +312,10 @@
 static int load_font_file(AVFilterContext *ctx, const char *path, int index,
                           const char **error)
 {
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = ctx->priv;
     int err;
 
-    err = FT_New_Face(dtext->library, path, index, &dtext->face);
+    err = FT_New_Face(s->library, path, index, &s->face);
     if (err) {
         *error = FT_ERRMSG(err);
         return AVERROR(EINVAL);
@@ -326,7 +326,7 @@
 #if CONFIG_FONTCONFIG
 static int load_font_fontconfig(AVFilterContext *ctx, const char **error)
 {
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = ctx->priv;
     FcConfig *fontconfig;
     FcPattern *pattern, *fpat;
     FcResult result = FcResultMatch;
@@ -339,7 +339,7 @@
         *error = "impossible to init fontconfig\n";
         return AVERROR(EINVAL);
     }
-    pattern = FcNameParse(dtext->fontfile ? dtext->fontfile :
+    pattern = FcNameParse(s->fontfile ? s->fontfile :
                           (uint8_t *)(intptr_t)"default");
     if (!pattern) {
         *error = "could not parse fontconfig pattern";
@@ -362,8 +362,8 @@
         return AVERROR(EINVAL);
     }
     av_log(ctx, AV_LOG_INFO, "Using \"%s\"\n", filename);
-    if (!dtext->fontsize)
-        dtext->fontsize = size + 0.5;
+    if (!s->fontsize)
+        s->fontsize = size + 0.5;
     err = load_font_file(ctx, filename, index, error);
     if (err)
         return err;
@@ -376,12 +376,12 @@
 
 static int load_font(AVFilterContext *ctx)
 {
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = ctx->priv;
     int err;
     const char *error = "unknown error\n";
 
     /* load the face, and set up the encoding, which is by default UTF-8 */
-    err = load_font_file(ctx, dtext->fontfile, 0, &error);
+    err = load_font_file(ctx, s->fontfile, 0, &error);
     if (!err)
         return 0;
 #if CONFIG_FONTCONFIG
@@ -390,28 +390,28 @@
         return 0;
 #endif
     av_log(ctx, AV_LOG_ERROR, "Could not load font \"%s\": %s\n",
-           dtext->fontfile, error);
+           s->fontfile, error);
     return err;
 }
 
 static int load_textfile(AVFilterContext *ctx)
 {
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = ctx->priv;
     int err;
     uint8_t *textbuf;
     size_t textbuf_size;
 
-    if ((err = av_file_map(dtext->textfile, &textbuf, &textbuf_size, 0, ctx)) < 0) {
+    if ((err = av_file_map(s->textfile, &textbuf, &textbuf_size, 0, ctx)) < 0) {
         av_log(ctx, AV_LOG_ERROR,
                "The text file '%s' could not be read or is empty\n",
-               dtext->textfile);
+               s->textfile);
         return err;
     }
 
-    if (!(dtext->text = av_realloc(dtext->text, textbuf_size + 1)))
+    if (!(s->text = av_realloc(s->text, textbuf_size + 1)))
         return AVERROR(ENOMEM);
-    memcpy(dtext->text, textbuf, textbuf_size);
-    dtext->text[textbuf_size] = 0;
+    memcpy(s->text, textbuf, textbuf_size);
+    s->text[textbuf_size] = 0;
     av_file_unmap(textbuf, textbuf_size);
 
     return 0;
@@ -420,16 +420,16 @@
 static av_cold int init(AVFilterContext *ctx)
 {
     int err;
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = ctx->priv;
     Glyph *glyph;
 
-    if (!dtext->fontfile && !CONFIG_FONTCONFIG) {
+    if (!s->fontfile && !CONFIG_FONTCONFIG) {
         av_log(ctx, AV_LOG_ERROR, "No font filename provided\n");
         return AVERROR(EINVAL);
     }
 
-    if (dtext->textfile) {
-        if (dtext->text) {
+    if (s->textfile) {
+        if (s->text) {
             av_log(ctx, AV_LOG_ERROR,
                    "Both text and text file provided. Please provide only one\n");
             return AVERROR(EINVAL);
@@ -438,45 +438,27 @@
             return err;
     }
 
-    if (dtext->reload && !dtext->textfile)
+    if (s->reload && !s->textfile)
         av_log(ctx, AV_LOG_WARNING, "No file to reload\n");
 
-    if (dtext->tc_opt_string) {
-        int ret = av_timecode_init_from_string(&dtext->tc, dtext->tc_rate,
-                                               dtext->tc_opt_string, ctx);
+    if (s->tc_opt_string) {
+        int ret = av_timecode_init_from_string(&s->tc, s->tc_rate,
+                                               s->tc_opt_string, ctx);
         if (ret < 0)
             return ret;
-        if (dtext->tc24hmax)
-            dtext->tc.flags |= AV_TIMECODE_FLAG_24HOURSMAX;
-        if (!dtext->text)
-            dtext->text = av_strdup("");
+        if (s->tc24hmax)
+            s->tc.flags |= AV_TIMECODE_FLAG_24HOURSMAX;
+        if (!s->text)
+            s->text = av_strdup("");
     }
 
-    if (!dtext->text) {
+    if (!s->text) {
         av_log(ctx, AV_LOG_ERROR,
                "Either text, a valid file or a timecode must be provided\n");
         return AVERROR(EINVAL);
     }
 
-    if ((err = av_parse_color(dtext->fontcolor.rgba, dtext->fontcolor_string, -1, ctx))) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Invalid font color '%s'\n", dtext->fontcolor_string);
-        return err;
-    }
-
-    if ((err = av_parse_color(dtext->boxcolor.rgba, dtext->boxcolor_string, -1, ctx))) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Invalid box color '%s'\n", dtext->boxcolor_string);
-        return err;
-    }
-
-    if ((err = av_parse_color(dtext->shadowcolor.rgba, dtext->shadowcolor_string, -1, ctx))) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Invalid shadow color '%s'\n", dtext->shadowcolor_string);
-        return err;
-    }
-
-    if ((err = FT_Init_FreeType(&(dtext->library)))) {
+    if ((err = FT_Init_FreeType(&(s->library)))) {
         av_log(ctx, AV_LOG_ERROR,
                "Could not load FreeType: %s\n", FT_ERRMSG(err));
         return AVERROR(EINVAL);
@@ -485,15 +467,15 @@
     err = load_font(ctx);
     if (err)
         return err;
-    if (!dtext->fontsize)
-        dtext->fontsize = 16;
-    if ((err = FT_Set_Pixel_Sizes(dtext->face, 0, dtext->fontsize))) {
+    if (!s->fontsize)
+        s->fontsize = 16;
+    if ((err = FT_Set_Pixel_Sizes(s->face, 0, s->fontsize))) {
         av_log(ctx, AV_LOG_ERROR, "Could not set font size to %d pixels: %s\n",
-               dtext->fontsize, FT_ERRMSG(err));
+               s->fontsize, FT_ERRMSG(err));
         return AVERROR(EINVAL);
     }
 
-    dtext->use_kerning = FT_HAS_KERNING(dtext->face);
+    s->use_kerning = FT_HAS_KERNING(s->face);
 
     /* load the fallback glyph with code 0 */
     load_glyph(ctx, NULL, 0);
@@ -503,13 +485,13 @@
         av_log(ctx, AV_LOG_ERROR, "Could not set tabsize.\n");
         return err;
     }
-    dtext->tabsize *= glyph->advance;
+    s->tabsize *= glyph->advance;
 
-    if (dtext->exp_mode == EXP_STRFTIME &&
-        (strchr(dtext->text, '%') || strchr(dtext->text, '\\')))
+    if (s->exp_mode == EXP_STRFTIME &&
+        (strchr(s->text, '%') || strchr(s->text, '\\')))
         av_log(ctx, AV_LOG_WARNING, "expansion=strftime is deprecated.\n");
 
-    av_bprint_init(&dtext->expanded_text, 0, AV_BPRINT_SIZE_UNLIMITED);
+    av_bprint_init(&s->expanded_text, 0, AV_BPRINT_SIZE_UNLIMITED);
 
     return 0;
 }
@@ -532,24 +514,24 @@
 
 static av_cold void uninit(AVFilterContext *ctx)
 {
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = ctx->priv;
 
-    av_expr_free(dtext->x_pexpr); dtext->x_pexpr = NULL;
-    av_expr_free(dtext->y_pexpr); dtext->y_pexpr = NULL;
-    av_expr_free(dtext->draw_pexpr); dtext->draw_pexpr = NULL;
-
-    av_freep(&dtext->positions);
-    dtext->nb_positions = 0;
+    av_expr_free(s->x_pexpr);
+    av_expr_free(s->y_pexpr);
+    av_expr_free(s->draw_pexpr);
+    s->x_pexpr = s->y_pexpr = s->draw_pexpr = NULL;
+    av_freep(&s->positions);
+    s->nb_positions = 0;
 
 
-    av_tree_enumerate(dtext->glyphs, NULL, NULL, glyph_enu_free);
-    av_tree_destroy(dtext->glyphs);
-    dtext->glyphs = NULL;
+    av_tree_enumerate(s->glyphs, NULL, NULL, glyph_enu_free);
+    av_tree_destroy(s->glyphs);
+    s->glyphs = NULL;
 
-    FT_Done_Face(dtext->face);
-    FT_Done_FreeType(dtext->library);
+    FT_Done_Face(s->face);
+    FT_Done_FreeType(s->library);
 
-    av_bprint_finalize(&dtext->expanded_text, NULL);
+    av_bprint_finalize(&s->expanded_text, NULL);
 }
 
 static inline int is_newline(uint32_t c)
@@ -560,33 +542,35 @@
 static int config_input(AVFilterLink *inlink)
 {
     AVFilterContext *ctx = inlink->dst;
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = ctx->priv;
     int ret;
 
-    ff_draw_init(&dtext->dc, inlink->format, 0);
-    ff_draw_color(&dtext->dc, &dtext->fontcolor,   dtext->fontcolor.rgba);
-    ff_draw_color(&dtext->dc, &dtext->shadowcolor, dtext->shadowcolor.rgba);
-    ff_draw_color(&dtext->dc, &dtext->boxcolor,    dtext->boxcolor.rgba);
+    ff_draw_init(&s->dc, inlink->format, 0);
+    ff_draw_color(&s->dc, &s->fontcolor,   s->fontcolor.rgba);
+    ff_draw_color(&s->dc, &s->shadowcolor, s->shadowcolor.rgba);
+    ff_draw_color(&s->dc, &s->boxcolor,    s->boxcolor.rgba);
 
-    dtext->var_values[VAR_w]     = dtext->var_values[VAR_W]     = dtext->var_values[VAR_MAIN_W] = inlink->w;
-    dtext->var_values[VAR_h]     = dtext->var_values[VAR_H]     = dtext->var_values[VAR_MAIN_H] = inlink->h;
-    dtext->var_values[VAR_SAR]   = inlink->sample_aspect_ratio.num ? av_q2d(inlink->sample_aspect_ratio) : 1;
-    dtext->var_values[VAR_DAR]   = (double)inlink->w / inlink->h * dtext->var_values[VAR_SAR];
-    dtext->var_values[VAR_HSUB]  = 1 << dtext->dc.hsub_max;
-    dtext->var_values[VAR_VSUB]  = 1 << dtext->dc.vsub_max;
-    dtext->var_values[VAR_X]     = NAN;
-    dtext->var_values[VAR_Y]     = NAN;
-    if (!dtext->reinit)
-        dtext->var_values[VAR_N] = 0;
-    dtext->var_values[VAR_T]     = NAN;
+    s->var_values[VAR_w]     = s->var_values[VAR_W]     = s->var_values[VAR_MAIN_W] = inlink->w;
+    s->var_values[VAR_h]     = s->var_values[VAR_H]     = s->var_values[VAR_MAIN_H] = inlink->h;
+    s->var_values[VAR_SAR]   = inlink->sample_aspect_ratio.num ? av_q2d(inlink->sample_aspect_ratio) : 1;
+    s->var_values[VAR_DAR]   = (double)inlink->w / inlink->h * s->var_values[VAR_SAR];
+    s->var_values[VAR_HSUB]  = 1 << s->dc.hsub_max;
+    s->var_values[VAR_VSUB]  = 1 << s->dc.vsub_max;
+    s->var_values[VAR_X]     = NAN;
+    s->var_values[VAR_Y]     = NAN;
+    s->var_values[VAR_T]     = NAN;
 
-    av_lfg_init(&dtext->prng, av_get_random_seed());
+    av_lfg_init(&s->prng, av_get_random_seed());
 
-    if ((ret = av_expr_parse(&dtext->x_pexpr, dtext->x_expr, var_names,
+    av_expr_free(s->x_pexpr);
+    av_expr_free(s->y_pexpr);
+    av_expr_free(s->draw_pexpr);
+    s->x_pexpr = s->y_pexpr = s->draw_pexpr = NULL;
+    if ((ret = av_expr_parse(&s->x_pexpr, s->x_expr, var_names,
                              NULL, NULL, fun2_names, fun2, 0, ctx)) < 0 ||
-        (ret = av_expr_parse(&dtext->y_pexpr, dtext->y_expr, var_names,
+        (ret = av_expr_parse(&s->y_pexpr, s->y_expr, var_names,
                              NULL, NULL, fun2_names, fun2, 0, ctx)) < 0 ||
-        (ret = av_expr_parse(&dtext->draw_pexpr, dtext->draw_expr, var_names,
+        (ret = av_expr_parse(&s->draw_pexpr, s->draw_expr, var_names,
                              NULL, NULL, fun2_names, fun2, 0, ctx)) < 0)
 
         return AVERROR(EINVAL);
@@ -596,12 +580,12 @@
 
 static int command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
 {
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = ctx->priv;
 
     if (!strcmp(cmd, "reinit")) {
         int ret;
         uninit(ctx);
-        dtext->reinit = 1;
+        s->reinit = 1;
         if ((ret = init(ctx)) < 0)
             return ret;
         return config_input(ctx->inputs[0]);
@@ -613,27 +597,38 @@
 static int func_pict_type(AVFilterContext *ctx, AVBPrint *bp,
                           char *fct, unsigned argc, char **argv, int tag)
 {
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = ctx->priv;
 
-    av_bprintf(bp, "%c", av_get_picture_type_char(dtext->var_values[VAR_PICT_TYPE]));
+    av_bprintf(bp, "%c", av_get_picture_type_char(s->var_values[VAR_PICT_TYPE]));
     return 0;
 }
 
 static int func_pts(AVFilterContext *ctx, AVBPrint *bp,
                     char *fct, unsigned argc, char **argv, int tag)
 {
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = ctx->priv;
 
-    av_bprintf(bp, "%.6f", dtext->var_values[VAR_T]);
+    av_bprintf(bp, "%.6f", s->var_values[VAR_T]);
     return 0;
 }
 
 static int func_frame_num(AVFilterContext *ctx, AVBPrint *bp,
                           char *fct, unsigned argc, char **argv, int tag)
 {
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = ctx->priv;
 
-    av_bprintf(bp, "%d", (int)dtext->var_values[VAR_N]);
+    av_bprintf(bp, "%d", (int)s->var_values[VAR_N]);
+    return 0;
+}
+
+static int func_metadata(AVFilterContext *ctx, AVBPrint *bp,
+                         char *fct, unsigned argc, char **argv, int tag)
+{
+    DrawTextContext *s = ctx->priv;
+    AVDictionaryEntry *e = av_dict_get(s->metadata, argv[0], NULL, 0);
+
+    if (e && e->value)
+        av_bprintf(bp, "%s", e->value);
     return 0;
 }
 
@@ -663,13 +658,13 @@
 static int func_eval_expr(AVFilterContext *ctx, AVBPrint *bp,
                           char *fct, unsigned argc, char **argv, int tag)
 {
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = ctx->priv;
     double res;
     int ret;
 
-    ret = av_expr_parse_and_eval(&res, argv[0], var_names, dtext->var_values,
+    ret = av_expr_parse_and_eval(&res, argv[0], var_names, s->var_values,
                                  NULL, NULL, fun2_names, fun2,
-                                 &dtext->prng, 0, ctx);
+                                 &s->prng, 0, ctx);
     if (ret < 0)
         av_log(ctx, AV_LOG_ERROR,
                "Expression '%s' for the expr text expansion function is not valid\n",
@@ -683,7 +678,7 @@
 static const struct drawtext_function {
     const char *name;
     unsigned argc_min, argc_max;
-    int tag; /** opaque argument to func */
+    int tag;                            /**< opaque argument to func */
     int (*func)(AVFilterContext *, AVBPrint *, char *, unsigned, char **, int);
 } functions[] = {
     { "expr",      1, 1, 0,   func_eval_expr },
@@ -694,6 +689,7 @@
     { "localtime", 0, 1, 'L', func_strftime },
     { "frame_num", 0, 0, 0,   func_frame_num },
     { "n",         0, 0, 0,   func_frame_num },
+    { "metadata",  1, 1, 0,   func_metadata },
 };
 
 static int eval_function(AVFilterContext *ctx, AVBPrint *bp, char *fct,
@@ -765,9 +761,9 @@
 
 static int expand_text(AVFilterContext *ctx)
 {
-    DrawTextContext *dtext = ctx->priv;
-    char *text = dtext->text;
-    AVBPrint *bp = &dtext->expanded_text;
+    DrawTextContext *s = ctx->priv;
+    char *text = s->text;
+    AVBPrint *bp = &s->expanded_text;
     int ret;
 
     av_bprint_clear(bp);
@@ -789,10 +785,10 @@
     return 0;
 }
 
-static int draw_glyphs(DrawTextContext *dtext, AVFrame *frame,
+static int draw_glyphs(DrawTextContext *s, AVFrame *frame,
                        int width, int height, const uint8_t rgbcolor[4], FFDrawColor *color, int x, int y)
 {
-    char *text = dtext->expanded_text.str;
+    char *text = s->expanded_text.str;
     uint32_t code = 0;
     int i, x1, y1;
     uint8_t *p;
@@ -807,16 +803,16 @@
             continue;
 
         dummy.code = code;
-        glyph = av_tree_find(dtext->glyphs, &dummy, (void *)glyph_cmp, NULL);
+        glyph = av_tree_find(s->glyphs, &dummy, (void *)glyph_cmp, NULL);
 
         if (glyph->bitmap.pixel_mode != FT_PIXEL_MODE_MONO &&
             glyph->bitmap.pixel_mode != FT_PIXEL_MODE_GRAY)
             return AVERROR(EINVAL);
 
-        x1 = dtext->positions[i].x+dtext->x+x;
-        y1 = dtext->positions[i].y+dtext->y+y;
+        x1 = s->positions[i].x+s->x+x;
+        y1 = s->positions[i].y+s->y+y;
 
-        ff_blend_mask(&dtext->dc, color,
+        ff_blend_mask(&s->dc, color,
                       frame->data, frame->linesize, width, height,
                       glyph->bitmap.buffer, glyph->bitmap.pitch,
                       glyph->bitmap.width, glyph->bitmap.rows,
@@ -830,13 +826,14 @@
 static int draw_text(AVFilterContext *ctx, AVFrame *frame,
                      int width, int height)
 {
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = ctx->priv;
     AVFilterLink *inlink = ctx->inputs[0];
+
     uint32_t code = 0, prev_code = 0;
     int x = 0, y = 0, i = 0, ret;
     int max_text_line_w = 0, len;
     int box_w, box_h;
-    char *text = dtext->text;
+    char *text = s->text;
     uint8_t *p;
     int y_min = 32000, y_max = -32000;
     int x_min = 32000, x_max = -32000;
@@ -846,16 +843,16 @@
 
     time_t now = time(0);
     struct tm ltime;
-    AVBPrint *bp = &dtext->expanded_text;
+    AVBPrint *bp = &s->expanded_text;
 
     av_bprint_clear(bp);
 
-    if(dtext->basetime != AV_NOPTS_VALUE)
-        now= frame->pts*av_q2d(ctx->inputs[0]->time_base) + dtext->basetime/1000000;
+    if(s->basetime != AV_NOPTS_VALUE)
+        now= frame->pts*av_q2d(ctx->inputs[0]->time_base) + s->basetime/1000000;
 
-    switch (dtext->exp_mode) {
+    switch (s->exp_mode) {
     case EXP_NONE:
-        av_bprintf(bp, "%s", dtext->text);
+        av_bprintf(bp, "%s", s->text);
         break;
     case EXP_NORMAL:
         if ((ret = expand_text(ctx)) < 0)
@@ -863,25 +860,25 @@
         break;
     case EXP_STRFTIME:
         localtime_r(&now, &ltime);
-        av_bprint_strftime(bp, dtext->text, &ltime);
+        av_bprint_strftime(bp, s->text, &ltime);
         break;
     }
 
-    if (dtext->tc_opt_string) {
+    if (s->tc_opt_string) {
         char tcbuf[AV_TIMECODE_STR_SIZE];
-        av_timecode_make_string(&dtext->tc, tcbuf, inlink->frame_count);
+        av_timecode_make_string(&s->tc, tcbuf, inlink->frame_count);
         av_bprint_clear(bp);
-        av_bprintf(bp, "%s%s", dtext->text, tcbuf);
+        av_bprintf(bp, "%s%s", s->text, tcbuf);
     }
 
     if (!av_bprint_is_complete(bp))
         return AVERROR(ENOMEM);
-    text = dtext->expanded_text.str;
-    if ((len = dtext->expanded_text.len) > dtext->nb_positions) {
-        if (!(dtext->positions =
-              av_realloc(dtext->positions, len*sizeof(*dtext->positions))))
+    text = s->expanded_text.str;
+    if ((len = s->expanded_text.len) > s->nb_positions) {
+        if (!(s->positions =
+              av_realloc(s->positions, len*sizeof(*s->positions))))
             return AVERROR(ENOMEM);
-        dtext->nb_positions = len;
+        s->nb_positions = len;
     }
 
     x = 0;
@@ -893,7 +890,7 @@
 
         /* get glyph */
         dummy.code = code;
-        glyph = av_tree_find(dtext->glyphs, &dummy, glyph_cmp, NULL);
+        glyph = av_tree_find(s->glyphs, &dummy, glyph_cmp, NULL);
         if (!glyph) {
             load_glyph(ctx, &glyph, code);
         }
@@ -903,8 +900,8 @@
         x_min = FFMIN(glyph->bbox.xMin, x_min);
         x_max = FFMAX(glyph->bbox.xMax, x_max);
     }
-    dtext->max_glyph_h = y_max - y_min;
-    dtext->max_glyph_w = x_max - x_min;
+    s->max_glyph_h = y_max - y_min;
+    s->max_glyph_w = x_max - x_min;
 
     /* compute and save position for each glyph */
     glyph = NULL;
@@ -917,8 +914,9 @@
 
         prev_code = code;
         if (is_newline(code)) {
+
             max_text_line_w = FFMAX(max_text_line_w, x);
-            y += dtext->max_glyph_h;
+            y += s->max_glyph_h;
             x = 0;
             continue;
         }
@@ -926,59 +924,59 @@
         /* get glyph */
         prev_glyph = glyph;
         dummy.code = code;
-        glyph = av_tree_find(dtext->glyphs, &dummy, glyph_cmp, NULL);
+        glyph = av_tree_find(s->glyphs, &dummy, glyph_cmp, NULL);
 
         /* kerning */
-        if (dtext->use_kerning && prev_glyph && glyph->code) {
-            FT_Get_Kerning(dtext->face, prev_glyph->code, glyph->code,
+        if (s->use_kerning && prev_glyph && glyph->code) {
+            FT_Get_Kerning(s->face, prev_glyph->code, glyph->code,
                            ft_kerning_default, &delta);
             x += delta.x >> 6;
         }
 
         /* save position */
-        dtext->positions[i].x = x + glyph->bitmap_left;
-        dtext->positions[i].y = y - glyph->bitmap_top + y_max;
-        if (code == '\t') x  = (x / dtext->tabsize + 1)*dtext->tabsize;
+        s->positions[i].x = x + glyph->bitmap_left;
+        s->positions[i].y = y - glyph->bitmap_top + y_max;
+        if (code == '\t') x  = (x / s->tabsize + 1)*s->tabsize;
         else              x += glyph->advance;
     }
 
     max_text_line_w = FFMAX(x, max_text_line_w);
 
-    dtext->var_values[VAR_TW] = dtext->var_values[VAR_TEXT_W] = max_text_line_w;
-    dtext->var_values[VAR_TH] = dtext->var_values[VAR_TEXT_H] = y + dtext->max_glyph_h;
+    s->var_values[VAR_TW] = s->var_values[VAR_TEXT_W] = max_text_line_w;
+    s->var_values[VAR_TH] = s->var_values[VAR_TEXT_H] = y + s->max_glyph_h;
 
-    dtext->var_values[VAR_MAX_GLYPH_W] = dtext->max_glyph_w;
-    dtext->var_values[VAR_MAX_GLYPH_H] = dtext->max_glyph_h;
-    dtext->var_values[VAR_MAX_GLYPH_A] = dtext->var_values[VAR_ASCENT ] = y_max;
-    dtext->var_values[VAR_MAX_GLYPH_D] = dtext->var_values[VAR_DESCENT] = y_min;
+    s->var_values[VAR_MAX_GLYPH_W] = s->max_glyph_w;
+    s->var_values[VAR_MAX_GLYPH_H] = s->max_glyph_h;
+    s->var_values[VAR_MAX_GLYPH_A] = s->var_values[VAR_ASCENT ] = y_max;
+    s->var_values[VAR_MAX_GLYPH_D] = s->var_values[VAR_DESCENT] = y_min;
 
-    dtext->var_values[VAR_LINE_H] = dtext->var_values[VAR_LH] = dtext->max_glyph_h;
+    s->var_values[VAR_LINE_H] = s->var_values[VAR_LH] = s->max_glyph_h;
 
-    dtext->x = dtext->var_values[VAR_X] = av_expr_eval(dtext->x_pexpr, dtext->var_values, &dtext->prng);
-    dtext->y = dtext->var_values[VAR_Y] = av_expr_eval(dtext->y_pexpr, dtext->var_values, &dtext->prng);
-    dtext->x = dtext->var_values[VAR_X] = av_expr_eval(dtext->x_pexpr, dtext->var_values, &dtext->prng);
-    dtext->draw = av_expr_eval(dtext->draw_pexpr, dtext->var_values, &dtext->prng);
+    s->x = s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, &s->prng);
+    s->y = s->var_values[VAR_Y] = av_expr_eval(s->y_pexpr, s->var_values, &s->prng);
+    s->x = s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, &s->prng);
+    s->draw = av_expr_eval(s->draw_pexpr, s->var_values, &s->prng);
 
-    if(!dtext->draw)
+    if(!s->draw)
         return 0;
 
     box_w = FFMIN(width - 1 , max_text_line_w);
-    box_h = FFMIN(height - 1, y + dtext->max_glyph_h);
+    box_h = FFMIN(height - 1, y + s->max_glyph_h);
 
     /* draw box */
-    if (dtext->draw_box)
-        ff_blend_rectangle(&dtext->dc, &dtext->boxcolor,
+    if (s->draw_box)
+        ff_blend_rectangle(&s->dc, &s->boxcolor,
                            frame->data, frame->linesize, width, height,
-                           dtext->x, dtext->y, box_w, box_h);
+                           s->x, s->y, box_w, box_h);
 
-    if (dtext->shadowx || dtext->shadowy) {
-        if ((ret = draw_glyphs(dtext, frame, width, height, dtext->shadowcolor.rgba,
-                               &dtext->shadowcolor, dtext->shadowx, dtext->shadowy)) < 0)
+    if (s->shadowx || s->shadowy) {
+        if ((ret = draw_glyphs(s, frame, width, height, s->shadowcolor.rgba,
+                               &s->shadowcolor, s->shadowx, s->shadowy)) < 0)
             return ret;
     }
 
-    if ((ret = draw_glyphs(dtext, frame, width, height, dtext->fontcolor.rgba,
-                           &dtext->fontcolor, 0, 0)) < 0)
+    if ((ret = draw_glyphs(s, frame, width, height, s->fontcolor.rgba,
+                           &s->fontcolor, 0, 0)) < 0)
         return ret;
 
     return 0;
@@ -988,25 +986,26 @@
 {
     AVFilterContext *ctx = inlink->dst;
     AVFilterLink *outlink = ctx->outputs[0];
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = ctx->priv;
     int ret;
 
-    if (dtext->reload)
+    if (s->reload)
         if ((ret = load_textfile(ctx)) < 0)
             return ret;
 
-    dtext->var_values[VAR_N] = inlink->frame_count;
-    dtext->var_values[VAR_T] = frame->pts == AV_NOPTS_VALUE ?
+    s->var_values[VAR_N] = inlink->frame_count+s->start_number;
+    s->var_values[VAR_T] = frame->pts == AV_NOPTS_VALUE ?
         NAN : frame->pts * av_q2d(inlink->time_base);
 
-    dtext->var_values[VAR_PICT_TYPE] = frame->pict_type;
+    s->var_values[VAR_PICT_TYPE] = frame->pict_type;
+    s->metadata = av_frame_get_metadata(frame);
 
     draw_text(ctx, frame, frame->width, frame->height);
 
     av_log(ctx, AV_LOG_DEBUG, "n:%d t:%f text_w:%d text_h:%d x:%d y:%d\n",
-           (int)dtext->var_values[VAR_N], dtext->var_values[VAR_T],
-           (int)dtext->var_values[VAR_TEXT_W], (int)dtext->var_values[VAR_TEXT_H],
-           dtext->x, dtext->y);
+           (int)s->var_values[VAR_N], s->var_values[VAR_T],
+           (int)s->var_values[VAR_TEXT_W], (int)s->var_values[VAR_TEXT_H],
+           s->x, s->y);
 
     return ff_filter_frame(outlink, frame);
 }
diff --git a/libavfilter/vf_edgedetect.c b/libavfilter/vf_edgedetect.c
index b4698a8..4c50d9f 100644
--- a/libavfilter/vf_edgedetect.c
+++ b/libavfilter/vf_edgedetect.c
@@ -327,5 +327,5 @@
     .inputs        = edgedetect_inputs,
     .outputs       = edgedetect_outputs,
     .priv_class    = &edgedetect_class,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_extractplanes.c b/libavfilter/vf_extractplanes.c
new file mode 100644
index 0000000..52dffcc
--- /dev/null
+++ b/libavfilter/vf_extractplanes.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 2013 Paul B Mahol
+ *
+ * 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
+ */
+
+#include "libavutil/avstring.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "avfilter.h"
+#include "drawutils.h"
+#include "internal.h"
+
+#define PLANE_R 0x01
+#define PLANE_G 0x02
+#define PLANE_B 0x04
+#define PLANE_A 0x08
+#define PLANE_Y 0x10
+#define PLANE_U 0x20
+#define PLANE_V 0x40
+
+typedef struct {
+    const AVClass *class;
+    int requested_planes;
+    int map[4];
+    int linesize[4];
+    int is_packed_rgb;
+    int depth;
+    int step;
+} ExtractPlanesContext;
+
+#define OFFSET(x) offsetof(ExtractPlanesContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption extractplanes_options[] = {
+    { "planes", "set planes",  OFFSET(requested_planes), AV_OPT_TYPE_FLAGS, {.i64=1}, 1, 0xff, FLAGS, "flags"},
+    {      "y", "set luma plane",  0, AV_OPT_TYPE_CONST, {.i64=PLANE_Y}, 0, 0, FLAGS, "flags"},
+    {      "u", "set u plane",     0, AV_OPT_TYPE_CONST, {.i64=PLANE_U}, 0, 0, FLAGS, "flags"},
+    {      "v", "set v plane",     0, AV_OPT_TYPE_CONST, {.i64=PLANE_V}, 0, 0, FLAGS, "flags"},
+    {      "r", "set red plane",   0, AV_OPT_TYPE_CONST, {.i64=PLANE_R}, 0, 0, FLAGS, "flags"},
+    {      "g", "set green plane", 0, AV_OPT_TYPE_CONST, {.i64=PLANE_G}, 0, 0, FLAGS, "flags"},
+    {      "b", "set blue plane",  0, AV_OPT_TYPE_CONST, {.i64=PLANE_B}, 0, 0, FLAGS, "flags"},
+    {      "a", "set alpha plane", 0, AV_OPT_TYPE_CONST, {.i64=PLANE_A}, 0, 0, FLAGS, "flags"},
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(extractplanes);
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat in_pixfmts[] = {
+        AV_PIX_FMT_YUV410P,
+        AV_PIX_FMT_YUV411P,
+        AV_PIX_FMT_YUV440P,
+        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P,
+        AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA422P,
+        AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P,
+        AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ444P,
+        AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA444P,
+        AV_PIX_FMT_YUV420P16LE, AV_PIX_FMT_YUVA420P16LE,
+        AV_PIX_FMT_YUV420P16BE, AV_PIX_FMT_YUVA420P16BE,
+        AV_PIX_FMT_YUV422P16LE, AV_PIX_FMT_YUVA422P16LE,
+        AV_PIX_FMT_YUV422P16BE, AV_PIX_FMT_YUVA422P16BE,
+        AV_PIX_FMT_YUV444P16LE, AV_PIX_FMT_YUVA444P16LE,
+        AV_PIX_FMT_YUV444P16BE, AV_PIX_FMT_YUVA444P16BE,
+        AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY8A,
+        AV_PIX_FMT_GRAY16LE, AV_PIX_FMT_GRAY16BE,
+        AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24,
+        AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA,
+        AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR,
+        AV_PIX_FMT_RGB48LE, AV_PIX_FMT_BGR48LE,
+        AV_PIX_FMT_RGB48BE, AV_PIX_FMT_BGR48BE,
+        AV_PIX_FMT_RGBA64LE, AV_PIX_FMT_BGRA64LE,
+        AV_PIX_FMT_RGBA64BE, AV_PIX_FMT_BGRA64BE,
+        AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP,
+        AV_PIX_FMT_GBRP16LE, AV_PIX_FMT_GBRP16BE,
+        AV_PIX_FMT_GBRAP16LE, AV_PIX_FMT_GBRAP16BE,
+        AV_PIX_FMT_NONE,
+    };
+    static const enum AVPixelFormat out8_pixfmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE };
+    static const enum AVPixelFormat out16le_pixfmts[] = { AV_PIX_FMT_GRAY16LE, AV_PIX_FMT_NONE };
+    static const enum AVPixelFormat out16be_pixfmts[] = { AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_NONE };
+    const enum AVPixelFormat *out_pixfmts;
+    const AVPixFmtDescriptor *desc;
+    AVFilterFormats *avff;
+    int i, depth = 0, be = 0;
+
+    if (!ctx->inputs[0]->in_formats ||
+        !ctx->inputs[0]->in_formats->nb_formats) {
+        return AVERROR(EAGAIN);
+    }
+
+    if (!ctx->inputs[0]->out_formats)
+        ff_formats_ref(ff_make_format_list(in_pixfmts), &ctx->inputs[0]->out_formats);
+
+    avff = ctx->inputs[0]->in_formats;
+    desc = av_pix_fmt_desc_get(avff->formats[0]);
+    depth = desc->comp[0].depth_minus1;
+    be = desc->flags & AV_PIX_FMT_FLAG_BE;
+    for (i = 1; i < avff->nb_formats; i++) {
+        desc = av_pix_fmt_desc_get(avff->formats[i]);
+        if (depth != desc->comp[0].depth_minus1 ||
+            be    != (desc->flags & AV_PIX_FMT_FLAG_BE)) {
+            return AVERROR(EAGAIN);
+        }
+    }
+
+    if (depth == 7)
+        out_pixfmts = out8_pixfmts;
+    else if (be)
+        out_pixfmts = out16be_pixfmts;
+    else
+        out_pixfmts = out16le_pixfmts;
+
+    for (i = 0; i < ctx->nb_outputs; i++)
+        ff_formats_ref(ff_make_format_list(out_pixfmts), &ctx->outputs[i]->in_formats);
+    return 0;
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->dst;
+    ExtractPlanesContext *e = ctx->priv;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+    int plane_avail, ret, i;
+    uint8_t rgba_map[4];
+
+    plane_avail = ((desc->flags & AV_PIX_FMT_FLAG_RGB) ? PLANE_R|PLANE_G|PLANE_B :
+                                                 PLANE_Y |
+                                ((desc->nb_components > 2) ? PLANE_U|PLANE_V : 0)) |
+                  ((desc->flags & AV_PIX_FMT_FLAG_ALPHA) ? PLANE_A : 0);
+    if (e->requested_planes & ~plane_avail) {
+        av_log(ctx, AV_LOG_ERROR, "Requested planes not available.\n");
+        return AVERROR(EINVAL);
+    }
+    if ((ret = av_image_fill_linesizes(e->linesize, inlink->format, inlink->w)) < 0)
+        return ret;
+
+    e->depth = (desc->comp[0].depth_minus1 + 1) >> 3;
+    e->step = av_get_padded_bits_per_pixel(desc) >> 3;
+    e->is_packed_rgb = !(desc->flags & AV_PIX_FMT_FLAG_PLANAR);
+    if (desc->flags & AV_PIX_FMT_FLAG_RGB) {
+        ff_fill_rgba_map(rgba_map, inlink->format);
+        for (i = 0; i < 4; i++)
+            e->map[i] = rgba_map[e->map[i]];
+    }
+
+    return 0;
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    AVFilterLink *inlink = ctx->inputs[0];
+    ExtractPlanesContext *e = ctx->priv;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+    const int output = outlink->srcpad - ctx->output_pads;
+
+    if (e->map[output] == 1 || e->map[output] == 2) {
+        outlink->h = FF_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
+        outlink->w = FF_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
+    }
+
+    return 0;
+}
+
+static void extract_from_packed(uint8_t *dst, int dst_linesize,
+                                const uint8_t *src, int src_linesize,
+                                int width, int height,
+                                int depth, int step, int comp)
+{
+    int x, y;
+
+    for (y = 0; y < height; y++) {
+        switch (depth) {
+        case 1:
+            for (x = 0; x < width; x++)
+                dst[x] = src[x * step + comp];
+            break;
+        case 2:
+            for (x = 0; x < width; x++) {
+                dst[x * 2    ] = src[x * step + comp * 2    ];
+                dst[x * 2 + 1] = src[x * step + comp * 2 + 1];
+            }
+            break;
+        }
+        dst += dst_linesize;
+        src += src_linesize;
+    }
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
+{
+    AVFilterContext *ctx = inlink->dst;
+    ExtractPlanesContext *e = ctx->priv;
+    int i, eof = 0, ret = 0;
+
+    for (i = 0; i < ctx->nb_outputs; i++) {
+        AVFilterLink *outlink = ctx->outputs[i];
+        const int idx = e->map[i];
+        AVFrame *out;
+
+        if (outlink->closed)
+            continue;
+
+        out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+        if (!out) {
+            ret = AVERROR(ENOMEM);
+            break;
+        }
+        av_frame_copy_props(out, frame);
+
+        if (e->is_packed_rgb) {
+            extract_from_packed(out->data[0], out->linesize[0],
+                                frame->data[0], frame->linesize[0],
+                                outlink->w, outlink->h,
+                                e->depth,
+                                e->step, idx);
+        } else {
+            av_image_copy_plane(out->data[0], out->linesize[0],
+                                frame->data[idx], frame->linesize[idx],
+                                e->linesize[idx], outlink->h);
+        }
+
+        ret = ff_filter_frame(outlink, out);
+        if (ret == AVERROR_EOF)
+            eof++;
+        else if (ret < 0)
+            break;
+    }
+    av_frame_free(&frame);
+
+    if (eof == ctx->nb_outputs)
+        ret = AVERROR_EOF;
+    else if (ret == AVERROR_EOF)
+        ret = 0;
+    return ret;
+}
+
+static int init(AVFilterContext *ctx)
+{
+    ExtractPlanesContext *e = ctx->priv;
+    int planes = (e->requested_planes & 0xf) | (e->requested_planes >> 4);
+    int i;
+
+    for (i = 0; i < 4; i++) {
+        char *name;
+        AVFilterPad pad = { 0 };
+
+        if (!(planes & (1 << i)))
+            continue;
+
+        name = av_asprintf("out%d", ctx->nb_outputs);
+        if (!name)
+            return AVERROR(ENOMEM);
+        e->map[ctx->nb_outputs] = i;
+        pad.name = name;
+        pad.type = AVMEDIA_TYPE_VIDEO;
+        pad.config_props = config_output;
+
+        ff_insert_outpad(ctx, ctx->nb_outputs, &pad);
+    }
+
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    int i;
+
+    for (i = 0; i < ctx->nb_outputs; i++)
+        av_freep(&ctx->output_pads[i].name);
+}
+
+static const AVFilterPad extractplanes_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = filter_frame,
+        .config_props = config_input,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_extractplanes = {
+    .name          = "extractplanes",
+    .description   = NULL_IF_CONFIG_SMALL("Extract planes as grayscale frames."),
+    .priv_size     = sizeof(ExtractPlanesContext),
+    .priv_class    = &extractplanes_class,
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+    .inputs        = extractplanes_inputs,
+    .outputs       = NULL,
+    .flags         = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
+};
+
+#if CONFIG_ALPHAEXTRACT_FILTER
+
+static int init_alphaextract(AVFilterContext *ctx)
+{
+    ExtractPlanesContext *e = ctx->priv;
+
+    e->requested_planes = PLANE_A;
+
+    return init(ctx);
+}
+
+AVFilter avfilter_vf_alphaextract = {
+    .name           = "alphaextract",
+    .description    = NULL_IF_CONFIG_SMALL("Extract an alpha channel as a "
+                      "grayscale image component."),
+    .priv_size      = sizeof(ExtractPlanesContext),
+    .init           = init_alphaextract,
+    .uninit         = uninit,
+    .query_formats  = query_formats,
+    .inputs         = extractplanes_inputs,
+    .outputs        = NULL,
+    .flags          = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
+};
+#endif  /* CONFIG_ALPHAEXTRACT_FILTER */
diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c
index 4dbd4c7..6c9b225 100644
--- a/libavfilter/vf_fade.c
+++ b/libavfilter/vf_fade.c
@@ -66,28 +66,28 @@
 
 static av_cold int init(AVFilterContext *ctx)
 {
-    FadeContext *fade = ctx->priv;
+    FadeContext *s = ctx->priv;
 
-    fade->fade_per_frame = (1 << 16) / fade->nb_frames;
-    fade->fade_state = VF_FADE_WAITING;
+    s->fade_per_frame = (1 << 16) / s->nb_frames;
+    s->fade_state = VF_FADE_WAITING;
 
-    if (fade->duration != 0) {
+    if (s->duration != 0) {
         // If duration (seconds) is non-zero, assume that we are not fading based on frames
-        fade->nb_frames = 0; // Mostly to clean up logging
+        s->nb_frames = 0; // Mostly to clean up logging
     }
 
     // Choose what to log. If both time-based and frame-based options, both lines will be in the log
-    if (fade->start_frame || fade->nb_frames) {
+    if (s->start_frame || s->nb_frames) {
         av_log(ctx, AV_LOG_VERBOSE,
                "type:%s start_frame:%d nb_frames:%d alpha:%d\n",
-               fade->type == FADE_IN ? "in" : "out", fade->start_frame,
-               fade->nb_frames,fade->alpha);
+               s->type == FADE_IN ? "in" : "out", s->start_frame,
+               s->nb_frames,s->alpha);
     }
-    if (fade->start_time || fade->duration) {
+    if (s->start_time || s->duration) {
         av_log(ctx, AV_LOG_VERBOSE,
                "type:%s start_time:%f duration:%f alpha:%d\n",
-               fade->type == FADE_IN ? "in" : "out", (fade->start_time / (double)AV_TIME_BASE),
-               (fade->duration / (double)AV_TIME_BASE),fade->alpha);
+               s->type == FADE_IN ? "in" : "out", (s->start_time / (double)AV_TIME_BASE),
+               (s->duration / (double)AV_TIME_BASE),s->alpha);
     }
 
     return 0;
@@ -120,134 +120,172 @@
 
 static int config_props(AVFilterLink *inlink)
 {
-    FadeContext *fade = inlink->dst->priv;
+    FadeContext *s = inlink->dst->priv;
     const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(inlink->format);
 
-    fade->hsub = pixdesc->log2_chroma_w;
-    fade->vsub = pixdesc->log2_chroma_h;
+    s->hsub = pixdesc->log2_chroma_w;
+    s->vsub = pixdesc->log2_chroma_h;
 
-    fade->bpp = av_get_bits_per_pixel(pixdesc) >> 3;
-    fade->alpha &= pixdesc->flags & PIX_FMT_ALPHA;
-    fade->is_packed_rgb = ff_fill_rgba_map(fade->rgba_map, inlink->format) >= 0;
+    s->bpp = av_get_bits_per_pixel(pixdesc) >> 3;
+    s->alpha &= !!(pixdesc->flags & AV_PIX_FMT_FLAG_ALPHA);
+    s->is_packed_rgb = ff_fill_rgba_map(s->rgba_map, inlink->format) >= 0;
 
     /* use CCIR601/709 black level for studio-level pixel non-alpha components */
-    fade->black_level =
-            ff_fmt_is_in(inlink->format, studio_level_pix_fmts) && !fade->alpha ? 16 : 0;
+    s->black_level =
+            ff_fmt_is_in(inlink->format, studio_level_pix_fmts) && !s->alpha ? 16 : 0;
     /* 32768 = 1 << 15, it is an integer representation
      * of 0.5 and is for rounding. */
-    fade->black_level_scaled = (fade->black_level << 16) + 32768;
+    s->black_level_scaled = (s->black_level << 16) + 32768;
     return 0;
 }
 
-static void fade_plane(int y, int h, int w,
-                       int fade_factor, int black_level, int black_level_scaled,
-                       uint8_t offset, uint8_t step, int bytes_per_plane,
-                       uint8_t *data, int line_size)
+static int filter_slice_luma(AVFilterContext *ctx, void *arg, int jobnr,
+                             int nb_jobs)
 {
-    uint8_t *p;
+    FadeContext *s = ctx->priv;
+    AVFrame *frame = arg;
+    int slice_start = (frame->height *  jobnr   ) / nb_jobs;
+    int slice_end   = (frame->height * (jobnr+1)) / nb_jobs;
     int i, j;
 
-    /* luma, alpha or rgb plane */
-    for (i = 0; i < h; i++) {
-        p = data + offset + (y+i) * line_size;
-        for (j = 0; j < w * bytes_per_plane; j++) {
-            /* fade->factor is using 16 lower-order bits for decimal places. */
-            *p = ((*p - black_level) * fade_factor + black_level_scaled) >> 16;
-            p+=step;
+    for (i = slice_start; i < slice_end; i++) {
+        uint8_t *p = frame->data[0] + i * frame->linesize[0];
+        for (j = 0; j < frame->width * s->bpp; j++) {
+            /* s->factor is using 16 lower-order bits for decimal
+             * places. 32768 = 1 << 15, it is an integer representation
+             * of 0.5 and is for rounding. */
+            *p = ((*p - s->black_level) * s->factor + s->black_level_scaled) >> 16;
+            p++;
         }
     }
+
+    return 0;
+}
+
+static int filter_slice_chroma(AVFilterContext *ctx, void *arg, int jobnr,
+                               int nb_jobs)
+{
+    FadeContext *s = ctx->priv;
+    AVFrame *frame = arg;
+    int i, j, plane;
+    const int width = FF_CEIL_RSHIFT(frame->width, s->hsub);
+    const int height= FF_CEIL_RSHIFT(frame->height, s->vsub);
+    int slice_start = (height *  jobnr   ) / nb_jobs;
+    int slice_end   = (height * (jobnr+1)) / nb_jobs;
+
+    for (plane = 1; plane < 3; plane++) {
+        for (i = slice_start; i < slice_end; i++) {
+            uint8_t *p = frame->data[plane] + i * frame->linesize[plane];
+            for (j = 0; j < width; j++) {
+                /* 8421367 = ((128 << 1) + 1) << 15. It is an integer
+                 * representation of 128.5. The .5 is for rounding
+                 * purposes. */
+                *p = ((*p - 128) * s->factor + 8421367) >> 16;
+                p++;
+            }
+        }
+    }
+
+    return 0;
+}
+
+static int filter_slice_alpha(AVFilterContext *ctx, void *arg, int jobnr,
+                              int nb_jobs)
+{
+    FadeContext *s = ctx->priv;
+    AVFrame *frame = arg;
+    int plane = s->is_packed_rgb ? 0 : A;
+    int slice_start = (frame->height *  jobnr   ) / nb_jobs;
+    int slice_end   = (frame->height * (jobnr+1)) / nb_jobs;
+    int i, j;
+
+    for (i = slice_start; i < slice_end; i++) {
+        uint8_t *p = frame->data[plane] + i * frame->linesize[plane] + s->is_packed_rgb*s->rgba_map[A];
+        int step = s->is_packed_rgb ? 4 : 1;
+        for (j = 0; j < frame->width; j++) {
+            /* s->factor is using 16 lower-order bits for decimal
+             * places. 32768 = 1 << 15, it is an integer representation
+             * of 0.5 and is for rounding. */
+            *p = ((*p - s->black_level) * s->factor + s->black_level_scaled) >> 16;
+            p += step;
+        }
+    }
+
+    return 0;
 }
 
 static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
 {
-    FadeContext *fade = inlink->dst->priv;
-    uint8_t *p;
-    int i, j, plane;
+    AVFilterContext *ctx = inlink->dst;
+    FadeContext *s       = ctx->priv;
     double frame_timestamp = frame->pts == AV_NOPTS_VALUE ? -1 : frame->pts * av_q2d(inlink->time_base);
 
     // Calculate Fade assuming this is a Fade In
-    if (fade->fade_state == VF_FADE_WAITING) {
-        fade->factor=0;
-        if ((frame_timestamp >= (fade->start_time/(double)AV_TIME_BASE))
-            && (fade->frame_index >= fade->start_frame)) {
+    if (s->fade_state == VF_FADE_WAITING) {
+        s->factor=0;
+        if ((frame_timestamp >= (s->start_time/(double)AV_TIME_BASE))
+            && (s->frame_index >= s->start_frame)) {
             // Time to start fading
-            fade->fade_state = VF_FADE_FADING;
+            s->fade_state = VF_FADE_FADING;
 
             // Save start time in case we are starting based on frames and fading based on time
-            if ((fade->start_time == 0) && (fade->start_frame != 0)) {
-                fade->start_time = frame_timestamp*(double)AV_TIME_BASE;
+            if ((s->start_time == 0) && (s->start_frame != 0)) {
+                s->start_time = frame_timestamp*(double)AV_TIME_BASE;
             }
 
             // Save start frame in case we are starting based on time and fading based on frames
-            if ((fade->start_time != 0) && (fade->start_frame == 0)) {
-                fade->start_frame = fade->frame_index;
+            if ((s->start_time != 0) && (s->start_frame == 0)) {
+                s->start_frame = s->frame_index;
             }
         }
     }
-    if (fade->fade_state == VF_FADE_FADING) {
-        if (fade->duration == 0) {
+    if (s->fade_state == VF_FADE_FADING) {
+        if (s->duration == 0) {
             // Fading based on frame count
-            fade->factor = (fade->frame_index - fade->start_frame) * fade->fade_per_frame;
-            if (fade->frame_index > (fade->start_frame + fade->nb_frames)) {
-                fade->fade_state = VF_FADE_DONE;
+            s->factor = (s->frame_index - s->start_frame) * s->fade_per_frame;
+            if (s->frame_index > (s->start_frame + s->nb_frames)) {
+                s->fade_state = VF_FADE_DONE;
             }
 
         } else {
             // Fading based on duration
-            fade->factor = (frame_timestamp - (fade->start_time/(double)AV_TIME_BASE))
-                            * (float) UINT16_MAX / (fade->duration/(double)AV_TIME_BASE);
-            if (frame_timestamp > ((fade->start_time/(double)AV_TIME_BASE)
-                                    + (fade->duration/(double)AV_TIME_BASE))) {
-                fade->fade_state = VF_FADE_DONE;
+            s->factor = (frame_timestamp - (s->start_time/(double)AV_TIME_BASE))
+                            * (float) UINT16_MAX / (s->duration/(double)AV_TIME_BASE);
+            if (frame_timestamp > ((s->start_time/(double)AV_TIME_BASE)
+                                    + (s->duration/(double)AV_TIME_BASE))) {
+                s->fade_state = VF_FADE_DONE;
             }
         }
     }
-    if (fade->fade_state == VF_FADE_DONE) {
-        fade->factor=UINT16_MAX;
+    if (s->fade_state == VF_FADE_DONE) {
+        s->factor=UINT16_MAX;
     }
 
-    fade->factor = av_clip_uint16(fade->factor);
+    s->factor = av_clip_uint16(s->factor);
 
     // Invert fade_factor if Fading Out
-    if (fade->type == 1) {
-        fade->factor=UINT16_MAX-fade->factor;
+    if (s->type == 1) {
+        s->factor=UINT16_MAX-s->factor;
     }
 
-    if (fade->factor < UINT16_MAX) {
-        if (fade->alpha) {
-            // alpha only
-            plane = fade->is_packed_rgb ? 0 : A; // alpha is on plane 0 for packed formats
-                                                 // or plane 3 for planar formats
-            fade_plane(0, frame->height, inlink->w,
-                       fade->factor, fade->black_level, fade->black_level_scaled,
-                       fade->is_packed_rgb ? fade->rgba_map[A] : 0, // alpha offset for packed formats
-                       fade->is_packed_rgb ? 4 : 1,                 // pixstep for 8 bit packed formats
-                       1, frame->data[plane], frame->linesize[plane]);
+    if (s->factor < UINT16_MAX) {
+        if (s->alpha) {
+            ctx->internal->execute(ctx, filter_slice_alpha, frame, NULL,
+                                FFMIN(frame->height, ctx->graph->nb_threads));
         } else {
             /* luma or rgb plane */
-            fade_plane(0, frame->height, inlink->w,
-                       fade->factor, fade->black_level, fade->black_level_scaled,
-                       0, 1, // offset & pixstep for Y plane or RGB packed format
-                       fade->bpp, frame->data[0], frame->linesize[0]);
+            ctx->internal->execute(ctx, filter_slice_luma, frame, NULL,
+                                FFMIN(frame->height, ctx->graph->nb_threads));
+
             if (frame->data[1] && frame->data[2]) {
                 /* chroma planes */
-                for (plane = 1; plane < 3; plane++) {
-                    for (i = 0; i < frame->height; i++) {
-                        p = frame->data[plane] + (i >> fade->vsub) * frame->linesize[plane];
-                        for (j = 0; j < inlink->w >> fade->hsub; j++) {
-                            /* 8421367 = ((128 << 1) + 1) << 15. It is an integer
-                             * representation of 128.5. The .5 is for rounding
-                             * purposes. */
-                            *p = ((*p - 128) * fade->factor + 8421367) >> 16;
-                            p++;
-                        }
-                    }
-                }
+                ctx->internal->execute(ctx, filter_slice_chroma, frame, NULL,
+                                    FFMIN(frame->height, ctx->graph->nb_threads));
             }
         }
     }
 
-    fade->frame_index++;
+    s->frame_index++;
 
     return ff_filter_frame(inlink->dst->outputs[0], frame);
 }
@@ -313,4 +351,5 @@
 
     .inputs    = avfilter_vf_fade_inputs,
     .outputs   = avfilter_vf_fade_outputs,
+    .flags     = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_field.c b/libavfilter/vf_field.c
index bbe66de..b281945 100644
--- a/libavfilter/vf_field.c
+++ b/libavfilter/vf_field.c
@@ -55,12 +55,8 @@
     AVFilterContext *ctx = outlink->src;
     FieldContext *field = ctx->priv;
     AVFilterLink *inlink = ctx->inputs[0];
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
-    int i;
 
-    for (i = 0; i < desc->nb_components; i++)
-        field->nb_planes = FFMAX(field->nb_planes, desc->comp[i].plane);
-    field->nb_planes++;
+    field->nb_planes = av_pix_fmt_count_planes(outlink->format);
 
     outlink->w = inlink->w;
     outlink->h = (inlink->h + (field->type == FIELD_TYPE_TOP)) / 2;
diff --git a/libavfilter/vf_fieldmatch.c b/libavfilter/vf_fieldmatch.c
index 3495895..89c4909 100644
--- a/libavfilter/vf_fieldmatch.c
+++ b/libavfilter/vf_fieldmatch.c
@@ -153,12 +153,12 @@
 
 static int get_width(const FieldMatchContext *fm, const AVFrame *f, int plane)
 {
-    return plane ? f->width >> fm->hsub : f->width;
+    return plane ? FF_CEIL_RSHIFT(f->width, fm->hsub) : f->width;
 }
 
 static int get_height(const FieldMatchContext *fm, const AVFrame *f, int plane)
 {
-    return plane ? f->height >> fm->vsub : f->height;
+    return plane ? FF_CEIL_RSHIFT(f->height, fm->vsub) : f->height;
 }
 
 static int64_t luma_abs_diff(const AVFrame *f1, const AVFrame *f2)
@@ -270,8 +270,8 @@
         uint8_t *cmkp  = fm->cmask_data[0];
         uint8_t *cmkpU = fm->cmask_data[1];
         uint8_t *cmkpV = fm->cmask_data[2];
-        const int width  = src->width  >> fm->hsub;
-        const int height = src->height >> fm->vsub;
+        const int width  = FF_CEIL_RSHIFT(src->width,  fm->hsub);
+        const int height = FF_CEIL_RSHIFT(src->height, fm->vsub);
         const int cmk_linesize   = fm->cmask_linesize[0] << 1;
         const int cmk_linesizeUV = fm->cmask_linesize[2];
         uint8_t *cmkpp  = cmkp - (cmk_linesize>>1);
@@ -608,7 +608,7 @@
                         const AVFrame *src, int field)
 {
     int plane;
-    for (plane = 0; plane < 4 && src->data[plane]; plane++)
+    for (plane = 0; plane < 4 && src->data[plane] && src->linesize[plane]; plane++)
         av_image_copy_plane(dst->data[plane] + field*dst->linesize[plane], dst->linesize[plane] << 1,
                             src->data[plane] + field*src->linesize[plane], src->linesize[plane] << 1,
                             get_width(fm, src, plane), get_height(fm, src, plane) / 2);
diff --git a/libavfilter/vf_fieldorder.c b/libavfilter/vf_fieldorder.c
index 653411d..7ff8841 100644
--- a/libavfilter/vf_fieldorder.c
+++ b/libavfilter/vf_fieldorder.c
@@ -51,8 +51,8 @@
         formats = NULL;
         for (pix_fmt = 0; pix_fmt < AV_PIX_FMT_NB; pix_fmt++) {
             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
-            if (!(desc->flags & PIX_FMT_HWACCEL ||
-                  desc->flags & PIX_FMT_BITSTREAM) &&
+            if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL ||
+                  desc->flags & AV_PIX_FMT_FLAG_BITSTREAM) &&
                 desc->nb_components && !desc->log2_chroma_h &&
                 (ret = ff_add_format(&formats, pix_fmt)) < 0) {
                 ff_formats_unref(&formats);
@@ -68,17 +68,15 @@
 
 static int config_input(AVFilterLink *inlink)
 {
-    AVFilterContext   *ctx        = inlink->dst;
-    FieldOrderContext *fieldorder = ctx->priv;
+    AVFilterContext   *ctx = inlink->dst;
+    FieldOrderContext *s   = ctx->priv;
     int               plane;
 
     /** full an array with the number of bytes that the video
      *  data occupies per line for each plane of the input video */
     for (plane = 0; plane < 4; plane++) {
-        fieldorder->line_size[plane] = av_image_get_linesize(
-                inlink->format,
-                inlink->w,
-                plane);
+        s->line_size[plane] = av_image_get_linesize(inlink->format, inlink->w,
+                                                    plane);
     }
 
     return 0;
@@ -108,7 +106,7 @@
             "picture will move %s one line\n",
             s->dst_tff ? "up" : "down");
     h = frame->height;
-    for (plane = 0; plane < 4 && frame->data[plane]; plane++) {
+    for (plane = 0; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++) {
         line_step = frame->linesize[plane];
         line_size = s->line_size[plane];
         data = frame->data[plane];
diff --git a/libavfilter/vf_format.c b/libavfilter/vf_format.c
index 56ce74c..25b3d19 100644
--- a/libavfilter/vf_format.c
+++ b/libavfilter/vf_format.c
@@ -50,14 +50,14 @@
 
 static av_cold int init(AVFilterContext *ctx)
 {
-    FormatContext *format = ctx->priv;
+    FormatContext *s = ctx->priv;
     const char *cur, *sep;
     char             pix_fmt_name[AV_PIX_FMT_NAME_MAXSIZE];
     int              pix_fmt_name_len, ret;
     enum AVPixelFormat pix_fmt;
 
     /* parse the list of formats */
-    for (cur = format->pix_fmts; cur; cur = sep ? sep + 1 : NULL) {
+    for (cur = s->pix_fmts; cur; cur = sep ? sep + 1 : NULL) {
         if (!(sep = strchr(cur, '|')))
             pix_fmt_name_len = strlen(cur);
         else
@@ -73,23 +73,25 @@
         if ((ret = ff_parse_pixel_format(&pix_fmt, pix_fmt_name, ctx)) < 0)
             return ret;
 
-        format->listed_pix_fmt_flags[pix_fmt] = 1;
+        s->listed_pix_fmt_flags[pix_fmt] = 1;
     }
 
     return 0;
 }
 
-static AVFilterFormats *make_format_list(FormatContext *format, int flag)
+static AVFilterFormats *make_format_list(FormatContext *s, int flag)
 {
-    AVFilterFormats *formats;
+    AVFilterFormats *formats = NULL;
     enum AVPixelFormat pix_fmt;
 
-    formats = av_mallocz(sizeof(AVFilterFormats));
-    formats->formats = av_malloc(sizeof(enum AVPixelFormat) * AV_PIX_FMT_NB);
-
     for (pix_fmt = 0; pix_fmt < AV_PIX_FMT_NB; pix_fmt++)
-        if (format->listed_pix_fmt_flags[pix_fmt] == flag)
-            formats->formats[formats->format_count++] = pix_fmt;
+        if (s->listed_pix_fmt_flags[pix_fmt] == flag) {
+            int ret = ff_add_format(&formats, pix_fmt);
+            if (ret < 0) {
+                ff_formats_unref(&formats);
+                return NULL;
+            }
+        }
 
     return formats;
 }
@@ -107,12 +109,8 @@
     return 0;
 }
 
-static const AVClass format_class = {
-    .class_name = "format",
-    .item_name  = av_default_item_name,
-    .option     = options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
+#define format_options options
+AVFILTER_DEFINE_CLASS(format);
 
 static const AVFilterPad avfilter_vf_format_inputs[] = {
     {
@@ -154,12 +152,8 @@
     return 0;
 }
 
-static const AVClass noformat_class = {
-    .class_name = "noformat",
-    .item_name  = av_default_item_name,
-    .option     = options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
+#define noformat_options options
+AVFILTER_DEFINE_CLASS(noformat);
 
 static const AVFilterPad avfilter_vf_noformat_inputs[] = {
     {
diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c
index 6a67158..e30e90b 100644
--- a/libavfilter/vf_fps.c
+++ b/libavfilter/vf_fps.c
@@ -44,6 +44,8 @@
     int64_t first_pts;      ///< pts of the first frame that arrived on this filter
     int64_t pts;            ///< pts of the first frame currently in the fifo
 
+    double start_time;      ///< pts, in seconds, of the expected first frame
+
     AVRational framerate;   ///< target framerate
     int rounding;           ///< AVRounding method for timestamps
 
@@ -59,6 +61,7 @@
 #define F AV_OPT_FLAG_FILTERING_PARAM
 static const AVOption fps_options[] = {
     { "fps", "A string describing desired output framerate", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, { .str = "25" }, .flags = V|F },
+    { "start_time", "Assume the first PTS should be this value.", OFFSET(start_time), AV_OPT_TYPE_DOUBLE, { .dbl = AV_NOPTS_VALUE}, INT64_MIN, INT64_MAX, V },
     { "round", "set rounding method for timestamps", OFFSET(rounding), AV_OPT_TYPE_INT, { .i64 = AV_ROUND_NEAR_INF }, 0, 5, V|F, "round" },
     { "zero", "round towards 0",      OFFSET(rounding), AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_ZERO     }, 0, 5, V|F, "round" },
     { "inf",  "round away from 0",    OFFSET(rounding), AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_INF      }, 0, 5, V|F, "round" },
@@ -77,6 +80,9 @@
     if (!(s->fifo = av_fifo_alloc(2*sizeof(AVFrame*))))
         return AVERROR(ENOMEM);
 
+    s->pts          = AV_NOPTS_VALUE;
+    s->first_pts    = AV_NOPTS_VALUE;
+
     av_log(ctx, AV_LOG_VERBOSE, "fps=%d/%d\n", s->framerate.num, s->framerate.den);
     return 0;
 }
@@ -111,7 +117,6 @@
     link->frame_rate= s->framerate;
     link->w         = link->src->inputs[0]->w;
     link->h         = link->src->inputs[0]->h;
-    s->pts          = AV_NOPTS_VALUE;
 
     return 0;
 }
@@ -177,7 +182,17 @@
             if (ret < 0)
                 return ret;
 
-            s->first_pts = s->pts = buf->pts;
+            if (s->start_time != AV_NOPTS_VALUE) {
+                double first_pts = s->start_time * AV_TIME_BASE;
+                first_pts = FFMIN(FFMAX(first_pts, INT64_MIN), INT64_MAX);
+                s->first_pts = s->pts = av_rescale_q(first_pts, AV_TIME_BASE_Q,
+                                                     inlink->time_base);
+                av_log(ctx, AV_LOG_VERBOSE, "Set first pts to (in:%"PRId64" out:%"PRId64")\n",
+                       s->first_pts, av_rescale_q(first_pts, AV_TIME_BASE_Q,
+                                                  outlink->time_base));
+            } else {
+                s->first_pts = s->pts = buf->pts;
+            }
         } else {
             av_log(ctx, AV_LOG_WARNING, "Discarding initial frame(s) with no "
                    "timestamp.\n");
diff --git a/libavfilter/vf_framestep.c b/libavfilter/vf_framestep.c
index fb20411..5c38d90 100644
--- a/libavfilter/vf_framestep.c
+++ b/libavfilter/vf_framestep.c
@@ -91,10 +91,11 @@
 };
 
 AVFilter avfilter_vf_framestep = {
-    .name      = "framestep",
+    .name        = "framestep",
     .description = NULL_IF_CONFIG_SMALL("Select one frame every N frames."),
-    .priv_size = sizeof(FrameStepContext),
-    .priv_class = &framestep_class,
-    .inputs    = framestep_inputs,
-    .outputs   = framestep_outputs,
+    .priv_size   = sizeof(FrameStepContext),
+    .priv_class  = &framestep_class,
+    .inputs      = framestep_inputs,
+    .outputs     = framestep_outputs,
+    .flags       = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c
index 399f09e..0278441 100644
--- a/libavfilter/vf_frei0r.c
+++ b/libavfilter/vf_frei0r.c
@@ -22,8 +22,6 @@
  * frei0r wrapper
  */
 
-/* #define DEBUG */
-
 #include <dlfcn.h>
 #include <frei0r.h>
 #include <stdio.h>
@@ -69,8 +67,7 @@
 
     char *dl_name;
     char *params;
-    char *size;
-    char *framerate;
+    AVRational framerate;
 
     /* only used by the source */
     int w, h;
@@ -80,8 +77,8 @@
 
 static void *load_sym(AVFilterContext *ctx, const char *sym_name)
 {
-    Frei0rContext *frei0r = ctx->priv;
-    void *sym = dlsym(frei0r->dl_handle, sym_name);
+    Frei0rContext *s = ctx->priv;
+    void *sym = dlsym(s->dl_handle, sym_name);
     if (!sym)
         av_log(ctx, AV_LOG_ERROR, "Could not find symbol '%s' in loaded module\n", sym_name);
     return sym;
@@ -89,7 +86,7 @@
 
 static int set_param(AVFilterContext *ctx, f0r_param_info_t info, int index, char *param)
 {
-    Frei0rContext *frei0r = ctx->priv;
+    Frei0rContext *s = ctx->priv;
     union {
         double d;
         f0r_param_color_t col;
@@ -127,7 +124,7 @@
         break;
     }
 
-    frei0r->set_param_value(frei0r->instance, &val, index);
+    s->set_param_value(s->instance, &val, index);
     return 0;
 
 fail:
@@ -138,15 +135,18 @@
 
 static int set_params(AVFilterContext *ctx, const char *params)
 {
-    Frei0rContext *frei0r = ctx->priv;
+    Frei0rContext *s = ctx->priv;
     int i;
 
-    for (i = 0; i < frei0r->plugin_info.num_params; i++) {
+    if (!params)
+        return 0;
+
+    for (i = 0; i < s->plugin_info.num_params; i++) {
         f0r_param_info_t info;
         char *param;
         int ret;
 
-        frei0r->get_param_info(&info, i);
+        s->get_param_info(&info, i);
 
         if (*params) {
             if (!(param = av_get_token(&params, "|")))
@@ -179,27 +179,27 @@
 
         case F0R_PARAM_BOOL:
             v = &d;
-            frei0r->get_param_value(frei0r->instance, v, i);
+            s->get_param_value(s->instance, v, i);
             av_log(ctx, AV_LOG_DEBUG, "%s", d >= 0.5 && d <= 1.0 ? "y" : "n");
             break;
         case F0R_PARAM_DOUBLE:
             v = &d;
-            frei0r->get_param_value(frei0r->instance, v, i);
+            s->get_param_value(s->instance, v, i);
             av_log(ctx, AV_LOG_DEBUG, "%f", d);
             break;
         case F0R_PARAM_COLOR:
             v = &col;
-            frei0r->get_param_value(frei0r->instance, v, i);
+            s->get_param_value(s->instance, v, i);
             av_log(ctx, AV_LOG_DEBUG, "%f/%f/%f", col.r, col.g, col.b);
             break;
         case F0R_PARAM_POSITION:
             v = &pos;
-            frei0r->get_param_value(frei0r->instance, v, i);
+            s->get_param_value(s->instance, v, i);
             av_log(ctx, AV_LOG_DEBUG, "%f/%f", pos.x, pos.y);
             break;
         default: /* F0R_PARAM_STRING */
             v = s;
-            frei0r->get_param_value(frei0r->instance, v, i);
+            s->get_param_value(s->instance, v, i);
             av_log(ctx, AV_LOG_DEBUG, "'%s'\n", s);
             break;
         }
@@ -224,7 +224,7 @@
 static av_cold int frei0r_init(AVFilterContext *ctx,
                                const char *dl_name, int type)
 {
-    Frei0rContext *frei0r = ctx->priv;
+    Frei0rContext *s = ctx->priv;
     f0r_init_f            f0r_init;
     f0r_get_plugin_info_f f0r_get_plugin_info;
     f0r_plugin_info_t *pi;
@@ -251,11 +251,11 @@
                 ret = AVERROR(ENOMEM);
                 goto check_path_end;
             }
-            ret = load_path(ctx, &frei0r->dl_handle, p1, dl_name);
+            ret = load_path(ctx, &s->dl_handle, p1, dl_name);
             av_free(p1);
             if (ret < 0)
                 goto check_path_end;
-            if (frei0r->dl_handle)
+            if (s->dl_handle)
                 break;
         }
 
@@ -264,39 +264,39 @@
         if (ret < 0)
             return ret;
     }
-    if (!frei0r->dl_handle && (path = getenv("HOME"))) {
+    if (!s->dl_handle && (path = getenv("HOME"))) {
         char *prefix = av_asprintf("%s/.frei0r-1/lib/", path);
         if (!prefix)
             return AVERROR(ENOMEM);
-        ret = load_path(ctx, &frei0r->dl_handle, prefix, dl_name);
+        ret = load_path(ctx, &s->dl_handle, prefix, dl_name);
         av_free(prefix);
         if (ret < 0)
             return ret;
     }
-    if (!frei0r->dl_handle) {
-        ret = load_path(ctx, &frei0r->dl_handle, "/usr/local/lib/frei0r-1/", dl_name);
+    if (!s->dl_handle) {
+        ret = load_path(ctx, &s->dl_handle, "/usr/local/lib/frei0r-1/", dl_name);
         if (ret < 0)
             return ret;
     }
-    if (!frei0r->dl_handle) {
-        ret = load_path(ctx, &frei0r->dl_handle, "/usr/lib/frei0r-1/", dl_name);
+    if (!s->dl_handle) {
+        ret = load_path(ctx, &s->dl_handle, "/usr/lib/frei0r-1/", dl_name);
         if (ret < 0)
             return ret;
     }
-    if (!frei0r->dl_handle) {
+    if (!s->dl_handle) {
         av_log(ctx, AV_LOG_ERROR, "Could not find module '%s'\n", dl_name);
         return AVERROR(EINVAL);
     }
 
     if (!(f0r_init                = load_sym(ctx, "f0r_init"           )) ||
         !(f0r_get_plugin_info     = load_sym(ctx, "f0r_get_plugin_info")) ||
-        !(frei0r->get_param_info  = load_sym(ctx, "f0r_get_param_info" )) ||
-        !(frei0r->get_param_value = load_sym(ctx, "f0r_get_param_value")) ||
-        !(frei0r->set_param_value = load_sym(ctx, "f0r_set_param_value")) ||
-        !(frei0r->update          = load_sym(ctx, "f0r_update"         )) ||
-        !(frei0r->construct       = load_sym(ctx, "f0r_construct"      )) ||
-        !(frei0r->destruct        = load_sym(ctx, "f0r_destruct"       )) ||
-        !(frei0r->deinit          = load_sym(ctx, "f0r_deinit"         )))
+        !(s->get_param_info  = load_sym(ctx, "f0r_get_param_info" )) ||
+        !(s->get_param_value = load_sym(ctx, "f0r_get_param_value")) ||
+        !(s->set_param_value = load_sym(ctx, "f0r_set_param_value")) ||
+        !(s->update          = load_sym(ctx, "f0r_update"         )) ||
+        !(s->construct       = load_sym(ctx, "f0r_construct"      )) ||
+        !(s->destruct        = load_sym(ctx, "f0r_destruct"       )) ||
+        !(s->deinit          = load_sym(ctx, "f0r_deinit"         )))
         return AVERROR(EINVAL);
 
     if (f0r_init() < 0) {
@@ -304,8 +304,8 @@
         return AVERROR(EINVAL);
     }
 
-    f0r_get_plugin_info(&frei0r->plugin_info);
-    pi = &frei0r->plugin_info;
+    f0r_get_plugin_info(&s->plugin_info);
+    pi = &s->plugin_info;
     if (pi->plugin_type != type) {
         av_log(ctx, AV_LOG_ERROR,
                "Invalid type '%s' for the plugin\n",
@@ -330,44 +330,46 @@
 
 static av_cold int filter_init(AVFilterContext *ctx)
 {
-    Frei0rContext *frei0r = ctx->priv;
+    Frei0rContext *s = ctx->priv;
 
-    return frei0r_init(ctx, frei0r->dl_name, F0R_PLUGIN_TYPE_FILTER);
+    return frei0r_init(ctx, s->dl_name, F0R_PLUGIN_TYPE_FILTER);
 }
 
 static av_cold void uninit(AVFilterContext *ctx)
 {
-    Frei0rContext *frei0r = ctx->priv;
+    Frei0rContext *s = ctx->priv;
 
-    if (frei0r->destruct && frei0r->instance)
-        frei0r->destruct(frei0r->instance);
-    if (frei0r->deinit)
-        frei0r->deinit();
-    if (frei0r->dl_handle)
-        dlclose(frei0r->dl_handle);
+    if (s->destruct && s->instance)
+        s->destruct(s->instance);
+    if (s->deinit)
+        s->deinit();
+    if (s->dl_handle)
+        dlclose(s->dl_handle);
 }
 
 static int config_input_props(AVFilterLink *inlink)
 {
     AVFilterContext *ctx = inlink->dst;
-    Frei0rContext *frei0r = ctx->priv;
+    Frei0rContext *s = ctx->priv;
 
-    if (!(frei0r->instance = frei0r->construct(inlink->w, inlink->h))) {
+    if (s->destruct && s->instance)
+        s->destruct(s->instance);
+    if (!(s->instance = s->construct(inlink->w, inlink->h))) {
         av_log(ctx, AV_LOG_ERROR, "Impossible to load frei0r instance\n");
         return AVERROR(EINVAL);
     }
 
-    return set_params(ctx, frei0r->params);
+    return set_params(ctx, s->params);
 }
 
 static int query_formats(AVFilterContext *ctx)
 {
-    Frei0rContext *frei0r = ctx->priv;
+    Frei0rContext *s = ctx->priv;
     AVFilterFormats *formats = NULL;
 
-    if        (frei0r->plugin_info.color_model == F0R_COLOR_MODEL_BGRA8888) {
+    if        (s->plugin_info.color_model == F0R_COLOR_MODEL_BGRA8888) {
         ff_add_format(&formats, AV_PIX_FMT_BGRA);
-    } else if (frei0r->plugin_info.color_model == F0R_COLOR_MODEL_RGBA8888) {
+    } else if (s->plugin_info.color_model == F0R_COLOR_MODEL_RGBA8888) {
         ff_add_format(&formats, AV_PIX_FMT_RGBA);
     } else {                                   /* F0R_COLOR_MODEL_PACKED32 */
         static const enum AVPixelFormat pix_fmts[] = {
@@ -385,7 +387,7 @@
 
 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
-    Frei0rContext *frei0r = inlink->dst->priv;
+    Frei0rContext *s = inlink->dst->priv;
     AVFilterLink *outlink = inlink->dst->outputs[0];
     AVFrame *out;
 
@@ -396,7 +398,7 @@
     }
     av_frame_copy_props(out, in);
 
-    frei0r->update(frei0r->instance, in->pts * av_q2d(inlink->time_base) * 1000,
+    s->update(s->instance, in->pts * av_q2d(inlink->time_base) * 1000,
                    (const uint32_t *)in->data[0],
                    (uint32_t *)out->data[0]);
 
@@ -407,18 +409,13 @@
 
 #define OFFSET(x) offsetof(Frei0rContext, x)
 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
-static const AVOption filter_options[] = {
+static const AVOption frei0r_options[] = {
     { "filter_name",   NULL, OFFSET(dl_name), AV_OPT_TYPE_STRING, .flags = FLAGS },
     { "filter_params", NULL, OFFSET(params),  AV_OPT_TYPE_STRING, .flags = FLAGS },
     { NULL },
 };
 
-static const AVClass filter_class = {
-    .class_name = "frei0r",
-    .item_name  = av_default_item_name,
-    .option     = filter_options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
+AVFILTER_DEFINE_CLASS(frei0r);
 
 static const AVFilterPad avfilter_vf_frei0r_inputs[] = {
     {
@@ -447,7 +444,7 @@
     .uninit = uninit,
 
     .priv_size = sizeof(Frei0rContext),
-    .priv_class = &filter_class,
+    .priv_class = &frei0r_class,
 
     .inputs    = avfilter_vf_frei0r_inputs,
 
@@ -456,75 +453,62 @@
 
 static av_cold int source_init(AVFilterContext *ctx)
 {
-    Frei0rContext *frei0r = ctx->priv;
-    AVRational frame_rate_q;
+    Frei0rContext *s = ctx->priv;
 
-    if (av_parse_video_size(&frei0r->w, &frei0r->h, frei0r->size) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid frame size: '%s'\n", frei0r->size);
-        return AVERROR(EINVAL);
-    }
+    s->time_base.num = s->framerate.den;
+    s->time_base.den = s->framerate.num;
 
-    if (av_parse_video_rate(&frame_rate_q, frei0r->framerate) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: '%s'\n", frei0r->framerate);
-        return AVERROR(EINVAL);
-    }
-    frei0r->time_base.num = frame_rate_q.den;
-    frei0r->time_base.den = frame_rate_q.num;
-
-    return frei0r_init(ctx, frei0r->dl_name, F0R_PLUGIN_TYPE_SOURCE);
+    return frei0r_init(ctx, s->dl_name, F0R_PLUGIN_TYPE_SOURCE);
 }
 
 static int source_config_props(AVFilterLink *outlink)
 {
     AVFilterContext *ctx = outlink->src;
-    Frei0rContext *frei0r = ctx->priv;
+    Frei0rContext *s = ctx->priv;
 
-    if (av_image_check_size(frei0r->w, frei0r->h, 0, ctx) < 0)
+    if (av_image_check_size(s->w, s->h, 0, ctx) < 0)
         return AVERROR(EINVAL);
-    outlink->w = frei0r->w;
-    outlink->h = frei0r->h;
-    outlink->time_base = frei0r->time_base;
+    outlink->w = s->w;
+    outlink->h = s->h;
+    outlink->time_base = s->time_base;
     outlink->sample_aspect_ratio = (AVRational){1,1};
 
-    if (!(frei0r->instance = frei0r->construct(outlink->w, outlink->h))) {
+    if (s->destruct && s->instance)
+        s->destruct(s->instance);
+    if (!(s->instance = s->construct(outlink->w, outlink->h))) {
         av_log(ctx, AV_LOG_ERROR, "Impossible to load frei0r instance\n");
         return AVERROR(EINVAL);
     }
 
-    return set_params(ctx, frei0r->params);
+    return set_params(ctx, s->params);
 }
 
 static int source_request_frame(AVFilterLink *outlink)
 {
-    Frei0rContext *frei0r = outlink->src->priv;
+    Frei0rContext *s = outlink->src->priv;
     AVFrame *frame = ff_get_video_buffer(outlink, outlink->w, outlink->h);
 
     if (!frame)
         return AVERROR(ENOMEM);
 
     frame->sample_aspect_ratio = (AVRational) {1, 1};
-    frame->pts = frei0r->pts++;
+    frame->pts = s->pts++;
 
-    frei0r->update(frei0r->instance, av_rescale_q(frame->pts, frei0r->time_base, (AVRational){1,1000}),
+    s->update(s->instance, av_rescale_q(frame->pts, s->time_base, (AVRational){1,1000}),
                    NULL, (uint32_t *)frame->data[0]);
 
     return ff_filter_frame(outlink, frame);
 }
 
-static const AVOption src_options[] = {
-    { "size",          "Dimensions of the generated video.", OFFSET(size),      AV_OPT_TYPE_STRING, { .str = "" },   .flags = FLAGS },
-    { "framerate",     NULL,                                 OFFSET(framerate), AV_OPT_TYPE_STRING, { .str = "25" }, .flags = FLAGS },
+static const AVOption frei0r_src_options[] = {
+    { "size",          "Dimensions of the generated video.", OFFSET(w),         AV_OPT_TYPE_IMAGE_SIZE, { .str = "320x240" }, .flags = FLAGS },
+    { "framerate",     NULL,                                 OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, { .str = "25" }, .flags = FLAGS },
     { "filter_name",   NULL,                                 OFFSET(dl_name),   AV_OPT_TYPE_STRING,                  .flags = FLAGS },
     { "filter_params", NULL,                                 OFFSET(params),    AV_OPT_TYPE_STRING,                  .flags = FLAGS },
     { NULL },
 };
 
-static const AVClass src_class = {
-    .class_name = "frei0r_src",
-    .item_name  = av_default_item_name,
-    .option     = src_options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
+AVFILTER_DEFINE_CLASS(frei0r_src);
 
 static const AVFilterPad avfilter_vsrc_frei0r_src_outputs[] = {
     {
@@ -541,7 +525,7 @@
     .description = NULL_IF_CONFIG_SMALL("Generate a frei0r source."),
 
     .priv_size = sizeof(Frei0rContext),
-    .priv_class = &src_class,
+    .priv_class = &frei0r_src_class,
     .init      = source_init,
     .uninit    = uninit,
 
diff --git a/libavfilter/vf_geq.c b/libavfilter/vf_geq.c
index 89467bc..70bcdbe 100644
--- a/libavfilter/vf_geq.c
+++ b/libavfilter/vf_geq.c
@@ -42,18 +42,26 @@
     int is_rgb;
 } GEQContext;
 
+enum { Y = 0, U, V, A, G, B, R };
+
 #define OFFSET(x) offsetof(GEQContext, x)
 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
 
 static const AVOption geq_options[] = {
-    { "lum_expr",   "set luminance expression",   OFFSET(expr_str[0]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
-    { "cb_expr",    "set chroma blue expression", OFFSET(expr_str[1]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
-    { "cr_expr",    "set chroma red expression",  OFFSET(expr_str[2]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
-    { "alpha_expr", "set alpha expression",       OFFSET(expr_str[3]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
-
-    { "r",          "set red expression",   OFFSET(expr_str[6]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
-    { "g",          "set green expression", OFFSET(expr_str[4]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
-    { "b",          "set blue expression",  OFFSET(expr_str[5]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "lum_expr",   "set luminance expression",   OFFSET(expr_str[Y]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "lum",        "set luminance expression",   OFFSET(expr_str[Y]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "cb_expr",    "set chroma blue expression", OFFSET(expr_str[U]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "cb",         "set chroma blue expression", OFFSET(expr_str[U]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "cr_expr",    "set chroma red expression",  OFFSET(expr_str[V]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "cr",         "set chroma red expression",  OFFSET(expr_str[V]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "alpha_expr", "set alpha expression",       OFFSET(expr_str[A]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "a",          "set alpha expression",       OFFSET(expr_str[A]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "red_expr",   "set red expression",         OFFSET(expr_str[R]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "r",          "set red expression",         OFFSET(expr_str[R]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "green_expr", "set green expression",       OFFSET(expr_str[G]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "g",          "set green expression",       OFFSET(expr_str[G]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "blue_expr",  "set blue expression",        OFFSET(expr_str[B]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "b",          "set blue expression",        OFFSET(expr_str[B]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
     {NULL},
 };
 
@@ -66,8 +74,8 @@
     AVFrame *picref = geq->picref;
     const uint8_t *src = picref->data[plane];
     const int linesize = picref->linesize[plane];
-    const int w = picref->width  >> ((plane == 1 || plane == 2) ? geq->hsub : 0);
-    const int h = picref->height >> ((plane == 1 || plane == 2) ? geq->vsub : 0);
+    const int w = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(picref->width,  geq->hsub) : picref->width;
+    const int h = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(picref->height, geq->vsub) : picref->height;
 
     if (!src)
         return 0;
@@ -97,42 +105,42 @@
     GEQContext *geq = ctx->priv;
     int plane, ret = 0;
 
-    if (!geq->expr_str[0] && !geq->expr_str[4] && !geq->expr_str[5] && !geq->expr_str[6]) {
+    if (!geq->expr_str[Y] && !geq->expr_str[G] && !geq->expr_str[B] && !geq->expr_str[R]) {
         av_log(ctx, AV_LOG_ERROR, "A luminance or RGB expression is mandatory\n");
         ret = AVERROR(EINVAL);
         goto end;
     }
-    geq->is_rgb = !geq->expr_str[0];
+    geq->is_rgb = !geq->expr_str[Y];
 
-    if ((geq->expr_str[0] || geq->expr_str[1] || geq->expr_str[2]) && (geq->expr_str[4] || geq->expr_str[5] || geq->expr_str[6])) {
+    if ((geq->expr_str[Y] || geq->expr_str[U] || geq->expr_str[V]) && (geq->expr_str[G] || geq->expr_str[B] || geq->expr_str[R])) {
         av_log(ctx, AV_LOG_ERROR, "Either YCbCr or RGB but not both must be specified\n");
         ret = AVERROR(EINVAL);
         goto end;
     }
 
-    if (!geq->expr_str[1] && !geq->expr_str[2]) {
+    if (!geq->expr_str[U] && !geq->expr_str[V]) {
         /* No chroma at all: fallback on luma */
-        geq->expr_str[1] = av_strdup(geq->expr_str[0]);
-        geq->expr_str[2] = av_strdup(geq->expr_str[0]);
+        geq->expr_str[U] = av_strdup(geq->expr_str[Y]);
+        geq->expr_str[V] = av_strdup(geq->expr_str[Y]);
     } else {
         /* One chroma unspecified, fallback on the other */
-        if (!geq->expr_str[1]) geq->expr_str[1] = av_strdup(geq->expr_str[2]);
-        if (!geq->expr_str[2]) geq->expr_str[2] = av_strdup(geq->expr_str[1]);
+        if (!geq->expr_str[U]) geq->expr_str[U] = av_strdup(geq->expr_str[V]);
+        if (!geq->expr_str[V]) geq->expr_str[V] = av_strdup(geq->expr_str[U]);
     }
 
-    if (!geq->expr_str[3])
-        geq->expr_str[3] = av_strdup("255");
-    if (!geq->expr_str[4])
-        geq->expr_str[4] = av_strdup("g(X,Y)");
-    if (!geq->expr_str[5])
-        geq->expr_str[5] = av_strdup("b(X,Y)");
-    if (!geq->expr_str[6])
-        geq->expr_str[6] = av_strdup("r(X,Y)");
+    if (!geq->expr_str[A])
+        geq->expr_str[A] = av_strdup("255");
+    if (!geq->expr_str[G])
+        geq->expr_str[G] = av_strdup("g(X,Y)");
+    if (!geq->expr_str[B])
+        geq->expr_str[B] = av_strdup("b(X,Y)");
+    if (!geq->expr_str[R])
+        geq->expr_str[R] = av_strdup("r(X,Y)");
 
     if (geq->is_rgb ?
-            (!geq->expr_str[4] || !geq->expr_str[5] || !geq->expr_str[6])
+            (!geq->expr_str[G] || !geq->expr_str[B] || !geq->expr_str[R])
                     :
-            (!geq->expr_str[1] || !geq->expr_str[2] || !geq->expr_str[3])) {
+            (!geq->expr_str[U] || !geq->expr_str[V] || !geq->expr_str[A])) {
         ret = AVERROR(ENOMEM);
         goto end;
     }
@@ -165,7 +173,7 @@
         AV_PIX_FMT_NONE
     };
     static const enum PixelFormat rgb_pix_fmts[] = {
-        AV_PIX_FMT_GBRP,
+        AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP,
         AV_PIX_FMT_NONE
     };
     if (geq->is_rgb) {
@@ -209,8 +217,8 @@
         int x, y;
         uint8_t *dst = out->data[plane];
         const int linesize = out->linesize[plane];
-        const int w = inlink->w >> ((plane == 1 || plane == 2) ? geq->hsub : 0);
-        const int h = inlink->h >> ((plane == 1 || plane == 2) ? geq->vsub : 0);
+        const int w = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(inlink->w, geq->hsub) : inlink->w;
+        const int h = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(inlink->h, geq->vsub) : inlink->h;
 
         values[VAR_W]  = w;
         values[VAR_H]  = h;
@@ -268,4 +276,5 @@
     .inputs        = geq_inputs,
     .outputs       = geq_outputs,
     .priv_class    = &geq_class,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c
index 48ac378..c3661e1 100644
--- a/libavfilter/vf_gradfun.c
+++ b/libavfilter/vf_gradfun.c
@@ -25,7 +25,7 @@
  * libmpcodecs/vf_gradfun.c
  *
  * Apply a boxblur debanding algorithm (based on the gradfun2db
- * Avisynth filter by prunedtree).
+ * AviSynth filter by prunedtree).
  * Foreach pixel, if it's within threshold of the blurred value, make it closer.
  * So now we have a smoothed and higher bitdepth version of all the shallow
  * gradients, while leaving detailed areas untouched.
@@ -123,36 +123,36 @@
 
 static av_cold int init(AVFilterContext *ctx)
 {
-    GradFunContext *gf = ctx->priv;
+    GradFunContext *s = ctx->priv;
 
-    gf->thresh  = (1 << 15) / gf->strength;
-    gf->radius  = av_clip((gf->radius + 1) & ~1, 4, 32);
+    s->thresh  = (1 << 15) / s->strength;
+    s->radius  = av_clip((s->radius + 1) & ~1, 4, 32);
 
-    gf->blur_line   = ff_gradfun_blur_line_c;
-    gf->filter_line = ff_gradfun_filter_line_c;
+    s->blur_line   = ff_gradfun_blur_line_c;
+    s->filter_line = ff_gradfun_filter_line_c;
 
     if (ARCH_X86)
-        ff_gradfun_init_x86(gf);
+        ff_gradfun_init_x86(s);
 
-    av_log(ctx, AV_LOG_VERBOSE, "threshold:%.2f radius:%d\n", gf->strength, gf->radius);
+    av_log(ctx, AV_LOG_VERBOSE, "threshold:%.2f radius:%d\n", s->strength, s->radius);
 
     return 0;
 }
 
 static av_cold void uninit(AVFilterContext *ctx)
 {
-    GradFunContext *gf = ctx->priv;
-    av_freep(&gf->buf);
+    GradFunContext *s = ctx->priv;
+    av_freep(&s->buf);
 }
 
 static int query_formats(AVFilterContext *ctx)
 {
     static const enum AVPixelFormat pix_fmts[] = {
         AV_PIX_FMT_YUV410P,            AV_PIX_FMT_YUV420P,
-        AV_PIX_FMT_GRAY8,              AV_PIX_FMT_NV12,
-        AV_PIX_FMT_NV21,               AV_PIX_FMT_YUV444P,
+        AV_PIX_FMT_GRAY8,              AV_PIX_FMT_YUV444P,
         AV_PIX_FMT_YUV422P,            AV_PIX_FMT_YUV411P,
         AV_PIX_FMT_YUV440P,
+        AV_PIX_FMT_GBRP,
         AV_PIX_FMT_NONE
     };
 
@@ -163,25 +163,26 @@
 
 static int config_input(AVFilterLink *inlink)
 {
-    GradFunContext *gf = inlink->dst->priv;
+    GradFunContext *s = inlink->dst->priv;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
     int hsub = desc->log2_chroma_w;
     int vsub = desc->log2_chroma_h;
 
-    gf->buf = av_mallocz((FFALIGN(inlink->w, 16) * (gf->radius + 1) / 2 + 32) * sizeof(uint16_t));
-    if (!gf->buf)
+    av_freep(&s->buf);
+    s->buf = av_mallocz((FFALIGN(inlink->w, 16) * (s->radius + 1) / 2 + 32) * sizeof(uint16_t));
+    if (!s->buf)
         return AVERROR(ENOMEM);
 
-    gf->chroma_w = -((-inlink->w) >> hsub);
-    gf->chroma_h = -((-inlink->h) >> vsub);
-    gf->chroma_r = av_clip(((((gf->radius >> hsub) + (gf->radius >> vsub)) / 2 ) + 1) & ~1, 4, 32);
+    s->chroma_w = FF_CEIL_RSHIFT(inlink->w, hsub);
+    s->chroma_h = FF_CEIL_RSHIFT(inlink->h, vsub);
+    s->chroma_r = av_clip(((((s->radius >> hsub) + (s->radius >> vsub)) / 2 ) + 1) & ~1, 4, 32);
 
     return 0;
 }
 
 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
-    GradFunContext *gf = inlink->dst->priv;
+    GradFunContext *s = inlink->dst->priv;
     AVFilterLink *outlink = inlink->dst->outputs[0];
     AVFrame *out;
     int p, direct;
@@ -199,18 +200,18 @@
         av_frame_copy_props(out, in);
     }
 
-    for (p = 0; p < 4 && in->data[p]; p++) {
+    for (p = 0; p < 4 && in->data[p] && in->linesize[p]; p++) {
         int w = inlink->w;
         int h = inlink->h;
-        int r = gf->radius;
+        int r = s->radius;
         if (p) {
-            w = gf->chroma_w;
-            h = gf->chroma_h;
-            r = gf->chroma_r;
+            w = s->chroma_w;
+            h = s->chroma_h;
+            r = s->chroma_r;
         }
 
         if (FFMIN(w, h) > 2 * r)
-            filter(gf, out->data[p], in->data[p], w, h, out->linesize[p], in->linesize[p], r);
+            filter(s, out->data[p], in->data[p], w, h, out->linesize[p], in->linesize[p], r);
         else if (out->data[p] != in->data[p])
             av_image_copy_plane(out->data[p], out->linesize[p], in->data[p], in->linesize[p], w, h);
     }
@@ -260,5 +261,5 @@
     .query_formats = query_formats,
     .inputs        = avfilter_vf_gradfun_inputs,
     .outputs       = avfilter_vf_gradfun_outputs,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c
index cb51981..0a9bc2c 100644
--- a/libavfilter/vf_hflip.c
+++ b/libavfilter/vf_hflip.c
@@ -47,8 +47,8 @@
 
     for (fmt = 0; fmt < AV_PIX_FMT_NB; fmt++) {
         const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
-        if (!(desc->flags & PIX_FMT_HWACCEL ||
-              desc->flags & PIX_FMT_BITSTREAM ||
+        if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL ||
+              desc->flags & AV_PIX_FMT_FLAG_BITSTREAM ||
               (desc->log2_chroma_w != desc->log2_chroma_h &&
                desc->comp[0].plane == desc->comp[1].plane)))
             ff_add_format(&pix_fmts, fmt);
@@ -60,12 +60,12 @@
 
 static int config_props(AVFilterLink *inlink)
 {
-    FlipContext *flip = inlink->dst->priv;
+    FlipContext *s = inlink->dst->priv;
     const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
 
-    av_image_fill_max_pixsteps(flip->max_step, NULL, pix_desc);
-    flip->hsub = pix_desc->log2_chroma_w;
-    flip->vsub = pix_desc->log2_chroma_h;
+    av_image_fill_max_pixsteps(s->max_step, NULL, pix_desc);
+    s->hsub = pix_desc->log2_chroma_w;
+    s->vsub = pix_desc->log2_chroma_h;
 
     return 0;
 }
@@ -73,11 +73,11 @@
 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
     AVFilterContext *ctx  = inlink->dst;
-    FlipContext *flip     = ctx->priv;
+    FlipContext *s     = ctx->priv;
     AVFilterLink *outlink = ctx->outputs[0];
     AVFrame *out;
     uint8_t *inrow, *outrow;
-    int i, j, plane, step, hsub, vsub;
+    int i, j, plane, step;
 
     out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     if (!out) {
@@ -87,20 +87,20 @@
     av_frame_copy_props(out, in);
 
     /* copy palette if required */
-    if (av_pix_fmt_desc_get(inlink->format)->flags & PIX_FMT_PAL)
+    if (av_pix_fmt_desc_get(inlink->format)->flags & AV_PIX_FMT_FLAG_PAL)
         memcpy(out->data[1], in->data[1], AVPALETTE_SIZE);
 
-    for (plane = 0; plane < 4 && in->data[plane]; plane++) {
-        step = flip->max_step[plane];
-        hsub = (plane == 1 || plane == 2) ? flip->hsub : 0;
-        vsub = (plane == 1 || plane == 2) ? flip->vsub : 0;
+    for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) {
+        const int width  = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(inlink->w, s->hsub) : inlink->w;
+        const int height = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(inlink->h, s->vsub) : inlink->h;
+        step = s->max_step[plane];
 
         outrow = out->data[plane];
-        inrow  = in ->data[plane] + ((inlink->w >> hsub) - 1) * step;
-        for (i = 0; i < in->height >> vsub; i++) {
+        inrow  = in ->data[plane] + (width - 1) * step;
+        for (i = 0; i < height; i++) {
             switch (step) {
             case 1:
-                for (j = 0; j < (inlink->w >> hsub); j++)
+                for (j = 0; j < width; j++)
                     outrow[j] = inrow[-j];
             break;
 
@@ -108,7 +108,7 @@
             {
                 uint16_t *outrow16 = (uint16_t *)outrow;
                 uint16_t * inrow16 = (uint16_t *) inrow;
-                for (j = 0; j < (inlink->w >> hsub); j++)
+                for (j = 0; j < width; j++)
                     outrow16[j] = inrow16[-j];
             }
             break;
@@ -117,7 +117,7 @@
             {
                 uint8_t *in  =  inrow;
                 uint8_t *out = outrow;
-                for (j = 0; j < (inlink->w >> hsub); j++, out += 3, in -= 3) {
+                for (j = 0; j < width; j++, out += 3, in -= 3) {
                     int32_t v = AV_RB24(in);
                     AV_WB24(out, v);
                 }
@@ -128,13 +128,13 @@
             {
                 uint32_t *outrow32 = (uint32_t *)outrow;
                 uint32_t * inrow32 = (uint32_t *) inrow;
-                for (j = 0; j < (inlink->w >> hsub); j++)
+                for (j = 0; j < width; j++)
                     outrow32[j] = inrow32[-j];
             }
             break;
 
             default:
-                for (j = 0; j < (inlink->w >> hsub); j++)
+                for (j = 0; j < width; j++)
                     memcpy(outrow + j*step, inrow - j*step, step);
             }
 
diff --git a/libavfilter/vf_histeq.c b/libavfilter/vf_histeq.c
index a4166c6..659b696 100644
--- a/libavfilter/vf_histeq.c
+++ b/libavfilter/vf_histeq.c
@@ -279,5 +279,5 @@
     .inputs        = histeq_inputs,
     .outputs       = histeq_outputs,
     .priv_class    = &histeq_class,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_histogram.c b/libavfilter/vf_histogram.c
index 3daa482..f17516e 100644
--- a/libavfilter/vf_histogram.c
+++ b/libavfilter/vf_histogram.c
@@ -39,7 +39,6 @@
     const AVClass *class;               ///< AVClass context for log and options purpose
     enum HistogramMode mode;
     unsigned       histogram[256];
-    unsigned       max_hval;
     int            ncomp;
     const uint8_t  *bg_color;
     const uint8_t  *fg_color;
@@ -48,6 +47,7 @@
     int            step;
     int            waveform_mode;
     int            display_mode;
+    int            levels_mode;
 } HistogramContext;
 
 #define OFFSET(x) offsetof(HistogramContext, x)
@@ -68,6 +68,9 @@
     { "display_mode", "set display mode", OFFSET(display_mode), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, "display_mode"},
     { "parade",  NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "display_mode" },
     { "overlay", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "display_mode" },
+    { "levels_mode", "set levels mode", OFFSET(levels_mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "levels_mode"},
+    { "linear",      NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "levels_mode" },
+    { "logarithmic", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "levels_mode" },
     { NULL },
 };
 
@@ -80,7 +83,7 @@
 
 static const enum AVPixelFormat levels_pix_fmts[] = {
     AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVJ444P,
-    AV_PIX_FMT_GRAY8, AV_PIX_FMT_GBRP, AV_PIX_FMT_NONE
+    AV_PIX_FMT_GRAY8, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, AV_PIX_FMT_NONE
 };
 
 static int query_formats(AVFilterContext *ctx)
@@ -119,6 +122,7 @@
     h->ncomp = desc->nb_components;
 
     switch (inlink->format) {
+    case AV_PIX_FMT_GBRAP:
     case AV_PIX_FMT_GBRP:
         h->bg_color = black_gbrp_color;
         h->fg_color = white_gbrp_color;
@@ -186,6 +190,8 @@
     case MODE_LEVELS:
         for (k = 0; k < h->ncomp; k++) {
             int start = k * (h->level_height + h->scale_height) * h->display_mode;
+            double max_hval_log;
+            unsigned max_hval = 0;
 
             for (i = 0; i < in->height; i++) {
                 src = in->data[k] + i * in->linesize[k];
@@ -194,10 +200,16 @@
             }
 
             for (i = 0; i < 256; i++)
-                h->max_hval = FFMAX(h->max_hval, h->histogram[i]);
+                max_hval = FFMAX(max_hval, h->histogram[i]);
+            max_hval_log = log2(max_hval + 1);
 
             for (i = 0; i < outlink->w; i++) {
-                int col_height = h->level_height - (h->histogram[i] * (int64_t)h->level_height + h->max_hval - 1) / h->max_hval;
+                int col_height;
+
+                if (h->levels_mode)
+                    col_height = round(h->level_height * (1. - (log2(h->histogram[i] + 1) / max_hval_log)));
+                else
+                    col_height = h->level_height - (h->histogram[i] * (int64_t)h->level_height + max_hval - 1) / max_hval;
 
                 for (j = h->level_height - 1; j >= col_height; j--) {
                     if (h->display_mode) {
@@ -212,7 +224,6 @@
             }
 
             memset(h->histogram, 0, 256 * sizeof(unsigned));
-            h->max_hval = 0;
         }
         break;
     case MODE_WAVEFORM:
diff --git a/libavfilter/vf_hqdn3d.c b/libavfilter/vf_hqdn3d.c
index 003f175..6961f71 100644
--- a/libavfilter/vf_hqdn3d.c
+++ b/libavfilter/vf_hqdn3d.c
@@ -29,6 +29,7 @@
 #include <float.h>
 
 #include "config.h"
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/intreadwrite.h"
@@ -76,7 +77,7 @@
 }
 
 av_always_inline
-static void denoise_spatial(HQDN3DContext *hqdn3d,
+static void denoise_spatial(HQDN3DContext *s,
                             uint8_t *src, uint8_t *dst,
                             uint16_t *line_ant, uint16_t *frame_ant,
                             int w, int h, int sstride, int dstride,
@@ -102,8 +103,8 @@
         src += sstride;
         dst += dstride;
         frame_ant += w;
-        if (hqdn3d->denoise_row[depth]) {
-            hqdn3d->denoise_row[depth](src, dst, line_ant, frame_ant, w, spatial, temporal);
+        if (s->denoise_row[depth]) {
+            s->denoise_row[depth](src, dst, line_ant, frame_ant, w, spatial, temporal);
             continue;
         }
         pixel_ant = LOAD(0);
@@ -120,7 +121,7 @@
 }
 
 av_always_inline
-static void denoise_depth(HQDN3DContext *hqdn3d,
+static void denoise_depth(HQDN3DContext *s,
                           uint8_t *src, uint8_t *dst,
                           uint16_t *line_ant, uint16_t **frame_ant_ptr,
                           int w, int h, int sstride, int dstride,
@@ -141,7 +142,7 @@
     }
 
     if (spatial[0])
-        denoise_spatial(hqdn3d, src, dst, line_ant, frame_ant,
+        denoise_spatial(s, src, dst, line_ant, frame_ant,
                         w, h, sstride, dstride, spatial, temporal, depth);
     else
         denoise_temporal(src, dst, frame_ant,
@@ -149,7 +150,7 @@
 }
 
 #define denoise(...) \
-    switch (hqdn3d->depth) {\
+    switch (s->depth) {\
         case  8: denoise_depth(__VA_ARGS__,  8); break;\
         case  9: denoise_depth(__VA_ARGS__,  9); break;\
         case 10: denoise_depth(__VA_ARGS__, 10); break;\
@@ -181,38 +182,38 @@
 #define PARAM2_DEFAULT 3.0
 #define PARAM3_DEFAULT 6.0
 
-static int init(AVFilterContext *ctx)
+static av_cold int init(AVFilterContext *ctx)
 {
-    HQDN3DContext *hqdn3d = ctx->priv;
+    HQDN3DContext *s = ctx->priv;
 
-    if (!hqdn3d->strength[LUMA_SPATIAL])
-        hqdn3d->strength[LUMA_SPATIAL] = PARAM1_DEFAULT;
-    if (!hqdn3d->strength[CHROMA_SPATIAL])
-        hqdn3d->strength[CHROMA_SPATIAL] = PARAM2_DEFAULT * hqdn3d->strength[LUMA_SPATIAL] / PARAM1_DEFAULT;
-    if (!hqdn3d->strength[LUMA_TMP])
-        hqdn3d->strength[LUMA_TMP]   = PARAM3_DEFAULT * hqdn3d->strength[LUMA_SPATIAL] / PARAM1_DEFAULT;
-    if (!hqdn3d->strength[CHROMA_TMP])
-        hqdn3d->strength[CHROMA_TMP] = hqdn3d->strength[LUMA_TMP] * hqdn3d->strength[CHROMA_SPATIAL] / hqdn3d->strength[LUMA_SPATIAL];
+    if (!s->strength[LUMA_SPATIAL])
+        s->strength[LUMA_SPATIAL] = PARAM1_DEFAULT;
+    if (!s->strength[CHROMA_SPATIAL])
+        s->strength[CHROMA_SPATIAL] = PARAM2_DEFAULT * s->strength[LUMA_SPATIAL] / PARAM1_DEFAULT;
+    if (!s->strength[LUMA_TMP])
+        s->strength[LUMA_TMP]   = PARAM3_DEFAULT * s->strength[LUMA_SPATIAL] / PARAM1_DEFAULT;
+    if (!s->strength[CHROMA_TMP])
+        s->strength[CHROMA_TMP] = s->strength[LUMA_TMP] * s->strength[CHROMA_SPATIAL] / s->strength[LUMA_SPATIAL];
 
     av_log(ctx, AV_LOG_VERBOSE, "ls:%f cs:%f lt:%f ct:%f\n",
-           hqdn3d->strength[LUMA_SPATIAL], hqdn3d->strength[CHROMA_SPATIAL],
-           hqdn3d->strength[LUMA_TMP], hqdn3d->strength[CHROMA_TMP]);
+           s->strength[LUMA_SPATIAL], s->strength[CHROMA_SPATIAL],
+           s->strength[LUMA_TMP], s->strength[CHROMA_TMP]);
 
     return 0;
 }
 
-static void uninit(AVFilterContext *ctx)
+static av_cold void uninit(AVFilterContext *ctx)
 {
-    HQDN3DContext *hqdn3d = ctx->priv;
+    HQDN3DContext *s = ctx->priv;
 
-    av_freep(&hqdn3d->coefs[0]);
-    av_freep(&hqdn3d->coefs[1]);
-    av_freep(&hqdn3d->coefs[2]);
-    av_freep(&hqdn3d->coefs[3]);
-    av_freep(&hqdn3d->line);
-    av_freep(&hqdn3d->frame_prev[0]);
-    av_freep(&hqdn3d->frame_prev[1]);
-    av_freep(&hqdn3d->frame_prev[2]);
+    av_freep(&s->coefs[0]);
+    av_freep(&s->coefs[1]);
+    av_freep(&s->coefs[2]);
+    av_freep(&s->coefs[3]);
+    av_freep(&s->line);
+    av_freep(&s->frame_prev[0]);
+    av_freep(&s->frame_prev[1]);
+    av_freep(&s->frame_prev[2]);
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -247,39 +248,42 @@
 
 static int config_input(AVFilterLink *inlink)
 {
-    HQDN3DContext *hqdn3d = inlink->dst->priv;
+    HQDN3DContext *s = inlink->dst->priv;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
     int i;
 
-    hqdn3d->hsub  = desc->log2_chroma_w;
-    hqdn3d->vsub  = desc->log2_chroma_h;
-    hqdn3d->depth = desc->comp[0].depth_minus1+1;
+    uninit(inlink->dst);
 
-    hqdn3d->line = av_malloc(inlink->w * sizeof(*hqdn3d->line));
-    if (!hqdn3d->line)
+    s->hsub  = desc->log2_chroma_w;
+    s->vsub  = desc->log2_chroma_h;
+    s->depth = desc->comp[0].depth_minus1+1;
+
+    s->line = av_malloc(inlink->w * sizeof(*s->line));
+    if (!s->line)
         return AVERROR(ENOMEM);
 
     for (i = 0; i < 4; i++) {
-        hqdn3d->coefs[i] = precalc_coefs(hqdn3d->strength[i], hqdn3d->depth);
-        if (!hqdn3d->coefs[i])
+        s->coefs[i] = precalc_coefs(s->strength[i], s->depth);
+        if (!s->coefs[i])
             return AVERROR(ENOMEM);
     }
 
     if (ARCH_X86)
-        ff_hqdn3d_init_x86(hqdn3d);
+        ff_hqdn3d_init_x86(s);
 
     return 0;
 }
 
 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
-    HQDN3DContext *hqdn3d = inlink->dst->priv;
-    AVFilterLink *outlink = inlink->dst->outputs[0];
+    AVFilterContext *ctx  = inlink->dst;
+    HQDN3DContext *s = ctx->priv;
+    AVFilterLink *outlink = ctx->outputs[0];
 
     AVFrame *out;
     int direct, c;
 
-    if (av_frame_is_writable(in)) {
+    if (av_frame_is_writable(in) && !ctx->is_disabled) {
         direct = 1;
         out = in;
     } else {
@@ -294,12 +298,18 @@
     }
 
     for (c = 0; c < 3; c++) {
-        denoise(hqdn3d, in->data[c], out->data[c],
-                hqdn3d->line, &hqdn3d->frame_prev[c],
-                in->width  >> (!!c * hqdn3d->hsub),
-                in->height >> (!!c * hqdn3d->vsub),
+        denoise(s, in->data[c], out->data[c],
+                s->line, &s->frame_prev[c],
+                FF_CEIL_RSHIFT(in->width,  (!!c * s->hsub)),
+                FF_CEIL_RSHIFT(in->height, (!!c * s->vsub)),
                 in->linesize[c], out->linesize[c],
-                hqdn3d->coefs[c?2:0], hqdn3d->coefs[c?3:1]);
+                s->coefs[c ? CHROMA_SPATIAL : LUMA_SPATIAL],
+                s->coefs[c ? CHROMA_TMP     : LUMA_TMP]);
+    }
+
+    if (ctx->is_disabled) {
+        av_frame_free(&out);
+        return ff_filter_frame(outlink, in);
     }
 
     if (!direct)
@@ -310,7 +320,7 @@
 
 #define OFFSET(x) offsetof(HQDN3DContext, x)
 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
-static const AVOption options[] = {
+static const AVOption hqdn3d_options[] = {
     { "luma_spatial",   "spatial luma strength",    OFFSET(strength[LUMA_SPATIAL]),   AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, 0, DBL_MAX, FLAGS },
     { "chroma_spatial", "spatial chroma strength",  OFFSET(strength[CHROMA_SPATIAL]), AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, 0, DBL_MAX, FLAGS },
     { "luma_tmp",       "temporal luma strength",   OFFSET(strength[LUMA_TMP]),       AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, 0, DBL_MAX, FLAGS },
@@ -318,12 +328,7 @@
     { NULL },
 };
 
-static const AVClass hqdn3d_class = {
-    .class_name = "hqdn3d",
-    .item_name  = av_default_item_name,
-    .option     = options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
+AVFILTER_DEFINE_CLASS(hqdn3d);
 
 static const AVFilterPad avfilter_vf_hqdn3d_inputs[] = {
     {
@@ -356,5 +361,5 @@
 
     .inputs    = avfilter_vf_hqdn3d_inputs,
     .outputs   = avfilter_vf_hqdn3d_outputs,
-    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/vf_hue.c b/libavfilter/vf_hue.c
index c62cba8..e5017fb 100644
--- a/libavfilter/vf_hue.c
+++ b/libavfilter/vf_hue.c
@@ -68,11 +68,17 @@
     float    saturation;
     char     *saturation_expr;
     AVExpr   *saturation_pexpr;
+    float    brightness;
+    char     *brightness_expr;
+    AVExpr   *brightness_pexpr;
     int      hsub;
     int      vsub;
     int32_t hue_sin;
     int32_t hue_cos;
     double   var_values[VAR_NB];
+    uint8_t  lut_l[256];
+    uint8_t  lut_u[256][256];
+    uint8_t  lut_v[256][256];
 } HueContext;
 
 #define OFFSET(x) offsetof(HueContext, x)
@@ -84,6 +90,8 @@
       { .str = "1" }, .flags = FLAGS },
     { "H", "set the hue angle radians expression", OFFSET(hue_expr), AV_OPT_TYPE_STRING,
       { .str = NULL }, .flags = FLAGS },
+    { "b", "set the brightness expression", OFFSET(brightness_expr), AV_OPT_TYPE_STRING,
+      { .str = "0" }, .flags = FLAGS },
     { NULL }
 };
 
@@ -94,12 +102,53 @@
     /*
      * Scale the value to the norm of the resulting (U,V) vector, that is
      * the saturation.
-     * This will be useful in the process_chrominance function.
+     * This will be useful in the apply_lut function.
      */
     hue->hue_sin = rint(sin(hue->hue) * (1 << 16) * hue->saturation);
     hue->hue_cos = rint(cos(hue->hue) * (1 << 16) * hue->saturation);
 }
 
+static inline void create_luma_lut(HueContext *h)
+{
+    const float b = h->brightness;
+    int i;
+
+    for (i = 0; i < 256; i++) {
+        h->lut_l[i] = av_clip_uint8(i + b * 25.5);
+    }
+}
+
+static inline void create_chrominance_lut(HueContext *h, const int32_t c,
+                                          const int32_t s)
+{
+    int32_t i, j, u, v, new_u, new_v;
+
+    /*
+     * If we consider U and V as the components of a 2D vector then its angle
+     * is the hue and the norm is the saturation
+     */
+    for (i = 0; i < 256; i++) {
+        for (j = 0; j < 256; j++) {
+            /* Normalize the components from range [16;140] to [-112;112] */
+            u = i - 128;
+            v = j - 128;
+            /*
+             * Apply the rotation of the vector : (c * u) - (s * v)
+             *                                    (s * u) + (c * v)
+             * De-normalize the components (without forgetting to scale 128
+             * by << 16)
+             * Finally scale back the result by >> 16
+             */
+            new_u = ((c * u) - (s * v) + (1 << 15) + (128 << 16)) >> 16;
+            new_v = ((s * u) + (c * v) + (1 << 15) + (128 << 16)) >> 16;
+
+            /* Prevent a potential overflow */
+            h->lut_u[i][j] = av_clip_uint8_c(new_u);
+            h->lut_v[i][j] = av_clip_uint8_c(new_v);
+        }
+    }
+}
+
 static int set_expr(AVExpr **pexpr_ptr, char **expr_ptr,
                     const char *expr, const char *option, void *log_ctx)
 {
@@ -148,14 +197,15 @@
         if (ret < 0)                                                    \
             return ret;                                                 \
     } while (0)
+    SET_EXPR(brightness, "b");
     SET_EXPR(saturation, "s");
     SET_EXPR(hue_deg,    "h");
     SET_EXPR(hue,        "H");
 #undef SET_EXPR
 
     av_log(ctx, AV_LOG_VERBOSE,
-           "H_expr:%s h_deg_expr:%s s_expr:%s\n",
-           hue->hue_expr, hue->hue_deg_expr, hue->saturation_expr);
+           "H_expr:%s h_deg_expr:%s s_expr:%s b_expr:%s\n",
+           hue->hue_expr, hue->hue_deg_expr, hue->saturation_expr, hue->brightness_expr);
     compute_sin_and_cos(hue);
 
     return 0;
@@ -165,6 +215,7 @@
 {
     HueContext *hue = ctx->priv;
 
+    av_expr_free(hue->brightness_pexpr);
     av_expr_free(hue->hue_deg_pexpr);
     av_expr_free(hue->hue_pexpr);
     av_expr_free(hue->saturation_pexpr);
@@ -202,36 +253,36 @@
     return 0;
 }
 
-static void process_chrominance(uint8_t *udst, uint8_t *vdst, const int dst_linesize,
-                                uint8_t *usrc, uint8_t *vsrc, const int src_linesize,
-                                int w, int h,
-                                const int32_t c, const int32_t s)
+static void apply_luma_lut(HueContext *s,
+                           uint8_t *ldst, const int dst_linesize,
+                           uint8_t *lsrc, const int src_linesize,
+                           int w, int h)
 {
-    int32_t u, v, new_u, new_v;
     int i;
 
-    /*
-     * If we consider U and V as the components of a 2D vector then its angle
-     * is the hue and the norm is the saturation
-     */
+    while (h--) {
+        for (i = 0; i < w; i++)
+            ldst[i] = s->lut_l[lsrc[i]];
+
+        lsrc += src_linesize;
+        ldst += dst_linesize;
+    }
+}
+
+static void apply_lut(HueContext *s,
+                      uint8_t *udst, uint8_t *vdst, const int dst_linesize,
+                      uint8_t *usrc, uint8_t *vsrc, const int src_linesize,
+                      int w, int h)
+{
+    int i;
+
     while (h--) {
         for (i = 0; i < w; i++) {
-            /* Normalize the components from range [16;140] to [-112;112] */
-            u = usrc[i] - 128;
-            v = vsrc[i] - 128;
-            /*
-             * Apply the rotation of the vector : (c * u) - (s * v)
-             *                                    (s * u) + (c * v)
-             * De-normalize the components (without forgetting to scale 128
-             * by << 16)
-             * Finally scale back the result by >> 16
-             */
-            new_u = ((c * u) - (s * v) + (1 << 15) + (128 << 16)) >> 16;
-            new_v = ((s * u) + (c * v) + (1 << 15) + (128 << 16)) >> 16;
+            const int u = usrc[i];
+            const int v = vsrc[i];
 
-            /* Prevent a potential overflow */
-            udst[i] = av_clip_uint8_c(new_u);
-            vdst[i] = av_clip_uint8_c(new_v);
+            udst[i] = s->lut_u[u][v];
+            vdst[i] = s->lut_v[u][v];
         }
 
         usrc += src_linesize;
@@ -249,6 +300,8 @@
     HueContext *hue = inlink->dst->priv;
     AVFilterLink *outlink = inlink->dst->outputs[0];
     AVFrame *outpic;
+    const int32_t old_hue_sin = hue->hue_sin, old_hue_cos = hue->hue_cos;
+    const float old_brightness = hue->brightness;
     int direct = 0;
 
     if (av_frame_is_writable(inpic)) {
@@ -278,6 +331,17 @@
         }
     }
 
+    if (hue->brightness_expr) {
+        hue->brightness = av_expr_eval(hue->brightness_pexpr, hue->var_values, NULL);
+
+        if (hue->brightness < -10 || hue->brightness > 10) {
+            hue->brightness = av_clipf(hue->brightness, -10, 10);
+            av_log(inlink->dst, AV_LOG_WARNING,
+                   "Brightness value not in range [%d,%d]: clipping value to %0.1f\n",
+                   -10, 10, hue->brightness);
+        }
+    }
+
     if (hue->hue_deg_expr) {
         hue->hue_deg = av_expr_eval(hue->hue_deg_pexpr, hue->var_values, NULL);
         hue->hue = hue->hue_deg * M_PI / 180;
@@ -287,26 +351,35 @@
     }
 
     av_log(inlink->dst, AV_LOG_DEBUG,
-           "H:%0.1f*PI h:%0.1f s:%0.f t:%0.1f n:%d\n",
-           hue->hue/M_PI, hue->hue_deg, hue->saturation,
+           "H:%0.1f*PI h:%0.1f s:%0.f b:%0.f t:%0.1f n:%d\n",
+           hue->hue/M_PI, hue->hue_deg, hue->saturation, hue->brightness,
            hue->var_values[VAR_T], (int)hue->var_values[VAR_N]);
 
     compute_sin_and_cos(hue);
+    if (old_hue_sin != hue->hue_sin || old_hue_cos != hue->hue_cos)
+        create_chrominance_lut(hue, hue->hue_cos, hue->hue_sin);
+
+    if (old_brightness != hue->brightness && hue->brightness)
+        create_luma_lut(hue);
 
     if (!direct) {
-        av_image_copy_plane(outpic->data[0], outpic->linesize[0],
-                            inpic->data[0],  inpic->linesize[0],
-                            inlink->w, inlink->h);
+        if (!hue->brightness)
+            av_image_copy_plane(outpic->data[0], outpic->linesize[0],
+                                inpic->data[0],  inpic->linesize[0],
+                                inlink->w, inlink->h);
         if (inpic->data[3])
             av_image_copy_plane(outpic->data[3], outpic->linesize[3],
                                 inpic->data[3],  inpic->linesize[3],
                                 inlink->w, inlink->h);
     }
 
-    process_chrominance(outpic->data[1], outpic->data[2], outpic->linesize[1],
-                        inpic->data[1],  inpic->data[2],  inpic->linesize[1],
-                        inlink->w >> hue->hsub, inlink->h >> hue->vsub,
-                        hue->hue_cos, hue->hue_sin);
+    apply_lut(hue, outpic->data[1], outpic->data[2], outpic->linesize[1],
+              inpic->data[1],  inpic->data[2],  inpic->linesize[1],
+              FF_CEIL_RSHIFT(inlink->w, hue->hsub),
+              FF_CEIL_RSHIFT(inlink->h, hue->vsub));
+    if (hue->brightness)
+        apply_luma_lut(hue, outpic->data[0], outpic->linesize[0],
+                       inpic->data[0], inpic->linesize[0], inlink->w, inlink->h);
 
     if (!direct)
         av_frame_free(&inpic);
@@ -335,6 +408,8 @@
         av_freep(&hue->hue_deg_expr);
     } else if (!strcmp(cmd, "s")) {
         SET_EXPR(saturation, "s");
+    } else if (!strcmp(cmd, "b")) {
+        SET_EXPR(brightness, "b");
     } else
         return AVERROR(ENOSYS);
 
@@ -372,5 +447,5 @@
     .inputs          = hue_inputs,
     .outputs         = hue_outputs,
     .priv_class      = &hue_class,
-    .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_idet.c b/libavfilter/vf_idet.c
index cd8bbe3..3b1281e 100644
--- a/libavfilter/vf_idet.c
+++ b/libavfilter/vf_idet.c
@@ -118,8 +118,8 @@
         int refs = idet->cur->linesize[i];
 
         if (i && i<3) {
-            w >>= idet->csp->log2_chroma_w;
-            h >>= idet->csp->log2_chroma_h;
+            w = FF_CEIL_RSHIFT(w, idet->csp->log2_chroma_w);
+            h = FF_CEIL_RSHIFT(h, idet->csp->log2_chroma_h);
         }
 
         for (y = 2; y < h - 2; y++) {
@@ -206,21 +206,6 @@
     return ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->cur));
 }
 
-static int request_frame(AVFilterLink *link)
-{
-    AVFilterContext *ctx = link->src;
-    IDETContext *idet = ctx->priv;
-
-    do {
-        int ret;
-
-        if ((ret = ff_request_frame(link->src->inputs[0])))
-            return ret;
-    } while (!idet->cur);
-
-    return 0;
-}
-
 static av_cold void uninit(AVFilterContext *ctx)
 {
     IDETContext *idet = ctx->priv;
@@ -273,6 +258,12 @@
     return 0;
 }
 
+static int config_output(AVFilterLink *outlink)
+{
+    outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP;
+    return 0;
+}
+
 static av_cold int init(AVFilterContext *ctx)
 {
     IDETContext *idet = ctx->priv;
@@ -299,7 +290,7 @@
     {
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
-        .request_frame = request_frame,
+        .config_props  = config_output,
     },
     { NULL }
 };
diff --git a/libavfilter/vf_il.c b/libavfilter/vf_il.c
index 7edd042..f3a1dc1 100644
--- a/libavfilter/vf_il.c
+++ b/libavfilter/vf_il.c
@@ -88,7 +88,7 @@
 
     for (fmt = 0; fmt < AV_PIX_FMT_NB; fmt++) {
         const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
-        if (!(desc->flags & PIX_FMT_PAL) && !(desc->flags & PIX_FMT_HWACCEL))
+        if (!(desc->flags & AV_PIX_FMT_FLAG_PAL) && !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
             ff_add_format(&formats, fmt);
     }
 
@@ -100,17 +100,15 @@
 {
     IlContext *il = inlink->dst->priv;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
-    int i, ret;
+    int ret;
 
-    for (i = 0; i < desc->nb_components; i++)
-        il->nb_planes = FFMAX(il->nb_planes, desc->comp[i].plane);
-    il->nb_planes++;
+    il->nb_planes = av_pix_fmt_count_planes(inlink->format);
 
-    il->has_alpha = !!(desc->flags & PIX_FMT_ALPHA);
+    il->has_alpha = !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA);
     if ((ret = av_image_fill_linesizes(il->linesize, inlink->format, inlink->w)) < 0)
         return ret;
 
-    il->chroma_height = inlink->h >> desc->log2_chroma_h;
+    il->chroma_height = FF_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
 
     return 0;
 }
@@ -211,4 +209,5 @@
     .inputs        = inputs,
     .outputs       = outputs,
     .priv_class    = &il_class,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_interlace.c b/libavfilter/vf_interlace.c
index 3e787ab..eab5cab 100644
--- a/libavfilter/vf_interlace.c
+++ b/libavfilter/vf_interlace.c
@@ -51,12 +51,11 @@
     enum ScanMode scan;    // top or bottom field first scanning
     int lowpass;           // enable or disable low pass filterning
     AVFrame *cur, *next;   // the two frames from which the new one is obtained
-    int got_output;        // signal an output frame is reday to request_frame()
 } InterlaceContext;
 
 #define OFFSET(x) offsetof(InterlaceContext, x)
 #define V AV_OPT_FLAG_VIDEO_PARAM
-static const AVOption options[] = {
+static const AVOption interlace_options[] = {
     { "scan", "scanning mode", OFFSET(scan),
         AV_OPT_TYPE_INT,   {.i64 = MODE_TFF }, 0, 1, .flags = V, .unit = "scan" },
     { "tff", "top field first", 0,
@@ -68,13 +67,7 @@
     { NULL }
 };
 
-static const AVClass class = {
-    .class_name = "interlace filter",
-    .item_name  = av_default_item_name,
-    .option     = options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
-
+AVFILTER_DEFINE_CLASS(interlace);
 
 static const enum AVPixelFormat formats_supported[] = {
     AV_PIX_FMT_YUV420P,  AV_PIX_FMT_YUV422P,  AV_PIX_FMT_YUV444P,
@@ -115,6 +108,7 @@
     // half framerate
     outlink->time_base.num *= 2;
     outlink->frame_rate.den *= 2;
+    outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP;
 
     av_log(ctx, AV_LOG_VERBOSE, "%s interlacing %s lowpass filter\n",
            s->scan == MODE_TFF ? "tff" : "bff", (s->lowpass) ? "with" : "without");
@@ -131,14 +125,14 @@
     int plane, i, j;
 
     for (plane = 0; plane < desc->nb_components; plane++) {
-        int lines = (plane == 1 || plane == 2) ? inlink->h >> vsub : inlink->h;
+        int lines = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(inlink->h, vsub) : inlink->h;
         int linesize = av_image_get_linesize(inlink->format, inlink->w, plane);
         uint8_t *dstp = dst_frame->data[plane];
         const uint8_t *srcp = src_frame->data[plane];
 
         av_assert0(linesize >= 0);
 
-        lines /= 2;
+        lines = (lines + (field_type == FIELD_UPPER)) / 2;
         if (field_type == FIELD_LOWER)
             srcp += src_frame->linesize[plane];
         if (field_type == FIELD_LOWER)
@@ -155,7 +149,7 @@
                     srcp_below = srcp; // there is no line below
                 for (i = 0; i < linesize; i++) {
                     // this calculation is an integer representation of
-                    // '0.5 * current + 0.25 * above + 0.25 + below'
+                    // '0.5 * current + 0.25 * above + 0.25 * below'
                     // '1 +' is for rounding.
                     dstp[i] = (1 + srcp[i] + srcp[i] + srcp_above[i] + srcp_below[i]) >> 2;
                 }
@@ -205,20 +199,6 @@
     av_frame_free(&s->next);
 
     ret = ff_filter_frame(outlink, out);
-    s->got_output = 1;
-
-    return ret;
-}
-
-static int request_frame(AVFilterLink *outlink)
-{
-    AVFilterContext *ctx = outlink->src;
-    InterlaceContext *s  = ctx->priv;
-    int ret = 0;
-
-    s->got_output = 0;
-    while (ret >= 0 && !s->got_output)
-        ret = ff_request_frame(ctx->inputs[0]);
 
     return ret;
 }
@@ -237,7 +217,6 @@
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_out_props,
-        .request_frame = request_frame,
     },
     { NULL }
 };
@@ -247,7 +226,7 @@
     .description   = NULL_IF_CONFIG_SMALL("Convert progressive video into interlaced."),
     .uninit        = uninit,
 
-    .priv_class    = &class,
+    .priv_class    = &interlace_class,
     .priv_size     = sizeof(InterlaceContext),
     .query_formats = query_formats,
 
diff --git a/libavfilter/vf_kerndeint.c b/libavfilter/vf_kerndeint.c
index 8a44868..5f81525 100644
--- a/libavfilter/vf_kerndeint.c
+++ b/libavfilter/vf_kerndeint.c
@@ -89,7 +89,7 @@
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
     int ret;
 
-    kerndeint->is_packed_rgb = av_pix_fmt_desc_get(inlink->format)->flags & PIX_FMT_RGB;
+    kerndeint->is_packed_rgb = av_pix_fmt_desc_get(inlink->format)->flags & AV_PIX_FMT_FLAG_RGB;
     kerndeint->vsub = desc->log2_chroma_h;
 
     ret = av_image_alloc(kerndeint->tmp_data, kerndeint->tmp_linesize,
@@ -150,8 +150,8 @@
     av_frame_copy_props(outpic, inpic);
     outpic->interlaced_frame = 0;
 
-    for (plane = 0; inpic->data[plane] && plane < 4; plane++) {
-        h = plane == 0 ? inlink->h : inlink->h >> kerndeint->vsub;
+    for (plane = 0; plane < 4 && inpic->data[plane] && inpic->linesize[plane]; plane++) {
+        h = plane == 0 ? inlink->h : FF_CEIL_RSHIFT(inlink->h, kerndeint->vsub);
         bwidth = kerndeint->tmp_bwidth[plane];
 
         srcp = srcp_saved = inpic->data[plane];
diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c
index b731a1f..fe114b3 100644
--- a/libavfilter/vf_libopencv.c
+++ b/libavfilter/vf_libopencv.c
@@ -23,8 +23,6 @@
  * libopencv wrapper functions
  */
 
-/* #define DEBUG */
-
 #include <opencv/cv.h>
 #include <opencv/cxcore.h>
 #include "libavutil/avstring.h"
@@ -88,8 +86,8 @@
 
 static av_cold int smooth_init(AVFilterContext *ctx, const char *args)
 {
-    OCVContext *ocv = ctx->priv;
-    SmoothContext *smooth = ocv->priv;
+    OCVContext *s = ctx->priv;
+    SmoothContext *smooth = s->priv;
     char type_str[128] = "gaussian";
 
     smooth->param1 = 3;
@@ -131,8 +129,8 @@
 
 static void smooth_end_frame_filter(AVFilterContext *ctx, IplImage *inimg, IplImage *outimg)
 {
-    OCVContext *ocv = ctx->priv;
-    SmoothContext *smooth = ocv->priv;
+    OCVContext *s = ctx->priv;
+    SmoothContext *smooth = s->priv;
     cvSmooth(inimg, outimg, smooth->type, smooth->param1, smooth->param2, smooth->param3, smooth->param4);
 }
 
@@ -254,8 +252,8 @@
 
 static av_cold int dilate_init(AVFilterContext *ctx, const char *args)
 {
-    OCVContext *ocv = ctx->priv;
-    DilateContext *dilate = ocv->priv;
+    OCVContext *s = ctx->priv;
+    DilateContext *dilate = s->priv;
     char default_kernel_str[] = "3x3+0x0/rect";
     char *kernel_str;
     const char *buf = args;
@@ -284,23 +282,23 @@
 
 static av_cold void dilate_uninit(AVFilterContext *ctx)
 {
-    OCVContext *ocv = ctx->priv;
-    DilateContext *dilate = ocv->priv;
+    OCVContext *s = ctx->priv;
+    DilateContext *dilate = s->priv;
 
     cvReleaseStructuringElement(&dilate->kernel);
 }
 
 static void dilate_end_frame_filter(AVFilterContext *ctx, IplImage *inimg, IplImage *outimg)
 {
-    OCVContext *ocv = ctx->priv;
-    DilateContext *dilate = ocv->priv;
+    OCVContext *s = ctx->priv;
+    DilateContext *dilate = s->priv;
     cvDilate(inimg, outimg, dilate->kernel, dilate->nb_iterations);
 }
 
 static void erode_end_frame_filter(AVFilterContext *ctx, IplImage *inimg, IplImage *outimg)
 {
-    OCVContext *ocv = ctx->priv;
-    DilateContext *dilate = ocv->priv;
+    OCVContext *s = ctx->priv;
+    DilateContext *dilate = s->priv;
     cvErode(inimg, outimg, dilate->kernel, dilate->nb_iterations);
 }
 
@@ -320,43 +318,43 @@
 
 static av_cold int init(AVFilterContext *ctx)
 {
-    OCVContext *ocv = ctx->priv;
+    OCVContext *s = ctx->priv;
     int i;
 
-    if (!ocv->name) {
+    if (!s->name) {
         av_log(ctx, AV_LOG_ERROR, "No libopencv filter name specified\n");
         return AVERROR(EINVAL);
     }
     for (i = 0; i < FF_ARRAY_ELEMS(ocv_filter_entries); i++) {
         OCVFilterEntry *entry = &ocv_filter_entries[i];
-        if (!strcmp(ocv->name, entry->name)) {
-            ocv->init             = entry->init;
-            ocv->uninit           = entry->uninit;
-            ocv->end_frame_filter = entry->end_frame_filter;
+        if (!strcmp(s->name, entry->name)) {
+            s->init             = entry->init;
+            s->uninit           = entry->uninit;
+            s->end_frame_filter = entry->end_frame_filter;
 
-            if (!(ocv->priv = av_mallocz(entry->priv_size)))
+            if (!(s->priv = av_mallocz(entry->priv_size)))
                 return AVERROR(ENOMEM);
-            return ocv->init(ctx, ocv->params);
+            return s->init(ctx, s->params);
         }
     }
 
-    av_log(ctx, AV_LOG_ERROR, "No libopencv filter named '%s'\n", ocv->name);
+    av_log(ctx, AV_LOG_ERROR, "No libopencv filter named '%s'\n", s->name);
     return AVERROR(EINVAL);
 }
 
 static av_cold void uninit(AVFilterContext *ctx)
 {
-    OCVContext *ocv = ctx->priv;
+    OCVContext *s = ctx->priv;
 
-    if (ocv->uninit)
-        ocv->uninit(ctx);
-    av_free(ocv->priv);
+    if (s->uninit)
+        s->uninit(ctx);
+    av_free(s->priv);
 }
 
 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
     AVFilterContext *ctx = inlink->dst;
-    OCVContext *ocv = ctx->priv;
+    OCVContext *s = ctx->priv;
     AVFilterLink *outlink= inlink->dst->outputs[0];
     AVFrame *out;
     IplImage inimg, outimg;
@@ -370,7 +368,7 @@
 
     fill_iplimage_from_frame(&inimg , in , inlink->format);
     fill_iplimage_from_frame(&outimg, out, inlink->format);
-    ocv->end_frame_filter(ctx, &inimg, &outimg);
+    s->end_frame_filter(ctx, &inimg, &outimg);
     fill_frame_from_iplimage(out, &outimg, inlink->format);
 
     av_frame_free(&in);
@@ -380,18 +378,13 @@
 
 #define OFFSET(x) offsetof(OCVContext, x)
 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
-static const AVOption options[] = {
+static const AVOption ocv_options[] = {
     { "filter_name",   NULL, OFFSET(name),   AV_OPT_TYPE_STRING, .flags = FLAGS },
     { "filter_params", NULL, OFFSET(params), AV_OPT_TYPE_STRING, .flags = FLAGS },
     { NULL },
 };
 
-static const AVClass ocv_class = {
-    .class_name = "ocv",
-    .item_name  = av_default_item_name,
-    .option     = options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
+AVFILTER_DEFINE_CLASS(ocv);
 
 static const AVFilterPad avfilter_vf_ocv_inputs[] = {
     {
diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c
index 4313e77..d2fd4a1 100644
--- a/libavfilter/vf_lut.c
+++ b/libavfilter/vf_lut.c
@@ -24,6 +24,7 @@
  * value, and apply it to input video.
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
 #include "libavutil/eval.h"
 #include "libavutil/opt.h"
@@ -96,20 +97,20 @@
 
 static av_cold void uninit(AVFilterContext *ctx)
 {
-    LutContext *lut = ctx->priv;
+    LutContext *s = ctx->priv;
     int i;
 
     for (i = 0; i < 4; i++) {
-        av_expr_free(lut->comp_expr[i]);
-        lut->comp_expr[i] = NULL;
-        av_freep(&lut->comp_expr_str[i]);
+        av_expr_free(s->comp_expr[i]);
+        s->comp_expr[i] = NULL;
+        av_freep(&s->comp_expr_str[i]);
     }
 }
 
 #define YUV_FORMATS                                         \
     AV_PIX_FMT_YUV444P,  AV_PIX_FMT_YUV422P,  AV_PIX_FMT_YUV420P,    \
     AV_PIX_FMT_YUV411P,  AV_PIX_FMT_YUV410P,  AV_PIX_FMT_YUV440P,    \
-    AV_PIX_FMT_YUVA420P,                                       \
+    AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P,   \
     AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P,   \
     AV_PIX_FMT_YUVJ440P
 
@@ -124,10 +125,10 @@
 
 static int query_formats(AVFilterContext *ctx)
 {
-    LutContext *lut = ctx->priv;
+    LutContext *s = ctx->priv;
 
-    const enum AVPixelFormat *pix_fmts = lut->is_rgb ? rgb_pix_fmts :
-                                       lut->is_yuv ? yuv_pix_fmts : all_pix_fmts;
+    const enum AVPixelFormat *pix_fmts = s->is_rgb ? rgb_pix_fmts :
+                                       s->is_yuv ? yuv_pix_fmts : all_pix_fmts;
 
     ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
     return 0;
@@ -138,9 +139,9 @@
  */
 static double clip(void *opaque, double val)
 {
-    LutContext *lut = opaque;
-    double minval = lut->var_values[VAR_MINVAL];
-    double maxval = lut->var_values[VAR_MAXVAL];
+    LutContext *s = opaque;
+    double minval = s->var_values[VAR_MINVAL];
+    double maxval = s->var_values[VAR_MAXVAL];
 
     return av_clip(val, minval, maxval);
 }
@@ -151,10 +152,10 @@
  */
 static double compute_gammaval(void *opaque, double gamma)
 {
-    LutContext *lut = opaque;
-    double val    = lut->var_values[VAR_CLIPVAL];
-    double minval = lut->var_values[VAR_MINVAL];
-    double maxval = lut->var_values[VAR_MAXVAL];
+    LutContext *s = opaque;
+    double val    = s->var_values[VAR_CLIPVAL];
+    double minval = s->var_values[VAR_MINVAL];
+    double maxval = s->var_values[VAR_MAXVAL];
 
     return pow((val-minval)/(maxval-minval), gamma) * (maxval-minval)+minval;
 }
@@ -174,17 +175,17 @@
 static int config_props(AVFilterLink *inlink)
 {
     AVFilterContext *ctx = inlink->dst;
-    LutContext *lut = ctx->priv;
+    LutContext *s = ctx->priv;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
     uint8_t rgba_map[4]; /* component index -> RGBA color index map */
     int min[4], max[4];
     int val, color, ret;
 
-    lut->hsub = desc->log2_chroma_w;
-    lut->vsub = desc->log2_chroma_h;
+    s->hsub = desc->log2_chroma_w;
+    s->vsub = desc->log2_chroma_h;
 
-    lut->var_values[VAR_W] = inlink->w;
-    lut->var_values[VAR_H] = inlink->h;
+    s->var_values[VAR_W] = inlink->w;
+    s->var_values[VAR_H] = inlink->h;
 
     switch (inlink->format) {
     case AV_PIX_FMT_YUV410P:
@@ -194,6 +195,8 @@
     case AV_PIX_FMT_YUV440P:
     case AV_PIX_FMT_YUV444P:
     case AV_PIX_FMT_YUVA420P:
+    case AV_PIX_FMT_YUVA422P:
+    case AV_PIX_FMT_YUVA444P:
         min[Y] = min[U] = min[V] = 16;
         max[Y] = 235;
         max[U] = max[V] = 240;
@@ -204,49 +207,51 @@
         max[0] = max[1] = max[2] = max[3] = 255;
     }
 
-    lut->is_yuv = lut->is_rgb = 0;
-    if      (ff_fmt_is_in(inlink->format, yuv_pix_fmts)) lut->is_yuv = 1;
-    else if (ff_fmt_is_in(inlink->format, rgb_pix_fmts)) lut->is_rgb = 1;
+    s->is_yuv = s->is_rgb = 0;
+    if      (ff_fmt_is_in(inlink->format, yuv_pix_fmts)) s->is_yuv = 1;
+    else if (ff_fmt_is_in(inlink->format, rgb_pix_fmts)) s->is_rgb = 1;
 
-    if (lut->is_rgb) {
+    if (s->is_rgb) {
         ff_fill_rgba_map(rgba_map, inlink->format);
-        lut->step = av_get_bits_per_pixel(desc) >> 3;
+        s->step = av_get_bits_per_pixel(desc) >> 3;
     }
 
     for (color = 0; color < desc->nb_components; color++) {
         double res;
-        int comp = lut->is_rgb ? rgba_map[color] : color;
+        int comp = s->is_rgb ? rgba_map[color] : color;
 
         /* create the parsed expression */
-        ret = av_expr_parse(&lut->comp_expr[color], lut->comp_expr_str[color],
+        av_expr_free(s->comp_expr[color]);
+        s->comp_expr[color] = NULL;
+        ret = av_expr_parse(&s->comp_expr[color], s->comp_expr_str[color],
                             var_names, funcs1_names, funcs1, NULL, NULL, 0, ctx);
         if (ret < 0) {
             av_log(ctx, AV_LOG_ERROR,
                    "Error when parsing the expression '%s' for the component %d and color %d.\n",
-                   lut->comp_expr_str[comp], comp, color);
+                   s->comp_expr_str[comp], comp, color);
             return AVERROR(EINVAL);
         }
 
         /* compute the lut */
-        lut->var_values[VAR_MAXVAL] = max[color];
-        lut->var_values[VAR_MINVAL] = min[color];
+        s->var_values[VAR_MAXVAL] = max[color];
+        s->var_values[VAR_MINVAL] = min[color];
 
         for (val = 0; val < 256; val++) {
-            lut->var_values[VAR_VAL] = val;
-            lut->var_values[VAR_CLIPVAL] = av_clip(val, min[color], max[color]);
-            lut->var_values[VAR_NEGVAL] =
-                av_clip(min[color] + max[color] - lut->var_values[VAR_VAL],
+            s->var_values[VAR_VAL] = val;
+            s->var_values[VAR_CLIPVAL] = av_clip(val, min[color], max[color]);
+            s->var_values[VAR_NEGVAL] =
+                av_clip(min[color] + max[color] - s->var_values[VAR_VAL],
                         min[color], max[color]);
 
-            res = av_expr_eval(lut->comp_expr[color], lut->var_values, lut);
+            res = av_expr_eval(s->comp_expr[color], s->var_values, s);
             if (isnan(res)) {
                 av_log(ctx, AV_LOG_ERROR,
                        "Error when evaluating the expression '%s' for the value %d for the component %d.\n",
-                       lut->comp_expr_str[color], val, comp);
+                       s->comp_expr_str[color], val, comp);
                 return AVERROR(EINVAL);
             }
-            lut->lut[comp][val] = av_clip((int)res, min[color], max[color]);
-            av_log(ctx, AV_LOG_DEBUG, "val[%d][%d] = %d\n", comp, val, lut->lut[comp][val]);
+            s->lut[comp][val] = av_clip((int)res, min[color], max[color]);
+            av_log(ctx, AV_LOG_DEBUG, "val[%d][%d] = %d\n", comp, val, s->lut[comp][val]);
         }
     }
 
@@ -256,7 +261,7 @@
 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
     AVFilterContext *ctx = inlink->dst;
-    LutContext *lut = ctx->priv;
+    LutContext *s = ctx->priv;
     AVFilterLink *outlink = ctx->outputs[0];
     AVFrame *out;
     uint8_t *inrow, *outrow, *inrow0, *outrow0;
@@ -274,41 +279,42 @@
         av_frame_copy_props(out, in);
     }
 
-    if (lut->is_rgb) {
+    if (s->is_rgb) {
         /* packed */
         inrow0  = in ->data[0];
         outrow0 = out->data[0];
 
         for (i = 0; i < in->height; i ++) {
             int w = inlink->w;
-            const uint8_t (*tab)[256] = (const uint8_t (*)[256])lut->lut;
+            const uint8_t (*tab)[256] = (const uint8_t (*)[256])s->lut;
             inrow  = inrow0;
             outrow = outrow0;
             for (j = 0; j < w; j++) {
-                switch (lut->step) {
+                switch (s->step) {
                 case 4:  outrow[3] = tab[3][inrow[3]]; // Fall-through
                 case 3:  outrow[2] = tab[2][inrow[2]]; // Fall-through
                 case 2:  outrow[1] = tab[1][inrow[1]]; // Fall-through
                 default: outrow[0] = tab[0][inrow[0]];
                 }
-                outrow += lut->step;
-                inrow  += lut->step;
+                outrow += s->step;
+                inrow  += s->step;
             }
             inrow0  += in ->linesize[0];
             outrow0 += out->linesize[0];
         }
     } else {
         /* planar */
-        for (plane = 0; plane < 4 && in->data[plane]; plane++) {
-            int vsub = plane == 1 || plane == 2 ? lut->vsub : 0;
-            int hsub = plane == 1 || plane == 2 ? lut->hsub : 0;
+        for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) {
+            int vsub = plane == 1 || plane == 2 ? s->vsub : 0;
+            int hsub = plane == 1 || plane == 2 ? s->hsub : 0;
+            int h = FF_CEIL_RSHIFT(inlink->h, vsub);
+            int w = FF_CEIL_RSHIFT(inlink->w, hsub);
 
             inrow  = in ->data[plane];
             outrow = out->data[plane];
 
-            for (i = 0; i < (in->height + (1<<vsub) - 1)>>vsub; i ++) {
-                const uint8_t *tab = lut->lut[plane];
-                int w = (inlink->w + (1<<hsub) - 1)>>hsub;
+            for (i = 0; i < h; i++) {
+                const uint8_t *tab = s->lut[plane];
                 for (j = 0; j < w; j++)
                     outrow[j] = tab[inrow[j]];
                 inrow  += in ->linesize[plane];
@@ -350,7 +356,7 @@
                                                                         \
         .inputs        = inputs,                                        \
         .outputs       = outputs,                                       \
-        .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,                \
+        .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,        \
     }
 
 #if CONFIG_LUT_FILTER
@@ -371,11 +377,11 @@
 #define lutyuv_options options
 AVFILTER_DEFINE_CLASS(lutyuv);
 
-static int lutyuv_init(AVFilterContext *ctx)
+static av_cold int lutyuv_init(AVFilterContext *ctx)
 {
-    LutContext *lut = ctx->priv;
+    LutContext *s = ctx->priv;
 
-    lut->is_yuv = 1;
+    s->is_yuv = 1;
 
     return 0;
 }
@@ -388,11 +394,11 @@
 #define lutrgb_options options
 AVFILTER_DEFINE_CLASS(lutrgb);
 
-static int lutrgb_init(AVFilterContext *ctx)
+static av_cold int lutrgb_init(AVFilterContext *ctx)
 {
-    LutContext *lut = ctx->priv;
+    LutContext *s = ctx->priv;
 
-    lut->is_rgb = 1;
+    s->is_rgb = 1;
 
     return 0;
 }
@@ -403,23 +409,23 @@
 #if CONFIG_NEGATE_FILTER
 
 static const AVOption negate_options[] = {
-    { "negate_alpha", NULL, OFFSET(negate_alpha), AV_OPT_TYPE_INT, { .i64 = 0 }, .flags = FLAGS },
+    { "negate_alpha", NULL, OFFSET(negate_alpha), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS },
     { NULL },
 };
 
 AVFILTER_DEFINE_CLASS(negate);
 
-static int negate_init(AVFilterContext *ctx)
+static av_cold int negate_init(AVFilterContext *ctx)
 {
-    LutContext *lut = ctx->priv;
+    LutContext *s = ctx->priv;
     int i;
 
-    av_log(ctx, AV_LOG_DEBUG, "negate_alpha:%d\n", lut->negate_alpha);
+    av_log(ctx, AV_LOG_DEBUG, "negate_alpha:%d\n", s->negate_alpha);
 
     for (i = 0; i < 4; i++) {
-        lut->comp_expr_str[i] = av_strdup((i == 3 && !lut->negate_alpha) ?
+        s->comp_expr_str[i] = av_strdup((i == 3 && !s->negate_alpha) ?
                                           "val" : "negval");
-        if (!lut->comp_expr_str[i]) {
+        if (!s->comp_expr_str[i]) {
             uninit(ctx);
             return AVERROR(ENOMEM);
         }
diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c
new file mode 100644
index 0000000..48002b8
--- /dev/null
+++ b/libavfilter/vf_lut3d.c
@@ -0,0 +1,798 @@
+/*
+ * Copyright (c) 2013 Clément Bœsch
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * 3D Lookup table filter
+ */
+
+#include "libavutil/opt.h"
+#include "libavutil/file.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/avassert.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/avstring.h"
+#include "avfilter.h"
+#include "drawutils.h"
+#include "dualinput.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
+
+#define R 0
+#define G 1
+#define B 2
+#define A 3
+
+enum interp_mode {
+    INTERPOLATE_NEAREST,
+    INTERPOLATE_TRILINEAR,
+    INTERPOLATE_TETRAHEDRAL,
+    NB_INTERP_MODE
+};
+
+struct rgbvec {
+    float r, g, b;
+};
+
+/* 3D LUT don't often go up to level 32, but it is common to have a Hald CLUT
+ * of 512x512 (64x64x64) */
+#define MAX_LEVEL 64
+
+typedef struct LUT3DContext {
+    const AVClass *class;
+    enum interp_mode interpolation;
+    char *file;
+    uint8_t rgba_map[4];
+    int step;
+    int is16bit;
+    struct rgbvec (*interp_8) (const struct LUT3DContext*, uint8_t,  uint8_t,  uint8_t);
+    struct rgbvec (*interp_16)(const struct LUT3DContext*, uint16_t, uint16_t, uint16_t);
+    struct rgbvec lut[MAX_LEVEL][MAX_LEVEL][MAX_LEVEL];
+    int lutsize;
+#if CONFIG_HALDCLUT_FILTER
+    uint8_t clut_rgba_map[4];
+    int clut_step;
+    int clut_is16bit;
+    int clut_width;
+    FFDualInputContext dinput;
+#endif
+} LUT3DContext;
+
+#define OFFSET(x) offsetof(LUT3DContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+#define COMMON_OPTIONS \
+    { "interp", "select interpolation mode", OFFSET(interpolation), AV_OPT_TYPE_INT, {.i64=INTERPOLATE_TETRAHEDRAL}, 0, NB_INTERP_MODE-1, FLAGS, "interp_mode" }, \
+        { "nearest",     "use values from the nearest defined points",            0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_NEAREST},     INT_MIN, INT_MAX, FLAGS, "interp_mode" }, \
+        { "trilinear",   "interpolate values using the 8 points defining a cube", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_TRILINEAR},   INT_MIN, INT_MAX, FLAGS, "interp_mode" }, \
+        { "tetrahedral", "interpolate values using a tetrahedron",                0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_TETRAHEDRAL}, INT_MIN, INT_MAX, FLAGS, "interp_mode" }, \
+    { NULL }
+
+static inline float lerpf(float v0, float v1, float f)
+{
+    return v0 + (v1 - v0) * f;
+}
+
+static inline struct rgbvec lerp(const struct rgbvec *v0, const struct rgbvec *v1, float f)
+{
+    struct rgbvec v = {
+        lerpf(v0->r, v1->r, f), lerpf(v0->g, v1->g, f), lerpf(v0->b, v1->b, f)
+    };
+    return v;
+}
+
+#define NEAR(x) ((int)((x) + .5))
+#define PREV(x) ((int)(x))
+#define NEXT(x) (FFMIN((int)(x) + 1, lut3d->lutsize - 1))
+
+/**
+ * Get the nearest defined point
+ */
+static inline struct rgbvec interp_nearest(const LUT3DContext *lut3d,
+                                           const struct rgbvec *s)
+{
+    return lut3d->lut[NEAR(s->r)][NEAR(s->g)][NEAR(s->b)];
+}
+
+/**
+ * Interpolate using the 8 vertices of a cube
+ * @see https://en.wikipedia.org/wiki/Trilinear_interpolation
+ */
+static inline struct rgbvec interp_trilinear(const LUT3DContext *lut3d,
+                                             const struct rgbvec *s)
+{
+    const int prev[] = {PREV(s->r), PREV(s->g), PREV(s->b)};
+    const int next[] = {NEXT(s->r), NEXT(s->g), NEXT(s->b)};
+    const struct rgbvec d = {s->r - prev[0], s->g - prev[1], s->b - prev[2]};
+    const struct rgbvec c000 = lut3d->lut[prev[0]][prev[1]][prev[2]];
+    const struct rgbvec c001 = lut3d->lut[prev[0]][prev[1]][next[2]];
+    const struct rgbvec c010 = lut3d->lut[prev[0]][next[1]][prev[2]];
+    const struct rgbvec c011 = lut3d->lut[prev[0]][next[1]][next[2]];
+    const struct rgbvec c100 = lut3d->lut[next[0]][prev[1]][prev[2]];
+    const struct rgbvec c101 = lut3d->lut[next[0]][prev[1]][next[2]];
+    const struct rgbvec c110 = lut3d->lut[next[0]][next[1]][prev[2]];
+    const struct rgbvec c111 = lut3d->lut[next[0]][next[1]][next[2]];
+    const struct rgbvec c00  = lerp(&c000, &c100, d.r);
+    const struct rgbvec c10  = lerp(&c010, &c110, d.r);
+    const struct rgbvec c01  = lerp(&c001, &c101, d.r);
+    const struct rgbvec c11  = lerp(&c011, &c111, d.r);
+    const struct rgbvec c0   = lerp(&c00,  &c10,  d.g);
+    const struct rgbvec c1   = lerp(&c01,  &c11,  d.g);
+    const struct rgbvec c    = lerp(&c0,   &c1,   d.b);
+    return c;
+}
+
+/**
+ * Tetrahedral interpolation. Based on code found in Truelight Software Library paper.
+ * @see http://www.filmlight.ltd.uk/pdf/whitepapers/FL-TL-TN-0057-SoftwareLib.pdf
+ */
+static inline struct rgbvec interp_tetrahedral(const LUT3DContext *lut3d,
+                                               const struct rgbvec *s)
+{
+    const int prev[] = {PREV(s->r), PREV(s->g), PREV(s->b)};
+    const int next[] = {NEXT(s->r), NEXT(s->g), NEXT(s->b)};
+    const struct rgbvec d = {s->r - prev[0], s->g - prev[1], s->b - prev[2]};
+    const struct rgbvec c000 = lut3d->lut[prev[0]][prev[1]][prev[2]];
+    const struct rgbvec c111 = lut3d->lut[next[0]][next[1]][next[2]];
+    struct rgbvec c;
+    if (d.r > d.g) {
+        if (d.g > d.b) {
+            const struct rgbvec c100 = lut3d->lut[next[0]][prev[1]][prev[2]];
+            const struct rgbvec c110 = lut3d->lut[next[0]][next[1]][prev[2]];
+            c.r = (1-d.r) * c000.r + (d.r-d.g) * c100.r + (d.g-d.b) * c110.r + (d.b) * c111.r;
+            c.g = (1-d.r) * c000.g + (d.r-d.g) * c100.g + (d.g-d.b) * c110.g + (d.b) * c111.g;
+            c.b = (1-d.r) * c000.b + (d.r-d.g) * c100.b + (d.g-d.b) * c110.b + (d.b) * c111.b;
+        } else if (d.r > d.b) {
+            const struct rgbvec c100 = lut3d->lut[next[0]][prev[1]][prev[2]];
+            const struct rgbvec c101 = lut3d->lut[next[0]][prev[1]][next[2]];
+            c.r = (1-d.r) * c000.r + (d.r-d.b) * c100.r + (d.b-d.g) * c101.r + (d.g) * c111.r;
+            c.g = (1-d.r) * c000.g + (d.r-d.b) * c100.g + (d.b-d.g) * c101.g + (d.g) * c111.g;
+            c.b = (1-d.r) * c000.b + (d.r-d.b) * c100.b + (d.b-d.g) * c101.b + (d.g) * c111.b;
+        } else {
+            const struct rgbvec c001 = lut3d->lut[prev[0]][prev[1]][next[2]];
+            const struct rgbvec c101 = lut3d->lut[next[0]][prev[1]][next[2]];
+            c.r = (1-d.b) * c000.r + (d.b-d.r) * c001.r + (d.r-d.g) * c101.r + (d.g) * c111.r;
+            c.g = (1-d.b) * c000.g + (d.b-d.r) * c001.g + (d.r-d.g) * c101.g + (d.g) * c111.g;
+            c.b = (1-d.b) * c000.b + (d.b-d.r) * c001.b + (d.r-d.g) * c101.b + (d.g) * c111.b;
+        }
+    } else {
+        if (d.b > d.g) {
+            const struct rgbvec c001 = lut3d->lut[prev[0]][prev[1]][next[2]];
+            const struct rgbvec c011 = lut3d->lut[prev[0]][next[1]][next[2]];
+            c.r = (1-d.b) * c000.r + (d.b-d.g) * c001.r + (d.g-d.r) * c011.r + (d.r) * c111.r;
+            c.g = (1-d.b) * c000.g + (d.b-d.g) * c001.g + (d.g-d.r) * c011.g + (d.r) * c111.g;
+            c.b = (1-d.b) * c000.b + (d.b-d.g) * c001.b + (d.g-d.r) * c011.b + (d.r) * c111.b;
+        } else if (d.b > d.r) {
+            const struct rgbvec c010 = lut3d->lut[prev[0]][next[1]][prev[2]];
+            const struct rgbvec c011 = lut3d->lut[prev[0]][next[1]][next[2]];
+            c.r = (1-d.g) * c000.r + (d.g-d.b) * c010.r + (d.b-d.r) * c011.r + (d.r) * c111.r;
+            c.g = (1-d.g) * c000.g + (d.g-d.b) * c010.g + (d.b-d.r) * c011.g + (d.r) * c111.g;
+            c.b = (1-d.g) * c000.b + (d.g-d.b) * c010.b + (d.b-d.r) * c011.b + (d.r) * c111.b;
+        } else {
+            const struct rgbvec c010 = lut3d->lut[prev[0]][next[1]][prev[2]];
+            const struct rgbvec c110 = lut3d->lut[next[0]][next[1]][prev[2]];
+            c.r = (1-d.g) * c000.r + (d.g-d.r) * c010.r + (d.r-d.b) * c110.r + (d.b) * c111.r;
+            c.g = (1-d.g) * c000.g + (d.g-d.r) * c010.g + (d.r-d.b) * c110.g + (d.b) * c111.g;
+            c.b = (1-d.g) * c000.b + (d.g-d.r) * c010.b + (d.r-d.b) * c110.b + (d.b) * c111.b;
+        }
+    }
+    return c;
+}
+
+#define DEFINE_INTERP_FUNC(name, nbits)                                     \
+static struct rgbvec interp_##nbits##_##name(const LUT3DContext *lut3d,     \
+                                             uint##nbits##_t r,             \
+                                             uint##nbits##_t g,             \
+                                             uint##nbits##_t b)             \
+{                                                                           \
+    const float scale = (1. / ((1<<nbits) - 1)) * (lut3d->lutsize - 1);     \
+    const struct rgbvec scaled_rgb = {r * scale, g * scale, b * scale};     \
+    return interp_##name(lut3d, &scaled_rgb);                               \
+}
+
+DEFINE_INTERP_FUNC(nearest,     8)
+DEFINE_INTERP_FUNC(trilinear,   8)
+DEFINE_INTERP_FUNC(tetrahedral, 8)
+
+DEFINE_INTERP_FUNC(nearest,     16)
+DEFINE_INTERP_FUNC(trilinear,   16)
+DEFINE_INTERP_FUNC(tetrahedral, 16)
+
+#define MAX_LINE_SIZE 512
+
+static int skip_line(const char *p)
+{
+    while (*p && av_isspace(*p))
+        p++;
+    return !*p || *p == '#';
+}
+
+#define NEXT_LINE(loop_cond) do {                           \
+    if (!fgets(line, sizeof(line), f)) {                    \
+        av_log(ctx, AV_LOG_ERROR, "Unexpected EOF\n");      \
+        return AVERROR_INVALIDDATA;                         \
+    }                                                       \
+} while (loop_cond)
+
+/* Basically r g and b float values on each line; seems to be generated by
+ * Davinci */
+static int parse_dat(AVFilterContext *ctx, FILE *f)
+{
+    LUT3DContext *lut3d = ctx->priv;
+    const int size = lut3d->lutsize;
+    int i, j, k;
+
+    for (k = 0; k < size; k++) {
+        for (j = 0; j < size; j++) {
+            for (i = 0; i < size; i++) {
+                char line[MAX_LINE_SIZE];
+                struct rgbvec *vec = &lut3d->lut[k][j][i];
+                NEXT_LINE(skip_line(line));
+                sscanf(line, "%f %f %f", &vec->r, &vec->g, &vec->b);
+            }
+        }
+    }
+    return 0;
+}
+
+/* Iridas format */
+static int parse_cube(AVFilterContext *ctx, FILE *f)
+{
+    LUT3DContext *lut3d = ctx->priv;
+    char line[MAX_LINE_SIZE];
+    float min[3] = {0.0, 0.0, 0.0};
+    float max[3] = {1.0, 1.0, 1.0};
+
+    while (fgets(line, sizeof(line), f)) {
+        if (!strncmp(line, "LUT_3D_SIZE ", 12)) {
+            int i, j, k;
+            const int size = strtol(line + 12, NULL, 0);
+
+            if (size < 2 || size > MAX_LEVEL) {
+                av_log(ctx, AV_LOG_ERROR, "Too large or invalid 3D LUT size\n");
+                return AVERROR(EINVAL);
+            }
+            lut3d->lutsize = size;
+            for (k = 0; k < size; k++) {
+                for (j = 0; j < size; j++) {
+                    for (i = 0; i < size; i++) {
+                        struct rgbvec *vec = &lut3d->lut[k][j][i];
+
+                        do {
+                            NEXT_LINE(0);
+                            if (!strncmp(line, "DOMAIN_", 7)) {
+                                float *vals = NULL;
+                                if      (!strncmp(line + 7, "MIN ", 4)) vals = min;
+                                else if (!strncmp(line + 7, "MAX ", 4)) vals = max;
+                                if (!vals)
+                                    return AVERROR_INVALIDDATA;
+                                sscanf(line + 11, "%f %f %f", vals, vals + 1, vals + 2);
+                                av_log(ctx, AV_LOG_DEBUG, "min: %f %f %f | max: %f %f %f\n",
+                                       min[0], min[1], min[2], max[0], max[1], max[2]);
+                                continue;
+                            }
+                        } while (skip_line(line));
+                        if (sscanf(line, "%f %f %f", &vec->r, &vec->g, &vec->b) != 3)
+                            return AVERROR_INVALIDDATA;
+                        vec->r *= max[0] - min[0];
+                        vec->g *= max[1] - min[1];
+                        vec->b *= max[2] - min[2];
+                    }
+                }
+            }
+            break;
+        }
+    }
+    return 0;
+}
+
+/* Assume 17x17x17 LUT with a 16-bit depth
+ * FIXME: it seems there are various 3dl formats */
+static int parse_3dl(AVFilterContext *ctx, FILE *f)
+{
+    char line[MAX_LINE_SIZE];
+    LUT3DContext *lut3d = ctx->priv;
+    int i, j, k;
+    const int size = 17;
+    const float scale = 16*16*16;
+
+    lut3d->lutsize = size;
+    NEXT_LINE(skip_line(line));
+    for (k = 0; k < size; k++) {
+        for (j = 0; j < size; j++) {
+            for (i = 0; i < size; i++) {
+                int r, g, b;
+                struct rgbvec *vec = &lut3d->lut[k][j][i];
+
+                NEXT_LINE(skip_line(line));
+                if (sscanf(line, "%d %d %d", &r, &g, &b) != 3)
+                    return AVERROR_INVALIDDATA;
+                vec->r = r / scale;
+                vec->g = g / scale;
+                vec->b = b / scale;
+            }
+        }
+    }
+    return 0;
+}
+
+/* Pandora format */
+static int parse_m3d(AVFilterContext *ctx, FILE *f)
+{
+    LUT3DContext *lut3d = ctx->priv;
+    float scale;
+    int i, j, k, size, in = -1, out = -1;
+    char line[MAX_LINE_SIZE];
+    uint8_t rgb_map[3] = {0, 1, 2};
+
+    while (fgets(line, sizeof(line), f)) {
+        if      (!strncmp(line, "in",  2)) in  = strtol(line + 2, NULL, 0);
+        else if (!strncmp(line, "out", 3)) out = strtol(line + 3, NULL, 0);
+        else if (!strncmp(line, "values", 6)) {
+            const char *p = line + 6;
+#define SET_COLOR(id) do {                  \
+    while (av_isspace(*p))                  \
+        p++;                                \
+    switch (*p) {                           \
+    case 'r': rgb_map[id] = 0; break;       \
+    case 'g': rgb_map[id] = 1; break;       \
+    case 'b': rgb_map[id] = 2; break;       \
+    }                                       \
+    while (*p && !av_isspace(*p))           \
+        p++;                                \
+} while (0)
+            SET_COLOR(0);
+            SET_COLOR(1);
+            SET_COLOR(2);
+            break;
+        }
+    }
+
+    if (in == -1 || out == -1) {
+        av_log(ctx, AV_LOG_ERROR, "in and out must be defined\n");
+        return AVERROR_INVALIDDATA;
+    }
+    if (in < 2 || out < 2 ||
+        in  > MAX_LEVEL*MAX_LEVEL*MAX_LEVEL ||
+        out > MAX_LEVEL*MAX_LEVEL*MAX_LEVEL) {
+        av_log(ctx, AV_LOG_ERROR, "invalid in (%d) or out (%d)\n", in, out);
+        return AVERROR_INVALIDDATA;
+    }
+    for (size = 1; size*size*size < in; size++);
+    lut3d->lutsize = size;
+    scale = 1. / (out - 1);
+
+    for (k = 0; k < size; k++) {
+        for (j = 0; j < size; j++) {
+            for (i = 0; i < size; i++) {
+                struct rgbvec *vec = &lut3d->lut[k][j][i];
+                float val[3];
+
+                NEXT_LINE(0);
+                if (sscanf(line, "%f %f %f", val, val + 1, val + 2) != 3)
+                    return AVERROR_INVALIDDATA;
+                vec->r = val[rgb_map[0]] * scale;
+                vec->g = val[rgb_map[1]] * scale;
+                vec->b = val[rgb_map[2]] * scale;
+            }
+        }
+    }
+    return 0;
+}
+
+static void set_identity_matrix(LUT3DContext *lut3d, int size)
+{
+    int i, j, k;
+    const float c = 1. / (size - 1);
+
+    lut3d->lutsize = size;
+    for (k = 0; k < size; k++) {
+        for (j = 0; j < size; j++) {
+            for (i = 0; i < size; i++) {
+                struct rgbvec *vec = &lut3d->lut[k][j][i];
+                vec->r = k * c;
+                vec->g = j * c;
+                vec->b = i * c;
+            }
+        }
+    }
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat pix_fmts[] = {
+        AV_PIX_FMT_RGB24,  AV_PIX_FMT_BGR24,
+        AV_PIX_FMT_RGBA,   AV_PIX_FMT_BGRA,
+        AV_PIX_FMT_ARGB,   AV_PIX_FMT_ABGR,
+        AV_PIX_FMT_0RGB,   AV_PIX_FMT_0BGR,
+        AV_PIX_FMT_RGB0,   AV_PIX_FMT_BGR0,
+        AV_PIX_FMT_RGB48,  AV_PIX_FMT_BGR48,
+        AV_PIX_FMT_RGBA64, AV_PIX_FMT_BGRA64,
+        AV_PIX_FMT_NONE
+    };
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+    LUT3DContext *lut3d = inlink->dst->priv;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+
+    switch (inlink->format) {
+    case AV_PIX_FMT_RGB48:
+    case AV_PIX_FMT_BGR48:
+    case AV_PIX_FMT_RGBA64:
+    case AV_PIX_FMT_BGRA64:
+        lut3d->is16bit = 1;
+    }
+
+    ff_fill_rgba_map(lut3d->rgba_map, inlink->format);
+    lut3d->step = av_get_padded_bits_per_pixel(desc) >> (3 + lut3d->is16bit);
+
+#define SET_FUNC(name) do {                                     \
+    if (lut3d->is16bit) lut3d->interp_16 = interp_16_##name;    \
+    else                lut3d->interp_8  = interp_8_##name;     \
+} while (0)
+
+    switch (lut3d->interpolation) {
+    case INTERPOLATE_NEAREST:     SET_FUNC(nearest);        break;
+    case INTERPOLATE_TRILINEAR:   SET_FUNC(trilinear);      break;
+    case INTERPOLATE_TETRAHEDRAL: SET_FUNC(tetrahedral);    break;
+    default:
+        av_assert0(0);
+    }
+
+    return 0;
+}
+
+#define FILTER(nbits) do {                                                                          \
+    uint8_t       *dstrow = out->data[0];                                                           \
+    const uint8_t *srcrow = in ->data[0];                                                           \
+                                                                                                    \
+    for (y = 0; y < inlink->h; y++) {                                                               \
+        uint##nbits##_t *dst = (uint##nbits##_t *)dstrow;                                           \
+        const uint##nbits##_t *src = (const uint##nbits##_t *)srcrow;                               \
+        for (x = 0; x < inlink->w * step; x += step) {                                              \
+            struct rgbvec vec = lut3d->interp_##nbits(lut3d, src[x + r], src[x + g], src[x + b]);   \
+            dst[x + r] = av_clip_uint##nbits(vec.r * (float)((1<<nbits) - 1));                      \
+            dst[x + g] = av_clip_uint##nbits(vec.g * (float)((1<<nbits) - 1));                      \
+            dst[x + b] = av_clip_uint##nbits(vec.b * (float)((1<<nbits) - 1));                      \
+            if (!direct && step == 4)                                                               \
+                dst[x + a] = src[x + a];                                                            \
+        }                                                                                           \
+        dstrow += out->linesize[0];                                                                 \
+        srcrow += in ->linesize[0];                                                                 \
+    }                                                                                               \
+} while (0)
+
+static AVFrame *apply_lut(AVFilterLink *inlink, AVFrame *in)
+{
+    int x, y, direct = 0;
+    AVFilterContext *ctx = inlink->dst;
+    LUT3DContext *lut3d = ctx->priv;
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+    AVFrame *out;
+    const int step = lut3d->step;
+    const uint8_t r = lut3d->rgba_map[R];
+    const uint8_t g = lut3d->rgba_map[G];
+    const uint8_t b = lut3d->rgba_map[B];
+    const uint8_t a = lut3d->rgba_map[A];
+
+    if (av_frame_is_writable(in)) {
+        direct = 1;
+        out = in;
+    } else {
+        out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+        if (!out) {
+            av_frame_free(&in);
+            return NULL;
+        }
+        av_frame_copy_props(out, in);
+    }
+
+    if (lut3d->is16bit) FILTER(16);
+    else                FILTER(8);
+
+    if (!direct)
+        av_frame_free(&in);
+
+    return out;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+{
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+    AVFrame *out = apply_lut(inlink, in);
+    if (!out)
+        return AVERROR(ENOMEM);
+    return ff_filter_frame(outlink, out);
+}
+
+#if CONFIG_LUT3D_FILTER
+static const AVOption lut3d_options[] = {
+    { "file", "set 3D LUT file name", OFFSET(file), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
+    COMMON_OPTIONS
+};
+
+AVFILTER_DEFINE_CLASS(lut3d);
+
+static av_cold int lut3d_init(AVFilterContext *ctx)
+{
+    int ret;
+    FILE *f;
+    const char *ext;
+    LUT3DContext *lut3d = ctx->priv;
+
+    if (!lut3d->file) {
+        set_identity_matrix(lut3d, 32);
+        return 0;
+    }
+
+    f = fopen(lut3d->file, "r");
+    if (!f) {
+        ret = AVERROR(errno);
+        av_log(ctx, AV_LOG_ERROR, "%s: %s\n", lut3d->file, av_err2str(ret));
+        return ret;
+    }
+
+    ext = strrchr(lut3d->file, '.');
+    if (!ext) {
+        av_log(ctx, AV_LOG_ERROR, "Unable to guess the format from the extension\n");
+        ret = AVERROR_INVALIDDATA;
+        goto end;
+    }
+    ext++;
+
+    if (!av_strcasecmp(ext, "dat")) {
+        lut3d->lutsize = 33;
+        ret = parse_dat(ctx, f);
+    } else if (!av_strcasecmp(ext, "3dl")) {
+        ret = parse_3dl(ctx, f);
+    } else if (!av_strcasecmp(ext, "cube")) {
+        ret = parse_cube(ctx, f);
+    } else if (!av_strcasecmp(ext, "m3d")) {
+        ret = parse_m3d(ctx, f);
+    } else {
+        av_log(ctx, AV_LOG_ERROR, "Unrecognized '.%s' file type\n", ext);
+        ret = AVERROR(EINVAL);
+    }
+
+    if (!ret && !lut3d->lutsize) {
+        av_log(ctx, AV_LOG_ERROR, "3D LUT is empty\n");
+        ret = AVERROR_INVALIDDATA;
+    }
+
+end:
+    fclose(f);
+    return ret;
+}
+
+static const AVFilterPad lut3d_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = filter_frame,
+        .config_props = config_input,
+    },
+    { NULL }
+};
+
+static const AVFilterPad lut3d_outputs[] = {
+     {
+         .name = "default",
+         .type = AVMEDIA_TYPE_VIDEO,
+     },
+     { NULL }
+};
+
+AVFilter avfilter_vf_lut3d = {
+    .name          = "lut3d",
+    .description   = NULL_IF_CONFIG_SMALL("Adjust colors using a 3D LUT."),
+    .priv_size     = sizeof(LUT3DContext),
+    .init          = lut3d_init,
+    .query_formats = query_formats,
+    .inputs        = lut3d_inputs,
+    .outputs       = lut3d_outputs,
+    .priv_class    = &lut3d_class,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
+};
+#endif
+
+#if CONFIG_HALDCLUT_FILTER
+
+static void update_clut(LUT3DContext *lut3d, const AVFrame *frame)
+{
+    const uint8_t *data = frame->data[0];
+    const int linesize  = frame->linesize[0];
+    const int w = lut3d->clut_width;
+    const int step = lut3d->clut_step;
+    const uint8_t *rgba_map = lut3d->clut_rgba_map;
+    const int level = lut3d->lutsize;
+
+#define LOAD_CLUT(nbits) do {                                           \
+    int i, j, k, x = 0, y = 0;                                          \
+                                                                        \
+    for (k = 0; k < level; k++) {                                       \
+        for (j = 0; j < level; j++) {                                   \
+            for (i = 0; i < level; i++) {                               \
+                const uint##nbits##_t *src = (const uint##nbits##_t *)  \
+                    (data + y*linesize + x*step);                       \
+                struct rgbvec *vec = &lut3d->lut[k][j][i];              \
+                vec->r = src[rgba_map[0]] / (float)((1<<(nbits)) - 1);  \
+                vec->g = src[rgba_map[1]] / (float)((1<<(nbits)) - 1);  \
+                vec->b = src[rgba_map[2]] / (float)((1<<(nbits)) - 1);  \
+                if (++x == w) {                                         \
+                    x = 0;                                              \
+                    y++;                                                \
+                }                                                       \
+            }                                                           \
+        }                                                               \
+    }                                                                   \
+} while (0)
+
+    if (!lut3d->clut_is16bit) LOAD_CLUT(8);
+    else                      LOAD_CLUT(16);
+}
+
+
+static int config_output(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+
+    outlink->w = ctx->inputs[0]->w;
+    outlink->h = ctx->inputs[0]->h;
+    outlink->time_base = ctx->inputs[0]->time_base;
+    return 0;
+}
+
+static int filter_frame_main(AVFilterLink *inlink, AVFrame *inpicref)
+{
+    LUT3DContext *s = inlink->dst->priv;
+    return ff_dualinput_filter_frame_main(&s->dinput, inlink, inpicref);
+}
+
+static int filter_frame_clut(AVFilterLink *inlink, AVFrame *inpicref)
+{
+    LUT3DContext *s = inlink->dst->priv;
+    return ff_dualinput_filter_frame_second(&s->dinput, inlink, inpicref);
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    LUT3DContext *s = outlink->src->priv;
+    return ff_dualinput_request_frame(&s->dinput, outlink);
+}
+
+static int config_clut(AVFilterLink *inlink)
+{
+    int size, level, w, h;
+    AVFilterContext *ctx = inlink->dst;
+    LUT3DContext *lut3d = ctx->priv;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+
+    lut3d->clut_is16bit = 0;
+    switch (inlink->format) {
+    case AV_PIX_FMT_RGB48:
+    case AV_PIX_FMT_BGR48:
+    case AV_PIX_FMT_RGBA64:
+    case AV_PIX_FMT_BGRA64:
+        lut3d->clut_is16bit = 1;
+    }
+
+    lut3d->clut_step = av_get_padded_bits_per_pixel(desc) >> 3;
+    ff_fill_rgba_map(lut3d->clut_rgba_map, inlink->format);
+
+    if (inlink->w > inlink->h)
+        av_log(ctx, AV_LOG_INFO, "Padding on the right (%dpx) of the "
+               "Hald CLUT will be ignored\n", inlink->w - inlink->h);
+    else if (inlink->w < inlink->h)
+        av_log(ctx, AV_LOG_INFO, "Padding at the bottom (%dpx) of the "
+               "Hald CLUT will be ignored\n", inlink->h - inlink->w);
+    lut3d->clut_width = w = h = FFMIN(inlink->w, inlink->h);
+
+    for (level = 1; level*level*level < w; level++);
+    size = level*level*level;
+    if (size != w) {
+        av_log(ctx, AV_LOG_WARNING, "The Hald CLUT width does not match the level\n");
+        return AVERROR_INVALIDDATA;
+    }
+    av_assert0(w == h && w == size);
+    level *= level;
+    if (level > MAX_LEVEL) {
+        const int max_clut_level = sqrt(MAX_LEVEL);
+        const int max_clut_size  = max_clut_level*max_clut_level*max_clut_level;
+        av_log(ctx, AV_LOG_ERROR, "Too large Hald CLUT "
+               "(maximum level is %d, or %dx%d CLUT)\n",
+               max_clut_level, max_clut_size, max_clut_size);
+        return AVERROR(EINVAL);
+    }
+    lut3d->lutsize = level;
+
+    return 0;
+}
+
+static AVFrame *update_apply_clut(AVFilterContext *ctx, AVFrame *main,
+                                  const AVFrame *second)
+{
+    AVFilterLink *inlink = ctx->inputs[0];
+    update_clut(ctx->priv, second);
+    return apply_lut(inlink, main);
+}
+
+static av_cold int haldclut_init(AVFilterContext *ctx)
+{
+    LUT3DContext *lut3d = ctx->priv;
+    lut3d->dinput.process = update_apply_clut;
+    return 0;
+}
+
+static av_cold void haldclut_uninit(AVFilterContext *ctx)
+{
+    LUT3DContext *lut3d = ctx->priv;
+    ff_dualinput_uninit(&lut3d->dinput);
+}
+
+static const AVOption haldclut_options[] = {
+    { "shortest",   "force termination when the shortest input terminates", OFFSET(dinput.shortest),   AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS },
+    { "repeatlast", "continue applying the last clut after eos",            OFFSET(dinput.repeatlast), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, FLAGS },
+    COMMON_OPTIONS
+};
+
+AVFILTER_DEFINE_CLASS(haldclut);
+
+static const AVFilterPad haldclut_inputs[] = {
+    {
+        .name         = "main",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = filter_frame_main,
+        .config_props = config_input,
+    },{
+        .name         = "clut",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = filter_frame_clut,
+        .config_props = config_clut,
+    },
+    { NULL }
+};
+
+static const AVFilterPad haldclut_outputs[] = {
+    {
+        .name = "default",
+        .type = AVMEDIA_TYPE_VIDEO,
+        .request_frame = request_frame,
+        .config_props = config_output,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_haldclut = {
+    .name          = "haldclut",
+    .description   = NULL_IF_CONFIG_SMALL("Adjust colors using a Hald CLUT."),
+    .priv_size     = sizeof(LUT3DContext),
+    .init          = haldclut_init,
+    .uninit        = haldclut_uninit,
+    .query_formats = query_formats,
+    .inputs        = haldclut_inputs,
+    .outputs       = haldclut_outputs,
+    .priv_class    = &haldclut_class,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
+};
+#endif
diff --git a/libavfilter/vf_mcdeint.c b/libavfilter/vf_mcdeint.c
new file mode 100644
index 0000000..4bd11a0
--- /dev/null
+++ b/libavfilter/vf_mcdeint.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * FFmpeg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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.
+ */
+
+/**
+ * @file
+ * Motion Compensation Deinterlacer
+ * Ported from MPlayer libmpcodecs/vf_mcdeint.c.
+ *
+ * Known Issues:
+ *
+ * The motion estimation is somewhat at the mercy of the input, if the
+ * input frames are created purely based on spatial interpolation then
+ * for example a thin black line or another random and not
+ * interpolateable pattern will cause problems.
+ * Note: completely ignoring the "unavailable" lines during motion
+ * estimation did not look any better, so the most obvious solution
+ * would be to improve tfields or penalize problematic motion vectors.
+ *
+ * If non iterative ME is used then snow currently ignores the OBMC
+ * window and as a result sometimes creates artifacts.
+ *
+ * Only past frames are used, we should ideally use future frames too,
+ * something like filtering the whole movie in forward and then
+ * backward direction seems like a interesting idea but the current
+ * filter framework is FAR from supporting such things.
+ *
+ * Combining the motion compensated image with the input image also is
+ * not as trivial as it seems, simple blindly taking even lines from
+ * one and odd ones from the other does not work at all as ME/MC
+ * sometimes has nothing in the previous frames which matches the
+ * current. The current algorithm has been found by trial and error
+ * and almost certainly can be improved...
+ */
+
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "libavcodec/avcodec.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+
+enum MCDeintMode {
+    MODE_FAST = 0,
+    MODE_MEDIUM,
+    MODE_SLOW,
+    MODE_EXTRA_SLOW,
+    MODE_NB,
+};
+
+enum MCDeintParity {
+    PARITY_TFF  =  0, ///< top field first
+    PARITY_BFF  =  1, ///< bottom field first
+};
+
+typedef struct {
+    const AVClass *class;
+    enum MCDeintMode mode;
+    enum MCDeintParity parity;
+    int qp;
+    AVCodecContext *enc_ctx;
+} MCDeintContext;
+
+#define OFFSET(x) offsetof(MCDeintContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+#define CONST(name, help, val, unit) { name, help, 0, AV_OPT_TYPE_CONST, {.i64=val}, INT_MIN, INT_MAX, FLAGS, unit }
+
+static const AVOption mcdeint_options[] = {
+    { "mode", "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_FAST}, 0, MODE_NB-1, FLAGS, .unit="mode" },
+    CONST("fast",       NULL, MODE_FAST,       "mode"),
+    CONST("medium",     NULL, MODE_MEDIUM,     "mode"),
+    CONST("slow",       NULL, MODE_SLOW,       "mode"),
+    CONST("extra_slow", NULL, MODE_EXTRA_SLOW, "mode"),
+
+    { "parity", "set the assumed picture field parity", OFFSET(parity), AV_OPT_TYPE_INT, {.i64=PARITY_BFF}, -1, 1, FLAGS, "parity" },
+    CONST("tff", "assume top field first",    PARITY_TFF, "parity"),
+    CONST("bff", "assume bottom field first", PARITY_BFF, "parity"),
+
+    { "qp", "set qp", OFFSET(qp), AV_OPT_TYPE_INT, {.i64=1}, INT_MIN, INT_MAX, FLAGS },
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(mcdeint);
+
+static int config_props(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->dst;
+    MCDeintContext *mcdeint = ctx->priv;
+    AVCodec *enc;
+    AVCodecContext *enc_ctx;
+    AVDictionary *opts = NULL;
+    int ret;
+
+    if (!(enc = avcodec_find_encoder(AV_CODEC_ID_SNOW))) {
+        av_log(ctx, AV_LOG_ERROR, "Snow encoder is not enabled in libavcodec\n");
+        return AVERROR(EINVAL);
+    }
+
+    mcdeint->enc_ctx = avcodec_alloc_context3(enc);
+    if (!mcdeint->enc_ctx)
+        return AVERROR(ENOMEM);
+    enc_ctx = mcdeint->enc_ctx;
+    enc_ctx->width  = inlink->w;
+    enc_ctx->height = inlink->h;
+    enc_ctx->time_base = (AVRational){1,25};  // meaningless
+    enc_ctx->gop_size = 300;
+    enc_ctx->max_b_frames = 0;
+    enc_ctx->pix_fmt = AV_PIX_FMT_YUV420P;
+    enc_ctx->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
+    enc_ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
+    enc_ctx->global_quality = 1;
+    enc_ctx->me_cmp = enc_ctx->me_sub_cmp = FF_CMP_SAD;
+    enc_ctx->mb_cmp = FF_CMP_SSE;
+    av_dict_set(&opts, "memc_only", "1", 0);
+
+    switch (mcdeint->mode) {
+    case MODE_EXTRA_SLOW:
+        enc_ctx->refs = 3;
+    case MODE_SLOW:
+        enc_ctx->me_method = ME_ITER;
+    case MODE_MEDIUM:
+        enc_ctx->flags |= CODEC_FLAG_4MV;
+        enc_ctx->dia_size = 2;
+    case MODE_FAST:
+        enc_ctx->flags |= CODEC_FLAG_QPEL;
+    }
+
+    ret = avcodec_open2(enc_ctx, enc, &opts);
+    av_dict_free(&opts);
+    if (ret < 0)
+        return ret;
+
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    MCDeintContext *mcdeint = ctx->priv;
+
+    if (mcdeint->enc_ctx) {
+        avcodec_close(mcdeint->enc_ctx);
+        av_freep(&mcdeint->enc_ctx);
+    }
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum PixelFormat pix_fmts[] = {
+        AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE
+    };
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+
+    return 0;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *inpic)
+{
+    MCDeintContext *mcdeint = inlink->dst->priv;
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+    AVFrame *outpic, *frame_dec;
+    AVPacket pkt;
+    int x, y, i, ret, got_frame = 0;
+
+    outpic = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+    if (!outpic) {
+        av_frame_free(&inpic);
+        return AVERROR(ENOMEM);
+    }
+    av_frame_copy_props(outpic, inpic);
+    inpic->quality = mcdeint->qp * FF_QP2LAMBDA;
+
+    av_init_packet(&pkt);
+    pkt.data = NULL;    // packet data will be allocated by the encoder
+    pkt.size = 0;
+
+    ret = avcodec_encode_video2(mcdeint->enc_ctx, &pkt, inpic, &got_frame);
+    if (ret < 0)
+        goto end;
+
+    frame_dec = mcdeint->enc_ctx->coded_frame;
+
+    for (i = 0; i < 3; i++) {
+        int is_chroma = !!i;
+        int w = FF_CEIL_RSHIFT(inlink->w, is_chroma);
+        int h = FF_CEIL_RSHIFT(inlink->h, is_chroma);
+        int fils = frame_dec->linesize[i];
+        int srcs = inpic    ->linesize[i];
+        int dsts = outpic   ->linesize[i];
+
+        for (y = 0; y < h; y++) {
+            if ((y ^ mcdeint->parity) & 1) {
+                for (x = 0; x < w; x++) {
+                    uint8_t *filp = &frame_dec->data[i][x + y*fils];
+                    uint8_t *srcp = &inpic    ->data[i][x + y*srcs];
+                    uint8_t *dstp = &outpic   ->data[i][x + y*dsts];
+
+                    if (y > 0 && y < h-1){
+                        int is_edge = x < 3 || x > w-4;
+                        int diff0 = filp[-fils] - srcp[-srcs];
+                        int diff1 = filp[+fils] - srcp[+srcs];
+                        int temp = filp[0];
+
+#define DELTA(j) av_clip(j, -x, w-1-x)
+
+#define GET_SCORE_EDGE(j)\
+   FFABS(srcp[-srcs+DELTA(-1+(j))] - srcp[+srcs+DELTA(-1-(j))])+\
+   FFABS(srcp[-srcs+DELTA(j)     ] - srcp[+srcs+DELTA(  -(j))])+\
+   FFABS(srcp[-srcs+DELTA(1+(j)) ] - srcp[+srcs+DELTA( 1-(j))])
+
+#define GET_SCORE(j)\
+   FFABS(srcp[-srcs-1+(j)] - srcp[+srcs-1-(j)])+\
+   FFABS(srcp[-srcs  +(j)] - srcp[+srcs  -(j)])+\
+   FFABS(srcp[-srcs+1+(j)] - srcp[+srcs+1-(j)])
+
+#define CHECK_EDGE(j)\
+    {   int score = GET_SCORE_EDGE(j);\
+        if (score < spatial_score){\
+            spatial_score = score;\
+            diff0 = filp[-fils+DELTA(j)]    - srcp[-srcs+DELTA(j)];\
+            diff1 = filp[+fils+DELTA(-(j))] - srcp[+srcs+DELTA(-(j))];\
+
+#define CHECK(j)\
+    {   int score = GET_SCORE(j);\
+        if (score < spatial_score){\
+            spatial_score= score;\
+            diff0 = filp[-fils+(j)] - srcp[-srcs+(j)];\
+            diff1 = filp[+fils-(j)] - srcp[+srcs-(j)];\
+
+                        if (is_edge) {
+                            int spatial_score = GET_SCORE_EDGE(0) - 1;
+                            CHECK_EDGE(-1) CHECK_EDGE(-2) }} }}
+                            CHECK_EDGE( 1) CHECK_EDGE( 2) }} }}
+                        } else {
+                            int spatial_score = GET_SCORE(0) - 1;
+                            CHECK(-1) CHECK(-2) }} }}
+                            CHECK( 1) CHECK( 2) }} }}
+                        }
+
+
+                        if (diff0 + diff1 > 0)
+                            temp -= (diff0 + diff1 - FFABS(FFABS(diff0) - FFABS(diff1)) / 2) / 2;
+                        else
+                            temp -= (diff0 + diff1 + FFABS(FFABS(diff0) - FFABS(diff1)) / 2) / 2;
+                        *filp = *dstp = temp > 255U ? ~(temp>>31) : temp;
+                    } else {
+                        *dstp = *filp;
+                    }
+                }
+            }
+        }
+
+        for (y = 0; y < h; y++) {
+            if (!((y ^ mcdeint->parity) & 1)) {
+                for (x = 0; x < w; x++) {
+                    frame_dec->data[i][x + y*fils] =
+                    outpic   ->data[i][x + y*dsts] = inpic->data[i][x + y*srcs];
+                }
+            }
+        }
+    }
+    mcdeint->parity ^= 1;
+
+end:
+    av_free_packet(&pkt);
+    av_frame_free(&inpic);
+    if (ret < 0) {
+        av_frame_free(&outpic);
+        return ret;
+    }
+    return ff_filter_frame(outlink, outpic);
+}
+
+static const AVFilterPad mcdeint_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = filter_frame,
+        .config_props = config_props,
+    },
+    { NULL }
+};
+
+static const AVFilterPad mcdeint_outputs[] = {
+    {
+        .name = "default",
+        .type = AVMEDIA_TYPE_VIDEO,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_mcdeint = {
+    .name          = "mcdeint",
+    .description   = NULL_IF_CONFIG_SMALL("Apply motion compensating deinterlacing."),
+    .priv_size     = sizeof(MCDeintContext),
+    .uninit        = uninit,
+    .query_formats = query_formats,
+    .inputs        = mcdeint_inputs,
+    .outputs       = mcdeint_outputs,
+    .priv_class    = &mcdeint_class,
+};
diff --git a/libavfilter/vf_mp.c b/libavfilter/vf_mp.c
index ccab7c8..112a102 100644
--- a/libavfilter/vf_mp.c
+++ b/libavfilter/vf_mp.c
@@ -129,17 +129,11 @@
 extern const vf_info_t ff_vf_info_fil;
 extern const vf_info_t ff_vf_info_fspp;
 extern const vf_info_t ff_vf_info_ilpack;
-extern const vf_info_t ff_vf_info_mcdeint;
-extern const vf_info_t ff_vf_info_ow;
-extern const vf_info_t ff_vf_info_perspective;
 extern const vf_info_t ff_vf_info_phase;
 extern const vf_info_t ff_vf_info_pp7;
 extern const vf_info_t ff_vf_info_pullup;
 extern const vf_info_t ff_vf_info_qp;
-extern const vf_info_t ff_vf_info_sab;
 extern const vf_info_t ff_vf_info_softpulldown;
-extern const vf_info_t ff_vf_info_spp;
-extern const vf_info_t ff_vf_info_tinterlace;
 extern const vf_info_t ff_vf_info_uspp;
 
 
@@ -150,17 +144,11 @@
     &ff_vf_info_fil,
     &ff_vf_info_fspp,
     &ff_vf_info_ilpack,
-    &ff_vf_info_mcdeint,
-    &ff_vf_info_ow,
-    &ff_vf_info_perspective,
     &ff_vf_info_phase,
     &ff_vf_info_pp7,
     &ff_vf_info_pullup,
     &ff_vf_info_qp,
-    &ff_vf_info_sab,
     &ff_vf_info_softpulldown,
-    &ff_vf_info_spp,
-    &ff_vf_info_tinterlace,
     &ff_vf_info_uspp,
 
     NULL
@@ -197,61 +185,6 @@
     return mp == conversion_map[i].fmt ? conversion_map[i].pix_fmt : AV_PIX_FMT_NONE;
 }
 
-static void ff_sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, SwsFilter **dstFilterParam)
-{
-        static int firstTime=1;
-        *flags=0;
-
-#if ARCH_X86
-        if(ff_gCpuCaps.hasMMX)
-                __asm__ volatile("emms\n\t"::: "memory"); //FIXME this should not be required but it IS (even for non-MMX versions)
-#endif
-        if(firstTime)
-        {
-                firstTime=0;
-                *flags= SWS_PRINT_INFO;
-        }
-        else if( ff_mp_msg_test(MSGT_VFILTER,MSGL_DBG2) ) *flags= SWS_PRINT_INFO;
-
-        switch(SWS_BILINEAR)
-        {
-                case 0: *flags|= SWS_FAST_BILINEAR; break;
-                case 1: *flags|= SWS_BILINEAR; break;
-                case 2: *flags|= SWS_BICUBIC; break;
-                case 3: *flags|= SWS_X; break;
-                case 4: *flags|= SWS_POINT; break;
-                case 5: *flags|= SWS_AREA; break;
-                case 6: *flags|= SWS_BICUBLIN; break;
-                case 7: *flags|= SWS_GAUSS; break;
-                case 8: *flags|= SWS_SINC; break;
-                case 9: *flags|= SWS_LANCZOS; break;
-                case 10:*flags|= SWS_SPLINE; break;
-                default:*flags|= SWS_BILINEAR; break;
-        }
-
-        *srcFilterParam= NULL;
-        *dstFilterParam= NULL;
-}
-
-//exact copy from vf_scale.c
-// will use sws_flags & src_filter (from cmd line)
-struct SwsContext *ff_sws_getContextFromCmdLine(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat)
-{
-        int flags, i;
-        SwsFilter *dstFilterParam, *srcFilterParam;
-        enum AVPixelFormat dfmt, sfmt;
-
-        for(i=0; conversion_map[i].fmt && dstFormat != conversion_map[i].fmt; i++);
-        dfmt= conversion_map[i].pix_fmt;
-        for(i=0; conversion_map[i].fmt && srcFormat != conversion_map[i].fmt; i++);
-        sfmt= conversion_map[i].pix_fmt;
-
-        if (srcFormat == IMGFMT_RGB8 || srcFormat == IMGFMT_BGR8) sfmt = AV_PIX_FMT_PAL8;
-        ff_sws_getFlagsAndFilterFromCmdLine(&flags, &srcFilterParam, &dstFilterParam);
-
-        return sws_getContext(srcW, srcH, sfmt, dstW, dstH, dfmt, flags , srcFilterParam, dstFilterParam, NULL);
-}
-
 typedef struct {
     const AVClass *class;
     vf_instance_t vf;
@@ -259,6 +192,7 @@
     AVFilterContext *avfctx;
     int frame_returned;
     char *filter;
+    enum AVPixelFormat in_pix_fmt;
 } MPContext;
 
 #define OFFSET(x) offsetof(MPContext, x)
@@ -532,8 +466,6 @@
   return mpi;
 }
 
-static void dummy_free(void *opaque, uint8_t *data){}
-
 int ff_vf_next_put_image(struct vf_instance *vf,mp_image_t *mpi, double pts){
     MPContext *m= (MPContext*)(((uint8_t*)vf) - offsetof(MPContext, vf));
     AVFilterLink *outlink     = m->avfctx->outputs[0];
@@ -555,6 +487,10 @@
     for(i=0; conversion_map[i].fmt && mpi->imgfmt != conversion_map[i].fmt; i++);
     picref->format = conversion_map[i].pix_fmt;
 
+    for(i=0; conversion_map[i].fmt && m->in_pix_fmt != conversion_map[i].pix_fmt; i++);
+    if (mpi->imgfmt == conversion_map[i].fmt)
+        picref->format = conversion_map[i].pix_fmt;
+
     memcpy(picref->linesize, mpi->stride, FFMIN(sizeof(picref->linesize), sizeof(mpi->stride)));
 
     for(i=0; i<4 && mpi->stride[i]; i++){
@@ -808,11 +744,17 @@
 
     for(i=0; conversion_map[i].fmt && conversion_map[i].pix_fmt != inlink->format; i++);
     ff_mp_image_setfmt(mpi,conversion_map[i].fmt);
+    m->in_pix_fmt = inlink->format;
 
     memcpy(mpi->planes, inpic->data,     FFMIN(sizeof(inpic->data)    , sizeof(mpi->planes)));
     memcpy(mpi->stride, inpic->linesize, FFMIN(sizeof(inpic->linesize), sizeof(mpi->stride)));
 
-    //FIXME pass interleced & tff flags around
+    if (inpic->interlaced_frame)
+        mpi->fields |= MP_IMGFIELD_INTERLACED;
+    if (inpic->top_field_first)
+        mpi->fields |= MP_IMGFIELD_TOP_FIRST;
+    if (inpic->repeat_pict)
+        mpi->fields |= MP_IMGFIELD_REPEAT_FIRST;
 
     // mpi->flags|=MP_IMGFLAG_ALLOCATED; ?
     mpi->flags |= MP_IMGFLAG_READABLE;
diff --git a/libavfilter/vf_mpdecimate.c b/libavfilter/vf_mpdecimate.c
index 2e386f7..45d510b 100644
--- a/libavfilter/vf_mpdecimate.c
+++ b/libavfilter/vf_mpdecimate.c
@@ -122,7 +122,8 @@
         int hsub = plane == 1 || plane == 2 ? decimate->hsub : 0;
         if (diff_planes(ctx,
                         cur->data[plane], ref->data[plane], ref->linesize[plane],
-                        ref->width>>hsub, ref->height>>vsub))
+                        FF_CEIL_RSHIFT(ref->width,  hsub),
+                        FF_CEIL_RSHIFT(ref->height, vsub)))
             return 0;
     }
 
diff --git a/libavfilter/vf_noise.c b/libavfilter/vf_noise.c
index 996311a..9fd2a67 100644
--- a/libavfilter/vf_noise.c
+++ b/libavfilter/vf_noise.c
@@ -35,7 +35,7 @@
 #include "internal.h"
 #include "video.h"
 
-#define MAX_NOISE 4096
+#define MAX_NOISE 5120
 #define MAX_SHIFT 1024
 #define MAX_RES (MAX_NOISE-MAX_SHIFT)
 
@@ -47,7 +47,6 @@
 typedef struct {
     int strength;
     unsigned flags;
-    int shiftptr;
     AVLFG lfg;
     int seed;
     int8_t *noise;
@@ -67,6 +66,10 @@
     void (*line_noise_avg)(uint8_t *dst, const uint8_t *src, int len, int8_t **shift);
 } NoiseContext;
 
+typedef struct ThreadData {
+    AVFrame *in, *out;
+} ThreadData;
+
 #define OFFSET(x) offsetof(NoiseContext, x)
 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
 
@@ -161,7 +164,6 @@
     }
 
     fp->noise = noise;
-    fp->shiftptr = 0;
     return 0;
 }
 
@@ -172,7 +174,7 @@
 
     for (fmt = 0; fmt < AV_PIX_FMT_NB; fmt++) {
         const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
-        if (desc->flags & PIX_FMT_PLANAR && !((desc->comp[0].depth_minus1 + 1) & 7))
+        if (desc->flags & AV_PIX_FMT_FLAG_PLANAR && !((desc->comp[0].depth_minus1 + 1) & 7))
             ff_add_format(&formats, fmt);
     }
 
@@ -184,16 +186,14 @@
 {
     NoiseContext *n = inlink->dst->priv;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
-    int i, ret;
+    int ret;
 
-    for (i = 0; i < desc->nb_components; i++)
-        n->nb_planes = FFMAX(n->nb_planes, desc->comp[i].plane);
-    n->nb_planes++;
+    n->nb_planes = av_pix_fmt_count_planes(inlink->format);
 
     if ((ret = av_image_fill_linesizes(n->linesize, inlink->format, inlink->w)) < 0)
         return ret;
 
-    n->height[1] = n->height[2] = inlink->h >> desc->log2_chroma_h;
+    n->height[1] = n->height[2] = FF_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
     n->height[0] = n->height[3] = inlink->h;
 
     return 0;
@@ -332,52 +332,63 @@
 
 static void noise(uint8_t *dst, const uint8_t *src,
                   int dst_linesize, int src_linesize,
-                  int width, int height, NoiseContext *n, int comp)
+                  int width, int start, int end, NoiseContext *n, int comp)
 {
-    int8_t *noise = n->param[comp].noise;
-    int flags = n->param[comp].flags;
-    AVLFG *lfg = &n->param[comp].lfg;
+    FilterParams *p = &n->param[comp];
+    int8_t *noise = p->noise;
+    const int flags = p->flags;
+    AVLFG *lfg = &p->lfg;
     int shift, y;
 
     if (!noise) {
-        if (dst != src) {
-            for (y = 0; y < height; y++) {
-                memcpy(dst, src, width);
-                dst += dst_linesize;
-                src += src_linesize;
-            }
-        }
-
+        if (dst != src)
+            av_image_copy_plane(dst, dst_linesize, src, src_linesize, width, end - start);
         return;
     }
 
-    for (y = 0; y < height; y++) {
+    for (y = start; y < end; y++) {
+        const int ix = y & (MAX_RES - 1);
         if (flags & NOISE_TEMPORAL)
             shift = av_lfg_get(lfg) & (MAX_SHIFT - 1);
         else
-            shift = n->rand_shift[y];
+            shift = n->rand_shift[ix];
 
         if (flags & NOISE_AVERAGED) {
-            n->line_noise_avg(dst, src, width, n->param[comp].prev_shift[y]);
-            n->param[comp].prev_shift[y][n->param[comp].shiftptr] = noise + shift;
+            n->line_noise_avg(dst, src, width, p->prev_shift[ix]);
+            p->prev_shift[ix][shift & 3] = noise + shift;
         } else {
             n->line_noise(dst, src, noise, width, shift);
         }
         dst += dst_linesize;
         src += src_linesize;
     }
+}
 
-    n->param[comp].shiftptr++;
-    if (n->param[comp].shiftptr == 3)
-        n->param[comp].shiftptr = 0;
+static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+    NoiseContext *s = ctx->priv;
+    ThreadData *td = arg;
+    int plane;
+
+    for (plane = 0; plane < s->nb_planes; plane++) {
+        const int height = s->height[plane];
+        const int start  = (height *  jobnr   ) / nb_jobs;
+        const int end    = (height * (jobnr+1)) / nb_jobs;
+        noise(td->out->data[plane] + start * td->out->linesize[plane],
+              td->in->data[plane]  + start * td->in->linesize[plane],
+              td->out->linesize[plane], td->in->linesize[plane],
+              s->linesize[plane], start, end, s, plane);
+    }
+    return 0;
 }
 
 static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
 {
-    NoiseContext *n = inlink->dst->priv;
-    AVFilterLink *outlink = inlink->dst->outputs[0];
+    AVFilterContext *ctx = inlink->dst;
+    AVFilterLink *outlink = ctx->outputs[0];
+    NoiseContext *n = ctx->priv;
+    ThreadData td;
     AVFrame *out;
-    int i;
 
     if (av_frame_is_writable(inpicref)) {
         out = inpicref;
@@ -390,9 +401,9 @@
         av_frame_copy_props(out, inpicref);
     }
 
-    for (i = 0; i < n->nb_planes; i++)
-        noise(out->data[i], inpicref->data[i], out->linesize[i],
-              inpicref->linesize[i], n->linesize[i], n->height[i], n, i);
+    td.in = inpicref; td.out = out;
+    ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(n->height[0], ctx->graph->nb_threads));
+    emms_c();
 
     if (inpicref != out)
         av_frame_free(&inpicref);
@@ -446,7 +457,6 @@
     {
         .name             = "default",
         .type             = AVMEDIA_TYPE_VIDEO,
-        .get_video_buffer = ff_null_get_video_buffer,
         .filter_frame     = filter_frame,
         .config_props     = config_input,
     },
@@ -471,5 +481,5 @@
     .inputs        = noise_inputs,
     .outputs       = noise_outputs,
     .priv_class    = &noise_class,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_null.c b/libavfilter/vf_null.c
index eafa268..0bafbf8 100644
--- a/libavfilter/vf_null.c
+++ b/libavfilter/vf_null.c
@@ -30,7 +30,6 @@
     {
         .name             = "default",
         .type             = AVMEDIA_TYPE_VIDEO,
-        .get_video_buffer = ff_null_get_video_buffer,
     },
     { NULL }
 };
@@ -46,10 +45,6 @@
 AVFilter avfilter_vf_null = {
     .name      = "null",
     .description = NULL_IF_CONFIG_SMALL("Pass the source unchanged to the output."),
-
-    .priv_size = 0,
-
     .inputs    = avfilter_vf_null_inputs,
-
     .outputs   = avfilter_vf_null_outputs,
 };
diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c
index dbb87f8..7d93c9e 100644
--- a/libavfilter/vf_overlay.c
+++ b/libavfilter/vf_overlay.c
@@ -25,8 +25,6 @@
  * overlay one video on top of another
  */
 
-/* #define DEBUG */
-
 #include "avfilter.h"
 #include "formats.h"
 #include "libavutil/common.h"
@@ -37,9 +35,8 @@
 #include "libavutil/imgutils.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
-#include "libavutil/timestamp.h"
 #include "internal.h"
-#include "bufferqueue.h"
+#include "dualinput.h"
 #include "drawutils.h"
 #include "video.h"
 
@@ -88,11 +85,8 @@
 typedef struct {
     const AVClass *class;
     int x, y;                   ///< position of overlayed picture
-    int enable;                 ///< tells if blending is enabled
 
     int allow_packed_rgb;
-    uint8_t frame_requested;
-    uint8_t overlay_eof;
     uint8_t main_is_packed_rgb;
     uint8_t main_rgba_map[4];
     uint8_t main_has_alpha;
@@ -102,42 +96,24 @@
     enum OverlayFormat { OVERLAY_FORMAT_YUV420, OVERLAY_FORMAT_YUV444, OVERLAY_FORMAT_RGB, OVERLAY_FORMAT_NB} format;
     enum EvalMode { EVAL_MODE_INIT, EVAL_MODE_FRAME, EVAL_MODE_NB } eval_mode;
 
-    AVFrame *overpicref;
-    struct FFBufQueue queue_main;
-    struct FFBufQueue queue_over;
+    FFDualInputContext dinput;
 
     int main_pix_step[4];       ///< steps per pixel for each plane of the main output
     int overlay_pix_step[4];    ///< steps per pixel for each plane of the overlay
     int hsub, vsub;             ///< chroma subsampling values
-    int shortest;               ///< terminate stream when the shortest input terminates
-    int repeatlast;             ///< repeat last overlay frame
 
     double var_values[VAR_VARS_NB];
     char *x_expr, *y_expr;
     AVExpr *x_pexpr, *y_pexpr;
 } OverlayContext;
 
-static av_cold int init(AVFilterContext *ctx)
-{
-    OverlayContext *over = ctx->priv;
-
-    if (over->allow_packed_rgb) {
-        av_log(ctx, AV_LOG_WARNING,
-               "The rgb option is deprecated and is overriding the format option, use format instead\n");
-        over->format = OVERLAY_FORMAT_RGB;
-    }
-    return 0;
-}
-
 static av_cold void uninit(AVFilterContext *ctx)
 {
-    OverlayContext *over = ctx->priv;
+    OverlayContext *s = ctx->priv;
 
-    av_frame_free(&over->overpicref);
-    ff_bufqueue_discard_all(&over->queue_main);
-    ff_bufqueue_discard_all(&over->queue_over);
-    av_expr_free(over->x_pexpr); over->x_pexpr = NULL;
-    av_expr_free(over->y_pexpr); over->y_pexpr = NULL;
+    ff_dualinput_uninit(&s->dinput);
+    av_expr_free(s->x_pexpr); s->x_pexpr = NULL;
+    av_expr_free(s->y_pexpr); s->y_pexpr = NULL;
 }
 
 static inline int normalize_xy(double d, int chroma_sub)
@@ -149,14 +125,13 @@
 
 static void eval_expr(AVFilterContext *ctx)
 {
-    OverlayContext  *over = ctx->priv;
+    OverlayContext *s = ctx->priv;
 
-    /* TODO: reindent */
-        over->var_values[VAR_X] = av_expr_eval(over->x_pexpr, over->var_values, NULL);
-        over->var_values[VAR_Y] = av_expr_eval(over->y_pexpr, over->var_values, NULL);
-        over->var_values[VAR_X] = av_expr_eval(over->x_pexpr, over->var_values, NULL);
-        over->x = normalize_xy(over->var_values[VAR_X], over->hsub);
-        over->y = normalize_xy(over->var_values[VAR_Y], over->vsub);
+    s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL);
+    s->var_values[VAR_Y] = av_expr_eval(s->y_pexpr, s->var_values, NULL);
+    s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL);
+    s->x = normalize_xy(s->var_values[VAR_X], s->hsub);
+    s->y = normalize_xy(s->var_values[VAR_Y], s->vsub);
 }
 
 static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void *log_ctx)
@@ -183,31 +158,31 @@
 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
                            char *res, int res_len, int flags)
 {
-    OverlayContext *over = ctx->priv;
+    OverlayContext *s = ctx->priv;
     int ret;
 
     if      (!strcmp(cmd, "x"))
-        ret = set_expr(&over->x_pexpr, args, cmd, ctx);
+        ret = set_expr(&s->x_pexpr, args, cmd, ctx);
     else if (!strcmp(cmd, "y"))
-        ret = set_expr(&over->y_pexpr, args, cmd, ctx);
+        ret = set_expr(&s->y_pexpr, args, cmd, ctx);
     else
         ret = AVERROR(ENOSYS);
 
     if (ret < 0)
         return ret;
 
-    if (over->eval_mode == EVAL_MODE_INIT) {
+    if (s->eval_mode == EVAL_MODE_INIT) {
         eval_expr(ctx);
         av_log(ctx, AV_LOG_VERBOSE, "x:%f xi:%d y:%f yi:%d\n",
-               over->var_values[VAR_X], over->x,
-               over->var_values[VAR_Y], over->y);
+               s->var_values[VAR_X], s->x,
+               s->var_values[VAR_Y], s->y);
     }
     return ret;
 }
 
 static int query_formats(AVFilterContext *ctx)
 {
-    OverlayContext *over = ctx->priv;
+    OverlayContext *s = ctx->priv;
 
     /* overlay formats contains alpha, for avoiding conversion with alpha information loss */
     static const enum AVPixelFormat main_pix_fmts_yuv420[] = {
@@ -239,7 +214,7 @@
     AVFilterFormats *main_formats;
     AVFilterFormats *overlay_formats;
 
-    switch (over->format) {
+    switch (s->format) {
     case OVERLAY_FORMAT_YUV420:
         main_formats    = ff_make_format_list(main_pix_fmts_yuv420);
         overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv420);
@@ -271,56 +246,56 @@
 
 static int config_input_main(AVFilterLink *inlink)
 {
-    OverlayContext *over = inlink->dst->priv;
+    OverlayContext *s = inlink->dst->priv;
     const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
 
-    av_image_fill_max_pixsteps(over->main_pix_step,    NULL, pix_desc);
+    av_image_fill_max_pixsteps(s->main_pix_step,    NULL, pix_desc);
 
-    over->hsub = pix_desc->log2_chroma_w;
-    over->vsub = pix_desc->log2_chroma_h;
+    s->hsub = pix_desc->log2_chroma_w;
+    s->vsub = pix_desc->log2_chroma_h;
 
-    over->main_is_packed_rgb =
-        ff_fill_rgba_map(over->main_rgba_map, inlink->format) >= 0;
-    over->main_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);
+    s->main_is_packed_rgb =
+        ff_fill_rgba_map(s->main_rgba_map, inlink->format) >= 0;
+    s->main_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);
     return 0;
 }
 
 static int config_input_overlay(AVFilterLink *inlink)
 {
     AVFilterContext *ctx  = inlink->dst;
-    OverlayContext  *over = inlink->dst->priv;
+    OverlayContext  *s = inlink->dst->priv;
     int ret;
     const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
 
-    av_image_fill_max_pixsteps(over->overlay_pix_step, NULL, pix_desc);
+    av_image_fill_max_pixsteps(s->overlay_pix_step, NULL, pix_desc);
 
     /* Finish the configuration by evaluating the expressions
        now when both inputs are configured. */
-    over->var_values[VAR_MAIN_W   ] = over->var_values[VAR_MW] = ctx->inputs[MAIN   ]->w;
-    over->var_values[VAR_MAIN_H   ] = over->var_values[VAR_MH] = ctx->inputs[MAIN   ]->h;
-    over->var_values[VAR_OVERLAY_W] = over->var_values[VAR_OW] = ctx->inputs[OVERLAY]->w;
-    over->var_values[VAR_OVERLAY_H] = over->var_values[VAR_OH] = ctx->inputs[OVERLAY]->h;
-    over->var_values[VAR_HSUB]  = 1<<pix_desc->log2_chroma_w;
-    over->var_values[VAR_VSUB]  = 1<<pix_desc->log2_chroma_h;
-    over->var_values[VAR_X]     = NAN;
-    over->var_values[VAR_Y]     = NAN;
-    over->var_values[VAR_N]     = 0;
-    over->var_values[VAR_T]     = NAN;
-    over->var_values[VAR_POS]   = NAN;
+    s->var_values[VAR_MAIN_W   ] = s->var_values[VAR_MW] = ctx->inputs[MAIN   ]->w;
+    s->var_values[VAR_MAIN_H   ] = s->var_values[VAR_MH] = ctx->inputs[MAIN   ]->h;
+    s->var_values[VAR_OVERLAY_W] = s->var_values[VAR_OW] = ctx->inputs[OVERLAY]->w;
+    s->var_values[VAR_OVERLAY_H] = s->var_values[VAR_OH] = ctx->inputs[OVERLAY]->h;
+    s->var_values[VAR_HSUB]  = 1<<pix_desc->log2_chroma_w;
+    s->var_values[VAR_VSUB]  = 1<<pix_desc->log2_chroma_h;
+    s->var_values[VAR_X]     = NAN;
+    s->var_values[VAR_Y]     = NAN;
+    s->var_values[VAR_N]     = 0;
+    s->var_values[VAR_T]     = NAN;
+    s->var_values[VAR_POS]   = NAN;
 
-    if ((ret = set_expr(&over->x_pexpr,      over->x_expr,      "x",      ctx)) < 0 ||
-        (ret = set_expr(&over->y_pexpr,      over->y_expr,      "y",      ctx)) < 0)
+    if ((ret = set_expr(&s->x_pexpr,      s->x_expr,      "x",      ctx)) < 0 ||
+        (ret = set_expr(&s->y_pexpr,      s->y_expr,      "y",      ctx)) < 0)
         return ret;
 
-    over->overlay_is_packed_rgb =
-        ff_fill_rgba_map(over->overlay_rgba_map, inlink->format) >= 0;
-    over->overlay_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);
+    s->overlay_is_packed_rgb =
+        ff_fill_rgba_map(s->overlay_rgba_map, inlink->format) >= 0;
+    s->overlay_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);
 
-    if (over->eval_mode == EVAL_MODE_INIT) {
+    if (s->eval_mode == EVAL_MODE_INIT) {
         eval_expr(ctx);
         av_log(ctx, AV_LOG_VERBOSE, "x:%f xi:%d y:%f yi:%d\n",
-               over->var_values[VAR_X], over->x,
-               over->var_values[VAR_Y], over->y);
+               s->var_values[VAR_X], s->x,
+               s->var_values[VAR_Y], s->y);
     }
 
     av_log(ctx, AV_LOG_VERBOSE,
@@ -357,10 +332,10 @@
  * Blend image in src to destination buffer dst at position (x, y).
  */
 static void blend_image(AVFilterContext *ctx,
-                        AVFrame *dst, AVFrame *src,
+                        AVFrame *dst, const AVFrame *src,
                         int x, int y)
 {
-    OverlayContext *over = ctx->priv;
+    OverlayContext *s = ctx->priv;
     int i, imax, j, jmax, k, kmax;
     const int src_w = src->width;
     const int src_h = src->height;
@@ -371,19 +346,19 @@
         y >= dst_h || y+dst_h < 0)
         return; /* no intersection */
 
-    if (over->main_is_packed_rgb) {
+    if (s->main_is_packed_rgb) {
         uint8_t alpha;          ///< the amount of overlay to blend on to main
-        const int dr = over->main_rgba_map[R];
-        const int dg = over->main_rgba_map[G];
-        const int db = over->main_rgba_map[B];
-        const int da = over->main_rgba_map[A];
-        const int dstep = over->main_pix_step[0];
-        const int sr = over->overlay_rgba_map[R];
-        const int sg = over->overlay_rgba_map[G];
-        const int sb = over->overlay_rgba_map[B];
-        const int sa = over->overlay_rgba_map[A];
-        const int sstep = over->overlay_pix_step[0];
-        const int main_has_alpha = over->main_has_alpha;
+        const int dr = s->main_rgba_map[R];
+        const int dg = s->main_rgba_map[G];
+        const int db = s->main_rgba_map[B];
+        const int da = s->main_rgba_map[A];
+        const int dstep = s->main_pix_step[0];
+        const int sr = s->overlay_rgba_map[R];
+        const int sg = s->overlay_rgba_map[G];
+        const int sb = s->overlay_rgba_map[B];
+        const int sa = s->overlay_rgba_map[A];
+        const int sstep = s->overlay_pix_step[0];
+        const int main_has_alpha = s->main_has_alpha;
         uint8_t *s, *sp, *d, *dp;
 
         i = FFMAX(-y, 0);
@@ -439,7 +414,7 @@
             sp += src->linesize[0];
         }
     } else {
-        const int main_has_alpha = over->main_has_alpha;
+        const int main_has_alpha = s->main_has_alpha;
         if (main_has_alpha) {
             uint8_t alpha;          ///< the amount of overlay to blend on to main
             uint8_t *s, *sa, *d, *da;
@@ -477,12 +452,12 @@
             }
         }
         for (i = 0; i < 3; i++) {
-            int hsub = i ? over->hsub : 0;
-            int vsub = i ? over->vsub : 0;
-            int src_wp = FFALIGN(src_w, 1<<hsub) >> hsub;
-            int src_hp = FFALIGN(src_h, 1<<vsub) >> vsub;
-            int dst_wp = FFALIGN(dst_w, 1<<hsub) >> hsub;
-            int dst_hp = FFALIGN(dst_h, 1<<vsub) >> vsub;
+            int hsub = i ? s->hsub : 0;
+            int vsub = i ? s->vsub : 0;
+            int src_wp = FF_CEIL_RSHIFT(src_w, hsub);
+            int src_hp = FF_CEIL_RSHIFT(src_h, vsub);
+            int dst_wp = FF_CEIL_RSHIFT(dst_w, hsub);
+            int dst_hp = FF_CEIL_RSHIFT(dst_h, vsub);
             int yp = y>>vsub;
             int xp = x>>hsub;
             uint8_t *s, *sp, *d, *dp, *a, *ap;
@@ -544,167 +519,60 @@
     }
 }
 
-static int try_filter_frame(AVFilterContext *ctx, AVFrame *mainpic)
+static AVFrame *do_blend(AVFilterContext *ctx, AVFrame *mainpic,
+                         const AVFrame *second)
 {
-    OverlayContext *over = ctx->priv;
+    OverlayContext *s = ctx->priv;
     AVFilterLink *inlink = ctx->inputs[0];
-    AVFrame *next_overpic;
-    int ret;
 
-    /* Discard obsolete overlay frames: if there is a next overlay frame with pts
-     * before the main frame, we can drop the current overlay. */
-    while (1) {
-        next_overpic = ff_bufqueue_peek(&over->queue_over, 0);
-        if (!next_overpic && over->overlay_eof && !over->repeatlast) {
-            av_frame_free(&over->overpicref);
-            break;
-        }
-        if (!next_overpic || av_compare_ts(next_overpic->pts, ctx->inputs[OVERLAY]->time_base,
-                                           mainpic->pts     , ctx->inputs[MAIN]->time_base) > 0)
-            break;
-        ff_bufqueue_get(&over->queue_over);
-        av_frame_free(&over->overpicref);
-        over->overpicref = next_overpic;
-    }
-
-    /* If there is no next frame and no EOF and the overlay frame is before
-     * the main frame, we can not know yet if it will be superseded. */
-    if (!over->queue_over.available && !over->overlay_eof &&
-        (!over->overpicref || av_compare_ts(over->overpicref->pts, ctx->inputs[OVERLAY]->time_base,
-                                            mainpic->pts         , ctx->inputs[MAIN]->time_base) < 0))
-        return AVERROR(EAGAIN);
-
-    /* At this point, we know that the current overlay frame extends to the
-     * time of the main frame. */
-    av_dlog(ctx, "main_pts:%s main_pts_time:%s",
-            av_ts2str(mainpic->pts), av_ts2timestr(mainpic->pts, &ctx->inputs[MAIN]->time_base));
-    if (over->overpicref)
-        av_dlog(ctx, " over_pts:%s over_pts_time:%s",
-                av_ts2str(over->overpicref->pts), av_ts2timestr(over->overpicref->pts, &ctx->inputs[OVERLAY]->time_base));
-    av_dlog(ctx, "\n");
-
-    if (over->overpicref) {
-        if (over->eval_mode == EVAL_MODE_FRAME) {
+        /* TODO: reindent */
+        if (s->eval_mode == EVAL_MODE_FRAME) {
             int64_t pos = av_frame_get_pkt_pos(mainpic);
 
-            over->var_values[VAR_N] = inlink->frame_count;
-            over->var_values[VAR_T] = mainpic->pts == AV_NOPTS_VALUE ?
+            s->var_values[VAR_N] = inlink->frame_count;
+            s->var_values[VAR_T] = mainpic->pts == AV_NOPTS_VALUE ?
                 NAN : mainpic->pts * av_q2d(inlink->time_base);
-            over->var_values[VAR_POS] = pos == -1 ? NAN : pos;
+            s->var_values[VAR_POS] = pos == -1 ? NAN : pos;
 
             eval_expr(ctx);
             av_log(ctx, AV_LOG_DEBUG, "n:%f t:%f pos:%f x:%f xi:%d y:%f yi:%d\n",
-                   over->var_values[VAR_N], over->var_values[VAR_T], over->var_values[VAR_POS],
-                   over->var_values[VAR_X], over->x,
-                   over->var_values[VAR_Y], over->y);
+                   s->var_values[VAR_N], s->var_values[VAR_T], s->var_values[VAR_POS],
+                   s->var_values[VAR_X], s->x,
+                   s->var_values[VAR_Y], s->y);
         }
-        if (over->enable)
-            blend_image(ctx, mainpic, over->overpicref, over->x, over->y);
 
-    }
-    ret = ff_filter_frame(ctx->outputs[0], mainpic);
-    av_assert1(ret != AVERROR(EAGAIN));
-    over->frame_requested = 0;
-    return ret;
-}
-
-static int try_filter_next_frame(AVFilterContext *ctx)
-{
-    OverlayContext *over = ctx->priv;
-    AVFrame *next_mainpic = ff_bufqueue_peek(&over->queue_main, 0);
-    int ret;
-
-    if (!next_mainpic)
-        return AVERROR(EAGAIN);
-    if ((ret = try_filter_frame(ctx, next_mainpic)) == AVERROR(EAGAIN))
-        return ret;
-    ff_bufqueue_get(&over->queue_main);
-    return ret;
-}
-
-static int flush_frames(AVFilterContext *ctx)
-{
-    int ret;
-
-    while (!(ret = try_filter_next_frame(ctx)));
-    return ret == AVERROR(EAGAIN) ? 0 : ret;
+    blend_image(ctx, mainpic, second, s->x, s->y);
+    return mainpic;
 }
 
 static int filter_frame_main(AVFilterLink *inlink, AVFrame *inpicref)
 {
-    AVFilterContext *ctx = inlink->dst;
-    OverlayContext *over = ctx->priv;
-    int ret;
-
-    if ((ret = flush_frames(ctx)) < 0)
-        return ret;
-    if ((ret = try_filter_frame(ctx, inpicref)) < 0) {
-        if (ret != AVERROR(EAGAIN))
-            return ret;
-        ff_bufqueue_add(ctx, &over->queue_main, inpicref);
-    }
-
-    if (!over->overpicref)
-        return 0;
-    flush_frames(ctx);
-
-    return 0;
+    OverlayContext *s = inlink->dst->priv;
+    return ff_dualinput_filter_frame_main(&s->dinput, inlink, inpicref);
 }
 
 static int filter_frame_over(AVFilterLink *inlink, AVFrame *inpicref)
 {
-    AVFilterContext *ctx = inlink->dst;
-    OverlayContext *over = ctx->priv;
-    int ret;
-
-    if ((ret = flush_frames(ctx)) < 0)
-        return ret;
-    ff_bufqueue_add(ctx, &over->queue_over, inpicref);
-    ret = try_filter_next_frame(ctx);
-    return ret == AVERROR(EAGAIN) ? 0 : ret;
+    OverlayContext *s = inlink->dst->priv;
+    return ff_dualinput_filter_frame_second(&s->dinput, inlink, inpicref);
 }
 
-#define DEF_FILTER_FRAME(name, mode, enable_value)                              \
-static int filter_frame_##name##_##mode(AVFilterLink *inlink, AVFrame *frame)   \
-{                                                                               \
-    AVFilterContext *ctx = inlink->dst;                                         \
-    OverlayContext *over = ctx->priv;                                           \
-    over->enable = enable_value;                                                \
-    return filter_frame_##name(inlink, frame);                                  \
-}
-
-DEF_FILTER_FRAME(main, enabled,  1);
-DEF_FILTER_FRAME(main, disabled, 0);
-DEF_FILTER_FRAME(over, enabled,  1);
-DEF_FILTER_FRAME(over, disabled, 0);
-
 static int request_frame(AVFilterLink *outlink)
 {
-    AVFilterContext *ctx = outlink->src;
-    OverlayContext *over = ctx->priv;
-    int input, ret;
+    OverlayContext *s = outlink->src->priv;
+    return ff_dualinput_request_frame(&s->dinput, outlink);
+}
 
-    if (!try_filter_next_frame(ctx))
-        return 0;
-    over->frame_requested = 1;
-    while (over->frame_requested) {
-        /* TODO if we had a frame duration, we could guess more accurately */
-        input = !over->overlay_eof && (over->queue_main.available ||
-                                       over->queue_over.available < 2) ?
-                OVERLAY : MAIN;
-        ret = ff_request_frame(ctx->inputs[input]);
-        /* EOF on main is reported immediately */
-        if (ret == AVERROR_EOF && input == OVERLAY) {
-            over->overlay_eof = 1;
-            if (over->shortest)
-                return ret;
-            if ((ret = try_filter_next_frame(ctx)) != AVERROR(EAGAIN))
-                return ret;
-            ret = 0; /* continue requesting frames on main */
-        }
-        if (ret < 0)
-            return ret;
+static av_cold int init(AVFilterContext *ctx)
+{
+    OverlayContext *s = ctx->priv;
+
+    if (s->allow_packed_rgb) {
+        av_log(ctx, AV_LOG_WARNING,
+               "The rgb option is deprecated and is overriding the format option, use format instead\n");
+        s->format = OVERLAY_FORMAT_RGB;
     }
+    s->dinput.process = do_blend;
     return 0;
 }
 
@@ -718,12 +586,12 @@
          { "init",  "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT},  .flags = FLAGS, .unit = "eval" },
          { "frame", "eval expressions per-frame",                  0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" },
     { "rgb", "force packed RGB in input and output (deprecated)", OFFSET(allow_packed_rgb), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS },
-    { "shortest", "force termination when the shortest input terminates", OFFSET(shortest), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS },
+    { "shortest", "force termination when the shortest input terminates", OFFSET(dinput.shortest), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS },
     { "format", "set output format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=OVERLAY_FORMAT_YUV420}, 0, OVERLAY_FORMAT_NB-1, FLAGS, "format" },
         { "yuv420", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420}, .flags = FLAGS, .unit = "format" },
         { "yuv444", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV444}, .flags = FLAGS, .unit = "format" },
         { "rgb",    "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_RGB},    .flags = FLAGS, .unit = "format" },
-    { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(repeatlast), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS },
+    { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(dinput.repeatlast), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS },
     { NULL }
 };
 
@@ -735,16 +603,14 @@
         .type         = AVMEDIA_TYPE_VIDEO,
         .get_video_buffer = ff_null_get_video_buffer,
         .config_props = config_input_main,
-        .filter_frame             = filter_frame_main_enabled,
-        .passthrough_filter_frame = filter_frame_main_disabled,
+        .filter_frame = filter_frame_main,
         .needs_writable = 1,
     },
     {
         .name         = "overlay",
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input_overlay,
-        .filter_frame             = filter_frame_over_enabled,
-        .passthrough_filter_frame = filter_frame_over_disabled,
+        .filter_frame = filter_frame_over,
     },
     { NULL }
 };
@@ -774,5 +640,5 @@
 
     .inputs    = avfilter_vf_overlay_inputs,
     .outputs   = avfilter_vf_overlay_outputs,
-    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/vf_owdenoise.c b/libavfilter/vf_owdenoise.c
new file mode 100644
index 0000000..cdc0e7c
--- /dev/null
+++ b/libavfilter/vf_owdenoise.c
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2007 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (c) 2013 Clément Bœsch <ubitux@gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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.
+ */
+
+/**
+ * @todo try to change to int
+ * @todo try lifting based implementation
+ * @todo optimize optimize optimize
+ * @todo hard thresholding
+ * @todo use QP to decide filter strength
+ * @todo wavelet normalization / least squares optimal signal vs. noise thresholds
+ */
+
+#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "avfilter.h"
+#include "internal.h"
+
+typedef struct {
+    const AVClass *class;
+    double luma_strength;
+    double chroma_strength;
+    int depth;
+    float *plane[16+1][4];
+    int linesize;
+    int hsub, vsub;
+} OWDenoiseContext;
+
+#define OFFSET(x) offsetof(OWDenoiseContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption owdenoise_options[] = {
+    { "depth",           "set depth",           OFFSET(depth),           AV_OPT_TYPE_INT,    {.i64 =   8}, 8,   16, FLAGS },
+    { "luma_strength",   "set luma strength",   OFFSET(luma_strength),   AV_OPT_TYPE_DOUBLE, {.dbl = 1.0}, 0, 1000, FLAGS },
+    { "ls",              "set luma strength",   OFFSET(luma_strength),   AV_OPT_TYPE_DOUBLE, {.dbl = 1.0}, 0, 1000, FLAGS },
+    { "chroma_strength", "set chroma strength", OFFSET(chroma_strength), AV_OPT_TYPE_DOUBLE, {.dbl = 1.0}, 0, 1000, FLAGS },
+    { "cs",              "set chroma strength", OFFSET(chroma_strength), AV_OPT_TYPE_DOUBLE, {.dbl = 1.0}, 0, 1000, FLAGS },
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(owdenoise);
+
+DECLARE_ALIGNED(8, static const uint8_t, dither)[8][8] = {
+    {  0,  48,  12,  60,   3,  51,  15,  63 },
+    { 32,  16,  44,  28,  35,  19,  47,  31 },
+    {  8,  56,   4,  52,  11,  59,   7,  55 },
+    { 40,  24,  36,  20,  43,  27,  39,  23 },
+    {  2,  50,  14,  62,   1,  49,  13,  61 },
+    { 34,  18,  46,  30,  33,  17,  45,  29 },
+    { 10,  58,   6,  54,   9,  57,   5,  53 },
+    { 42,  26,  38,  22,  41,  25,  37,  21 },
+};
+
+static const double coeff[2][5] = {
+    {
+         0.6029490182363579  * M_SQRT2,
+         0.2668641184428723  * M_SQRT2,
+        -0.07822326652898785 * M_SQRT2,
+        -0.01686411844287495 * M_SQRT2,
+         0.02674875741080976 * M_SQRT2,
+    },{
+         1.115087052456994   / M_SQRT2,
+        -0.5912717631142470  / M_SQRT2,
+        -0.05754352622849957 / M_SQRT2,
+         0.09127176311424948 / M_SQRT2,
+    }
+};
+
+static const double icoeff[2][5] = {
+    {
+         1.115087052456994   / M_SQRT2,
+         0.5912717631142470  / M_SQRT2,
+        -0.05754352622849957 / M_SQRT2,
+        -0.09127176311424948 / M_SQRT2,
+    },{
+         0.6029490182363579  * M_SQRT2,
+        -0.2668641184428723  * M_SQRT2,
+        -0.07822326652898785 * M_SQRT2,
+         0.01686411844287495 * M_SQRT2,
+         0.02674875741080976 * M_SQRT2,
+    }
+};
+
+static inline int mirror(int x, int w)
+{
+    while ((unsigned)x > (unsigned)w) {
+        x = -x;
+        if (x < 0)
+            x += 2 * w;
+    }
+    return x;
+}
+
+static inline void decompose(float *dst_l, float *dst_h, const float *src,
+                             int linesize, int w)
+{
+    int x, i;
+    for (x = 0; x < w; x++) {
+        double sum_l = src[x * linesize] * coeff[0][0];
+        double sum_h = src[x * linesize] * coeff[1][0];
+        for (i = 1; i <= 4; i++) {
+            const double s = src[mirror(x - i, w - 1) * linesize]
+                           + src[mirror(x + i, w - 1) * linesize];
+
+            sum_l += coeff[0][i] * s;
+            sum_h += coeff[1][i] * s;
+        }
+        dst_l[x * linesize] = sum_l;
+        dst_h[x * linesize] = sum_h;
+    }
+}
+
+static inline void compose(float *dst, const float *src_l, const float *src_h,
+                           int linesize, int w)
+{
+    int x, i;
+    for (x = 0; x < w; x++) {
+        double sum_l = src_l[x * linesize] * icoeff[0][0];
+        double sum_h = src_h[x * linesize] * icoeff[1][0];
+        for (i = 1; i <= 4; i++) {
+            const int x0 = mirror(x - i, w - 1) * linesize;
+            const int x1 = mirror(x + i, w - 1) * linesize;
+
+            sum_l += icoeff[0][i] * (src_l[x0] + src_l[x1]);
+            sum_h += icoeff[1][i] * (src_h[x0] + src_h[x1]);
+        }
+        dst[x * linesize] = (sum_l + sum_h) * 0.5;
+    }
+}
+
+static inline void decompose2D(float *dst_l, float *dst_h, const float *src,
+                               int xlinesize, int ylinesize,
+                               int step, int w, int h)
+{
+    int y, x;
+    for (y = 0; y < h; y++)
+        for (x = 0; x < step; x++)
+            decompose(dst_l + ylinesize*y + xlinesize*x,
+                      dst_h + ylinesize*y + xlinesize*x,
+                      src   + ylinesize*y + xlinesize*x,
+                      step * xlinesize, (w - x + step - 1) / step);
+}
+
+static inline void compose2D(float *dst, const float *src_l, const float *src_h,
+                             int xlinesize, int ylinesize,
+                             int step, int w, int h)
+{
+    int y, x;
+    for (y = 0; y < h; y++)
+        for (x = 0; x < step; x++)
+            compose(dst   + ylinesize*y + xlinesize*x,
+                    src_l + ylinesize*y + xlinesize*x,
+                    src_h + ylinesize*y + xlinesize*x,
+                    step * xlinesize, (w - x + step - 1) / step);
+}
+
+static void decompose2D2(float *dst[4], float *src, float *temp[2],
+                         int linesize, int step, int w, int h)
+{
+    decompose2D(temp[0], temp[1], src,     1, linesize, step, w, h);
+    decompose2D( dst[0],  dst[1], temp[0], linesize, 1, step, h, w);
+    decompose2D( dst[2],  dst[3], temp[1], linesize, 1, step, h, w);
+}
+
+static void compose2D2(float *dst, float *src[4], float *temp[2],
+                       int linesize, int step, int w, int h)
+{
+    compose2D(temp[0],  src[0],  src[1], linesize, 1, step, h, w);
+    compose2D(temp[1],  src[2],  src[3], linesize, 1, step, h, w);
+    compose2D(dst,     temp[0], temp[1], 1, linesize, step, w, h);
+}
+
+static void filter(OWDenoiseContext *s,
+                   uint8_t       *dst, int dst_linesize,
+                   const uint8_t *src, int src_linesize,
+                   int width, int height, double strength)
+{
+    int x, y, i, j, depth = s->depth;
+
+    while (1<<depth > width || 1<<depth > height)
+        depth--;
+
+    for (y = 0; y < height; y++)
+        for(x = 0; x < width; x++)
+            s->plane[0][0][y*s->linesize + x] = src[y*src_linesize + x];
+
+    for (i = 0; i < depth; i++)
+        decompose2D2(s->plane[i + 1], s->plane[i][0], s->plane[0] + 1, s->linesize, 1<<i, width, height);
+
+    for (i = 0; i < depth; i++) {
+        for (j = 1; j < 4; j++) {
+            for (y = 0; y < height; y++) {
+                for (x = 0; x < width; x++) {
+                    double v = s->plane[i + 1][j][y*s->linesize + x];
+                    if      (v >  strength) v -= strength;
+                    else if (v < -strength) v += strength;
+                    else                    v  = 0;
+                    s->plane[i + 1][j][x + y*s->linesize] = v;
+                }
+            }
+        }
+    }
+    for (i = depth-1; i >= 0; i--)
+        compose2D2(s->plane[i][0], s->plane[i + 1], s->plane[0] + 1, s->linesize, 1<<i, width, height);
+
+    for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x++) {
+            i = s->plane[0][0][y*s->linesize + x] + dither[x&7][y&7]*(1.0/64) + 1.0/128; // yes the rounding is insane but optimal :)
+            if ((unsigned)i > 255U) i = ~(i >> 31);
+            dst[y*dst_linesize + x] = i;
+        }
+    }
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+{
+    int direct = 0;
+    AVFilterContext *ctx = inlink->dst;
+    OWDenoiseContext *s = ctx->priv;
+    AVFilterLink *outlink = ctx->outputs[0];
+    AVFrame *out;
+    const int cw = FF_CEIL_RSHIFT(inlink->w, s->hsub);
+    const int ch = FF_CEIL_RSHIFT(inlink->h, s->vsub);
+
+    if (av_frame_is_writable(in)) {
+        direct = 1;
+        out = in;
+    } else {
+        out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+        if (!out) {
+            av_frame_free(&in);
+            return AVERROR(ENOMEM);
+        }
+        av_frame_copy_props(out, in);
+    }
+
+    filter(s, out->data[0], out->linesize[0], in->data[0], in->linesize[0], inlink->w, inlink->h, s->luma_strength);
+    filter(s, out->data[1], out->linesize[1], in->data[1], in->linesize[1], cw,        ch,        s->chroma_strength);
+    filter(s, out->data[2], out->linesize[2], in->data[2], in->linesize[2], cw,        ch,        s->chroma_strength);
+
+    if (!direct) {
+        if (in->data[3])
+            av_image_copy_plane(out->data[3], out->linesize[3],
+                                in ->data[3], in ->linesize[3],
+                                inlink->w, inlink->h);
+        av_frame_free(&in);
+    }
+
+    return ff_filter_frame(outlink, out);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat pix_fmts[] = {
+        AV_PIX_FMT_YUV444P,      AV_PIX_FMT_YUV422P,
+        AV_PIX_FMT_YUV420P,      AV_PIX_FMT_YUV411P,
+        AV_PIX_FMT_YUV410P,      AV_PIX_FMT_YUV440P,
+        AV_PIX_FMT_YUVA444P,     AV_PIX_FMT_YUVA422P,
+        AV_PIX_FMT_YUVA420P,
+        AV_PIX_FMT_NONE
+    };
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+    int i, j;
+    OWDenoiseContext *s = inlink->dst->priv;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+    const int h = FFALIGN(inlink->h, 16);
+
+    s->hsub = desc->log2_chroma_w;
+    s->vsub = desc->log2_chroma_h;
+
+    s->linesize = FFALIGN(inlink->w, 16);
+    for (j = 0; j < 4; j++) {
+        for (i = 0; i <= s->depth; i++) {
+            s->plane[i][j] = av_malloc(s->linesize * h * sizeof(s->plane[0][0][0]));
+            if (!s->plane[i][j])
+                return AVERROR(ENOMEM);
+        }
+    }
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    int i, j;
+    OWDenoiseContext *s = ctx->priv;
+
+    for (j = 0; j < 4; j++)
+        for (i = 0; i <= s->depth; i++)
+            av_freep(&s->plane[i][j]);
+}
+
+static const AVFilterPad owdenoise_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = filter_frame,
+        .config_props = config_input,
+    },
+    { NULL }
+};
+
+static const AVFilterPad owdenoise_outputs[] = {
+     {
+         .name = "default",
+         .type = AVMEDIA_TYPE_VIDEO,
+     },
+     { NULL }
+};
+
+AVFilter avfilter_vf_owdenoise = {
+    .name          = "owdenoise",
+    .description   = NULL_IF_CONFIG_SMALL("Denoise using wavelets."),
+    .priv_size     = sizeof(OWDenoiseContext),
+    .uninit        = uninit,
+    .query_formats = query_formats,
+    .inputs        = owdenoise_inputs,
+    .outputs       = owdenoise_outputs,
+    .priv_class    = &owdenoise_class,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
+};
diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c
index 3407679..023ef7f 100644
--- a/libavfilter/vf_pad.c
+++ b/libavfilter/vf_pad.c
@@ -88,32 +88,21 @@
     char *h_expr;           ///< height expression string
     char *x_expr;           ///< width  expression string
     char *y_expr;           ///< height expression string
-    char *color_str;
     uint8_t rgba_color[4];  ///< color for the padding area
     FFDrawContext draw;
     FFDrawColor color;
 } PadContext;
 
-static av_cold int init(AVFilterContext *ctx)
-{
-    PadContext *pad = ctx->priv;
-
-    if (av_parse_color(pad->rgba_color, pad->color_str, -1, ctx) < 0)
-        return AVERROR(EINVAL);
-
-    return 0;
-}
-
 static int config_input(AVFilterLink *inlink)
 {
     AVFilterContext *ctx = inlink->dst;
-    PadContext *pad = ctx->priv;
+    PadContext *s = ctx->priv;
     int ret;
     double var_values[VARS_NB], res;
     char *expr;
 
-    ff_draw_init(&pad->draw, inlink->format, 0);
-    ff_draw_color(&pad->draw, &pad->color, pad->rgba_color);
+    ff_draw_init(&s->draw, inlink->format, 0);
+    ff_draw_color(&s->draw, &s->color, s->rgba_color);
 
     var_values[VAR_IN_W]  = var_values[VAR_IW] = inlink->w;
     var_values[VAR_IN_H]  = var_values[VAR_IH] = inlink->h;
@@ -123,72 +112,72 @@
     var_values[VAR_SAR]   = inlink->sample_aspect_ratio.num ?
         (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
     var_values[VAR_DAR]   = var_values[VAR_A] * var_values[VAR_SAR];
-    var_values[VAR_HSUB]  = 1 << pad->draw.hsub_max;
-    var_values[VAR_VSUB]  = 1 << pad->draw.vsub_max;
+    var_values[VAR_HSUB]  = 1 << s->draw.hsub_max;
+    var_values[VAR_VSUB]  = 1 << s->draw.vsub_max;
 
     /* evaluate width and height */
-    av_expr_parse_and_eval(&res, (expr = pad->w_expr),
+    av_expr_parse_and_eval(&res, (expr = s->w_expr),
                            var_names, var_values,
                            NULL, NULL, NULL, NULL, NULL, 0, ctx);
-    pad->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res;
-    if ((ret = av_expr_parse_and_eval(&res, (expr = pad->h_expr),
+    s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res;
+    if ((ret = av_expr_parse_and_eval(&res, (expr = s->h_expr),
                                       var_names, var_values,
                                       NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
         goto eval_fail;
-    pad->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = res;
+    s->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = res;
     /* evaluate the width again, as it may depend on the evaluated output height */
-    if ((ret = av_expr_parse_and_eval(&res, (expr = pad->w_expr),
+    if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr),
                                       var_names, var_values,
                                       NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
         goto eval_fail;
-    pad->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res;
+    s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res;
 
     /* evaluate x and y */
-    av_expr_parse_and_eval(&res, (expr = pad->x_expr),
+    av_expr_parse_and_eval(&res, (expr = s->x_expr),
                            var_names, var_values,
                            NULL, NULL, NULL, NULL, NULL, 0, ctx);
-    pad->x = var_values[VAR_X] = res;
-    if ((ret = av_expr_parse_and_eval(&res, (expr = pad->y_expr),
+    s->x = var_values[VAR_X] = res;
+    if ((ret = av_expr_parse_and_eval(&res, (expr = s->y_expr),
                                       var_names, var_values,
                                       NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
         goto eval_fail;
-    pad->y = var_values[VAR_Y] = res;
+    s->y = var_values[VAR_Y] = res;
     /* evaluate x again, as it may depend on the evaluated y value */
-    if ((ret = av_expr_parse_and_eval(&res, (expr = pad->x_expr),
+    if ((ret = av_expr_parse_and_eval(&res, (expr = s->x_expr),
                                       var_names, var_values,
                                       NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
         goto eval_fail;
-    pad->x = var_values[VAR_X] = res;
+    s->x = var_values[VAR_X] = res;
 
     /* sanity check params */
-    if (pad->w < 0 || pad->h < 0 || pad->x < 0 || pad->y < 0) {
+    if (s->w < 0 || s->h < 0 || s->x < 0 || s->y < 0) {
         av_log(ctx, AV_LOG_ERROR, "Negative values are not acceptable.\n");
         return AVERROR(EINVAL);
     }
 
-    if (!pad->w)
-        pad->w = inlink->w;
-    if (!pad->h)
-        pad->h = inlink->h;
+    if (!s->w)
+        s->w = inlink->w;
+    if (!s->h)
+        s->h = inlink->h;
 
-    pad->w    = ff_draw_round_to_sub(&pad->draw, 0, -1, pad->w);
-    pad->h    = ff_draw_round_to_sub(&pad->draw, 1, -1, pad->h);
-    pad->x    = ff_draw_round_to_sub(&pad->draw, 0, -1, pad->x);
-    pad->y    = ff_draw_round_to_sub(&pad->draw, 1, -1, pad->y);
-    pad->in_w = ff_draw_round_to_sub(&pad->draw, 0, -1, inlink->w);
-    pad->in_h = ff_draw_round_to_sub(&pad->draw, 1, -1, inlink->h);
+    s->w    = ff_draw_round_to_sub(&s->draw, 0, -1, s->w);
+    s->h    = ff_draw_round_to_sub(&s->draw, 1, -1, s->h);
+    s->x    = ff_draw_round_to_sub(&s->draw, 0, -1, s->x);
+    s->y    = ff_draw_round_to_sub(&s->draw, 1, -1, s->y);
+    s->in_w = ff_draw_round_to_sub(&s->draw, 0, -1, inlink->w);
+    s->in_h = ff_draw_round_to_sub(&s->draw, 1, -1, inlink->h);
 
     av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d x:%d y:%d color:0x%02X%02X%02X%02X\n",
-           inlink->w, inlink->h, pad->w, pad->h, pad->x, pad->y,
-           pad->rgba_color[0], pad->rgba_color[1], pad->rgba_color[2], pad->rgba_color[3]);
+           inlink->w, inlink->h, s->w, s->h, s->x, s->y,
+           s->rgba_color[0], s->rgba_color[1], s->rgba_color[2], s->rgba_color[3]);
 
-    if (pad->x <  0 || pad->y <  0                      ||
-        pad->w <= 0 || pad->h <= 0                      ||
-        (unsigned)pad->x + (unsigned)inlink->w > pad->w ||
-        (unsigned)pad->y + (unsigned)inlink->h > pad->h) {
+    if (s->x <  0 || s->y <  0                      ||
+        s->w <= 0 || s->h <= 0                      ||
+        (unsigned)s->x + (unsigned)inlink->w > s->w ||
+        (unsigned)s->y + (unsigned)inlink->h > s->h) {
         av_log(ctx, AV_LOG_ERROR,
                "Input area %d:%d:%d:%d not within the padded area 0:0:%d:%d or zero-sized\n",
-               pad->x, pad->y, pad->x + inlink->w, pad->y + inlink->h, pad->w, pad->h);
+               s->x, s->y, s->x + inlink->w, s->y + inlink->h, s->w, s->h);
         return AVERROR(EINVAL);
     }
 
@@ -203,20 +192,20 @@
 
 static int config_output(AVFilterLink *outlink)
 {
-    PadContext *pad = outlink->src->priv;
+    PadContext *s = outlink->src->priv;
 
-    outlink->w = pad->w;
-    outlink->h = pad->h;
+    outlink->w = s->w;
+    outlink->h = s->h;
     return 0;
 }
 
 static AVFrame *get_video_buffer(AVFilterLink *inlink, int w, int h)
 {
-    PadContext *pad = inlink->dst->priv;
+    PadContext *s = inlink->dst->priv;
 
     AVFrame *frame = ff_get_video_buffer(inlink->dst->outputs[0],
-                                         w + (pad->w - pad->in_w),
-                                         h + (pad->h - pad->in_h));
+                                         w + (s->w - s->in_w),
+                                         h + (s->h - s->in_h));
     int plane;
 
     if (!frame)
@@ -225,11 +214,11 @@
     frame->width  = w;
     frame->height = h;
 
-    for (plane = 0; plane < 4 && frame->data[plane]; plane++) {
-        int hsub = pad->draw.hsub[plane];
-        int vsub = pad->draw.vsub[plane];
-        frame->data[plane] += (pad->x >> hsub) * pad->draw.pixelstep[plane] +
-                              (pad->y >> vsub) * frame->linesize[plane];
+    for (plane = 0; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++) {
+        int hsub = s->draw.hsub[plane];
+        int vsub = s->draw.vsub[plane];
+        frame->data[plane] += (s->x >> hsub) * s->draw.pixelstep[plane] +
+                              (s->y >> vsub) * frame->linesize[plane];
     }
 
     return frame;
@@ -271,7 +260,6 @@
             (buf->data + buf->size) - end < req_end)
             return 1;
 
-#define SIGN(x) ((x) > 0 ? 1 : -1)
         for (j = 0; j < FF_ARRAY_ELEMS(planes) && planes[j] >= 0; j++) {
             int vsub1 = s->draw.vsub[planes[j]];
             uint8_t *start1 = frame->data[planes[j]];
@@ -280,8 +268,8 @@
             if (i == j)
                 continue;
 
-            if (SIGN(start - end1) != SIGN(start - end1 - req_start) ||
-                SIGN(end - start1) != SIGN(end - start1 + req_end))
+            if (FFSIGN(start - end1) != FFSIGN(start - end1 - req_start) ||
+                FFSIGN(end - start1) != FFSIGN(end - start1 + req_end))
                 return 1;
         }
     }
@@ -304,15 +292,15 @@
 
 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
-    PadContext *pad = inlink->dst->priv;
+    PadContext *s = inlink->dst->priv;
     AVFrame *out;
-    int needs_copy = frame_needs_copy(pad, in);
+    int needs_copy = frame_needs_copy(s, in);
 
     if (needs_copy) {
         av_log(inlink->dst, AV_LOG_DEBUG, "Direct padding impossible allocating new frame\n");
         out = ff_get_video_buffer(inlink->dst->outputs[0],
-                                  FFMAX(inlink->w, pad->w),
-                                  FFMAX(inlink->h, pad->h));
+                                  FFMAX(inlink->w, s->w),
+                                  FFMAX(inlink->h, s->h));
         if (!out) {
             av_frame_free(&in);
             return AVERROR(ENOMEM);
@@ -323,45 +311,45 @@
         int i;
 
         out = in;
-        for (i = 0; i < 4 && out->data[i]; i++) {
-            int hsub = pad->draw.hsub[i];
-            int vsub = pad->draw.vsub[i];
-            out->data[i] -= (pad->x >> hsub) * pad->draw.pixelstep[i] +
-                            (pad->y >> vsub) * out->linesize[i];
+        for (i = 0; i < 4 && out->data[i] && out->linesize[i]; i++) {
+            int hsub = s->draw.hsub[i];
+            int vsub = s->draw.vsub[i];
+            out->data[i] -= (s->x >> hsub) * s->draw.pixelstep[i] +
+                            (s->y >> vsub) * out->linesize[i];
         }
     }
 
     /* top bar */
-    if (pad->y) {
-        ff_fill_rectangle(&pad->draw, &pad->color,
+    if (s->y) {
+        ff_fill_rectangle(&s->draw, &s->color,
                           out->data, out->linesize,
-                          0, 0, pad->w, pad->y);
+                          0, 0, s->w, s->y);
     }
 
     /* bottom bar */
-    if (pad->h > pad->y + pad->in_h) {
-        ff_fill_rectangle(&pad->draw, &pad->color,
+    if (s->h > s->y + s->in_h) {
+        ff_fill_rectangle(&s->draw, &s->color,
                           out->data, out->linesize,
-                          0, pad->y + pad->in_h, pad->w, pad->h - pad->y - pad->in_h);
+                          0, s->y + s->in_h, s->w, s->h - s->y - s->in_h);
     }
 
     /* left border */
-    ff_fill_rectangle(&pad->draw, &pad->color, out->data, out->linesize,
-                      0, pad->y, pad->x, in->height);
+    ff_fill_rectangle(&s->draw, &s->color, out->data, out->linesize,
+                      0, s->y, s->x, in->height);
 
     if (needs_copy) {
-        ff_copy_rectangle2(&pad->draw,
+        ff_copy_rectangle2(&s->draw,
                           out->data, out->linesize, in->data, in->linesize,
-                          pad->x, pad->y, 0, 0, in->width, in->height);
+                          s->x, s->y, 0, 0, in->width, in->height);
     }
 
     /* right border */
-    ff_fill_rectangle(&pad->draw, &pad->color, out->data, out->linesize,
-                      pad->x + pad->in_w, pad->y, pad->w - pad->x - pad->in_w,
+    ff_fill_rectangle(&s->draw, &s->color, out->data, out->linesize,
+                      s->x + s->in_w, s->y, s->w - s->x - s->in_w,
                       in->height);
 
-    out->width  = pad->w;
-    out->height = pad->h;
+    out->width  = s->w;
+    out->height = s->h;
 
     if (in != out)
         av_frame_free(&in);
@@ -378,7 +366,7 @@
     { "h",      "set the pad area height expression",      OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, CHAR_MIN, CHAR_MAX, FLAGS },
     { "x",      "set the x offset expression for the input image position", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS },
     { "y",      "set the y offset expression for the input image position", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS },
-    { "color",  "set the color of the padded area border", OFFSET(color_str), AV_OPT_TYPE_STRING, {.str = "black"}, .flags = FLAGS },
+    { "color",  "set the color of the padded area border", OFFSET(rgba_color), AV_OPT_TYPE_COLOR, {.str = "black"}, .flags = FLAGS },
     { NULL },
 };
 
@@ -410,7 +398,6 @@
 
     .priv_size     = sizeof(PadContext),
     .priv_class    = &pad_class,
-    .init          = init,
     .query_formats = query_formats,
 
     .inputs    = avfilter_vf_pad_inputs,
diff --git a/libavfilter/vf_perspective.c b/libavfilter/vf_perspective.c
new file mode 100644
index 0000000..da8c089
--- /dev/null
+++ b/libavfilter/vf_perspective.c
@@ -0,0 +1,403 @@
+/*
+ * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (c) 2013 Paul B Mahol
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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
+ */
+
+#include "libavutil/eval.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/opt.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
+
+#define SUB_PIXEL_BITS  8
+#define SUB_PIXELS      (1 << SUB_PIXEL_BITS)
+#define COEFF_BITS      11
+
+#define LINEAR 0
+#define CUBIC  1
+
+typedef struct PerspectiveContext {
+    const AVClass *class;
+    char *expr_str[4][2];
+    double ref[4][2];
+    int32_t (*pv)[2];
+    int32_t coeff[SUB_PIXELS][4];
+    int interpolation;
+    int linesize[4];
+    int height[4];
+    int hsub, vsub;
+    int nb_planes;
+
+    void (*perspective)(struct PerspectiveContext *s,
+                        uint8_t *dst, int dst_linesize,
+                        uint8_t *src, int src_linesize,
+                        int w, int h, int hsub, int vsub);
+} PerspectiveContext;
+
+#define OFFSET(x) offsetof(PerspectiveContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+
+static const AVOption perspective_options[] = {
+    { "x0", "set top left x coordinate",     OFFSET(expr_str[0][0]), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, FLAGS },
+    { "y0", "set top left y coordinate",     OFFSET(expr_str[0][1]), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, FLAGS },
+    { "x1", "set top right x coordinate",    OFFSET(expr_str[1][0]), AV_OPT_TYPE_STRING, {.str="W"}, 0, 0, FLAGS },
+    { "y1", "set top right y coordinate",    OFFSET(expr_str[1][1]), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, FLAGS },
+    { "x2", "set bottom left x coordinate",  OFFSET(expr_str[2][0]), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, FLAGS },
+    { "y2", "set bottom left y coordinate",  OFFSET(expr_str[2][1]), AV_OPT_TYPE_STRING, {.str="H"}, 0, 0, FLAGS },
+    { "x3", "set bottom right x coordinate", OFFSET(expr_str[3][0]), AV_OPT_TYPE_STRING, {.str="W"}, 0, 0, FLAGS },
+    { "y3", "set bottom right y coordinate", OFFSET(expr_str[3][1]), AV_OPT_TYPE_STRING, {.str="H"}, 0, 0, FLAGS },
+    { "interpolation", "set interpolation", OFFSET(interpolation), AV_OPT_TYPE_INT, {.i64=LINEAR}, 0, 1, FLAGS, "interpolation" },
+    {      "linear", "", 0, AV_OPT_TYPE_CONST, {.i64=LINEAR}, 0, 0, FLAGS, "interpolation" },
+    {       "cubic", "", 0, AV_OPT_TYPE_CONST, {.i64=CUBIC},  0, 0, FLAGS, "interpolation" },
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(perspective);
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat pix_fmts[] = {
+        AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P,
+        AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ422P,AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ411P,
+        AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P,
+        AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE
+    };
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+static inline double get_coeff(double d)
+{
+    double coeff, A = -0.60;
+
+    d = fabs(d);
+
+    if (d < 1.0)
+        coeff = (1.0 - (A + 3.0) * d * d + (A + 2.0) * d * d * d);
+    else if (d < 2.0)
+        coeff = (-4.0 * A + 8.0 * A * d - 5.0 * A * d * d + A * d * d * d);
+    else
+        coeff = 0.0;
+
+    return coeff;
+}
+
+static const char *const var_names[] = {   "W",   "H", NULL };
+enum                                   { VAR_W, VAR_H, VAR_VARS_NB };
+
+static int config_input(AVFilterLink *inlink)
+{
+    double x0, x1, x2, x3, x4, x5, x6, x7, q;
+    AVFilterContext *ctx = inlink->dst;
+    PerspectiveContext *s = ctx->priv;
+    double (*ref)[2] = s->ref;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+    double values[VAR_VARS_NB] = { [VAR_W] = inlink->w, [VAR_H] = inlink->h };
+    int h = inlink->h;
+    int w = inlink->w;
+    int x, y, i, j, ret;
+
+    for (i = 0; i < 4; i++) {
+        for (j = 0; j < 2; j++) {
+            if (!s->expr_str[i][j])
+                return AVERROR(EINVAL);
+            ret = av_expr_parse_and_eval(&s->ref[i][j], s->expr_str[i][j],
+                                         var_names, &values[0],
+                                         NULL, NULL, NULL, NULL,
+                                         0, 0, ctx);
+            if (ret < 0)
+                return ret;
+        }
+    }
+
+    s->hsub = desc->log2_chroma_w;
+    s->vsub = desc->log2_chroma_h;
+    s->nb_planes = av_pix_fmt_count_planes(inlink->format);
+    if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0)
+        return ret;
+
+    s->height[1] = s->height[2] = FF_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
+    s->height[0] = s->height[3] = inlink->h;
+
+    s->pv = av_realloc_f(s->pv, w * h, 2 * sizeof(*s->pv));
+    if (!s->pv)
+        return AVERROR(ENOMEM);
+
+    x6 = ((ref[0][0] - ref[1][0] - ref[2][0] + ref[3][0]) *
+          (ref[2][1] - ref[3][1]) -
+         ( ref[0][1] - ref[1][1] - ref[2][1] + ref[3][1]) *
+          (ref[2][0] - ref[3][0])) * h;
+    x7 = ((ref[0][1] - ref[1][1] - ref[2][1] + ref[3][1]) *
+          (ref[1][0] - ref[3][0]) -
+         ( ref[0][0] - ref[1][0] - ref[2][0] + ref[3][0]) *
+          (ref[1][1] - ref[3][1])) * w;
+    q =  ( ref[1][0] - ref[3][0]) * (ref[2][1] - ref[3][1]) -
+         ( ref[2][0] - ref[3][0]) * (ref[1][1] - ref[3][1]);
+
+    x0 = q * (ref[1][0] - ref[0][0]) * h + x6 * ref[1][0];
+    x1 = q * (ref[2][0] - ref[0][0]) * w + x7 * ref[2][0];
+    x2 = q *  ref[0][0] * w * h;
+    x3 = q * (ref[1][1] - ref[0][1]) * h + x6 * ref[1][1];
+    x4 = q * (ref[2][1] - ref[0][1]) * w + x7 * ref[2][1];
+    x5 = q *  ref[0][1] * w * h;
+
+    for (y = 0; y < h; y++){
+        for (x = 0; x < w; x++){
+            int u, v;
+
+            u = (int)floor(SUB_PIXELS * (x0 * x + x1 * y + x2) /
+                                        (x6 * x + x7 * y + q * w * h) + 0.5);
+            v = (int)floor(SUB_PIXELS * (x3 * x + x4 * y + x5) /
+                                        (x6 * x + x7 * y + q * w * h) + 0.5);
+
+            s->pv[x + y * w][0] = u;
+            s->pv[x + y * w][1] = v;
+        }
+    }
+
+    for (i = 0; i < SUB_PIXELS; i++){
+        double d = i / (double)SUB_PIXELS;
+        double temp[4];
+        double sum = 0;
+
+        for (j = 0; j < 4; j++)
+            temp[j] = get_coeff(j - d - 1);
+
+        for (j = 0; j < 4; j++)
+            sum += temp[j];
+
+        for (j = 0; j < 4; j++)
+            s->coeff[i][j] = (int)floor((1 << COEFF_BITS) * temp[j] / sum + 0.5);
+    }
+
+    return 0;
+}
+
+static void resample_cubic(PerspectiveContext *s,
+                           uint8_t *dst, int dst_linesize,
+                           uint8_t *src, int src_linesize,
+                           int w, int h, int hsub, int vsub)
+{
+    const int linesize = s->linesize[0];
+    int x, y;
+
+    for (y = 0; y < h; y++) {
+        int sy = y << vsub;
+        for (x = 0; x < w; x++) {
+            int u, v, subU, subV, sum, sx;
+
+            sx   = x << hsub;
+            u    = s->pv[sx + sy * linesize][0] >> hsub;
+            v    = s->pv[sx + sy * linesize][1] >> vsub;
+            subU = u & (SUB_PIXELS - 1);
+            subV = v & (SUB_PIXELS - 1);
+            u  >>= SUB_PIXEL_BITS;
+            v  >>= SUB_PIXEL_BITS;
+
+            if (u > 0 && v > 0 && u < w - 2 && v < h - 2){
+                const int index = u + v*src_linesize;
+                const int a = s->coeff[subU][0];
+                const int b = s->coeff[subU][1];
+                const int c = s->coeff[subU][2];
+                const int d = s->coeff[subU][3];
+
+                sum = s->coeff[subV][0] * (a * src[index - 1 -     src_linesize] + b * src[index - 0 -     src_linesize]  +
+                                      c *      src[index + 1 -     src_linesize] + d * src[index + 2 -     src_linesize]) +
+                      s->coeff[subV][1] * (a * src[index - 1                   ] + b * src[index - 0                   ]  +
+                                      c *      src[index + 1                   ] + d * src[index + 2                   ]) +
+                      s->coeff[subV][2] * (a * src[index - 1 +     src_linesize] + b * src[index - 0 +     src_linesize]  +
+                                      c *      src[index + 1 +     src_linesize] + d * src[index + 2 +     src_linesize]) +
+                      s->coeff[subV][3] * (a * src[index - 1 + 2 * src_linesize] + b * src[index - 0 + 2 * src_linesize]  +
+                                      c *      src[index + 1 + 2 * src_linesize] + d * src[index + 2 + 2 * src_linesize]);
+            } else {
+                int dx, dy;
+
+                sum = 0;
+
+                for (dy = 0; dy < 4; dy++) {
+                    int iy = v + dy - 1;
+
+                    if (iy < 0)
+                        iy = 0;
+                    else if (iy >= h)
+                        iy = h-1;
+                    for (dx = 0; dx < 4; dx++) {
+                        int ix = u + dx - 1;
+
+                        if (ix < 0)
+                            ix = 0;
+                        else if (ix >= w)
+                            ix = w - 1;
+
+                        sum += s->coeff[subU][dx] * s->coeff[subV][dy] * src[ ix + iy * src_linesize];
+                    }
+                }
+            }
+
+            sum = (sum + (1<<(COEFF_BITS * 2 - 1))) >> (COEFF_BITS * 2);
+            sum = av_clip(sum, 0, 255);
+            dst[x + y * dst_linesize] = sum;
+        }
+    }
+}
+
+static void resample_linear(PerspectiveContext *s,
+                            uint8_t *dst, int dst_linesize,
+                            uint8_t *src, int src_linesize,
+                            int w, int h, int hsub, int vsub)
+{
+    const int linesize = s->linesize[0];
+    int x, y;
+
+    for (y = 0; y < h; y++){
+        int sy = y << vsub;
+        for (x = 0; x < w; x++){
+            int u, v, subU, subV, sum, sx, index, subUI, subVI;
+
+            sx   = x << hsub;
+            u    = s->pv[sx + sy * linesize][0] >> hsub;
+            v    = s->pv[sx + sy * linesize][1] >> vsub;
+            subU = u & (SUB_PIXELS - 1);
+            subV = v & (SUB_PIXELS - 1);
+            u  >>= SUB_PIXEL_BITS;
+            v  >>= SUB_PIXEL_BITS;
+
+            index = u + v * src_linesize;
+            subUI = SUB_PIXELS - subU;
+            subVI = SUB_PIXELS - subV;
+
+            if ((unsigned)u < (unsigned)(w - 1)){
+                if((unsigned)v < (unsigned)(h - 1)){
+                    sum = subVI * (subUI * src[index] + subU * src[index + 1]) +
+                          subV  * (subUI * src[index + src_linesize] + subU * src[index + src_linesize + 1]);
+                    sum = (sum + (1 << (SUB_PIXEL_BITS * 2 - 1)))>> (SUB_PIXEL_BITS * 2);
+                } else {
+                    if (v < 0)
+                        v = 0;
+                    else
+                        v = h - 1;
+                    index = u + v * src_linesize;
+                    sum   = subUI * src[index] + subU * src[index + 1];
+                    sum   = (sum + (1 << (SUB_PIXEL_BITS - 1))) >> SUB_PIXEL_BITS;
+                }
+            } else {
+                if (u < 0)
+                    u = 0;
+                else
+                    u = w - 1;
+                if ((unsigned)v < (unsigned)(h - 1)){
+                    index = u + v * src_linesize;
+                    sum   = subVI * src[index] + subV * src[index + src_linesize];
+                    sum   = (sum + (1 << (SUB_PIXEL_BITS - 1))) >> SUB_PIXEL_BITS;
+                } else {
+                    if (v < 0)
+                        v = 0;
+                    else
+                        v = h - 1;
+                    index = u + v * src_linesize;
+                    sum   = src[index];
+                }
+            }
+
+            sum = av_clip(sum, 0, 255);
+            dst[x + y * dst_linesize] = sum;
+        }
+    }
+}
+
+static av_cold int init(AVFilterContext *ctx)
+{
+    PerspectiveContext *s = ctx->priv;
+
+    switch (s->interpolation) {
+    case LINEAR: s->perspective = resample_linear; break;
+    case CUBIC:  s->perspective = resample_cubic;  break;
+    }
+
+    return 0;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
+{
+    AVFilterContext *ctx = inlink->dst;
+    AVFilterLink *outlink = ctx->outputs[0];
+    PerspectiveContext *s = ctx->priv;
+    AVFrame *out;
+    int plane;
+
+    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+    if (!out) {
+        av_frame_free(&frame);
+        return AVERROR(ENOMEM);
+    }
+    av_frame_copy_props(out, frame);
+
+    for (plane = 0; plane < s->nb_planes; plane++) {
+        int hsub = plane == 1 || plane == 2 ? s->hsub : 0;
+        int vsub = plane == 1 || plane == 2 ? s->vsub : 0;
+        s->perspective(s, out->data[plane], out->linesize[plane],
+                       frame->data[plane], frame->linesize[plane],
+                       s->linesize[plane], s->height[plane], hsub, vsub);
+    }
+
+    av_frame_free(&frame);
+    return ff_filter_frame(outlink, out);
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    PerspectiveContext *s = ctx->priv;
+
+    av_freep(&s->pv);
+}
+
+static const AVFilterPad perspective_inputs[] = {
+    {
+        .name             = "default",
+        .type             = AVMEDIA_TYPE_VIDEO,
+        .filter_frame     = filter_frame,
+        .config_props     = config_input,
+    },
+    { NULL }
+};
+
+static const AVFilterPad perspective_outputs[] = {
+    {
+        .name          = "default",
+        .type          = AVMEDIA_TYPE_VIDEO,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_perspective = {
+    .name          = "perspective",
+    .description   = NULL_IF_CONFIG_SMALL("Correct the perspective of video."),
+    .priv_size     = sizeof(PerspectiveContext),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+    .inputs        = perspective_inputs,
+    .outputs       = perspective_outputs,
+    .priv_class    = &perspective_class,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
+};
diff --git a/libavfilter/vf_pixdesctest.c b/libavfilter/vf_pixdesctest.c
index 42afc63..89ac7b2 100644
--- a/libavfilter/vf_pixdesctest.c
+++ b/libavfilter/vf_pixdesctest.c
@@ -46,6 +46,7 @@
 
     priv->pix_desc = av_pix_fmt_desc_get(inlink->format);
 
+    av_freep(&priv->line);
     if (!(priv->line = av_malloc(sizeof(*priv->line) * inlink->w)))
         return AVERROR(ENOMEM);
 
@@ -58,6 +59,8 @@
     AVFilterLink *outlink    = inlink->dst->outputs[0];
     AVFrame *out;
     int i, c, w = inlink->w, h = inlink->h;
+    const int cw = FF_CEIL_RSHIFT(w, priv->pix_desc->log2_chroma_w);
+    const int ch = FF_CEIL_RSHIFT(h, priv->pix_desc->log2_chroma_h);
 
     out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     if (!out) {
@@ -68,23 +71,22 @@
     av_frame_copy_props(out, in);
 
     for (i = 0; i < 4; i++) {
-        int h = outlink->h;
-        h = i == 1 || i == 2 ? h>>priv->pix_desc->log2_chroma_h : h;
+        const int h1 = i == 1 || i == 2 ? ch : h;
         if (out->data[i]) {
             uint8_t *data = out->data[i] +
-                (out->linesize[i] > 0 ? 0 : out->linesize[i] * (h-1));
-            memset(data, 0, FFABS(out->linesize[i]) * h);
+                (out->linesize[i] > 0 ? 0 : out->linesize[i] * (h1-1));
+            memset(data, 0, FFABS(out->linesize[i]) * h1);
         }
     }
 
     /* copy palette */
-    if (priv->pix_desc->flags & PIX_FMT_PAL ||
-        priv->pix_desc->flags & PIX_FMT_PSEUDOPAL)
+    if (priv->pix_desc->flags & AV_PIX_FMT_FLAG_PAL ||
+        priv->pix_desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)
         memcpy(out->data[1], in->data[1], AVPALETTE_SIZE);
 
     for (c = 0; c < priv->pix_desc->nb_components; c++) {
-        int w1 = c == 1 || c == 2 ? w>>priv->pix_desc->log2_chroma_w : w;
-        int h1 = c == 1 || c == 2 ? h>>priv->pix_desc->log2_chroma_h : h;
+        const int w1 = c == 1 || c == 2 ? cw : w;
+        const int h1 = c == 1 || c == 2 ? ch : h;
 
         for (i = 0; i < h1; i++) {
             av_read_image_line(priv->line,
diff --git a/libavfilter/vf_pp.c b/libavfilter/vf_pp.c
index 0571cfc..eebc232 100644
--- a/libavfilter/vf_pp.c
+++ b/libavfilter/vf_pp.c
@@ -125,6 +125,8 @@
         return AVERROR(ENOMEM);
     }
     av_frame_copy_props(outbuf, inbuf);
+    outbuf->width  = inbuf->width;
+    outbuf->height = inbuf->height;
     qp_table = av_frame_get_qp_table(inbuf, &qstride, &qp_type);
 
     pp_postprocess((const uint8_t **)inbuf->data, inbuf->linesize,
@@ -180,5 +182,5 @@
     .outputs         = pp_outputs,
     .process_command = pp_process_command,
     .priv_class      = &pp_class,
-    .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_psnr.c b/libavfilter/vf_psnr.c
new file mode 100644
index 0000000..6bc866f
--- /dev/null
+++ b/libavfilter/vf_psnr.c
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2011 Roger Pau Monné <roger.pau@entel.upc.edu>
+ * Copyright (c) 2011 Stefano Sabatini
+ * Copyright (c) 2013 Paul B Mahol
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * Caculate the PSNR between two input videos.
+ */
+
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "avfilter.h"
+#include "dualinput.h"
+#include "drawutils.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
+
+typedef struct PSNRContext {
+    const AVClass *class;
+    FFDualInputContext dinput;
+    double mse, min_mse, max_mse;
+    uint64_t nb_frames;
+    FILE *stats_file;
+    char *stats_file_str;
+    int max[4], average_max;
+    int is_rgb;
+    uint8_t rgba_map[4];
+    char comps[4];
+    const AVPixFmtDescriptor *desc;
+} PSNRContext;
+
+#define OFFSET(x) offsetof(PSNRContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+
+static const AVOption psnr_options[] = {
+    {"stats_file", "Set file where to store per-frame difference information", OFFSET(stats_file_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS },
+    {"f",          "Set file where to store per-frame difference information", OFFSET(stats_file_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS },
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(psnr);
+
+static inline int pow2(int base)
+{
+    return base*base;
+}
+
+static inline double get_psnr(double mse, uint64_t nb_frames, int max)
+{
+    return 10.0 * log(pow2(max) / (mse / nb_frames)) / log(10.0);
+}
+
+static inline
+void compute_images_mse(const uint8_t *main_data[4], const int main_linesizes[4],
+                        const uint8_t *ref_data[4], const int ref_linesizes[4],
+                        int w, int h, const AVPixFmtDescriptor *desc,
+                        double mse[4])
+{
+    int i, c, j;
+
+    for (c = 0; c < desc->nb_components; c++) {
+        int hsub = c == 1 || c == 2 ? desc->log2_chroma_w : 0;
+        int vsub = c == 1 || c == 2 ? desc->log2_chroma_h : 0;
+        const int outw = FF_CEIL_RSHIFT(w, hsub);
+        const int outh = FF_CEIL_RSHIFT(h, vsub);
+        const uint8_t *main_line = main_data[c];
+        const uint8_t *ref_line = ref_data[c];
+        const int ref_linesize = ref_linesizes[c];
+        const int main_linesize = main_linesizes[c];
+        int m = 0;
+
+        for (i = 0; i < outh; i++) {
+            for (j = 0; j < outw; j++)
+                m += pow2(main_line[j] - ref_line[j]);
+            ref_line += ref_linesize;
+            main_line += main_linesize;
+        }
+        mse[c] = m / (outw * outh);
+    }
+}
+
+static void set_meta(AVDictionary **metadata, const char *key, char comp, float d)
+{
+    char value[128];
+    snprintf(value, sizeof(value), "%0.2f", d);
+    if (comp) {
+        char key2[128];
+        snprintf(key2, sizeof(key2), "%s%c", key, comp);
+        av_dict_set(metadata, key2, value, 0);
+    } else {
+        av_dict_set(metadata, key, value, 0);
+    }
+}
+
+static AVFrame *do_psnr(AVFilterContext *ctx, AVFrame *main,
+                        const AVFrame *ref)
+{
+    PSNRContext *s = ctx->priv;
+    double comp_mse[4], mse = 0;
+    int j, c;
+    AVDictionary **metadata = avpriv_frame_get_metadatap(main);
+
+    compute_images_mse((const uint8_t **)main->data, main->linesize,
+                       (const uint8_t **)ref->data, ref->linesize,
+                       main->width, main->height, s->desc, comp_mse);
+
+    for (j = 0; j < s->desc->nb_components; j++)
+        mse += comp_mse[j];
+    mse /= s->desc->nb_components;
+
+    s->min_mse = FFMIN(s->min_mse, mse);
+    s->max_mse = FFMAX(s->max_mse, mse);
+
+    s->mse += mse;
+    s->nb_frames++;
+
+    for (j = 0; j < s->desc->nb_components; j++) {
+        c = s->is_rgb ? s->rgba_map[j] : j;
+        set_meta(metadata, "lavfi.psnr.mse.", s->comps[j], comp_mse[c]);
+        set_meta(metadata, "lavfi.psnr.mse_avg", 0, mse);
+        set_meta(metadata, "lavfi.psnr.psnr.", s->comps[j], get_psnr(comp_mse[c], 1, s->max[c]));
+        set_meta(metadata, "lavfi.psnr.psnr_avg", 0, get_psnr(mse, 1, s->average_max));
+    }
+
+    if (s->stats_file) {
+        fprintf(s->stats_file, "n:%"PRId64" mse_avg:%0.2f ", s->nb_frames, mse);
+        for (j = 0; j < s->desc->nb_components; j++) {
+            c = s->is_rgb ? s->rgba_map[j] : j;
+            fprintf(s->stats_file, "mse_%c:%0.2f ", s->comps[j], comp_mse[c]);
+        }
+        for (j = 0; j < s->desc->nb_components; j++) {
+            c = s->is_rgb ? s->rgba_map[j] : j;
+            fprintf(s->stats_file, "psnr_%c:%0.2f ", s->comps[j],
+                    get_psnr(comp_mse[c], 1, s->max[c]));
+        }
+        fprintf(s->stats_file, "\n");
+    }
+
+    return main;
+}
+
+static av_cold int init(AVFilterContext *ctx)
+{
+    PSNRContext *s = ctx->priv;
+
+    s->min_mse = +INFINITY;
+    s->max_mse = -INFINITY;
+
+    if (s->stats_file_str) {
+        s->stats_file = fopen(s->stats_file_str, "w");
+        if (!s->stats_file) {
+            int err = AVERROR(errno);
+            char buf[128];
+            av_strerror(err, buf, sizeof(buf));
+            av_log(ctx, AV_LOG_ERROR, "Could not open stats file %s: %s\n",
+                   s->stats_file_str, buf);
+            return err;
+        }
+    }
+
+    s->dinput.process = do_psnr;
+    return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum PixelFormat pix_fmts[] = {
+        AV_PIX_FMT_GRAY8,
+        AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP,
+        AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV422P,
+        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P,
+        AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ422P,
+        AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ411P,
+        AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P,
+        AV_PIX_FMT_NONE
+    };
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+static int config_input_ref(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx  = inlink->dst;
+    PSNRContext *s = ctx->priv;
+    int j;
+
+    s->desc = av_pix_fmt_desc_get(inlink->format);
+    if (ctx->inputs[0]->w != ctx->inputs[1]->w ||
+        ctx->inputs[0]->h != ctx->inputs[1]->h) {
+        av_log(ctx, AV_LOG_ERROR, "Width and heigth of input videos must be same.\n");
+        return AVERROR(EINVAL);
+    }
+    if (ctx->inputs[0]->format != ctx->inputs[1]->format) {
+        av_log(ctx, AV_LOG_ERROR, "Inputs must be of same pixel format.\n");
+        return AVERROR(EINVAL);
+    }
+
+    switch (inlink->format) {
+    case AV_PIX_FMT_YUV410P:
+    case AV_PIX_FMT_YUV411P:
+    case AV_PIX_FMT_YUV420P:
+    case AV_PIX_FMT_YUV422P:
+    case AV_PIX_FMT_YUV440P:
+    case AV_PIX_FMT_YUV444P:
+    case AV_PIX_FMT_YUVA420P:
+    case AV_PIX_FMT_YUVA422P:
+    case AV_PIX_FMT_YUVA444P:
+        s->max[0] = 235;
+        s->max[3] = 255;
+        s->max[1] = s->max[2] = 240;
+        break;
+    default:
+        s->max[0] = s->max[1] = s->max[2] = s->max[3] = 255;
+    }
+
+    s->is_rgb = ff_fill_rgba_map(s->rgba_map, inlink->format) >= 0;
+    s->comps[0] = s->is_rgb ? 'r' : 'y' ;
+    s->comps[1] = s->is_rgb ? 'g' : 'u' ;
+    s->comps[2] = s->is_rgb ? 'b' : 'v' ;
+    s->comps[3] = 'a';
+
+    for (j = 0; j < s->desc->nb_components; j++)
+        s->average_max += s->max[j];
+    s->average_max /= s->desc->nb_components;
+
+    return 0;
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    AVFilterLink *mainlink = ctx->inputs[0];
+
+    outlink->w = mainlink->w;
+    outlink->h = mainlink->h;
+    outlink->time_base = mainlink->time_base;
+    outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio;
+    outlink->frame_rate = mainlink->frame_rate;
+
+    return 0;
+}
+
+static int filter_frame_main(AVFilterLink *inlink, AVFrame *inpicref)
+{
+    PSNRContext *s = inlink->dst->priv;
+    return ff_dualinput_filter_frame_main(&s->dinput, inlink, inpicref);
+}
+
+static int filter_frame_ref(AVFilterLink *inlink, AVFrame *inpicref)
+{
+    PSNRContext *s = inlink->dst->priv;
+    return ff_dualinput_filter_frame_second(&s->dinput, inlink, inpicref);
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    PSNRContext *s = outlink->src->priv;
+    return ff_dualinput_request_frame(&s->dinput, outlink);
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    PSNRContext *s = ctx->priv;
+
+    if (s->nb_frames > 0) {
+        av_log(ctx, AV_LOG_INFO, "PSNR average:%0.2f min:%0.2f max:%0.2f\n",
+               get_psnr(s->mse, s->nb_frames, s->average_max),
+               get_psnr(s->max_mse, 1, s->average_max),
+               get_psnr(s->min_mse, 1, s->average_max));
+    }
+
+    ff_dualinput_uninit(&s->dinput);
+
+    if (s->stats_file)
+        fclose(s->stats_file);
+}
+
+static const AVFilterPad psnr_inputs[] = {
+    {
+        .name             = "main",
+        .type             = AVMEDIA_TYPE_VIDEO,
+        .filter_frame     = filter_frame_main,
+    },{
+        .name             = "reference",
+        .type             = AVMEDIA_TYPE_VIDEO,
+        .filter_frame     = filter_frame_ref,
+        .config_props     = config_input_ref,
+    },
+    { NULL }
+};
+
+static const AVFilterPad psnr_outputs[] = {
+    {
+        .name          = "default",
+        .type          = AVMEDIA_TYPE_VIDEO,
+        .config_props  = config_output,
+        .request_frame = request_frame,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_psnr = {
+    .name           = "psnr",
+    .description    = NULL_IF_CONFIG_SMALL("Calculate the PSNR between two video streams."),
+    .init           = init,
+    .uninit         = uninit,
+    .query_formats  = query_formats,
+    .priv_size      = sizeof(PSNRContext),
+    .priv_class     = &psnr_class,
+    .inputs         = psnr_inputs,
+    .outputs        = psnr_outputs,
+};
diff --git a/libavfilter/vf_removelogo.c b/libavfilter/vf_removelogo.c
index dfc75d1..2b385fc 100644
--- a/libavfilter/vf_removelogo.c
+++ b/libavfilter/vf_removelogo.c
@@ -527,7 +527,7 @@
     return ff_filter_frame(outlink, outpicref);
 }
 
-static void uninit(AVFilterContext *ctx)
+static av_cold void uninit(AVFilterContext *ctx)
 {
     RemovelogoContext *removelogo = ctx->priv;
     int a, b;
@@ -578,5 +578,5 @@
     .inputs        = removelogo_inputs,
     .outputs       = removelogo_outputs,
     .priv_class    = &removelogo_class,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_rotate.c b/libavfilter/vf_rotate.c
new file mode 100644
index 0000000..b967d76
--- /dev/null
+++ b/libavfilter/vf_rotate.c
@@ -0,0 +1,456 @@
+/*
+ * Copyright (c) 2013 Stefano Sabatini
+ * Copyright (c) 2008 Vitor Sessak
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * rotation filter, partially based on the tests/rotozoom.c program
+*/
+
+#include "libavutil/avstring.h"
+#include "libavutil/eval.h"
+#include "libavutil/opt.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/pixdesc.h"
+
+#include "avfilter.h"
+#include "drawutils.h"
+#include "internal.h"
+#include "video.h"
+
+static const char *var_names[] = {
+    "in_w" , "iw",  ///< width of the input video
+    "in_h" , "ih",  ///< height of the input video
+    "out_w", "ow",  ///< width of the input video
+    "out_h", "oh",  ///< height of the input video
+    "hsub", "vsub",
+    "n",            ///< number of frame
+    "t",            ///< timestamp expressed in seconds
+    NULL
+};
+
+enum var_name {
+    VAR_IN_W , VAR_IW,
+    VAR_IN_H , VAR_IH,
+    VAR_OUT_W, VAR_OW,
+    VAR_OUT_H, VAR_OH,
+    VAR_HSUB, VAR_VSUB,
+    VAR_N,
+    VAR_T,
+    VAR_VARS_NB
+};
+
+typedef struct {
+    const AVClass *class;
+    double angle;
+    char *angle_expr_str;   ///< expression for the angle
+    AVExpr *angle_expr;     ///< parsed expression for the angle
+    char *outw_expr_str, *outh_expr_str;
+    int outh, outw;
+    uint8_t fillcolor[4];   ///< color expressed either in YUVA or RGBA colorspace for the padding area
+    char *fillcolor_str;
+    int fillcolor_enable;
+    int hsub, vsub;
+    int nb_planes;
+    int use_bilinear;
+    float sinx, cosx;
+    double var_values[VAR_VARS_NB];
+    FFDrawContext draw;
+    FFDrawColor color;
+} RotContext;
+
+#define OFFSET(x) offsetof(RotContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+
+static const AVOption rotate_options[] = {
+    { "angle",     "set angle (in radians)",       OFFSET(angle_expr_str), AV_OPT_TYPE_STRING, {.str="0"}, CHAR_MIN, CHAR_MAX, .flags=FLAGS },
+    { "a",         "set angle (in radians)",       OFFSET(angle_expr_str), AV_OPT_TYPE_STRING, {.str="0"}, CHAR_MIN, CHAR_MAX, .flags=FLAGS },
+    { "out_w",     "set output width expression",  OFFSET(outw_expr_str), AV_OPT_TYPE_STRING, {.str="iw"}, CHAR_MIN, CHAR_MAX, .flags=FLAGS },
+    { "ow",        "set output width expression",  OFFSET(outw_expr_str), AV_OPT_TYPE_STRING, {.str="iw"}, CHAR_MIN, CHAR_MAX, .flags=FLAGS },
+    { "out_h",     "set output height expression", OFFSET(outh_expr_str), AV_OPT_TYPE_STRING, {.str="ih"}, CHAR_MIN, CHAR_MAX, .flags=FLAGS },
+    { "oh",        "set output width expression",  OFFSET(outh_expr_str), AV_OPT_TYPE_STRING, {.str="ih"}, CHAR_MIN, CHAR_MAX, .flags=FLAGS },
+    { "fillcolor", "set background fill color",    OFFSET(fillcolor_str), AV_OPT_TYPE_STRING, {.str="black"}, CHAR_MIN, CHAR_MAX, .flags=FLAGS },
+    { "c",         "set background fill color",    OFFSET(fillcolor_str), AV_OPT_TYPE_STRING, {.str="black"}, CHAR_MIN, CHAR_MAX, .flags=FLAGS },
+    { "bilinear",  "use bilinear interpolation",   OFFSET(use_bilinear),  AV_OPT_TYPE_INT, {.i64=1}, 0, 1, .flags=FLAGS },
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(rotate);
+
+static av_cold int init(AVFilterContext *ctx)
+{
+    RotContext *rot = ctx->priv;
+
+    if (!strcmp(rot->fillcolor_str, "none"))
+        rot->fillcolor_enable = 0;
+    else if (av_parse_color(rot->fillcolor, rot->fillcolor_str, -1, ctx) >= 0)
+        rot->fillcolor_enable = 1;
+    else
+        return AVERROR(EINVAL);
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    RotContext *rot = ctx->priv;
+
+    av_expr_free(rot->angle_expr);
+    rot->angle_expr = NULL;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static enum PixelFormat pix_fmts[] = {
+        AV_PIX_FMT_GBRP,   AV_PIX_FMT_GBRAP,
+        AV_PIX_FMT_ARGB,   AV_PIX_FMT_RGBA,
+        AV_PIX_FMT_ABGR,   AV_PIX_FMT_BGRA,
+        AV_PIX_FMT_0RGB,   AV_PIX_FMT_RGB0,
+        AV_PIX_FMT_0BGR,   AV_PIX_FMT_BGR0,
+        AV_PIX_FMT_RGB24,  AV_PIX_FMT_BGR24,
+        AV_PIX_FMT_GRAY8,
+        AV_PIX_FMT_YUV410P,
+        AV_PIX_FMT_YUV444P,  AV_PIX_FMT_YUVJ444P,
+        AV_PIX_FMT_YUV420P,  AV_PIX_FMT_YUVJ420P,
+        AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA420P,
+        AV_PIX_FMT_NONE
+    };
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+static double get_rotated_w(void *opaque, double angle)
+{
+    RotContext *rot = opaque;
+    double inw = rot->var_values[VAR_IN_W];
+    double inh = rot->var_values[VAR_IN_H];
+    float sinx = sin(angle);
+    float cosx = cos(angle);
+
+    return FFMAX(0, inh * sinx) + FFMAX(0, -inw * cosx) +
+           FFMAX(0, inw * cosx) + FFMAX(0, -inh * sinx);
+}
+
+static double get_rotated_h(void *opaque, double angle)
+{
+    RotContext *rot = opaque;
+    double inw = rot->var_values[VAR_IN_W];
+    double inh = rot->var_values[VAR_IN_H];
+    float sinx = sin(angle);
+    float cosx = cos(angle);
+
+    return FFMAX(0, -inh * cosx) + FFMAX(0, -inw * sinx) +
+           FFMAX(0,  inh * cosx) + FFMAX(0,  inw * sinx);
+}
+
+static double (* const func1[])(void *, double) = {
+    get_rotated_w,
+    get_rotated_h,
+    NULL
+};
+
+static const char * const func1_names[] = {
+    "rotw",
+    "roth",
+    NULL
+};
+
+static int config_props(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    RotContext *rot = ctx->priv;
+    AVFilterLink *inlink = ctx->inputs[0];
+    const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(inlink->format);
+    int ret;
+    double res;
+    char *expr;
+
+    ff_draw_init(&rot->draw, inlink->format, 0);
+    ff_draw_color(&rot->draw, &rot->color, rot->fillcolor);
+
+    rot->hsub = pixdesc->log2_chroma_w;
+    rot->vsub = pixdesc->log2_chroma_h;
+
+    rot->var_values[VAR_IN_W] = rot->var_values[VAR_IW] = inlink->w;
+    rot->var_values[VAR_IN_H] = rot->var_values[VAR_IH] = inlink->h;
+    rot->var_values[VAR_HSUB] = 1<<rot->hsub;
+    rot->var_values[VAR_VSUB] = 1<<rot->vsub;
+    rot->var_values[VAR_N] = NAN;
+    rot->var_values[VAR_T] = NAN;
+    rot->var_values[VAR_OUT_W] = rot->var_values[VAR_OW] = NAN;
+    rot->var_values[VAR_OUT_H] = rot->var_values[VAR_OH] = NAN;
+
+    av_expr_free(rot->angle_expr);
+    rot->angle_expr = NULL;
+    if ((ret = av_expr_parse(&rot->angle_expr, expr = rot->angle_expr_str, var_names,
+                             func1_names, func1, NULL, NULL, 0, ctx)) < 0) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Error occurred parsing angle expression '%s'\n", rot->angle_expr_str);
+        return ret;
+    }
+
+#define SET_SIZE_EXPR(name, opt_name) do {                                         \
+    ret = av_expr_parse_and_eval(&res, expr = rot->name##_expr_str,                \
+                                 var_names, rot->var_values,                       \
+                                 func1_names, func1, NULL, NULL, rot, 0, ctx);     \
+    if (ret < 0 || isnan(res) || isinf(res) || res <= 0) {                         \
+        av_log(ctx, AV_LOG_ERROR,                                                  \
+               "Error parsing or evaluating expression for option %s: "            \
+               "invalid expression '%s' or non-positive or indefinite value %f\n", \
+               opt_name, expr, res);                                               \
+        return ret;                                                                \
+    }                                                                              \
+} while (0)
+
+    /* evaluate width and height */
+    av_expr_parse_and_eval(&res, expr = rot->outw_expr_str, var_names, rot->var_values,
+                           func1_names, func1, NULL, NULL, rot, 0, ctx);
+    rot->var_values[VAR_OUT_W] = rot->var_values[VAR_OW] = res;
+    rot->outw = res + 0.5;
+    SET_SIZE_EXPR(outh, "out_w");
+    rot->var_values[VAR_OUT_H] = rot->var_values[VAR_OH] = res;
+    rot->outh = res + 0.5;
+
+    /* evaluate the width again, as it may depend on the evaluated output height */
+    SET_SIZE_EXPR(outw, "out_h");
+    rot->var_values[VAR_OUT_W] = rot->var_values[VAR_OW] = res;
+    rot->outw = res + 0.5;
+
+    /* compute number of planes */
+    rot->nb_planes = av_pix_fmt_count_planes(inlink->format);
+    outlink->w = rot->outw;
+    outlink->h = rot->outh;
+    return 0;
+}
+
+#define FIXP (1<<16)
+#define INT_PI 205887 //(M_PI * FIXP)
+
+/**
+ * Compute the sin of a using integer values.
+ * Input and output values are scaled by FIXP.
+ */
+static int64_t int_sin(int64_t a)
+{
+    int64_t a2, res = 0;
+    int i;
+    if (a < 0) a = INT_PI-a; // 0..inf
+    a %= 2 * INT_PI;         // 0..2PI
+
+    if (a >= INT_PI*3/2) a -= 2*INT_PI;  // -PI/2 .. 3PI/2
+    if (a >= INT_PI/2  ) a = INT_PI - a; // -PI/2 ..  PI/2
+
+    /* compute sin using Taylor series approximated to the third term */
+    a2 = (a*a)/FIXP;
+    for (i = 2; i < 7; i += 2) {
+        res += a;
+        a = -a*a2 / (FIXP*i*(i+1));
+    }
+    return res;
+}
+
+/**
+ * Interpolate the color in src at position x and y using bilinear
+ * interpolation.
+ */
+static uint8_t *interpolate_bilinear(uint8_t *dst_color,
+                                     const uint8_t *src, int src_linesize, int src_linestep,
+                                     int x, int y, int max_x, int max_y)
+{
+    int int_x = av_clip(x>>16, 0, max_x);
+    int int_y = av_clip(y>>16, 0, max_y);
+    int frac_x = x&0xFFFF;
+    int frac_y = y&0xFFFF;
+    int i;
+    int int_x1 = FFMIN(int_x+1, max_x);
+    int int_y1 = FFMIN(int_y+1, max_y);
+
+    for (i = 0; i < src_linestep; i++) {
+        int s00 = src[src_linestep * int_x  + i + src_linesize * int_y ];
+        int s01 = src[src_linestep * int_x1 + i + src_linesize * int_y ];
+        int s10 = src[src_linestep * int_x  + i + src_linesize * int_y1];
+        int s11 = src[src_linestep * int_x1 + i + src_linesize * int_y1];
+        int s0 = (((1<<16) - frac_x)*s00 + frac_x*s01);
+        int s1 = (((1<<16) - frac_x)*s10 + frac_x*s11);
+
+        dst_color[i] = ((int64_t)((1<<16) - frac_y)*s0 + (int64_t)frac_y*s1) >> 32;
+    }
+
+    return dst_color;
+}
+
+#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb))
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+{
+    AVFilterContext *ctx = inlink->dst;
+    AVFilterLink *outlink = ctx->outputs[0];
+    AVFrame *out;
+    RotContext *rot = ctx->priv;
+    int angle_int, s, c, plane;
+    double res;
+
+    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+    if (!out) {
+        av_frame_free(&in);
+        return AVERROR(ENOMEM);
+    }
+    av_frame_copy_props(out, in);
+
+    rot->var_values[VAR_N] = inlink->frame_count;
+    rot->var_values[VAR_T] = TS2T(in->pts, inlink->time_base);
+    rot->angle = res = av_expr_eval(rot->angle_expr, rot->var_values, rot);
+
+    av_log(ctx, AV_LOG_DEBUG, "n:%f time:%f angle:%f/PI\n",
+           rot->var_values[VAR_N], rot->var_values[VAR_T], rot->angle/M_PI);
+
+    angle_int = res * FIXP;
+    s = int_sin(angle_int);
+    c = int_sin(angle_int + INT_PI/2);
+
+    /* fill background */
+    if (rot->fillcolor_enable)
+        ff_fill_rectangle(&rot->draw, &rot->color, out->data, out->linesize,
+                          0, 0, outlink->w, outlink->h);
+
+    for (plane = 0; plane < rot->nb_planes; plane++) {
+        int hsub = plane == 1 || plane == 2 ? rot->hsub : 0;
+        int vsub = plane == 1 || plane == 2 ? rot->vsub : 0;
+        int inw  = FF_CEIL_RSHIFT(inlink->w, hsub);
+        int inh  = FF_CEIL_RSHIFT(inlink->h, vsub);
+        int outw = FF_CEIL_RSHIFT(outlink->w, hsub);
+        int outh = FF_CEIL_RSHIFT(outlink->h, hsub);
+
+        const int xi = -outw/2 * c;
+        const int yi =  outw/2 * s;
+        int xprime = -outh/2 * s;
+        int yprime = -outh/2 * c;
+        int i, j, x, y;
+
+        for (j = 0; j < outh; j++) {
+            x = xprime + xi + FIXP*inw/2;
+            y = yprime + yi + FIXP*inh/2;
+
+            for (i = 0; i < outw; i++) {
+                int32_t v;
+                int x1, y1;
+                uint8_t *pin, *pout;
+                x += c;
+                y -= s;
+                x1 = x>>16;
+                y1 = y>>16;
+
+                /* the out-of-range values avoid border artifacts */
+                if (x1 >= -1 && x1 <= inw && y1 >= -1 && y1 <= inh) {
+                    uint8_t inp_inv[4]; /* interpolated input value */
+                    pout = out->data[plane] + j * out->linesize[plane] + i * rot->draw.pixelstep[plane];
+                    if (rot->use_bilinear) {
+                        pin = interpolate_bilinear(inp_inv,
+                                                   in->data[plane], in->linesize[plane], rot->draw.pixelstep[plane],
+                                                   x, y, inw-1, inh-1);
+                    } else {
+                        int x2 = av_clip(x1, 0, inw-1);
+                        int y2 = av_clip(y1, 0, inh-1);
+                        pin = in->data[plane] + y2 * in->linesize[plane] + x2 * rot->draw.pixelstep[plane];
+                    }
+                    switch (rot->draw.pixelstep[plane]) {
+                    case 1:
+                        *pout = *pin;
+                        break;
+                    case 2:
+                        *((uint16_t *)pout) = *((uint16_t *)pin);
+                        break;
+                    case 3:
+                        v = AV_RB24(pin);
+                        AV_WB24(pout, v);
+                        break;
+                    case 4:
+                        *((uint32_t *)pout) = *((uint32_t *)pin);
+                        break;
+                    default:
+                        memcpy(pout, pin, rot->draw.pixelstep[plane]);
+                        break;
+                    }
+                }
+            }
+            xprime += s;
+            yprime += c;
+        }
+    }
+
+    av_frame_free(&in);
+    return ff_filter_frame(outlink, out);
+}
+
+static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
+                           char *res, int res_len, int flags)
+{
+    RotContext *rot = ctx->priv;
+    int ret;
+
+    if (!strcmp(cmd, "angle") || !strcmp(cmd, "a")) {
+        AVExpr *old = rot->angle_expr;
+        ret = av_expr_parse(&rot->angle_expr, args, var_names,
+                            NULL, NULL, NULL, NULL, 0, ctx);
+        if (ret < 0) {
+            av_log(ctx, AV_LOG_ERROR,
+                   "Error when parsing the expression '%s' for angle command\n", args);
+            rot->angle_expr = old;
+            return ret;
+        }
+        av_expr_free(old);
+    } else
+        ret = AVERROR(ENOSYS);
+
+    return ret;
+}
+
+static const AVFilterPad rotate_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = filter_frame,
+    },
+    { NULL }
+};
+
+static const AVFilterPad rotate_outputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .config_props = config_props,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_rotate = {
+    .name          = "rotate",
+    .description   = NULL_IF_CONFIG_SMALL("Rotate the input image."),
+    .priv_size     = sizeof(RotContext),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+    .process_command = process_command,
+    .inputs        = rotate_inputs,
+    .outputs       = rotate_outputs,
+    .priv_class    = &rotate_class,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
+};
diff --git a/libavfilter/vf_sab.c b/libavfilter/vf_sab.c
new file mode 100644
index 0000000..1d970fa
--- /dev/null
+++ b/libavfilter/vf_sab.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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.
+ */
+
+/**
+ * @file
+ * Shape Adaptive Blur filter, ported from MPlayer libmpcodecs/vf_sab.c
+ */
+
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "libswscale/swscale.h"
+
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+
+typedef struct {
+    float radius;
+    float pre_filter_radius;
+    float strength;
+    float quality;
+    struct SwsContext *pre_filter_context;
+    uint8_t *pre_filter_buf;
+    int pre_filter_linesize;
+    int dist_width;
+    int dist_linesize;
+    int *dist_coeff;
+#define COLOR_DIFF_COEFF_SIZE 512
+    int color_diff_coeff[COLOR_DIFF_COEFF_SIZE];
+} FilterParam;
+
+typedef struct {
+    const AVClass *class;
+    FilterParam  luma;
+    FilterParam  chroma;
+    int          hsub;
+    int          vsub;
+    unsigned int sws_flags;
+} SabContext;
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat pix_fmts[] = {
+        AV_PIX_FMT_YUV420P,
+        AV_PIX_FMT_YUV410P,
+        AV_PIX_FMT_YUV444P,
+        AV_PIX_FMT_YUV422P,
+        AV_PIX_FMT_YUV411P,
+        AV_PIX_FMT_NONE
+    };
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+
+    return 0;
+}
+
+#define RADIUS_MIN 0.1
+#define RADIUS_MAX 4.0
+
+#define PRE_FILTER_RADIUS_MIN 0.1
+#define PRE_FILTER_RADIUS_MAX 2.0
+
+#define STRENGTH_MIN 0.1
+#define STRENGTH_MAX 100.0
+
+#define OFFSET(x) offsetof(SabContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+
+static const AVOption sab_options[] = {
+    { "luma_radius",            "set luma radius", OFFSET(luma.radius), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, RADIUS_MIN, RADIUS_MAX, .flags=FLAGS },
+    { "lr"         ,            "set luma radius", OFFSET(luma.radius), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, RADIUS_MIN, RADIUS_MAX, .flags=FLAGS },
+    { "luma_pre_filter_radius", "set luma pre-filter radius", OFFSET(luma.pre_filter_radius), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, PRE_FILTER_RADIUS_MIN, PRE_FILTER_RADIUS_MAX, .flags=FLAGS },
+    { "lpfr",                   "set luma pre-filter radius", OFFSET(luma.pre_filter_radius), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, PRE_FILTER_RADIUS_MIN, PRE_FILTER_RADIUS_MAX, .flags=FLAGS },
+    { "luma_strength",          "set luma strength", OFFSET(luma.strength), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, STRENGTH_MIN, STRENGTH_MAX, .flags=FLAGS },
+    { "ls",                     "set luma strength", OFFSET(luma.strength), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, STRENGTH_MIN, STRENGTH_MAX, .flags=FLAGS },
+
+    { "chroma_radius",            "set chroma radius", OFFSET(chroma.radius), AV_OPT_TYPE_FLOAT, {.dbl=RADIUS_MIN-1}, RADIUS_MIN-1, RADIUS_MAX, .flags=FLAGS },
+    { "cr",                       "set chroma radius", OFFSET(chroma.radius), AV_OPT_TYPE_FLOAT, {.dbl=RADIUS_MIN-1}, RADIUS_MIN-1, RADIUS_MAX, .flags=FLAGS },
+    { "chroma_pre_filter_radius", "set chroma pre-filter radius",  OFFSET(chroma.pre_filter_radius), AV_OPT_TYPE_FLOAT, {.dbl=PRE_FILTER_RADIUS_MIN-1},
+                                  PRE_FILTER_RADIUS_MIN-1, PRE_FILTER_RADIUS_MAX, .flags=FLAGS },
+    { "cpfr",                     "set chroma pre-filter radius",  OFFSET(chroma.pre_filter_radius), AV_OPT_TYPE_FLOAT, {.dbl=PRE_FILTER_RADIUS_MIN-1},
+                                  PRE_FILTER_RADIUS_MIN-1, PRE_FILTER_RADIUS_MAX, .flags=FLAGS },
+    { "chroma_strength",          "set chroma strength", OFFSET(chroma.strength), AV_OPT_TYPE_FLOAT, {.dbl=STRENGTH_MIN-1}, STRENGTH_MIN-1, STRENGTH_MAX, .flags=FLAGS },
+    { "cs",                       "set chroma strength", OFFSET(chroma.strength), AV_OPT_TYPE_FLOAT, {.dbl=STRENGTH_MIN-1}, STRENGTH_MIN-1, STRENGTH_MAX, .flags=FLAGS },
+
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(sab);
+
+static av_cold int init(AVFilterContext *ctx)
+{
+    SabContext *sab = ctx->priv;
+
+    /* make chroma default to luma values, if not explicitly set */
+    if (sab->chroma.radius < RADIUS_MIN)
+        sab->chroma.radius = sab->luma.radius;
+    if (sab->chroma.pre_filter_radius < PRE_FILTER_RADIUS_MIN)
+        sab->chroma.pre_filter_radius = sab->luma.pre_filter_radius;
+    if (sab->chroma.strength < STRENGTH_MIN)
+        sab->chroma.strength = sab->luma.strength;
+
+    sab->luma.quality = sab->chroma.quality = 3.0;
+    sab->sws_flags = SWS_POINT;
+
+    av_log(ctx, AV_LOG_VERBOSE,
+           "luma_radius:%f luma_pre_filter_radius::%f luma_strength:%f "
+           "chroma_radius:%f chroma_pre_filter_radius:%f chroma_strength:%f\n",
+           sab->luma  .radius, sab->luma  .pre_filter_radius, sab->luma  .strength,
+           sab->chroma.radius, sab->chroma.pre_filter_radius, sab->chroma.strength);
+    return 0;
+}
+
+static void close_filter_param(FilterParam *f)
+{
+    if (f->pre_filter_context) {
+        sws_freeContext(f->pre_filter_context);
+        f->pre_filter_context = NULL;
+    }
+    av_freep(&f->pre_filter_buf);
+    av_freep(&f->dist_coeff);
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    SabContext *sab = ctx->priv;
+
+    close_filter_param(&sab->luma);
+    close_filter_param(&sab->chroma);
+}
+
+static int open_filter_param(FilterParam *f, int width, int height, unsigned int sws_flags)
+{
+    SwsVector *vec;
+    SwsFilter sws_f;
+    int i, x, y;
+    int linesize = FFALIGN(width, 8);
+
+    f->pre_filter_buf = av_malloc(linesize * height);
+    if (!f->pre_filter_buf)
+        return AVERROR(ENOMEM);
+
+    f->pre_filter_linesize = linesize;
+    vec = sws_getGaussianVec(f->pre_filter_radius, f->quality);
+    sws_f.lumH = sws_f.lumV = vec;
+    sws_f.chrH = sws_f.chrV = NULL;
+    f->pre_filter_context = sws_getContext(width, height, AV_PIX_FMT_GRAY8,
+                                           width, height, AV_PIX_FMT_GRAY8,
+                                           sws_flags, &sws_f, NULL, NULL);
+    sws_freeVec(vec);
+
+    vec = sws_getGaussianVec(f->strength, 5.0);
+    for (i = 0; i < COLOR_DIFF_COEFF_SIZE; i++) {
+        double d;
+        int index = i-COLOR_DIFF_COEFF_SIZE/2 + vec->length/2;
+
+        if (index < 0 || index >= vec->length) d = 0.0;
+        else                                   d = vec->coeff[index];
+
+        f->color_diff_coeff[i] = (int)(d/vec->coeff[vec->length/2]*(1<<12) + 0.5);
+    }
+    sws_freeVec(vec);
+
+    vec = sws_getGaussianVec(f->radius, f->quality);
+    f->dist_width    = vec->length;
+    f->dist_linesize = FFALIGN(vec->length, 8);
+    f->dist_coeff    = av_malloc(f->dist_width * f->dist_linesize * sizeof(*f->dist_coeff));
+    if (!f->dist_coeff) {
+        sws_freeVec(vec);
+        return AVERROR(ENOMEM);
+    }
+
+    for (y = 0; y < vec->length; y++) {
+        for (x = 0; x < vec->length; x++) {
+            double d = vec->coeff[x] * vec->coeff[y];
+            f->dist_coeff[x + y*f->dist_linesize] = (int)(d*(1<<10) + 0.5);
+        }
+    }
+    sws_freeVec(vec);
+
+    return 0;
+}
+
+static int config_props(AVFilterLink *inlink)
+{
+    SabContext *sab = inlink->dst->priv;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+    int ret;
+
+    sab->hsub = desc->log2_chroma_w;
+    sab->vsub = desc->log2_chroma_h;
+
+    close_filter_param(&sab->luma);
+    ret = open_filter_param(&sab->luma, inlink->w, inlink->h, sab->sws_flags);
+    if (ret < 0)
+        return ret;
+
+    close_filter_param(&sab->chroma);
+    ret = open_filter_param(&sab->chroma,
+                            FF_CEIL_RSHIFT(inlink->w, sab->hsub),
+                            FF_CEIL_RSHIFT(inlink->h, sab->vsub), sab->sws_flags);
+    return ret;
+}
+
+#define NB_PLANES 4
+
+static void blur(uint8_t       *dst, const int dst_linesize,
+                 const uint8_t *src, const int src_linesize,
+                 const int w, const int h, FilterParam *fp)
+{
+    int x, y;
+    FilterParam f = *fp;
+    const int radius = f.dist_width/2;
+
+    const uint8_t * const src2[NB_PLANES] = { src };
+    int          src2_linesize[NB_PLANES] = { src_linesize };
+    uint8_t     *dst2[NB_PLANES] = { f.pre_filter_buf };
+    int dst2_linesize[NB_PLANES] = { f.pre_filter_linesize };
+
+    sws_scale(f.pre_filter_context, src2, src2_linesize, 0, h, dst2, dst2_linesize);
+
+#define UPDATE_FACTOR do {                                              \
+        int factor;                                                     \
+        factor = f.color_diff_coeff[COLOR_DIFF_COEFF_SIZE/2 + pre_val - \
+                 f.pre_filter_buf[ix + iy*f.pre_filter_linesize]] * f.dist_coeff[dx + dy*f.dist_linesize]; \
+        sum += src[ix + iy*src_linesize] * factor;                      \
+        div += factor;                                                  \
+    } while (0)
+
+    for (y = 0; y < h; y++) {
+        for (x = 0; x < w; x++) {
+            int sum = 0;
+            int div = 0;
+            int dy;
+            const int pre_val = f.pre_filter_buf[x + y*f.pre_filter_linesize];
+            if (x >= radius && x < w - radius) {
+                for (dy = 0; dy < radius*2 + 1; dy++) {
+                    int dx;
+                    int iy = y+dy - radius;
+                    if      (iy < 0)  iy = -iy;
+                    else if (iy >= h) iy = h+h-iy-1;
+
+                    for (dx = 0; dx < radius*2 + 1; dx++) {
+                        const int ix = x+dx - radius;
+                        UPDATE_FACTOR;
+                    }
+                }
+            } else {
+                for (dy = 0; dy < radius*2+1; dy++) {
+                    int dx;
+                    int iy = y+dy - radius;
+                    if      (iy <  0) iy = -iy;
+                    else if (iy >= h) iy = h+h-iy-1;
+
+                    for (dx = 0; dx < radius*2 + 1; dx++) {
+                        int ix = x+dx - radius;
+                        if      (ix < 0)  ix = -ix;
+                        else if (ix >= w) ix = w+w-ix-1;
+                        UPDATE_FACTOR;
+                    }
+                }
+            }
+            dst[x + y*dst_linesize] = (sum + div/2) / div;
+        }
+    }
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *inpic)
+{
+    SabContext  *sab = inlink->dst->priv;
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+    AVFrame *outpic;
+
+    outpic = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+    if (!outpic) {
+        av_frame_free(&inpic);
+        return AVERROR(ENOMEM);
+    }
+    av_frame_copy_props(outpic, inpic);
+
+    blur(outpic->data[0], outpic->linesize[0], inpic->data[0],  inpic->linesize[0],
+         inlink->w, inlink->h, &sab->luma);
+    if (inpic->data[2]) {
+        int cw = FF_CEIL_RSHIFT(inlink->w, sab->hsub);
+        int ch = FF_CEIL_RSHIFT(inlink->h, sab->vsub);
+        blur(outpic->data[1], outpic->linesize[1], inpic->data[1], inpic->linesize[1], cw, ch, &sab->chroma);
+        blur(outpic->data[2], outpic->linesize[2], inpic->data[2], inpic->linesize[2], cw, ch, &sab->chroma);
+    }
+
+    av_frame_free(&inpic);
+    return ff_filter_frame(outlink, outpic);
+}
+
+static const AVFilterPad sab_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = filter_frame,
+        .config_props = config_props,
+    },
+    { NULL }
+};
+
+static const AVFilterPad sab_outputs[] = {
+    {
+        .name = "default",
+        .type = AVMEDIA_TYPE_VIDEO,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_sab = {
+    .name          = "sab",
+    .description   = NULL_IF_CONFIG_SMALL("Apply shape adaptive blur."),
+    .priv_size     = sizeof(SabContext),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+    .inputs        = sab_inputs,
+    .outputs       = sab_outputs,
+    .priv_class    = &sab_class,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
+};
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index cce2cc2..d764d21 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -71,6 +71,7 @@
     const AVClass *class;
     struct SwsContext *sws;     ///< software scaler context
     struct SwsContext *isws[2]; ///< software scaler context for interlaced material
+    AVDictionary *opts;
 
     /**
      * New dimensions. Special values are:
@@ -90,9 +91,22 @@
     char *w_expr;               ///< width  expression string
     char *h_expr;               ///< height expression string
     char *flags_str;
+
+    char *in_color_matrix;
+    char *out_color_matrix;
+
+    int in_range;
+    int out_range;
+
+    int out_h_chr_pos;
+    int out_v_chr_pos;
+    int in_h_chr_pos;
+    int in_v_chr_pos;
+
+    int force_original_aspect_ratio;
 } ScaleContext;
 
-static av_cold int init(AVFilterContext *ctx)
+static av_cold int init_dict(AVFilterContext *ctx, AVDictionary **opts)
 {
     ScaleContext *scale = ctx->priv;
     int ret;
@@ -136,6 +150,8 @@
         if (ret < 0)
             return ret;
     }
+    scale->opts = *opts;
+    *opts = NULL;
 
     return 0;
 }
@@ -147,7 +163,7 @@
     sws_freeContext(scale->isws[0]);
     sws_freeContext(scale->isws[1]);
     scale->sws = NULL;
-    av_opt_free(scale);
+    av_dict_free(&scale->opts);
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -159,7 +175,8 @@
     if (ctx->inputs[0]) {
         formats = NULL;
         for (pix_fmt = 0; pix_fmt < AV_PIX_FMT_NB; pix_fmt++)
-            if (   sws_isSupportedInput(pix_fmt)
+            if ((sws_isSupportedInput(pix_fmt) ||
+                 sws_isSupportedEndiannessConversion(pix_fmt))
                 && (ret = ff_add_format(&formats, pix_fmt)) < 0) {
                 ff_formats_unref(&formats);
                 return ret;
@@ -169,7 +186,8 @@
     if (ctx->outputs[0]) {
         formats = NULL;
         for (pix_fmt = 0; pix_fmt < AV_PIX_FMT_NB; pix_fmt++)
-            if (   (sws_isSupportedOutput(pix_fmt) || pix_fmt == AV_PIX_FMT_PAL8)
+            if ((sws_isSupportedOutput(pix_fmt) || pix_fmt == AV_PIX_FMT_PAL8 ||
+                 sws_isSupportedEndiannessConversion(pix_fmt))
                 && (ret = ff_add_format(&formats, pix_fmt)) < 0) {
                 ff_formats_unref(&formats);
                 return ret;
@@ -180,6 +198,28 @@
     return 0;
 }
 
+static const int *parse_yuv_type(const char *s, enum AVColorSpace colorspace)
+{
+    if (!s)
+        s = "bt601";
+
+    if (s && strstr(s, "bt709")) {
+        colorspace = AVCOL_SPC_BT709;
+    } else if (s && strstr(s, "fcc")) {
+        colorspace = AVCOL_SPC_FCC;
+    } else if (s && strstr(s, "smpte240m")) {
+        colorspace = AVCOL_SPC_SMPTE240M;
+    } else if (s && (strstr(s, "bt601") || strstr(s, "bt470") || strstr(s, "smpte170m"))) {
+        colorspace = AVCOL_SPC_BT470BG;
+    }
+
+    if (colorspace < 1 || colorspace > 7) {
+        colorspace = AVCOL_SPC_BT470BG;
+    }
+
+    return sws_getCoefficients(colorspace);
+}
+
 static int config_props(AVFilterLink *outlink)
 {
     AVFilterContext *ctx = outlink->src;
@@ -240,6 +280,19 @@
     if (h == -1)
         h = av_rescale(w, inlink->h, inlink->w);
 
+    if (scale->force_original_aspect_ratio) {
+        int tmp_w = av_rescale(h, inlink->w, inlink->h);
+        int tmp_h = av_rescale(w, inlink->h, inlink->w);
+
+        if (scale->force_original_aspect_ratio == 1) {
+             w = FFMIN(tmp_w, w);
+             h = FFMIN(tmp_h, h);
+        } else {
+             w = FFMAX(tmp_w, w);
+             h = FFMAX(tmp_h, h);
+        }
+    }
+
     if (w > INT_MAX || h > INT_MAX ||
         (h * inlink->w) > INT_MAX  ||
         (w * inlink->h) > INT_MAX)
@@ -250,33 +303,59 @@
 
     /* TODO: make algorithm configurable */
 
-    scale->input_is_pal = desc->flags & PIX_FMT_PAL ||
-                          desc->flags & PIX_FMT_PSEUDOPAL;
+    scale->input_is_pal = desc->flags & AV_PIX_FMT_FLAG_PAL ||
+                          desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL;
     if (outfmt == AV_PIX_FMT_PAL8) outfmt = AV_PIX_FMT_BGR8;
-    scale->output_is_pal = av_pix_fmt_desc_get(outfmt)->flags & PIX_FMT_PAL ||
-                           av_pix_fmt_desc_get(outfmt)->flags & PIX_FMT_PSEUDOPAL;
+    scale->output_is_pal = av_pix_fmt_desc_get(outfmt)->flags & AV_PIX_FMT_FLAG_PAL ||
+                           av_pix_fmt_desc_get(outfmt)->flags & AV_PIX_FMT_FLAG_PSEUDOPAL;
 
     if (scale->sws)
         sws_freeContext(scale->sws);
+    if (scale->isws[0])
+        sws_freeContext(scale->isws[0]);
+    if (scale->isws[1])
+        sws_freeContext(scale->isws[1]);
+    scale->isws[0] = scale->isws[1] = scale->sws = NULL;
     if (inlink->w == outlink->w && inlink->h == outlink->h &&
         inlink->format == outlink->format)
-        scale->sws = NULL;
+        ;
     else {
-        scale->sws = sws_getContext(inlink ->w, inlink ->h, inlink ->format,
-                                    outlink->w, outlink->h, outfmt,
-                                    scale->flags, NULL, NULL, NULL);
-        if (scale->isws[0])
-            sws_freeContext(scale->isws[0]);
-        scale->isws[0] = sws_getContext(inlink ->w, inlink ->h/2, inlink ->format,
-                                        outlink->w, outlink->h/2, outfmt,
-                                        scale->flags, NULL, NULL, NULL);
-        if (scale->isws[1])
-            sws_freeContext(scale->isws[1]);
-        scale->isws[1] = sws_getContext(inlink ->w, inlink ->h/2, inlink ->format,
-                                        outlink->w, outlink->h/2, outfmt,
-                                        scale->flags, NULL, NULL, NULL);
-        if (!scale->sws || !scale->isws[0] || !scale->isws[1])
-            return AVERROR(EINVAL);
+        struct SwsContext **swscs[3] = {&scale->sws, &scale->isws[0], &scale->isws[1]};
+        int i;
+
+        for (i = 0; i < 3; i++) {
+            struct SwsContext **s = swscs[i];
+            *s = sws_alloc_context();
+            if (!*s)
+                return AVERROR(ENOMEM);
+
+            if (scale->opts) {
+                AVDictionaryEntry *e = NULL;
+
+                while ((e = av_dict_get(scale->opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
+                    if ((ret = av_opt_set(*s, e->key, e->value, 0)) < 0)
+                        return ret;
+                }
+            }
+
+            av_opt_set_int(*s, "srcw", inlink ->w, 0);
+            av_opt_set_int(*s, "srch", inlink ->h >> !!i, 0);
+            av_opt_set_int(*s, "src_format", inlink->format, 0);
+            av_opt_set_int(*s, "dstw", outlink->w, 0);
+            av_opt_set_int(*s, "dsth", outlink->h >> !!i, 0);
+            av_opt_set_int(*s, "dst_format", outfmt, 0);
+            av_opt_set_int(*s, "sws_flags", scale->flags, 0);
+
+            av_opt_set_int(*s, "src_h_chr_pos", scale->in_h_chr_pos, 0);
+            av_opt_set_int(*s, "src_v_chr_pos", scale->in_v_chr_pos, 0);
+            av_opt_set_int(*s, "dst_h_chr_pos", scale->out_h_chr_pos, 0);
+            av_opt_set_int(*s, "dst_v_chr_pos", scale->out_v_chr_pos, 0);
+
+            if ((ret = sws_init_context(*s, NULL, NULL)) < 0)
+                return ret;
+            if (!scale->interlaced)
+                break;
+        }
     }
 
     if (inlink->sample_aspect_ratio.num){
@@ -331,6 +410,7 @@
     AVFrame *out;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
     char buf[32];
+    int in_range;
 
     if(   in->width  != link->w
        || in->height != link->h
@@ -368,6 +448,45 @@
     if(scale->output_is_pal)
         avpriv_set_systematic_pal2((uint32_t*)out->data[1], outlink->format == AV_PIX_FMT_PAL8 ? AV_PIX_FMT_BGR8 : outlink->format);
 
+    in_range = av_frame_get_color_range(in);
+
+    if (   scale->in_color_matrix
+        || scale->out_color_matrix
+        || scale-> in_range != AVCOL_RANGE_UNSPECIFIED
+        || in_range != AVCOL_RANGE_UNSPECIFIED
+        || scale->out_range != AVCOL_RANGE_UNSPECIFIED) {
+        int in_full, out_full, brightness, contrast, saturation;
+        const int *inv_table, *table;
+
+        sws_getColorspaceDetails(scale->sws, (int **)&inv_table, &in_full,
+                                 (int **)&table, &out_full,
+                                 &brightness, &contrast, &saturation);
+
+        if (scale->in_color_matrix)
+            inv_table = parse_yuv_type(scale->in_color_matrix, av_frame_get_colorspace(in));
+        if (scale->out_color_matrix)
+            table     = parse_yuv_type(scale->out_color_matrix, AVCOL_SPC_UNSPECIFIED);
+
+        if (scale-> in_range != AVCOL_RANGE_UNSPECIFIED)
+            in_full  = (scale-> in_range == AVCOL_RANGE_JPEG);
+        else if (in_range != AVCOL_RANGE_UNSPECIFIED)
+            in_full  = (in_range == AVCOL_RANGE_JPEG);
+        if (scale->out_range != AVCOL_RANGE_UNSPECIFIED)
+            out_full = (scale->out_range == AVCOL_RANGE_JPEG);
+
+        sws_setColorspaceDetails(scale->sws, inv_table, in_full,
+                                 table, out_full,
+                                 brightness, contrast, saturation);
+        if (scale->isws[0])
+            sws_setColorspaceDetails(scale->isws[0], inv_table, in_full,
+                                     table, out_full,
+                                     brightness, contrast, saturation);
+        if (scale->isws[1])
+            sws_setColorspaceDetails(scale->isws[1], inv_table, in_full,
+                                     table, out_full,
+                                     brightness, contrast, saturation);
+    }
+
     av_reduce(&out->sample_aspect_ratio.num, &out->sample_aspect_ratio.den,
               (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w,
               (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h,
@@ -384,6 +503,11 @@
     return ff_filter_frame(outlink, out);
 }
 
+static const AVClass *child_class_next(const AVClass *prev)
+{
+    return prev ? NULL : sws_get_class();
+}
+
 #define OFFSET(x) offsetof(ScaleContext, x)
 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
 
@@ -396,10 +520,34 @@
     { "interl", "set interlacing", OFFSET(interlaced), AV_OPT_TYPE_INT, {.i64 = 0 }, -1, 1, FLAGS },
     { "size",   "set video size",          OFFSET(size_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, FLAGS },
     { "s",      "set video size",          OFFSET(size_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, FLAGS },
+    {  "in_color_matrix", "set input YCbCr type",   OFFSET(in_color_matrix),  AV_OPT_TYPE_STRING, { .str = "auto" }, .flags = FLAGS },
+    { "out_color_matrix", "set output YCbCr type",  OFFSET(out_color_matrix), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS },
+    {  "in_range", "set input color range",  OFFSET( in_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 2, FLAGS, "range" },
+    { "out_range", "set output color range", OFFSET(out_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 2, FLAGS, "range" },
+    { "auto",   NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 0, FLAGS, "range" },
+    { "full",   NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, "range" },
+    { "jpeg",   NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, "range" },
+    { "mpeg",   NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, "range" },
+    { "tv",     NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, "range" },
+    { "pc",     NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, "range" },
+    { "in_v_chr_pos",   "input vertical chroma position in luma grid/256"  , OFFSET(in_v_chr_pos), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 512, FLAGS },
+    { "in_h_chr_pos",   "input horizontal chroma position in luma grid/256", OFFSET(in_h_chr_pos), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 512, FLAGS },
+    { "out_v_chr_pos",   "output vertical chroma position in luma grid/256"  , OFFSET(out_v_chr_pos), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 512, FLAGS },
+    { "out_h_chr_pos",   "output horizontal chroma position in luma grid/256", OFFSET(out_h_chr_pos), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 512, FLAGS },
+    { "force_original_aspect_ratio", "decrease or increase w/h if necessary to keep the original AR", OFFSET(force_original_aspect_ratio), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 2, FLAGS, "force_oar" },
+    { "disable",  NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, FLAGS, "force_oar" },
+    { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, "force_oar" },
+    { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, "force_oar" },
     { NULL },
 };
 
-AVFILTER_DEFINE_CLASS(scale);
+static const AVClass scale_class = {
+    .class_name       = "scale",
+    .item_name        = av_default_item_name,
+    .option           = scale_options,
+    .version          = LIBAVUTIL_VERSION_INT,
+    .child_class_next = child_class_next,
+};
 
 static const AVFilterPad avfilter_vf_scale_inputs[] = {
     {
@@ -423,7 +571,7 @@
     .name      = "scale",
     .description = NULL_IF_CONFIG_SMALL("Scale the input video to width:height size and/or convert the image format."),
 
-    .init      = init,
+    .init_dict = init_dict,
     .uninit    = uninit,
 
     .query_formats = query_formats,
diff --git a/libavfilter/vf_separatefields.c b/libavfilter/vf_separatefields.c
index c91c0c1..8fce6de 100644
--- a/libavfilter/vf_separatefields.c
+++ b/libavfilter/vf_separatefields.c
@@ -33,7 +33,7 @@
     SeparateFieldsContext *sf = ctx->priv;
     AVFilterLink *inlink = ctx->inputs[0];
 
-    sf->nb_planes = av_pix_fmt_count_planes(inlink->format);;
+    sf->nb_planes = av_pix_fmt_count_planes(inlink->format);
 
     if (inlink->h & 1) {
         av_log(ctx, AV_LOG_ERROR, "height must be even\n");
@@ -77,8 +77,10 @@
 
     inpicref->pts = outlink->frame_count * sf->ts_unit;
     ret = ff_filter_frame(outlink, inpicref);
-    if (ret < 0)
+    if (ret < 0) {
+        av_frame_free(&second);
         return ret;
+    }
 
     second->pts = outlink->frame_count * sf->ts_unit;
     return ff_filter_frame(outlink, second);
diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c
index dd97843..82becc4 100644
--- a/libavfilter/vf_showinfo.c
+++ b/libavfilter/vf_showinfo.c
@@ -31,22 +31,17 @@
 #include "internal.h"
 #include "video.h"
 
-typedef struct {
-    unsigned int frame;
-} ShowInfoContext;
-
 static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
 {
     AVFilterContext *ctx = inlink->dst;
-    ShowInfoContext *showinfo = ctx->priv;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
     uint32_t plane_checksum[4] = {0}, checksum = 0;
     int i, plane, vsub = desc->log2_chroma_h;
 
-    for (plane = 0; plane < 4 && frame->data[plane]; plane++) {
+    for (plane = 0; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++) {
         int64_t linesize = av_image_get_linesize(frame->format, frame->width, plane);
         uint8_t *data = frame->data[plane];
-        int h = plane == 1 || plane == 2 ? inlink->h >> vsub : inlink->h;
+        int h = plane == 1 || plane == 2 ? FF_CEIL_RSHIFT(inlink->h, vsub) : inlink->h;
 
         if (linesize < 0)
             return linesize;
@@ -59,10 +54,10 @@
     }
 
     av_log(ctx, AV_LOG_INFO,
-           "n:%d pts:%s pts_time:%s pos:%"PRId64" "
+           "n:%"PRId64" pts:%s pts_time:%s pos:%"PRId64" "
            "fmt:%s sar:%d/%d s:%dx%d i:%c iskey:%d type:%c "
            "checksum:%08X plane_checksum:[%08X",
-           showinfo->frame,
+           inlink->frame_count,
            av_ts2str(frame->pts), av_ts2timestr(frame->pts, &inlink->time_base), av_frame_get_pkt_pos(frame),
            desc->name,
            frame->sample_aspect_ratio.num, frame->sample_aspect_ratio.den,
@@ -73,11 +68,10 @@
            av_get_picture_type_char(frame->pict_type),
            checksum, plane_checksum[0]);
 
-    for (plane = 1; plane < 4 && frame->data[plane]; plane++)
+    for (plane = 1; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++)
         av_log(ctx, AV_LOG_INFO, " %08X", plane_checksum[plane]);
     av_log(ctx, AV_LOG_INFO, "]\n");
 
-    showinfo->frame++;
     return ff_filter_frame(inlink->dst->outputs[0], frame);
 }
 
@@ -103,8 +97,6 @@
     .name        = "showinfo",
     .description = NULL_IF_CONFIG_SMALL("Show textual information for each video frame."),
 
-    .priv_size = sizeof(ShowInfoContext),
-
     .inputs    = avfilter_vf_showinfo_inputs,
 
     .outputs   = avfilter_vf_showinfo_outputs,
diff --git a/libavfilter/vf_smartblur.c b/libavfilter/vf_smartblur.c
index 4dd1664..a0013a2 100644
--- a/libavfilter/vf_smartblur.c
+++ b/libavfilter/vf_smartblur.c
@@ -166,7 +166,8 @@
 
     alloc_sws_context(&sblur->luma, inlink->w, inlink->h, sblur->sws_flags);
     alloc_sws_context(&sblur->chroma,
-                      inlink->w >> sblur->hsub, inlink->h >> sblur->vsub,
+                      FF_CEIL_RSHIFT(inlink->w, sblur->hsub),
+                      FF_CEIL_RSHIFT(inlink->h, sblur->vsub),
                       sblur->sws_flags);
 
     return 0;
@@ -241,8 +242,8 @@
     SmartblurContext  *sblur  = inlink->dst->priv;
     AVFilterLink *outlink     = inlink->dst->outputs[0];
     AVFrame *outpic;
-    int cw = inlink->w >> sblur->hsub;
-    int ch = inlink->h >> sblur->vsub;
+    int cw = FF_CEIL_RSHIFT(inlink->w, sblur->hsub);
+    int ch = FF_CEIL_RSHIFT(inlink->h, sblur->vsub);
 
     outpic = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     if (!outpic) {
@@ -301,5 +302,5 @@
     .inputs        = smartblur_inputs,
     .outputs       = smartblur_outputs,
     .priv_class    = &smartblur_class,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_spp.c b/libavfilter/vf_spp.c
new file mode 100644
index 0000000..9dbd852
--- /dev/null
+++ b/libavfilter/vf_spp.c
@@ -0,0 +1,437 @@
+/*
+ * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (c) 2013 Clément Bœsch <ubitux@gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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.
+ */
+
+/**
+ * @file
+ * Simple post processing filter
+ *
+ * This implementation is based on an algorithm described in
+ * "Aria Nosratinia Embedded Post-Processing for
+ * Enhancement of Compressed Images (1999)"
+ *
+ * Originally written by Michael Niedermayer for the MPlayer project, and
+ * ported by Clément Bœsch for FFmpeg.
+ */
+
+#include "libavcodec/dsputil.h"
+#include "libavutil/avassert.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "internal.h"
+#include "vf_spp.h"
+
+enum mode {
+    MODE_HARD,
+    MODE_SOFT,
+    NB_MODES
+};
+
+#define OFFSET(x) offsetof(SPPContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption spp_options[] = {
+    { "quality", "set quality", OFFSET(log2_count), AV_OPT_TYPE_INT, {.i64 = 3}, 0, MAX_LEVEL, FLAGS },
+    { "qp", "force a constant quantizer parameter", OFFSET(qp), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 63, FLAGS },
+    { "mode", "set thresholding mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64 = MODE_HARD}, 0, NB_MODES - 1, FLAGS, "mode" },
+        { "hard", "hard thresholding", 0, AV_OPT_TYPE_CONST, {.i64 = MODE_HARD}, INT_MIN, INT_MAX, FLAGS, "mode" },
+        { "soft", "soft thresholding", 0, AV_OPT_TYPE_CONST, {.i64 = MODE_SOFT}, INT_MIN, INT_MAX, FLAGS, "mode" },
+    { "use_bframe_qp", "use B-frames' QP", OFFSET(use_bframe_qp), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS },
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(spp);
+
+// XXX: share between filters?
+DECLARE_ALIGNED(8, static const uint8_t, ldither)[8][8] = {
+    {  0,  48,  12,  60,   3,  51,  15,  63 },
+    { 32,  16,  44,  28,  35,  19,  47,  31 },
+    {  8,  56,   4,  52,  11,  59,   7,  55 },
+    { 40,  24,  36,  20,  43,  27,  39,  23 },
+    {  2,  50,  14,  62,   1,  49,  13,  61 },
+    { 34,  18,  46,  30,  33,  17,  45,  29 },
+    { 10,  58,   6,  54,   9,  57,   5,  53 },
+    { 42,  26,  38,  22,  41,  25,  37,  21 },
+};
+
+static const uint8_t offset[127][2] = {
+    {0,0},
+    {0,0}, {4,4},                                           // quality = 1
+    {0,0}, {2,2}, {6,4}, {4,6},                             // quality = 2
+    {0,0}, {5,1}, {2,2}, {7,3}, {4,4}, {1,5}, {6,6}, {3,7}, // quality = 3
+
+    {0,0}, {4,0}, {1,1}, {5,1}, {3,2}, {7,2}, {2,3}, {6,3}, // quality = 4
+    {0,4}, {4,4}, {1,5}, {5,5}, {3,6}, {7,6}, {2,7}, {6,7},
+
+    {0,0}, {0,2}, {0,4}, {0,6}, {1,1}, {1,3}, {1,5}, {1,7}, // quality = 5
+    {2,0}, {2,2}, {2,4}, {2,6}, {3,1}, {3,3}, {3,5}, {3,7},
+    {4,0}, {4,2}, {4,4}, {4,6}, {5,1}, {5,3}, {5,5}, {5,7},
+    {6,0}, {6,2}, {6,4}, {6,6}, {7,1}, {7,3}, {7,5}, {7,7},
+
+    {0,0}, {4,4}, {0,4}, {4,0}, {2,2}, {6,6}, {2,6}, {6,2}, // quality = 6
+    {0,2}, {4,6}, {0,6}, {4,2}, {2,0}, {6,4}, {2,4}, {6,0},
+    {1,1}, {5,5}, {1,5}, {5,1}, {3,3}, {7,7}, {3,7}, {7,3},
+    {1,3}, {5,7}, {1,7}, {5,3}, {3,1}, {7,5}, {3,5}, {7,1},
+    {0,1}, {4,5}, {0,5}, {4,1}, {2,3}, {6,7}, {2,7}, {6,3},
+    {0,3}, {4,7}, {0,7}, {4,3}, {2,1}, {6,5}, {2,5}, {6,1},
+    {1,0}, {5,4}, {1,4}, {5,0}, {3,2}, {7,6}, {3,6}, {7,2},
+    {1,2}, {5,6}, {1,6}, {5,2}, {3,0}, {7,4}, {3,4}, {7,0},
+};
+
+static void hardthresh_c(int16_t dst[64], const int16_t src[64],
+                         int qp, const uint8_t *permutation)
+{
+    int i;
+    int bias = 0; // FIXME
+
+    unsigned threshold1 = qp * ((1<<4) - bias) - 1;
+    unsigned threshold2 = threshold1 << 1;
+
+    memset(dst, 0, 64 * sizeof(dst[0]));
+    dst[0] = (src[0] + 4) >> 3;
+
+    for (i = 1; i < 64; i++) {
+        int level = src[i];
+        if (((unsigned)(level + threshold1)) > threshold2) {
+            const int j = permutation[i];
+            dst[j] = (level + 4) >> 3;
+        }
+    }
+}
+
+static void softthresh_c(int16_t dst[64], const int16_t src[64],
+                         int qp, const uint8_t *permutation)
+{
+    int i;
+    int bias = 0; //FIXME
+
+    unsigned threshold1 = qp * ((1<<4) - bias) - 1;
+    unsigned threshold2 = threshold1 << 1;
+
+    memset(dst, 0, 64 * sizeof(dst[0]));
+    dst[0] = (src[0] + 4) >> 3;
+
+    for (i = 1; i < 64; i++) {
+        int level = src[i];
+        if (((unsigned)(level + threshold1)) > threshold2) {
+            const int j = permutation[i];
+            if (level > 0) dst[j] = (level - threshold1 + 4) >> 3;
+            else           dst[j] = (level + threshold1 + 4) >> 3;
+        }
+    }
+}
+
+static void store_slice_c(uint8_t *dst, const int16_t *src,
+                          int dst_linesize, int src_linesize,
+                          int width, int height, int log2_scale,
+                          const uint8_t dither[8][8])
+{
+    int y, x;
+
+#define STORE(pos) do {                                                     \
+    temp = ((src[x + y*src_linesize + pos] << log2_scale) + d[pos]) >> 6;   \
+    if (temp & 0x100)                                                       \
+        temp = ~(temp >> 31);                                               \
+    dst[x + y*dst_linesize + pos] = temp;                                   \
+} while (0)
+
+    for (y = 0; y < height; y++) {
+        const uint8_t *d = dither[y];
+        for (x = 0; x < width; x += 8) {
+            int temp;
+            STORE(0);
+            STORE(1);
+            STORE(2);
+            STORE(3);
+            STORE(4);
+            STORE(5);
+            STORE(6);
+            STORE(7);
+        }
+    }
+}
+
+static inline void add_block(int16_t *dst, int linesize, const int16_t block[64])
+{
+    int y;
+
+    for (y = 0; y < 8; y++) {
+        *(uint32_t *)&dst[0 + y*linesize] += *(uint32_t *)&block[0 + y*8];
+        *(uint32_t *)&dst[2 + y*linesize] += *(uint32_t *)&block[2 + y*8];
+        *(uint32_t *)&dst[4 + y*linesize] += *(uint32_t *)&block[4 + y*8];
+        *(uint32_t *)&dst[6 + y*linesize] += *(uint32_t *)&block[6 + y*8];
+    }
+}
+
+// XXX: export the function?
+static inline int norm_qscale(int qscale, int type)
+{
+    switch (type) {
+    case FF_QSCALE_TYPE_MPEG1: return qscale;
+    case FF_QSCALE_TYPE_MPEG2: return qscale >> 1;
+    case FF_QSCALE_TYPE_H264:  return qscale >> 2;
+    case FF_QSCALE_TYPE_VP56:  return (63 - qscale + 2) >> 2;
+    }
+    return qscale;
+}
+
+static void filter(SPPContext *p, uint8_t *dst, uint8_t *src,
+                   int dst_linesize, int src_linesize, int width, int height,
+                   const uint8_t *qp_table, int qp_stride, int is_luma)
+{
+    int x, y, i;
+    const int count = 1 << p->log2_count;
+    const int linesize = is_luma ? p->temp_linesize : FFALIGN(width+16, 16);
+    DECLARE_ALIGNED(16, uint64_t, block_align)[32];
+    int16_t *block  = (int16_t *)block_align;
+    int16_t *block2 = (int16_t *)(block_align + 16);
+
+    for (y = 0; y < height; y++) {
+        int index = 8 + 8*linesize + y*linesize;
+        memcpy(p->src + index, src + y*src_linesize, width);
+        for (x = 0; x < 8; x++) {
+            p->src[index         - x - 1] = p->src[index +         x    ];
+            p->src[index + width + x    ] = p->src[index + width - x - 1];
+        }
+    }
+    for (y = 0; y < 8; y++) {
+        memcpy(p->src + (       7-y)*linesize, p->src + (       y+8)*linesize, linesize);
+        memcpy(p->src + (height+8+y)*linesize, p->src + (height-y+7)*linesize, linesize);
+    }
+
+    for (y = 0; y < height + 8; y += 8) {
+        memset(p->temp + (8 + y) * linesize, 0, 8 * linesize * sizeof(*p->temp));
+        for (x = 0; x < width + 8; x += 8) {
+            int qp;
+
+            if (p->qp) {
+                qp = p->qp;
+            } else{
+                const int qps = 3 + is_luma;
+                qp = qp_table[(FFMIN(x, width - 1) >> qps) + (FFMIN(y, height - 1) >> qps) * qp_stride];
+                qp = FFMAX(1, norm_qscale(qp, p->qscale_type));
+            }
+            for (i = 0; i < count; i++) {
+                const int x1 = x + offset[i + count - 1][0];
+                const int y1 = y + offset[i + count - 1][1];
+                const int index = x1 + y1*linesize;
+                p->dsp.get_pixels(block, p->src + index, linesize);
+                p->dsp.fdct(block);
+                p->requantize(block2, block, qp, p->dsp.idct_permutation);
+                p->dsp.idct(block2);
+                add_block(p->temp + index, linesize, block2);
+            }
+        }
+        if (y)
+            p->store_slice(dst + (y - 8) * dst_linesize, p->temp + 8 + y*linesize,
+                           dst_linesize, linesize, width,
+                           FFMIN(8, height + 8 - y), MAX_LEVEL - p->log2_count,
+                           ldither);
+    }
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum PixelFormat pix_fmts[] = {
+        AV_PIX_FMT_YUV444P,  AV_PIX_FMT_YUV422P,
+        AV_PIX_FMT_YUV420P,  AV_PIX_FMT_YUV411P,
+        AV_PIX_FMT_YUV410P,  AV_PIX_FMT_YUV440P,
+        AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P,
+        AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ440P,
+        AV_PIX_FMT_NONE
+    };
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+    SPPContext *spp = inlink->dst->priv;
+    const int h = FFALIGN(inlink->h + 16, 16);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+
+    spp->hsub = desc->log2_chroma_w;
+    spp->vsub = desc->log2_chroma_h;
+    spp->temp_linesize = FFALIGN(inlink->w + 16, 16);
+    spp->temp = av_malloc(spp->temp_linesize * h * sizeof(*spp->temp));
+    spp->src  = av_malloc(spp->temp_linesize * h * sizeof(*spp->src));
+    if (!spp->use_bframe_qp) {
+        /* we are assuming here the qp blocks will not be smaller that 16x16 */
+        spp->non_b_qp_alloc_size = FF_CEIL_RSHIFT(inlink->w, 4) * FF_CEIL_RSHIFT(inlink->h, 4);
+        spp->non_b_qp_table = av_calloc(spp->non_b_qp_alloc_size, sizeof(*spp->non_b_qp_table));
+        if (!spp->non_b_qp_table)
+            return AVERROR(ENOMEM);
+    }
+    if (!spp->temp || !spp->src)
+        return AVERROR(ENOMEM);
+    return 0;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+{
+    AVFilterContext *ctx = inlink->dst;
+    SPPContext *spp = ctx->priv;
+    AVFilterLink *outlink = ctx->outputs[0];
+    AVFrame *out = in;
+    int qp_stride = 0;
+    const int8_t *qp_table = NULL;
+
+    /* if we are not in a constant user quantizer mode and we don't want to use
+     * the quantizers from the B-frames (B-frames often have a higher QP), we
+     * need to save the qp table from the last non B-frame; this is what the
+     * following code block does */
+    if (!spp->qp) {
+        qp_table = av_frame_get_qp_table(in, &qp_stride, &spp->qscale_type);
+
+        if (qp_table && !spp->use_bframe_qp && in->pict_type != AV_PICTURE_TYPE_B) {
+            int w, h;
+
+            /* if the qp stride is not set, it means the QP are only defined on
+             * a line basis */
+            if (!qp_stride) {
+                w = FF_CEIL_RSHIFT(inlink->w, 4);
+                h = 1;
+            } else {
+                w = FF_CEIL_RSHIFT(qp_stride, 4);
+                h = FF_CEIL_RSHIFT(inlink->h, 4);
+            }
+            av_assert0(w * h <= spp->non_b_qp_alloc_size);
+            memcpy(spp->non_b_qp_table, qp_table, w * h);
+        }
+    }
+
+    if (spp->log2_count && !ctx->is_disabled) {
+        if (!spp->use_bframe_qp && spp->non_b_qp_table)
+            qp_table = spp->non_b_qp_table;
+
+        if (qp_table || spp->qp) {
+            const int cw = FF_CEIL_RSHIFT(inlink->w, spp->hsub);
+            const int ch = FF_CEIL_RSHIFT(inlink->h, spp->vsub);
+
+            /* get a new frame if in-place is not possible or if the dimensions
+             * are not multiple of 8 */
+            if (!av_frame_is_writable(in) || (inlink->w & 7) || (inlink->h & 7)) {
+                const int aligned_w = FFALIGN(inlink->w, 8);
+                const int aligned_h = FFALIGN(inlink->h, 8);
+
+                out = ff_get_video_buffer(outlink, aligned_w, aligned_h);
+                if (!out) {
+                    av_frame_free(&in);
+                    return AVERROR(ENOMEM);
+                }
+                av_frame_copy_props(out, in);
+                out->width  = in->width;
+                out->height = in->height;
+            }
+
+            filter(spp, out->data[0], in->data[0], out->linesize[0], in->linesize[0], inlink->w, inlink->h, qp_table, qp_stride, 1);
+            filter(spp, out->data[1], in->data[1], out->linesize[1], in->linesize[1], cw,        ch,        qp_table, qp_stride, 0);
+            filter(spp, out->data[2], in->data[2], out->linesize[2], in->linesize[2], cw,        ch,        qp_table, qp_stride, 0);
+            emms_c();
+        }
+    }
+
+    if (in != out) {
+        if (in->data[3])
+            av_image_copy_plane(out->data[3], out->linesize[3],
+                                in ->data[3], in ->linesize[3],
+                                inlink->w, inlink->h);
+        av_frame_free(&in);
+    }
+    return ff_filter_frame(outlink, out);
+}
+
+static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
+                           char *res, int res_len, int flags)
+{
+    SPPContext *spp = ctx->priv;
+
+    if (!strcmp(cmd, "level")) {
+        if (!strcmp(args, "max"))
+            spp->log2_count = MAX_LEVEL;
+        else
+            spp->log2_count = av_clip(strtol(args, NULL, 10), 0, MAX_LEVEL);
+        return 0;
+    }
+    return AVERROR(ENOSYS);
+}
+
+static av_cold int init(AVFilterContext *ctx)
+{
+    SPPContext *spp = ctx->priv;
+
+    spp->avctx = avcodec_alloc_context3(NULL);
+    if (!spp->avctx)
+        return AVERROR(ENOMEM);
+    avpriv_dsputil_init(&spp->dsp, spp->avctx);
+    spp->store_slice = store_slice_c;
+    switch (spp->mode) {
+    case MODE_HARD: spp->requantize = hardthresh_c; break;
+    case MODE_SOFT: spp->requantize = softthresh_c; break;
+    }
+    if (ARCH_X86)
+        ff_spp_init_x86(spp);
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    SPPContext *spp = ctx->priv;
+
+    av_freep(&spp->temp);
+    av_freep(&spp->src);
+    if (spp->avctx) {
+        avcodec_close(spp->avctx);
+        av_freep(&spp->avctx);
+    }
+    av_freep(&spp->non_b_qp_table);
+}
+
+static const AVFilterPad spp_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .config_props = config_input,
+        .filter_frame = filter_frame,
+    },
+    { NULL }
+};
+
+static const AVFilterPad spp_outputs[] = {
+    {
+        .name = "default",
+        .type = AVMEDIA_TYPE_VIDEO,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_spp = {
+    .name            = "spp",
+    .description     = NULL_IF_CONFIG_SMALL("Apply a simple post processing filter."),
+    .priv_size       = sizeof(SPPContext),
+    .init            = init,
+    .uninit          = uninit,
+    .query_formats   = query_formats,
+    .inputs          = spp_inputs,
+    .outputs         = spp_outputs,
+    .process_command = process_command,
+    .priv_class      = &spp_class,
+    .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
+};
diff --git a/libavfilter/vf_spp.h b/libavfilter/vf_spp.h
new file mode 100644
index 0000000..c4293b6
--- /dev/null
+++ b/libavfilter/vf_spp.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (c) 2013 Clément Bœsch
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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.
+ */
+
+#ifndef AVFILTER_SPP_H
+#define AVFILTER_SPP_H
+
+#include "libavcodec/avcodec.h"
+#include "libavcodec/dsputil.h"
+#include "avfilter.h"
+
+#define MAX_LEVEL 6 /* quality levels */
+
+typedef struct {
+    const AVClass *av_class;
+
+    int log2_count;
+    int qp;
+    int mode;
+    int qscale_type;
+    int temp_linesize;
+    uint8_t *src;
+    int16_t *temp;
+    AVCodecContext *avctx;
+    DSPContext dsp;
+    int8_t *non_b_qp_table;
+    int non_b_qp_alloc_size;
+    int use_bframe_qp;
+    int hsub, vsub;
+
+    void (*store_slice)(uint8_t *dst, const int16_t *src,
+                        int dst_stride, int src_stride,
+                        int width, int height, int log2_scale,
+                        const uint8_t dither[8][8]);
+
+    void (*requantize)(int16_t dst[64], const int16_t src[64],
+                       int qp, const uint8_t *permutation);
+} SPPContext;
+
+void ff_spp_init_x86(SPPContext *s);
+
+#endif /* AVFILTER_SPP_H */
diff --git a/libavfilter/vf_stereo3d.c b/libavfilter/vf_stereo3d.c
index cc4bef6..56b523b 100644
--- a/libavfilter/vf_stereo3d.c
+++ b/libavfilter/vf_stereo3d.c
@@ -56,6 +56,8 @@
     ABOVE_BELOW_RL,     // above-below (right eye above, left eye below)
     ABOVE_BELOW_2_LR,   // above-below with half height resolution
     ABOVE_BELOW_2_RL,   // above-below with half height resolution
+    ALTERNATING_LR,     // alternating frames (left eye first, right eye second)
+    ALTERNATING_RL,     // alternating frames (right eye first, left eye second)
     STEREO_CODE_COUNT   // TODO: needs autodetection
 };
 
@@ -134,18 +136,24 @@
     int ana_matrix[3][6];
     int nb_planes;
     int linesize[4];
+    int pheight[4];
+    int hsub, vsub;
     int pixstep[4];
+    AVFrame *prev;
+    double ts_unit;
 } Stereo3DContext;
 
 #define OFFSET(x) offsetof(Stereo3DContext, x)
 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
 
 static const AVOption stereo3d_options[] = {
-    { "in",    "set input format",  OFFSET(in.format),  AV_OPT_TYPE_INT, {.i64=SIDE_BY_SIDE_LR}, SIDE_BY_SIDE_LR, ABOVE_BELOW_2_RL, FLAGS, "in"},
+    { "in",    "set input format",  OFFSET(in.format),  AV_OPT_TYPE_INT, {.i64=SIDE_BY_SIDE_LR}, SIDE_BY_SIDE_LR, STEREO_CODE_COUNT-1, FLAGS, "in"},
     { "ab2l",  "above below half height left first",  0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_LR},  0, 0, FLAGS, "in" },
     { "ab2r",  "above below half height right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_RL},  0, 0, FLAGS, "in" },
     { "abl",   "above below left first",              0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_LR},    0, 0, FLAGS, "in" },
     { "abr",   "above below right first",             0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_RL},    0, 0, FLAGS, "in" },
+    { "al",    "alternating frames left first",       0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_LR},    0, 0, FLAGS, "in" },
+    { "ar",    "alternating frames right first",      0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_RL},    0, 0, FLAGS, "in" },
     { "sbs2l", "side by side half width left first",  0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_LR}, 0, 0, FLAGS, "in" },
     { "sbs2r", "side by side half width right first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_RL}, 0, 0, FLAGS, "in" },
     { "sbsl",  "side by side left first",             0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_LR},   0, 0, FLAGS, "in" },
@@ -159,6 +167,8 @@
     { "agmd",  "anaglyph green magenta dubois",       0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_GM_DUBOIS}, 0, 0, FLAGS, "out" },
     { "agmg",  "anaglyph green magenta gray",         0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_GM_GRAY},   0, 0, FLAGS, "out" },
     { "agmh",  "anaglyph green magenta half color",   0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_GM_HALF},   0, 0, FLAGS, "out" },
+    { "al",    "alternating frames left first",       0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_LR},     0, 0, FLAGS, "out" },
+    { "ar",    "alternating frames right first",      0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_RL},     0, 0, FLAGS, "out" },
     { "arbg",  "anaglyph red blue gray",              0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_RB_GRAY},   0, 0, FLAGS, "out" },
     { "arcc",  "anaglyph red cyan color",             0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_RC_COLOR},  0, 0, FLAGS, "out" },
     { "arcd",  "anaglyph red cyan dubois",            0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_RC_DUBOIS}, 0, 0, FLAGS, "out" },
@@ -199,14 +209,39 @@
     AV_PIX_FMT_GBRP12BE, AV_PIX_FMT_GBRP12LE,
     AV_PIX_FMT_GBRP14BE, AV_PIX_FMT_GBRP14LE,
     AV_PIX_FMT_GBRP16BE, AV_PIX_FMT_GBRP16LE,
+    AV_PIX_FMT_YUV410P,
+    AV_PIX_FMT_YUV411P,
+    AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P,
+    AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA422P,
+    AV_PIX_FMT_YUV440P,
     AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA444P,
+    AV_PIX_FMT_YUVJ411P,
+    AV_PIX_FMT_YUVJ420P,
+    AV_PIX_FMT_YUVJ422P,
+    AV_PIX_FMT_YUVJ440P,
     AV_PIX_FMT_YUVJ444P,
+    AV_PIX_FMT_YUV420P9LE,  AV_PIX_FMT_YUVA420P9LE,
+    AV_PIX_FMT_YUV420P9BE,  AV_PIX_FMT_YUVA420P9BE,
+    AV_PIX_FMT_YUV422P9LE,  AV_PIX_FMT_YUVA422P9LE,
+    AV_PIX_FMT_YUV422P9BE,  AV_PIX_FMT_YUVA422P9BE,
     AV_PIX_FMT_YUV444P9LE,  AV_PIX_FMT_YUVA444P9LE,
     AV_PIX_FMT_YUV444P9BE,  AV_PIX_FMT_YUVA444P9BE,
+    AV_PIX_FMT_YUV420P10LE, AV_PIX_FMT_YUVA420P10LE,
+    AV_PIX_FMT_YUV420P10BE, AV_PIX_FMT_YUVA420P10BE,
+    AV_PIX_FMT_YUV422P10LE, AV_PIX_FMT_YUVA422P10LE,
+    AV_PIX_FMT_YUV422P10BE, AV_PIX_FMT_YUVA422P10BE,
     AV_PIX_FMT_YUV444P10LE, AV_PIX_FMT_YUVA444P10LE,
     AV_PIX_FMT_YUV444P10BE, AV_PIX_FMT_YUVA444P10BE,
+    AV_PIX_FMT_YUV420P12BE,  AV_PIX_FMT_YUV420P12LE,
+    AV_PIX_FMT_YUV422P12BE,  AV_PIX_FMT_YUV422P12LE,
     AV_PIX_FMT_YUV444P12BE,  AV_PIX_FMT_YUV444P12LE,
+    AV_PIX_FMT_YUV420P14BE,  AV_PIX_FMT_YUV420P14LE,
+    AV_PIX_FMT_YUV422P14BE,  AV_PIX_FMT_YUV422P14LE,
     AV_PIX_FMT_YUV444P14BE,  AV_PIX_FMT_YUV444P14LE,
+    AV_PIX_FMT_YUV420P16LE, AV_PIX_FMT_YUVA420P16LE,
+    AV_PIX_FMT_YUV420P16BE, AV_PIX_FMT_YUVA420P16BE,
+    AV_PIX_FMT_YUV422P16LE, AV_PIX_FMT_YUVA422P16LE,
+    AV_PIX_FMT_YUV422P16BE, AV_PIX_FMT_YUVA422P16BE,
     AV_PIX_FMT_YUV444P16LE, AV_PIX_FMT_YUVA444P16LE,
     AV_PIX_FMT_YUV444P16BE, AV_PIX_FMT_YUVA444P16BE,
     AV_PIX_FMT_NONE
@@ -249,6 +284,8 @@
     AVFilterLink *inlink = ctx->inputs[0];
     Stereo3DContext *s = ctx->priv;
     AVRational aspect = inlink->sample_aspect_ratio;
+    AVRational fps = inlink->frame_rate;
+    AVRational tb = inlink->time_base;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(outlink->format);
     int ret;
 
@@ -317,6 +354,12 @@
         s->in.row_left  =
         s->height       = inlink->h / 2;
         break;
+    case ALTERNATING_RL:
+    case ALTERNATING_LR:
+        outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP;
+        fps.den        *= 2;
+        tb.num         *= 2;
+        break;
     default:
         av_log(ctx, AV_LOG_ERROR, "input format %d is not supported\n", s->in.format);
         return AVERROR(EINVAL);
@@ -349,25 +392,25 @@
         memcpy(s->ana_matrix, ana_coeff[s->out.format], sizeof(s->ana_matrix));
         break;
     case SIDE_BY_SIDE_2_LR:
-        aspect.num      /= 2;
+        aspect.den      *= 2;
     case SIDE_BY_SIDE_LR:
         s->out.width     = s->width * 2;
         s->out.off_right = s->width;
         break;
     case SIDE_BY_SIDE_2_RL:
-        aspect.num      /= 2;
+        aspect.den      *= 2;
     case SIDE_BY_SIDE_RL:
         s->out.width     = s->width * 2;
         s->out.off_left  = s->width;
         break;
     case ABOVE_BELOW_2_LR:
-        aspect.den      /= 2;
+        aspect.num      *= 2;
     case ABOVE_BELOW_LR:
         s->out.height    = s->height * 2;
         s->out.row_right = s->height;
         break;
     case ABOVE_BELOW_2_RL:
-        aspect.den      /= 2;
+        aspect.num      *= 2;
     case ABOVE_BELOW_RL:
         s->out.height    = s->height * 2;
         s->out.row_left  = s->height;
@@ -389,19 +432,31 @@
         s->in.row_left   = s->in.row_right;
     case MONO_L:
         break;
+    case ALTERNATING_RL:
+    case ALTERNATING_LR:
+        fps.num         *= 2;
+        tb.den          *= 2;
+        break;
     default:
-        av_log(ctx, AV_LOG_ERROR, "output format is not supported\n");
+        av_log(ctx, AV_LOG_ERROR, "output format %d is not supported\n", s->out.format);
         return AVERROR(EINVAL);
     }
 
     outlink->w = s->out.width;
     outlink->h = s->out.height;
+    outlink->frame_rate = fps;
+    outlink->time_base = tb;
     outlink->sample_aspect_ratio = aspect;
 
     if ((ret = av_image_fill_linesizes(s->linesize, outlink->format, s->width)) < 0)
         return ret;
     s->nb_planes = av_pix_fmt_count_planes(outlink->format);
     av_image_fill_max_pixsteps(s->pixstep, NULL, desc);
+    s->ts_unit = av_q2d(av_inv_q(av_mul_q(outlink->frame_rate, outlink->time_base)));
+    s->pheight[1] = s->pheight[2] = FF_CEIL_RSHIFT(s->height, desc->log2_chroma_h);
+    s->pheight[0] = s->pheight[3] = s->height;
+    s->hsub = desc->log2_chroma_w;
+    s->vsub = desc->log2_chroma_h;
 
     return 0;
 }
@@ -422,26 +477,59 @@
     AVFilterContext *ctx  = inlink->dst;
     Stereo3DContext *s = ctx->priv;
     AVFilterLink *outlink = ctx->outputs[0];
-    AVFrame *out;
+    AVFrame *out, *oleft, *oright, *ileft, *iright;
     int out_off_left[4], out_off_right[4];
     int in_off_left[4], in_off_right[4];
     int i;
 
-    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+    switch (s->in.format) {
+    case ALTERNATING_LR:
+    case ALTERNATING_RL:
+        if (!s->prev) {
+            s->prev = inpicref;
+            return 0;
+        }
+        ileft  = s->prev;
+        iright = inpicref;
+        if (s->in.format == ALTERNATING_RL)
+            FFSWAP(AVFrame *, ileft, iright);
+        break;
+    default:
+        ileft = iright = inpicref;
+    };
+
+    out = oleft = oright = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     if (!out) {
+        av_frame_free(&s->prev);
         av_frame_free(&inpicref);
         return AVERROR(ENOMEM);
     }
     av_frame_copy_props(out, inpicref);
 
+    if (s->out.format == ALTERNATING_LR ||
+        s->out.format == ALTERNATING_RL) {
+        oright = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+        if (!oright) {
+            av_frame_free(&oleft);
+            av_frame_free(&s->prev);
+            av_frame_free(&inpicref);
+            return AVERROR(ENOMEM);
+        }
+        av_frame_copy_props(oright, inpicref);
+    }
+
     for (i = 0; i < 4; i++) {
-        in_off_left[i]   = (s->in.row_left   + s->in.off_lstep)  * inpicref->linesize[i] + s->in.off_left   * s->pixstep[i];
-        in_off_right[i]  = (s->in.row_right  + s->in.off_rstep)  * inpicref->linesize[i] + s->in.off_right  * s->pixstep[i];
-        out_off_left[i]  = (s->out.row_left  + s->out.off_lstep) * out->linesize[i]      + s->out.off_left  * s->pixstep[i];
-        out_off_right[i] = (s->out.row_right + s->out.off_rstep) * out->linesize[i]      + s->out.off_right * s->pixstep[i];
+        int hsub = i == 1 || i == 2 ? s->hsub : 0;
+        int vsub = i == 1 || i == 2 ? s->vsub : 0;
+        in_off_left[i]   = (FF_CEIL_RSHIFT(s->in.row_left,   vsub) + s->in.off_lstep)  * ileft->linesize[i]  + FF_CEIL_RSHIFT(s->in.off_left   * s->pixstep[i], hsub);
+        in_off_right[i]  = (FF_CEIL_RSHIFT(s->in.row_right,  vsub) + s->in.off_rstep)  * iright->linesize[i] + FF_CEIL_RSHIFT(s->in.off_right  * s->pixstep[i], hsub);
+        out_off_left[i]  = (FF_CEIL_RSHIFT(s->out.row_left,  vsub) + s->out.off_lstep) * oleft->linesize[i]  + FF_CEIL_RSHIFT(s->out.off_left  * s->pixstep[i], hsub);
+        out_off_right[i] = (FF_CEIL_RSHIFT(s->out.row_right, vsub) + s->out.off_rstep) * oright->linesize[i] + FF_CEIL_RSHIFT(s->out.off_right * s->pixstep[i], hsub);
     }
 
     switch (s->out.format) {
+    case ALTERNATING_LR:
+    case ALTERNATING_RL:
     case SIDE_BY_SIDE_LR:
     case SIDE_BY_SIDE_RL:
     case SIDE_BY_SIDE_2_LR:
@@ -453,25 +541,26 @@
     case INTERLEAVE_ROWS_LR:
     case INTERLEAVE_ROWS_RL:
         for (i = 0; i < s->nb_planes; i++) {
-            av_image_copy_plane(out->data[i] + out_off_left[i],
-                                out->linesize[i] * s->row_step,
-                                inpicref->data[i] + in_off_left[i],
-                                inpicref->linesize[i] * s->row_step,
-                                s->linesize[i], s->height);
-            av_image_copy_plane(out->data[i] + out_off_right[i],
-                                out->linesize[i] * s->row_step,
-                                inpicref->data[i] + in_off_right[i],
-                                inpicref->linesize[i] * s->row_step,
-                                s->linesize[i], s->height);
+            av_image_copy_plane(oleft->data[i] + out_off_left[i],
+                                oleft->linesize[i] * s->row_step,
+                                ileft->data[i] + in_off_left[i],
+                                ileft->linesize[i] * s->row_step,
+                                s->linesize[i], s->pheight[i]);
+            av_image_copy_plane(oright->data[i] + out_off_right[i],
+                                oright->linesize[i] * s->row_step,
+                                iright->data[i] + in_off_right[i],
+                                iright->linesize[i] * s->row_step,
+                                s->linesize[i], s->pheight[i]);
         }
         break;
     case MONO_L:
+        iright = ileft;
     case MONO_R:
         for (i = 0; i < s->nb_planes; i++) {
             av_image_copy_plane(out->data[i], out->linesize[i],
-                                inpicref->data[i] + in_off_left[i],
-                                inpicref->linesize[i],
-                                s->linesize[i], s->height);
+                                iright->data[i] + in_off_left[i],
+                                iright->linesize[i],
+                                s->linesize[i], s->pheight[i]);
         }
         break;
     case ANAGLYPH_RB_GRAY:
@@ -489,7 +578,8 @@
     case ANAGLYPH_YB_COLOR:
     case ANAGLYPH_YB_DUBOIS: {
         int i, x, y, il, ir, o;
-        uint8_t *src = inpicref->data[0];
+        uint8_t *lsrc = ileft->data[0];
+        uint8_t *rsrc = iright->data[0];
         uint8_t *dst = out->data[0];
         int out_width = s->out.width;
         int *ana_matrix[3];
@@ -499,12 +589,12 @@
 
         for (y = 0; y < s->out.height; y++) {
             o   = out->linesize[0] * y;
-            il  = in_off_left[0]  + y * inpicref->linesize[0];
-            ir  = in_off_right[0] + y * inpicref->linesize[0];
+            il  = in_off_left[0]  + y * ileft->linesize[0];
+            ir  = in_off_right[0] + y * iright->linesize[0];
             for (x = 0; x < out_width; x++, il += 3, ir += 3, o+= 3) {
-                dst[o    ] = ana_convert(ana_matrix[0], src + il, src + ir);
-                dst[o + 1] = ana_convert(ana_matrix[1], src + il, src + ir);
-                dst[o + 2] = ana_convert(ana_matrix[2], src + il, src + ir);
+                dst[o    ] = ana_convert(ana_matrix[0], lsrc + il, rsrc + ir);
+                dst[o + 1] = ana_convert(ana_matrix[1], lsrc + il, rsrc + ir);
+                dst[o + 2] = ana_convert(ana_matrix[2], lsrc + il, rsrc + ir);
             }
         }
         break;
@@ -514,9 +604,28 @@
     }
 
     av_frame_free(&inpicref);
+    av_frame_free(&s->prev);
+    if (oright != oleft) {
+        if (s->out.format == ALTERNATING_LR)
+            FFSWAP(AVFrame *, oleft, oright);
+        oright->pts = outlink->frame_count * s->ts_unit;
+        ff_filter_frame(outlink, oright);
+        out = oleft;
+        oleft->pts = outlink->frame_count * s->ts_unit;
+    } else if (s->in.format == ALTERNATING_LR ||
+               s->in.format == ALTERNATING_RL) {
+        out->pts = outlink->frame_count * s->ts_unit;
+    }
     return ff_filter_frame(outlink, out);
 }
 
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    Stereo3DContext *s = ctx->priv;
+
+    av_frame_free(&s->prev);
+}
+
 static const AVFilterPad stereo3d_inputs[] = {
     {
         .name             = "default",
@@ -539,6 +648,7 @@
     .name          = "stereo3d",
     .description   = NULL_IF_CONFIG_SMALL("Convert video stereoscopic 3D view."),
     .priv_size     = sizeof(Stereo3DContext),
+    .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = stereo3d_inputs,
     .outputs       = stereo3d_outputs,
diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c
index 10f07a4..b5f5bc9 100644
--- a/libavfilter/vf_subtitles.c
+++ b/libavfilter/vf_subtitles.c
@@ -323,7 +323,7 @@
     pkt.size = 0;
     while (av_read_frame(fmt, &pkt) >= 0) {
         int i, got_subtitle;
-        AVSubtitle sub;
+        AVSubtitle sub = {0};
 
         if (pkt.stream_index == sid) {
             ret = avcodec_decode_subtitle2(dec_ctx, &sub, &got_subtitle, &pkt);
diff --git a/libavfilter/vf_swapuv.c b/libavfilter/vf_swapuv.c
index 2ca97f9..daa73f2 100644
--- a/libavfilter/vf_swapuv.c
+++ b/libavfilter/vf_swapuv.c
@@ -54,7 +54,7 @@
 {
     int i;
 
-    if (desc->flags & ~(PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA) ||
+    if (desc->flags & ~(AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA) ||
         desc->nb_components < 3 ||
         (desc->comp[1].depth_minus1 != desc->comp[2].depth_minus1))
         return 0;
diff --git a/libavfilter/vf_telecine.c b/libavfilter/vf_telecine.c
index 136df22..6e14548 100644
--- a/libavfilter/vf_telecine.c
+++ b/libavfilter/vf_telecine.c
@@ -103,7 +103,7 @@
 
     for (fmt = 0; fmt < AV_PIX_FMT_NB; fmt++) {
         const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
-        if (!(desc->flags & PIX_FMT_HWACCEL))
+        if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
             ff_add_format(&pix_fmts, fmt);
     }
 
@@ -129,7 +129,7 @@
     if ((ret = av_image_fill_linesizes(tc->stride, inlink->format, inlink->w)) < 0)
         return ret;
 
-    tc->planeheight[1] = tc->planeheight[2] = inlink->h >> desc->log2_chroma_h;
+    tc->planeheight[1] = tc->planeheight[2] = FF_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
     tc->planeheight[0] = tc->planeheight[3] = inlink->h;
 
     tc->nb_planes = av_pix_fmt_count_planes(inlink->format);
@@ -156,6 +156,8 @@
     outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP;
     outlink->frame_rate = fps;
     outlink->time_base = av_mul_q(inlink->time_base, tc->pts);
+    av_log(ctx, AV_LOG_VERBOSE, "TB: %d/%d -> %d/%d\n",
+           inlink->time_base.num, inlink->time_base.den, outlink->time_base.num, outlink->time_base.den);
 
     tc->ts_unit = av_q2d(av_inv_q(av_mul_q(fps, outlink->time_base)));
 
diff --git a/libavfilter/vf_tile.c b/libavfilter/vf_tile.c
index f5eb763..fb3ac85 100644
--- a/libavfilter/vf_tile.c
+++ b/libavfilter/vf_tile.c
@@ -41,6 +41,7 @@
     FFDrawContext draw;
     FFDrawColor blank;
     AVFrame *out_ref;
+    uint8_t rgba_color[4];
 } TileContext;
 
 #define REASONABLE_SIZE 1024
@@ -57,6 +58,7 @@
         AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1024, FLAGS },
     { "padding", "set inner border thickness in pixels", OFFSET(padding),
         AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1024, FLAGS },
+    { "color",   "set the color of the unused area", OFFSET(rgba_color), AV_OPT_TYPE_COLOR, {.str = "black"}, .flags = FLAGS },
     {NULL},
 };
 
@@ -113,8 +115,7 @@
     outlink->frame_rate = av_mul_q(inlink->frame_rate,
                                    (AVRational){ 1, tile->nb_frames });
     ff_draw_init(&tile->draw, inlink->format, 0);
-    /* TODO make the color an option, or find an unified way of choosing it */
-    ff_draw_color(&tile->draw, &tile->blank, (uint8_t[]){ 0, 0, 0, -1 });
+    ff_draw_color(&tile->draw, &tile->blank, tile->rgba_color);
 
     outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP;
 
diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c
index 13b8ce2..1f4de81 100644
--- a/libavfilter/vf_tinterlace.c
+++ b/libavfilter/vf_tinterlace.c
@@ -114,6 +114,7 @@
     TInterlaceContext *tinterlace = ctx->priv;
 
     tinterlace->vsub = desc->log2_chroma_h;
+    outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP;
     outlink->w = inlink->w;
     outlink->h = tinterlace->mode == MODE_MERGE || tinterlace->mode == MODE_PAD ?
         inlink->h*2 : inlink->h;
@@ -130,7 +131,7 @@
 
         /* fill black picture with black */
         for (i = 0; i < 4 && tinterlace->black_data[i]; i++) {
-            int h = i == 1 || i == 2 ? outlink->h >> desc->log2_chroma_h : outlink->h;
+            int h = i == 1 || i == 2 ? FF_CEIL_RSHIFT(outlink->h, desc->log2_chroma_h) : outlink->h;
             memset(tinterlace->black_data[i], black[i],
                    tinterlace->black_linesize[i] * h);
         }
@@ -175,7 +176,7 @@
     int h, i;
 
     for (plane = 0; plane < desc->nb_components; plane++) {
-        int lines = plane == 1 || plane == 2 ? src_h >> vsub : src_h;
+        int lines = plane == 1 || plane == 2 ? FF_CEIL_RSHIFT(src_h, vsub) : src_h;
         int linesize = av_image_get_linesize(format, w, plane);
         uint8_t *dstp = dst[plane];
         const uint8_t *srcp = src[plane];
@@ -183,7 +184,7 @@
         if (linesize < 0)
             return;
 
-        lines /= k;
+        lines = (lines + (src_field == FIELD_UPPER)) / k;
         if (src_field == FIELD_LOWER)
             srcp += src_linesize[plane];
         if (interleave && dst_field == FIELD_LOWER)
@@ -201,7 +202,7 @@
                 if (h == 1) srcp_below = srcp;     // there is no line below
                 for (i = 0; i < linesize; i++) {
                     // this calculation is an integer representation of
-                    // '0.5 * current + 0.25 * above + 0.25 + below'
+                    // '0.5 * current + 0.25 * above + 0.25 * below'
                     // '1 +' is for rounding. */
                     dstp[i] = (1 + srcp[i] + srcp[i] + srcp_above[i] + srcp_below[i]) >> 2;
                 }
@@ -351,21 +352,6 @@
     return ret;
 }
 
-static int request_frame(AVFilterLink *outlink)
-{
-    TInterlaceContext *tinterlace = outlink->src->priv;
-    AVFilterLink *inlink = outlink->src->inputs[0];
-
-    do {
-        int ret;
-
-        if ((ret = ff_request_frame(inlink)) < 0)
-            return ret;
-    } while (!tinterlace->cur);
-
-    return 0;
-}
-
 static const AVFilterPad tinterlace_inputs[] = {
     {
         .name         = "default",
@@ -380,7 +366,6 @@
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_out_props,
-        .request_frame = request_frame,
     },
     { NULL }
 };
diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c
index 2b1fa1f..2170b8a 100644
--- a/libavfilter/vf_transpose.c
+++ b/libavfilter/vf_transpose.c
@@ -67,9 +67,9 @@
 
     for (fmt = 0; fmt < AV_PIX_FMT_NB; fmt++) {
         const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
-        if (!(desc->flags & PIX_FMT_PAL ||
-              desc->flags & PIX_FMT_HWACCEL ||
-              desc->flags & PIX_FMT_BITSTREAM ||
+        if (!(desc->flags & AV_PIX_FMT_FLAG_PAL ||
+              desc->flags & AV_PIX_FMT_FLAG_HWACCEL ||
+              desc->flags & AV_PIX_FMT_FLAG_BITSTREAM ||
               desc->log2_chroma_w != desc->log2_chroma_h))
             ff_add_format(&pix_fmts, fmt);
     }
@@ -133,44 +133,34 @@
         ff_default_get_video_buffer(inlink, w, h);
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+typedef struct ThreadData {
+    AVFrame *in, *out;
+} ThreadData;
+
+static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr,
+                        int nb_jobs)
 {
-    TransContext *trans = inlink->dst->priv;
-    AVFilterLink *outlink = inlink->dst->outputs[0];
-    AVFrame *out;
+    TransContext *trans = ctx->priv;
+    ThreadData *td = arg;
+    AVFrame *out = td->out;
+    AVFrame *in = td->in;
     int plane;
 
-    if (trans->passthrough)
-        return ff_filter_frame(outlink, in);
-
-    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
-    if (!out) {
-        av_frame_free(&in);
-        return AVERROR(ENOMEM);
-    }
-
-    out->pts = in->pts;
-
-    if (in->sample_aspect_ratio.num == 0) {
-        out->sample_aspect_ratio = in->sample_aspect_ratio;
-    } else {
-        out->sample_aspect_ratio.num = in->sample_aspect_ratio.den;
-        out->sample_aspect_ratio.den = in->sample_aspect_ratio.num;
-    }
-
     for (plane = 0; out->data[plane]; plane++) {
         int hsub = plane == 1 || plane == 2 ? trans->hsub : 0;
         int vsub = plane == 1 || plane == 2 ? trans->vsub : 0;
         int pixstep = trans->pixsteps[plane];
         int inh  = in->height  >> vsub;
-        int outw = out->width  >> hsub;
-        int outh = out->height >> vsub;
+        int outw = FF_CEIL_RSHIFT(out->width,  hsub);
+        int outh = FF_CEIL_RSHIFT(out->height, vsub);
+        int start = (outh *  jobnr   ) / nb_jobs;
+        int end   = (outh * (jobnr+1)) / nb_jobs;
         uint8_t *dst, *src;
         int dstlinesize, srclinesize;
         int x, y;
 
-        dst = out->data[plane];
         dstlinesize = out->linesize[plane];
+        dst = out->data[plane] + start * dstlinesize;
         src = in->data[plane];
         srclinesize = in->linesize[plane];
 
@@ -180,11 +170,11 @@
         }
 
         if (trans->dir&2) {
-            dst += out->linesize[plane] * (outh-1);
+            dst = out->data[plane] + dstlinesize * (outh-start-1);
             dstlinesize *= -1;
         }
 
-        for (y = 0; y < outh; y++) {
+        for (y = start; y < end; y++) {
             switch (pixstep) {
             case 1:
                 for (x = 0; x < outw; x++)
@@ -219,6 +209,36 @@
         }
     }
 
+    return 0;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+{
+    AVFilterContext *ctx = inlink->dst;
+    TransContext *trans = ctx->priv;
+    AVFilterLink *outlink = ctx->outputs[0];
+    ThreadData td;
+    AVFrame *out;
+
+    if (trans->passthrough)
+        return ff_filter_frame(outlink, in);
+
+    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+    if (!out) {
+        av_frame_free(&in);
+        return AVERROR(ENOMEM);
+    }
+    av_frame_copy_props(out, in);
+
+    if (in->sample_aspect_ratio.num == 0) {
+        out->sample_aspect_ratio = in->sample_aspect_ratio;
+    } else {
+        out->sample_aspect_ratio.num = in->sample_aspect_ratio.den;
+        out->sample_aspect_ratio.den = in->sample_aspect_ratio.num;
+    }
+
+    td.in = in, td.out = out;
+    ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(outlink->h, ctx->graph->nb_threads));
     av_frame_free(&in);
     return ff_filter_frame(outlink, out);
 }
@@ -227,18 +247,17 @@
 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
 
 static const AVOption transpose_options[] = {
-    { "dir", "Transpose direction", OFFSET(dir), AV_OPT_TYPE_INT, { .i64 = TRANSPOSE_CCLOCK_FLIP },
-        TRANSPOSE_CCLOCK_FLIP, TRANSPOSE_CLOCK_FLIP, FLAGS, "dir" },
-        { "cclock_flip", "counter-clockwise with vertical flip", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK_FLIP }, .unit = "dir" },
-        { "clock",       "clockwise",                            0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK       }, .unit = "dir" },
-        { "cclock",      "counter-clockwise",                    0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK      }, .unit = "dir" },
-        { "clock_flip",  "clockwise with vertical flip",         0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK_FLIP  }, .unit = "dir" },
+    { "dir", "set transpose direction", OFFSET(dir), AV_OPT_TYPE_INT, { .i64 = TRANSPOSE_CCLOCK_FLIP }, 0, 7, FLAGS, "dir" },
+        { "cclock_flip", "rotate counter-clockwise with vertical flip", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK_FLIP }, .unit = "dir" },
+        { "clock",       "rotate clockwise",                            0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK       }, .unit = "dir" },
+        { "cclock",      "rotate counter-clockwise",                    0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK      }, .unit = "dir" },
+        { "clock_flip",  "rotate clockwise with vertical flip",         0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK_FLIP  }, .unit = "dir" },
 
     { "passthrough", "do not apply transposition if the input matches the specified geometry",
       OFFSET(passthrough), AV_OPT_TYPE_INT, {.i64=TRANSPOSE_PT_TYPE_NONE},  0, INT_MAX, FLAGS, "passthrough" },
-    { "none",      "always apply transposition",   0, AV_OPT_TYPE_CONST, {.i64=TRANSPOSE_PT_TYPE_NONE},      INT_MIN, INT_MAX, FLAGS, "passthrough" },
-    { "portrait",  "preserve portrait geometry",   0, AV_OPT_TYPE_CONST, {.i64=TRANSPOSE_PT_TYPE_PORTRAIT},  INT_MIN, INT_MAX, FLAGS, "passthrough" },
-    { "landscape", "preserve landscape geometry",  0, AV_OPT_TYPE_CONST, {.i64=TRANSPOSE_PT_TYPE_LANDSCAPE}, INT_MIN, INT_MAX, FLAGS, "passthrough" },
+        { "none",      "always apply transposition",   0, AV_OPT_TYPE_CONST, {.i64=TRANSPOSE_PT_TYPE_NONE},      INT_MIN, INT_MAX, FLAGS, "passthrough" },
+        { "portrait",  "preserve portrait geometry",   0, AV_OPT_TYPE_CONST, {.i64=TRANSPOSE_PT_TYPE_PORTRAIT},  INT_MIN, INT_MAX, FLAGS, "passthrough" },
+        { "landscape", "preserve landscape geometry",  0, AV_OPT_TYPE_CONST, {.i64=TRANSPOSE_PT_TYPE_LANDSCAPE}, INT_MIN, INT_MAX, FLAGS, "passthrough" },
 
     { NULL },
 };
@@ -275,4 +294,5 @@
 
     .inputs    = avfilter_vf_transpose_inputs,
     .outputs   = avfilter_vf_transpose_outputs,
+    .flags     = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c
index 2d7aab2..9b659bd 100644
--- a/libavfilter/vf_unsharp.c
+++ b/libavfilter/vf_unsharp.c
@@ -36,46 +36,21 @@
  * http://www.engin.umd.umich.edu/~jwvm/ece581/21_GBlur.pdf
  */
 
-#include <float.h> /* DBL_MAX */
-
 #include "avfilter.h"
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
 #include "libavutil/common.h"
+#include "libavutil/imgutils.h"
 #include "libavutil/mem.h"
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
-
-#define MIN_MATRIX_SIZE 3
-#define MAX_MATRIX_SIZE 63
-
-/* right-shift and round-up */
-#define SHIFTUP(x,shift) (-((-(x))>>(shift)))
-
-typedef struct FilterParam {
-    int msize_x;                             ///< matrix width
-    int msize_y;                             ///< matrix height
-    int amount;                              ///< effect amount
-    int steps_x;                             ///< horizontal step count
-    int steps_y;                             ///< vertical step count
-    int scalebits;                           ///< bits to shift pixel
-    int32_t halfscale;                       ///< amount to add to pixel
-    uint32_t *sc[MAX_MATRIX_SIZE - 1];       ///< finite state machine storage
-} FilterParam;
-
-typedef struct {
-    const AVClass *class;
-    int lmsize_x, lmsize_y, cmsize_x, cmsize_y;
-    float lamount, camount;
-    FilterParam luma;   ///< luma parameters (width, height, amount)
-    FilterParam chroma; ///< chroma parameters (width, height, amount)
-    int hsub, vsub;
-} UnsharpContext;
+#include "unsharp.h"
+#include "unsharp_opencl.h"
 
 static void apply_unsharp(      uint8_t *dst, int dst_stride,
                           const uint8_t *src, int src_stride,
-                          int width, int height, FilterParam *fp)
+                          int width, int height, UnsharpFilterParam *fp)
 {
     uint32_t **sc = fp->sc;
     uint32_t sr[MAX_MATRIX_SIZE - 1], tmp1, tmp2;
@@ -90,11 +65,7 @@
     const int32_t halfscale = fp->halfscale;
 
     if (!amount) {
-        if (dst_stride == src_stride)
-            memcpy(dst, src, src_stride * height);
-        else
-            for (y = 0; y < height; y++, dst += dst_stride, src += src_stride)
-                memcpy(dst, src, width);
+        av_image_copy_plane(dst, dst_stride, src, src_stride, width, height);
         return;
     }
 
@@ -131,7 +102,25 @@
     }
 }
 
-static void set_filter_param(FilterParam *fp, int msize_x, int msize_y, float amount)
+static int apply_unsharp_c(AVFilterContext *ctx, AVFrame *in, AVFrame *out)
+{
+    AVFilterLink *inlink = ctx->inputs[0];
+    UnsharpContext *unsharp = ctx->priv;
+    int i, plane_w[3], plane_h[3];
+    UnsharpFilterParam *fp[3];
+    plane_w[0] = inlink->w;
+    plane_w[1] = plane_w[2] = FF_CEIL_RSHIFT(inlink->w, unsharp->hsub);
+    plane_h[0] = inlink->h;
+    plane_h[1] = plane_h[2] = FF_CEIL_RSHIFT(inlink->h, unsharp->vsub);
+    fp[0] = &unsharp->luma;
+    fp[1] = fp[2] = &unsharp->chroma;
+    for (i = 0; i < 3; i++) {
+        apply_unsharp(out->data[i], out->linesize[i], in->data[i], in->linesize[i], plane_w[i], plane_h[i], fp[i]);
+    }
+    return 0;
+}
+
+static void set_filter_param(UnsharpFilterParam *fp, int msize_x, int msize_y, float amount)
 {
     fp->msize_x = msize_x;
     fp->msize_y = msize_y;
@@ -145,12 +134,24 @@
 
 static av_cold int init(AVFilterContext *ctx)
 {
+    int ret = 0;
     UnsharpContext *unsharp = ctx->priv;
 
 
     set_filter_param(&unsharp->luma,   unsharp->lmsize_x, unsharp->lmsize_y, unsharp->lamount);
     set_filter_param(&unsharp->chroma, unsharp->cmsize_x, unsharp->cmsize_y, unsharp->camount);
 
+    unsharp->apply_unsharp = apply_unsharp_c;
+    if (!CONFIG_OPENCL && unsharp->opencl) {
+        av_log(ctx, AV_LOG_ERROR, "OpenCL support was not enabled in this build, cannot be selected\n");
+        return AVERROR(EINVAL);
+    }
+    if (CONFIG_OPENCL && unsharp->opencl) {
+        unsharp->apply_unsharp = ff_opencl_apply_unsharp;
+        ret = ff_opencl_unsharp_init(ctx);
+        if (ret < 0)
+            return ret;
+    }
     return 0;
 }
 
@@ -167,7 +168,7 @@
     return 0;
 }
 
-static int init_filter_param(AVFilterContext *ctx, FilterParam *fp, const char *effect_type, int width)
+static int init_filter_param(AVFilterContext *ctx, UnsharpFilterParam *fp, const char *effect_type, int width)
 {
     int z;
     const char *effect = fp->amount == 0 ? "none" : fp->amount < 0 ? "blur" : "sharpen";
@@ -201,14 +202,14 @@
     ret = init_filter_param(link->dst, &unsharp->luma,   "luma",   link->w);
     if (ret < 0)
         return ret;
-    ret = init_filter_param(link->dst, &unsharp->chroma, "chroma", SHIFTUP(link->w, unsharp->hsub));
+    ret = init_filter_param(link->dst, &unsharp->chroma, "chroma", FF_CEIL_RSHIFT(link->w, unsharp->hsub));
     if (ret < 0)
         return ret;
 
     return 0;
 }
 
-static void free_filter_param(FilterParam *fp)
+static void free_filter_param(UnsharpFilterParam *fp)
 {
     int z;
 
@@ -220,6 +221,10 @@
 {
     UnsharpContext *unsharp = ctx->priv;
 
+    if (CONFIG_OPENCL && unsharp->opencl) {
+        ff_opencl_unsharp_uninit(ctx);
+    }
+
     free_filter_param(&unsharp->luma);
     free_filter_param(&unsharp->chroma);
 }
@@ -229,8 +234,7 @@
     UnsharpContext *unsharp = link->dst->priv;
     AVFilterLink *outlink   = link->dst->outputs[0];
     AVFrame *out;
-    int cw = SHIFTUP(link->w, unsharp->hsub);
-    int ch = SHIFTUP(link->h, unsharp->vsub);
+    int ret = 0;
 
     out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     if (!out) {
@@ -238,12 +242,18 @@
         return AVERROR(ENOMEM);
     }
     av_frame_copy_props(out, in);
+    if (CONFIG_OPENCL && unsharp->opencl) {
+        ret = ff_opencl_unsharp_process_inout_buf(link->dst, in, out);
+        if (ret < 0)
+            goto end;
+    }
 
-    apply_unsharp(out->data[0], out->linesize[0], in->data[0], in->linesize[0], link->w, link->h, &unsharp->luma);
-    apply_unsharp(out->data[1], out->linesize[1], in->data[1], in->linesize[1], cw,      ch,      &unsharp->chroma);
-    apply_unsharp(out->data[2], out->linesize[2], in->data[2], in->linesize[2], cw,      ch,      &unsharp->chroma);
-
+    ret = unsharp->apply_unsharp(link->dst, in, out);
+end:
     av_frame_free(&in);
+
+    if (ret < 0)
+        return ret;
     return ff_filter_frame(outlink, out);
 }
 
@@ -252,18 +262,19 @@
 #define MIN_SIZE 3
 #define MAX_SIZE 63
 static const AVOption unsharp_options[] = {
-    { "luma_msize_x",   "luma matrix horizontal size",   OFFSET(lmsize_x), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
-    { "lx",             "luma matrix horizontal size",   OFFSET(lmsize_x), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
-    { "luma_msize_y",   "luma matrix vertical size",     OFFSET(lmsize_y), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
-    { "ly",             "luma matrix vertical size",     OFFSET(lmsize_y), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
-    { "luma_amount",    "luma effect strength",          OFFSET(lamount),  AV_OPT_TYPE_FLOAT, { .dbl = 1 },       -2,        5, FLAGS },
-    { "la",             "luma effect strength",          OFFSET(lamount),  AV_OPT_TYPE_FLOAT, { .dbl = 1 },       -2,        5, FLAGS },
-    { "chroma_msize_x", "chroma matrix horizontal size", OFFSET(cmsize_x), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
-    { "cx",             "chroma matrix horizontal size", OFFSET(cmsize_x), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
-    { "chroma_msize_y", "chroma matrix vertical size",   OFFSET(cmsize_y), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
-    { "cy",             "chroma matrix vertical size",   OFFSET(cmsize_y), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
-    { "chroma_amount",  "chroma effect strength",        OFFSET(camount),  AV_OPT_TYPE_FLOAT, { .dbl = 0 },       -2,        5, FLAGS },
-    { "ca",             "chroma effect strength",        OFFSET(camount),  AV_OPT_TYPE_FLOAT, { .dbl = 0 },       -2,        5, FLAGS },
+    { "luma_msize_x",   "set luma matrix horizontal size",   OFFSET(lmsize_x), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
+    { "lx",             "set luma matrix horizontal size",   OFFSET(lmsize_x), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
+    { "luma_msize_y",   "set luma matrix vertical size",     OFFSET(lmsize_y), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
+    { "ly",             "set luma matrix vertical size",     OFFSET(lmsize_y), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
+    { "luma_amount",    "set luma effect strength",          OFFSET(lamount),  AV_OPT_TYPE_FLOAT, { .dbl = 1 },       -2,        5, FLAGS },
+    { "la",             "set luma effect strength",          OFFSET(lamount),  AV_OPT_TYPE_FLOAT, { .dbl = 1 },       -2,        5, FLAGS },
+    { "chroma_msize_x", "set chroma matrix horizontal size", OFFSET(cmsize_x), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
+    { "cx",             "set chroma matrix horizontal size", OFFSET(cmsize_x), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
+    { "chroma_msize_y", "set chroma matrix vertical size",   OFFSET(cmsize_y), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
+    { "cy",             "set chroma matrix vertical size",   OFFSET(cmsize_y), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
+    { "chroma_amount",  "set chroma effect strength",        OFFSET(camount),  AV_OPT_TYPE_FLOAT, { .dbl = 0 },       -2,        5, FLAGS },
+    { "ca",             "set chroma effect strength",        OFFSET(camount),  AV_OPT_TYPE_FLOAT, { .dbl = 0 },       -2,        5, FLAGS },
+    { "opencl",         "use OpenCL filtering capabilities", OFFSET(opencl), AV_OPT_TYPE_INT, { .i64 = 0 },        0,        1, FLAGS },
     { NULL },
 };
 
@@ -300,5 +311,5 @@
 
     .inputs    = avfilter_vf_unsharp_inputs,
     .outputs   = avfilter_vf_unsharp_outputs,
-    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_vflip.c b/libavfilter/vf_vflip.c
index 28fa800..fc05e61 100644
--- a/libavfilter/vf_vflip.c
+++ b/libavfilter/vf_vflip.c
@@ -55,9 +55,10 @@
 
     for (i = 0; i < 4; i ++) {
         int vsub = i == 1 || i == 2 ? flip->vsub : 0;
+        int height = FF_CEIL_RSHIFT(h, vsub);
 
         if (frame->data[i]) {
-            frame->data[i] += (((h + (1<<vsub) - 1) >> vsub) - 1) * frame->linesize[i];
+            frame->data[i] += (height - 1) * frame->linesize[i];
             frame->linesize[i] = -frame->linesize[i];
         }
     }
@@ -72,9 +73,10 @@
 
     for (i = 0; i < 4; i ++) {
         int vsub = i == 1 || i == 2 ? flip->vsub : 0;
+        int height = FF_CEIL_RSHIFT(link->h, vsub);
 
         if (frame->data[i]) {
-            frame->data[i] += (((link->h + (1<<vsub)-1)>> vsub)-1) * frame->linesize[i];
+            frame->data[i] += (height - 1) * frame->linesize[i];
             frame->linesize[i] = -frame->linesize[i];
         }
     }
diff --git a/libavfilter/vf_vignette.c b/libavfilter/vf_vignette.c
new file mode 100644
index 0000000..b5fed65
--- /dev/null
+++ b/libavfilter/vf_vignette.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright (c) 2013 Clément Bœsch
+ *
+ * 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
+ */
+
+#include <float.h>  /* DBL_MAX */
+
+#include "libavutil/opt.h"
+#include "libavutil/eval.h"
+#include "libavutil/avassert.h"
+#include "libavutil/pixdesc.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
+
+static const char *const var_names[] = {
+    "w",    // stream width
+    "h",    // stream height
+    "n",    // frame count
+    "pts",  // presentation timestamp expressed in AV_TIME_BASE units
+    "r",    // frame rate
+    "t",    // timestamp expressed in seconds
+    "tb",   // timebase
+    NULL
+};
+
+enum var_name {
+    VAR_W,
+    VAR_H,
+    VAR_N,
+    VAR_PTS,
+    VAR_R,
+    VAR_T,
+    VAR_TB,
+    VAR_NB
+};
+
+typedef struct {
+    const AVClass *class;
+    const AVPixFmtDescriptor *desc;
+    int backward;
+    enum EvalMode { EVAL_MODE_INIT, EVAL_MODE_FRAME, EVAL_MODE_NB } eval_mode;
+#define DEF_EXPR_FIELDS(name) AVExpr *name##_pexpr; char *name##_expr; double name
+    DEF_EXPR_FIELDS(angle);
+    DEF_EXPR_FIELDS(x0);
+    DEF_EXPR_FIELDS(y0);
+    double var_values[VAR_NB];
+    float *fmap;
+    int fmap_linesize;
+    double dmax;
+    float xscale, yscale;
+    uint32_t dither;
+    int do_dither;
+    AVRational aspect;
+    AVRational scale;
+} VignetteContext;
+
+#define OFFSET(x) offsetof(VignetteContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption vignette_options[] = {
+    { "angle", "set lens angle", OFFSET(angle_expr), AV_OPT_TYPE_STRING, {.str="PI/5"}, .flags = FLAGS },
+    { "a",     "set lens angle", OFFSET(angle_expr), AV_OPT_TYPE_STRING, {.str="PI/5"}, .flags = FLAGS },
+    { "x0", "set circle center position on x-axis", OFFSET(x0_expr), AV_OPT_TYPE_STRING, {.str="w/2"}, .flags = FLAGS },
+    { "y0", "set circle center position on y-axis", OFFSET(y0_expr), AV_OPT_TYPE_STRING, {.str="h/2"}, .flags = FLAGS },
+    { "mode", "set forward/backward mode", OFFSET(backward), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS, "mode" },
+        { "forward",  NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0}, INT_MIN, INT_MAX, FLAGS, "mode"},
+        { "backward", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1}, INT_MIN, INT_MAX, FLAGS, "mode"},
+    { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_INIT}, 0, EVAL_MODE_NB-1, FLAGS, "eval" },
+         { "init",  "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT},  .flags = FLAGS, .unit = "eval" },
+         { "frame", "eval expressions for each frame",             0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" },
+    { "dither", "set dithering", OFFSET(do_dither), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, FLAGS },
+    { "aspect", "set aspect ratio", OFFSET(aspect), AV_OPT_TYPE_RATIONAL, {.dbl = 1}, 0, DBL_MAX, .flags = FLAGS },
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(vignette);
+
+static av_cold int init(AVFilterContext *ctx)
+{
+    VignetteContext *s = ctx->priv;
+
+#define PARSE_EXPR(name) do {                                               \
+    int ret = av_expr_parse(&s->name##_pexpr,  s->name##_expr, var_names,   \
+                            NULL, NULL, NULL, NULL, 0, ctx);                \
+    if (ret < 0) {                                                          \
+        av_log(ctx, AV_LOG_ERROR, "Unable to parse expression for '"        \
+               AV_STRINGIFY(name) "'\n");                                   \
+        return ret;                                                         \
+    }                                                                       \
+} while (0)
+
+    PARSE_EXPR(angle);
+    PARSE_EXPR(x0);
+    PARSE_EXPR(y0);
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    VignetteContext *s = ctx->priv;
+    av_freep(&s->fmap);
+    av_expr_free(s->angle_pexpr);
+    av_expr_free(s->x0_pexpr);
+    av_expr_free(s->y0_pexpr);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat pix_fmts[] = {
+        AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P,
+        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV411P,
+        AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P,
+        AV_PIX_FMT_RGB24,   AV_PIX_FMT_BGR24,
+        AV_PIX_FMT_GRAY8,
+        AV_PIX_FMT_NONE
+    };
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+static double get_natural_factor(const VignetteContext *s, int x, int y)
+{
+    const int xx = (x - s->x0) * s->xscale;
+    const int yy = (y - s->y0) * s->yscale;
+    const double dnorm = hypot(xx, yy) / s->dmax;
+    if (dnorm > 1) {
+        return 0;
+    } else {
+        const double c = cos(s->angle * dnorm);
+        return (c*c)*(c*c); // do not remove braces, it helps compilers
+    }
+}
+
+#define TS2D(ts)     ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
+#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts) * av_q2d(tb))
+
+static void update_context(VignetteContext *s, AVFilterLink *inlink, AVFrame *frame)
+{
+    int x, y;
+    float *dst = s->fmap;
+    int dst_linesize = s->fmap_linesize;
+
+    if (frame) {
+        s->var_values[VAR_N]   = inlink->frame_count;
+        s->var_values[VAR_T]   = TS2T(frame->pts, inlink->time_base);
+        s->var_values[VAR_PTS] = TS2D(frame->pts);
+    } else {
+        s->var_values[VAR_N]   = 0;
+        s->var_values[VAR_T]   = NAN;
+        s->var_values[VAR_PTS] = NAN;
+    }
+
+    s->angle = av_clipf(av_expr_eval(s->angle_pexpr, s->var_values, NULL), 0, M_PI_2);
+    s->x0 = av_expr_eval(s->x0_pexpr, s->var_values, NULL);
+    s->y0 = av_expr_eval(s->y0_pexpr, s->var_values, NULL);
+
+    if (s->backward) {
+        for (y = 0; y < inlink->h; y++) {
+            for (x = 0; x < inlink->w; x++)
+                dst[x] = 1. / get_natural_factor(s, x, y);
+            dst += dst_linesize;
+        }
+    } else {
+        for (y = 0; y < inlink->h; y++) {
+            for (x = 0; x < inlink->w; x++)
+                dst[x] = get_natural_factor(s, x, y);
+            dst += dst_linesize;
+        }
+    }
+}
+
+static inline double get_dither_value(VignetteContext *s)
+{
+    double dv = 0;
+    if (s->do_dither) {
+        dv = s->dither / (double)(1LL<<32);
+        s->dither = s->dither * 1664525 + 1013904223;
+    }
+    return dv;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+{
+    unsigned x, y;
+    AVFilterContext *ctx = inlink->dst;
+    VignetteContext *s = ctx->priv;
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+    AVFrame *out;
+
+    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+    if (!out) {
+        av_frame_free(&in);
+        return AVERROR(ENOMEM);
+    }
+    av_frame_copy_props(out, in);
+
+    if (s->eval_mode == EVAL_MODE_FRAME)
+        update_context(s, inlink, in);
+
+    if (s->desc->flags & AV_PIX_FMT_FLAG_RGB) {
+        uint8_t       *dst = out->data[0];
+        const uint8_t *src = in ->data[0];
+        const float *fmap = s->fmap;
+        const int dst_linesize = out->linesize[0];
+        const int src_linesize = in ->linesize[0];
+        const int fmap_linesize = s->fmap_linesize;
+
+        for (y = 0; y < inlink->h; y++) {
+            uint8_t       *dstp = dst;
+            const uint8_t *srcp = src;
+
+            for (x = 0; x < inlink->w; x++, dstp += 3, srcp += 3) {
+                const float f = fmap[x];
+
+                dstp[0] = av_clip_uint8(srcp[0] * f + get_dither_value(s));
+                dstp[1] = av_clip_uint8(srcp[1] * f + get_dither_value(s));
+                dstp[2] = av_clip_uint8(srcp[2] * f + get_dither_value(s));
+            }
+            dst += dst_linesize;
+            src += src_linesize;
+            fmap += fmap_linesize;
+        }
+    } else {
+        int plane;
+
+        for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) {
+            uint8_t       *dst = out->data[plane];
+            const uint8_t *src = in ->data[plane];
+            const float *fmap = s->fmap;
+            const int dst_linesize = out->linesize[plane];
+            const int src_linesize = in ->linesize[plane];
+            const int fmap_linesize = s->fmap_linesize;
+            const int chroma = plane == 1 || plane == 2;
+            const int hsub = chroma ? s->desc->log2_chroma_w : 0;
+            const int vsub = chroma ? s->desc->log2_chroma_h : 0;
+            const int w = FF_CEIL_RSHIFT(inlink->w, hsub);
+            const int h = FF_CEIL_RSHIFT(inlink->h, vsub);
+
+            for (y = 0; y < h; y++) {
+                uint8_t *dstp = dst;
+                const uint8_t *srcp = src;
+
+                for (x = 0; x < w; x++) {
+                    const double dv = get_dither_value(s);
+                    if (chroma) *dstp++ = av_clip_uint8(fmap[x << hsub] * (*srcp++ - 127) + 127 + dv);
+                    else        *dstp++ = av_clip_uint8(fmap[x        ] *  *srcp++              + dv);
+                }
+                dst += dst_linesize;
+                src += src_linesize;
+                fmap += fmap_linesize << vsub;
+            }
+        }
+    }
+
+    return ff_filter_frame(outlink, out);
+}
+
+static int config_props(AVFilterLink *inlink)
+{
+    VignetteContext *s = inlink->dst->priv;
+    AVRational sar = inlink->sample_aspect_ratio;
+
+    s->desc = av_pix_fmt_desc_get(inlink->format);
+    s->var_values[VAR_W]  = inlink->w;
+    s->var_values[VAR_H]  = inlink->h;
+    s->var_values[VAR_TB] = av_q2d(inlink->time_base);
+    s->var_values[VAR_R]  = inlink->frame_rate.num == 0 || inlink->frame_rate.den == 0 ?
+        NAN : av_q2d(inlink->frame_rate);
+
+    if (!sar.num || !sar.den)
+        sar.num = sar.den = 1;
+    if (sar.num > sar.den) {
+        s->xscale = av_q2d(av_div_q(sar, s->aspect));
+        s->yscale = 1;
+    } else {
+        s->yscale = av_q2d(av_div_q(s->aspect, sar));
+        s->xscale = 1;
+    }
+    s->dmax = hypot(inlink->w / 2., inlink->h / 2.);
+    av_log(s, AV_LOG_DEBUG, "xscale=%f yscale=%f dmax=%f\n",
+           s->xscale, s->yscale, s->dmax);
+
+    s->fmap_linesize = FFALIGN(inlink->w, 32);
+    s->fmap = av_malloc(s->fmap_linesize * inlink->h * sizeof(*s->fmap));
+    if (!s->fmap)
+        return AVERROR(ENOMEM);
+
+    if (s->eval_mode == EVAL_MODE_INIT)
+        update_context(s, inlink, NULL);
+
+    return 0;
+}
+
+static const AVFilterPad vignette_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = filter_frame,
+        .config_props = config_props,
+    },
+    { NULL }
+};
+
+static const AVFilterPad vignette_outputs[] = {
+     {
+         .name = "default",
+         .type = AVMEDIA_TYPE_VIDEO,
+     },
+     { NULL }
+};
+
+AVFilter avfilter_vf_vignette = {
+    .name          = "vignette",
+    .description   = NULL_IF_CONFIG_SMALL("Make or reverse a vignette effect."),
+    .priv_size     = sizeof(VignetteContext),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+    .inputs        = vignette_inputs,
+    .outputs       = vignette_outputs,
+    .priv_class    = &vignette_class,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
+};
diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c
index 5d8934b..5789da6 100644
--- a/libavfilter/vf_yadif.c
+++ b/libavfilter/vf_yadif.c
@@ -28,8 +28,13 @@
 #include "video.h"
 #include "yadif.h"
 
-#undef NDEBUG
-#include <assert.h>
+typedef struct ThreadData {
+    AVFrame *frame;
+    int plane;
+    int w, h;
+    int parity;
+    int tff;
+} ThreadData;
 
 #define CHECK(j)\
     {   int score = FFABS(cur[mrefs - 1 + (j)] - cur[prefs - 1 - (j)])\
@@ -103,6 +108,7 @@
     FILTER(0, w, 1)
 }
 
+#define MAX_ALIGN 8
 static void filter_edges(void *dst1, void *prev1, void *cur1, void *next1,
                          int w, int prefs, int mrefs, int parity, int mode)
 {
@@ -118,13 +124,14 @@
      * for is_not_edge should let the compiler ignore the whole branch. */
     FILTER(0, 3, 0)
 
-    dst  = (uint8_t*)dst1  + w - 3;
-    prev = (uint8_t*)prev1 + w - 3;
-    cur  = (uint8_t*)cur1  + w - 3;
-    next = (uint8_t*)next1 + w - 3;
+    dst  = (uint8_t*)dst1  + w - (MAX_ALIGN-1);
+    prev = (uint8_t*)prev1 + w - (MAX_ALIGN-1);
+    cur  = (uint8_t*)cur1  + w - (MAX_ALIGN-1);
+    next = (uint8_t*)next1 + w - (MAX_ALIGN-1);
     prev2 = (uint8_t*)(parity ? prev : cur);
     next2 = (uint8_t*)(parity ? cur  : next);
 
+    FILTER(w - (MAX_ALIGN-1), w - 3, 1)
     FILTER(w - 3, w, 0)
 }
 
@@ -162,60 +169,77 @@
 
     FILTER(0, 3, 0)
 
-    dst   = (uint16_t*)dst1  + w - 3;
-    prev  = (uint16_t*)prev1 + w - 3;
-    cur   = (uint16_t*)cur1  + w - 3;
-    next  = (uint16_t*)next1 + w - 3;
+    dst   = (uint16_t*)dst1  + w - (MAX_ALIGN/2-1);
+    prev  = (uint16_t*)prev1 + w - (MAX_ALIGN/2-1);
+    cur   = (uint16_t*)cur1  + w - (MAX_ALIGN/2-1);
+    next  = (uint16_t*)next1 + w - (MAX_ALIGN/2-1);
     prev2 = (uint16_t*)(parity ? prev : cur);
     next2 = (uint16_t*)(parity ? cur  : next);
 
+    FILTER(w - (MAX_ALIGN/2-1), w - 3, 1)
     FILTER(w - 3, w, 0)
 }
 
+static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+    YADIFContext *s = ctx->priv;
+    ThreadData *td  = arg;
+    int refs = s->cur->linesize[td->plane];
+    int df = (s->csp->comp[td->plane].depth_minus1 + 8) / 8;
+    int pix_3 = 3 * df;
+    int slice_start = (td->h *  jobnr   ) / nb_jobs;
+    int slice_end   = (td->h * (jobnr+1)) / nb_jobs;
+    int y;
+
+    /* filtering reads 3 pixels to the left/right; to avoid invalid reads,
+     * we need to call the c variant which avoids this for border pixels
+     */
+    for (y = slice_start; y < slice_end; y++) {
+        if ((y ^ td->parity) & 1) {
+            uint8_t *prev = &s->prev->data[td->plane][y * refs];
+            uint8_t *cur  = &s->cur ->data[td->plane][y * refs];
+            uint8_t *next = &s->next->data[td->plane][y * refs];
+            uint8_t *dst  = &td->frame->data[td->plane][y * td->frame->linesize[td->plane]];
+            int     mode  = y == 1 || y + 2 == td->h ? 2 : s->mode;
+            s->filter_line(dst + pix_3, prev + pix_3, cur + pix_3,
+                           next + pix_3, td->w - (3 + MAX_ALIGN/df-1),
+                           y + 1 < td->h ? refs : -refs,
+                           y ? -refs : refs,
+                           td->parity ^ td->tff, mode);
+            s->filter_edges(dst, prev, cur, next, td->w,
+                            y + 1 < td->h ? refs : -refs,
+                            y ? -refs : refs,
+                            td->parity ^ td->tff, mode);
+        } else {
+            memcpy(&td->frame->data[td->plane][y * td->frame->linesize[td->plane]],
+                   &s->cur->data[td->plane][y * refs], td->w * df);
+        }
+    }
+    return 0;
+}
+
 static void filter(AVFilterContext *ctx, AVFrame *dstpic,
                    int parity, int tff)
 {
     YADIFContext *yadif = ctx->priv;
-    int y, i;
+    ThreadData td = { .frame = dstpic, .parity = parity, .tff = tff };
+    int i;
 
     for (i = 0; i < yadif->csp->nb_components; i++) {
         int w = dstpic->width;
         int h = dstpic->height;
-        int refs = yadif->cur->linesize[i];
-        int df = (yadif->csp->comp[i].depth_minus1 + 8) / 8;
-        int pix_3 = 3 * df;
 
         if (i == 1 || i == 2) {
-        /* Why is this not part of the per-plane description thing? */
-            w >>= yadif->csp->log2_chroma_w;
-            h >>= yadif->csp->log2_chroma_h;
+            w = FF_CEIL_RSHIFT(w, yadif->csp->log2_chroma_w);
+            h = FF_CEIL_RSHIFT(h, yadif->csp->log2_chroma_h);
         }
 
-        /* filtering reads 3 pixels to the left/right; to avoid invalid reads,
-         * we need to call the c variant which avoids this for border pixels
-         */
 
-        for (y = 0; y < h; y++) {
-            if ((y ^ parity) & 1) {
-                uint8_t *prev = &yadif->prev->data[i][y * refs];
-                uint8_t *cur  = &yadif->cur ->data[i][y * refs];
-                uint8_t *next = &yadif->next->data[i][y * refs];
-                uint8_t *dst  = &dstpic->data[i][y * dstpic->linesize[i]];
-                int     mode  = y == 1 || y + 2 == h ? 2 : yadif->mode;
-                yadif->filter_line(dst + pix_3, prev + pix_3, cur + pix_3,
-                                   next + pix_3, w - 6,
-                                   y + 1 < h ? refs : -refs,
-                                   y ? -refs : refs,
-                                   parity ^ tff, mode);
-                yadif->filter_edges(dst, prev, cur, next, w,
-                                    y + 1 < h ? refs : -refs,
-                                    y ? -refs : refs,
-                                    parity ^ tff, mode);
-            } else {
-                memcpy(&dstpic->data[i][y * dstpic->linesize[i]],
-                       &yadif->cur->data[i][y * refs], w * df);
-            }
-        }
+        td.w       = w;
+        td.h       = h;
+        td.plane   = i;
+
+        ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(h, ctx->graph->nb_threads));
     }
 
     emms_c();
@@ -280,7 +304,7 @@
     if (!yadif->cur)
         return 0;
 
-    if (yadif->deint && !yadif->cur->interlaced_frame) {
+    if ((yadif->deint && !yadif->cur->interlaced_frame) || ctx->is_disabled) {
         yadif->out  = av_frame_clone(yadif->cur);
         if (!yadif->out)
             return AVERROR(ENOMEM);
@@ -484,4 +508,5 @@
 
     .inputs    = avfilter_vf_yadif_inputs,
     .outputs   = avfilter_vf_yadif_outputs,
+    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vsrc_life.c b/libavfilter/vsrc_life.c
index 85f0989..e56f51e 100644
--- a/libavfilter/vsrc_life.c
+++ b/libavfilter/vsrc_life.c
@@ -65,9 +65,6 @@
     uint32_t random_seed;
     int stitch;
     int mold;
-    char  *life_color_str;
-    char *death_color_str;
-    char  *mold_color_str;
     uint8_t  life_color[4];
     uint8_t death_color[4];
     uint8_t  mold_color[4];
@@ -93,9 +90,9 @@
     { "seed",        "set the seed for filling the initial grid randomly", OFFSET(random_seed), AV_OPT_TYPE_INT, {.i64=-1}, -1, UINT32_MAX, FLAGS },
     { "stitch",      "stitch boundaries", OFFSET(stitch), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS },
     { "mold",        "set mold speed for dead cells", OFFSET(mold), AV_OPT_TYPE_INT, {.i64=0}, 0, 0xFF, FLAGS },
-    { "life_color",  "set life color",  OFFSET( life_color_str), AV_OPT_TYPE_STRING, {.str="white"}, CHAR_MIN, CHAR_MAX, FLAGS },
-    { "death_color", "set death color", OFFSET(death_color_str), AV_OPT_TYPE_STRING, {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS },
-    { "mold_color",  "set mold color",  OFFSET( mold_color_str), AV_OPT_TYPE_STRING, {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "life_color",  "set life color",  OFFSET( life_color), AV_OPT_TYPE_COLOR, {.str="white"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "death_color", "set death color", OFFSET(death_color), AV_OPT_TYPE_COLOR, {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "mold_color",  "set mold color",  OFFSET( mold_color), AV_OPT_TYPE_COLOR, {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS },
     { NULL },
 };
 
@@ -231,19 +228,6 @@
     if ((ret = parse_rule(&life->born_rule, &life->stay_rule, life->rule_str, ctx)) < 0)
         return ret;
 
-#define PARSE_COLOR(name) do { \
-    if ((ret = av_parse_color(life->name ## _color, life->name ## _color_str, -1, ctx))) { \
-        av_log(ctx, AV_LOG_ERROR, "Invalid " #name " color '%s'\n", \
-               life->name ## _color_str); \
-        return ret; \
-    } \
-    av_freep(&life->name ## _color_str); \
-} while (0)
-
-    PARSE_COLOR(life);
-    PARSE_COLOR(death);
-    PARSE_COLOR(mold);
-
     if (!life->mold && memcmp(life->mold_color, "\x00\x00\x00", 3))
         av_log(ctx, AV_LOG_WARNING,
                "Mold color is set while mold isn't, ignoring the color.\n");
diff --git a/libavfilter/vsrc_mptestsrc.c b/libavfilter/vsrc_mptestsrc.c
index e931c76..fe07140 100644
--- a/libavfilter/vsrc_mptestsrc.c
+++ b/libavfilter/vsrc_mptestsrc.c
@@ -301,7 +301,8 @@
 {
     MPTestContext *test = outlink->src->priv;
     AVFrame *picref;
-    int w = WIDTH, h = HEIGHT, cw = w>>test->hsub, ch = h>>test->vsub;
+    int w = WIDTH, h = HEIGHT,
+        cw = FF_CEIL_RSHIFT(w, test->hsub), ch = FF_CEIL_RSHIFT(h, test->vsub);
     unsigned int frame = test->frame_nb;
     enum test_type tt = test->test;
     int i;
diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c
index 1b474a2..be3266a 100644
--- a/libavfilter/vsrc_testsrc.c
+++ b/libavfilter/vsrc_testsrc.c
@@ -55,75 +55,51 @@
     int64_t pts;
     int64_t duration;           ///< duration expressed in microseconds
     AVRational sar;             ///< sample aspect ratio
-    int nb_decimals;
     int draw_once;              ///< draw only the first frame, always put out the same picture
+    int draw_once_reset;        ///< draw only the first frame or in case of reset
     AVFrame *picref;            ///< cached reference containing the painted picture
 
     void (* fill_picture_fn)(AVFilterContext *ctx, AVFrame *frame);
 
+    /* only used by testsrc */
+    int nb_decimals;
+
     /* only used by color */
-    char *color_str;
     FFDrawContext draw;
     FFDrawColor color;
     uint8_t color_rgba[4];
 
     /* only used by rgbtest */
     uint8_t rgba_map[4];
+
+    /* only used by haldclut */
+    int level;
 } TestSourceContext;
 
 #define OFFSET(x) offsetof(TestSourceContext, x)
 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
 
-#define COMMON_OPTIONS \
+#define SIZE_OPTIONS \
     { "size",     "set video size",     OFFSET(w),        AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\
     { "s",        "set video size",     OFFSET(w),        AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\
+
+#define COMMON_OPTIONS_NOSIZE \
     { "rate",     "set video rate",     OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },\
     { "r",        "set video rate",     OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },\
     { "duration", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\
     { "d",        "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\
     { "sar",      "set video sample aspect ratio", OFFSET(sar), AV_OPT_TYPE_RATIONAL, {.dbl= 1},  0, INT_MAX, FLAGS },
 
-
-static const AVOption color_options[] = {
-    /* only used by color */
-    { "color", "set color", OFFSET(color_str), AV_OPT_TYPE_STRING, {.str = "black"}, CHAR_MIN, CHAR_MAX, FLAGS },
-    { "c",     "set color", OFFSET(color_str), AV_OPT_TYPE_STRING, {.str = "black"}, CHAR_MIN, CHAR_MAX, FLAGS },
-
-    COMMON_OPTIONS
-    { NULL },
-};
+#define COMMON_OPTIONS SIZE_OPTIONS COMMON_OPTIONS_NOSIZE
 
 static const AVOption options[] = {
     COMMON_OPTIONS
-    /* only used by testsrc */
-    { "decimals", "set number of decimals to show", OFFSET(nb_decimals), AV_OPT_TYPE_INT, {.i64=0},  0, 17, FLAGS },
-    { "n",        "set number of decimals to show", OFFSET(nb_decimals), AV_OPT_TYPE_INT, {.i64=0},  0, 17, FLAGS },
-
-    { NULL },
+    { NULL }
 };
 
 static av_cold int init(AVFilterContext *ctx)
 {
     TestSourceContext *test = ctx->priv;
-    int ret = 0;
-
-    if (test->nb_decimals && strcmp(ctx->filter->name, "testsrc")) {
-        av_log(ctx, AV_LOG_WARNING,
-               "Option 'decimals' is ignored with source '%s'\n",
-               ctx->filter->name);
-    }
-
-    if (test->color_str) {
-        if (!strcmp(ctx->filter->name, "color")) {
-            ret = av_parse_color(test->color_rgba, test->color_str, -1, ctx);
-            if (ret < 0)
-                return ret;
-        } else {
-            av_log(ctx, AV_LOG_WARNING,
-                   "Option 'color' is ignored with source '%s'\n",
-                   ctx->filter->name);
-        }
-    }
 
     test->time_base = av_inv_q(test->frame_rate);
     test->nb_frame = 0;
@@ -166,6 +142,10 @@
         return AVERROR_EOF;
 
     if (test->draw_once) {
+        if (test->draw_once_reset) {
+            av_frame_free(&test->picref);
+            test->draw_once_reset = 0;
+        }
         if (!test->picref) {
             test->picref =
                 ff_get_video_buffer(outlink, test->w, test->h);
@@ -195,6 +175,13 @@
 
 #if CONFIG_COLOR_FILTER
 
+static const AVOption color_options[] = {
+    { "color", "set color", OFFSET(color_rgba), AV_OPT_TYPE_COLOR, {.str = "black"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "c",     "set color", OFFSET(color_rgba), AV_OPT_TYPE_COLOR, {.str = "black"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    COMMON_OPTIONS
+    { NULL }
+};
+
 AVFILTER_DEFINE_CLASS(color);
 
 static void color_fill_picture(AVFilterContext *ctx, AVFrame *picref)
@@ -236,11 +223,31 @@
     if ((ret = config_props(inlink)) < 0)
         return ret;
 
-    av_log(ctx, AV_LOG_VERBOSE, "color:0x%02x%02x%02x%02x\n",
-           test->color_rgba[0], test->color_rgba[1], test->color_rgba[2], test->color_rgba[3]);
     return 0;
 }
 
+static int color_process_command(AVFilterContext *ctx, const char *cmd, const char *args,
+                                 char *res, int res_len, int flags)
+{
+    TestSourceContext *test = ctx->priv;
+    int ret;
+
+    if (!strcmp(cmd, "color") || !strcmp(cmd, "c")) {
+        uint8_t color_rgba[4];
+
+        ret = av_parse_color(color_rgba, args, -1, ctx);
+        if (ret < 0)
+            return ret;
+
+        memcpy(test->color_rgba, color_rgba, sizeof(color_rgba));
+        ff_draw_color(&test->draw, &test->color, test->color_rgba);
+        test->draw_once_reset = 1;
+        return 0;
+    }
+
+    return AVERROR(ENOSYS);
+}
+
 static const AVFilterPad color_outputs[] = {
     {
         .name          = "default",
@@ -263,10 +270,140 @@
     .query_formats = color_query_formats,
     .inputs        = NULL,
     .outputs       = color_outputs,
+    .process_command = color_process_command,
 };
 
 #endif /* CONFIG_COLOR_FILTER */
 
+#if CONFIG_HALDCLUTSRC_FILTER
+
+static const AVOption haldclutsrc_options[] = {
+    { "level", "set level", OFFSET(level), AV_OPT_TYPE_INT, {.i64 = 6}, 2, 8, FLAGS },
+    COMMON_OPTIONS_NOSIZE
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(haldclutsrc);
+
+static void haldclutsrc_fill_picture(AVFilterContext *ctx, AVFrame *frame)
+{
+    int i, j, k, x = 0, y = 0, is16bit = 0, step;
+    uint32_t alpha = 0;
+    const TestSourceContext *hc = ctx->priv;
+    int level = hc->level;
+    float scale;
+    const int w = frame->width;
+    const int h = frame->height;
+    const uint8_t *data = frame->data[0];
+    const int linesize  = frame->linesize[0];
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
+    uint8_t rgba_map[4];
+
+    av_assert0(w == h && w == level*level*level);
+
+    ff_fill_rgba_map(rgba_map, frame->format);
+
+    switch (frame->format) {
+    case AV_PIX_FMT_RGB48:
+    case AV_PIX_FMT_BGR48:
+    case AV_PIX_FMT_RGBA64:
+    case AV_PIX_FMT_BGRA64:
+        is16bit = 1;
+        alpha = 0xffff;
+        break;
+    case AV_PIX_FMT_RGBA:
+    case AV_PIX_FMT_BGRA:
+    case AV_PIX_FMT_ARGB:
+    case AV_PIX_FMT_ABGR:
+        alpha = 0xff;
+        break;
+    }
+
+    step  = av_get_padded_bits_per_pixel(desc) >> (3 + is16bit);
+    scale = ((float)(1 << (8*(is16bit+1))) - 1) / (level*level - 1);
+
+#define LOAD_CLUT(nbits) do {                                                   \
+    uint##nbits##_t *dst = ((uint##nbits##_t *)(data + y*linesize)) + x*step;   \
+    dst[rgba_map[0]] = av_clip_uint##nbits(i * scale);                          \
+    dst[rgba_map[1]] = av_clip_uint##nbits(j * scale);                          \
+    dst[rgba_map[2]] = av_clip_uint##nbits(k * scale);                          \
+    if (step == 4)                                                              \
+        dst[rgba_map[3]] = alpha;                                               \
+} while (0)
+
+    level *= level;
+    for (k = 0; k < level; k++) {
+        for (j = 0; j < level; j++) {
+            for (i = 0; i < level; i++) {
+                if (!is16bit)
+                    LOAD_CLUT(8);
+                else
+                    LOAD_CLUT(16);
+                if (++x == w) {
+                    x = 0;
+                    y++;
+                }
+            }
+        }
+    }
+}
+
+static av_cold int haldclutsrc_init(AVFilterContext *ctx)
+{
+    TestSourceContext *hc = ctx->priv;
+    hc->fill_picture_fn = haldclutsrc_fill_picture;
+    hc->draw_once = 1;
+    return init(ctx);
+}
+
+static int haldclutsrc_query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat pix_fmts[] = {
+        AV_PIX_FMT_RGB24,  AV_PIX_FMT_BGR24,
+        AV_PIX_FMT_RGBA,   AV_PIX_FMT_BGRA,
+        AV_PIX_FMT_ARGB,   AV_PIX_FMT_ABGR,
+        AV_PIX_FMT_0RGB,   AV_PIX_FMT_0BGR,
+        AV_PIX_FMT_RGB0,   AV_PIX_FMT_BGR0,
+        AV_PIX_FMT_RGB48,  AV_PIX_FMT_BGR48,
+        AV_PIX_FMT_RGBA64, AV_PIX_FMT_BGRA64,
+        AV_PIX_FMT_NONE,
+    };
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+static int haldclutsrc_config_props(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    TestSourceContext *hc = ctx->priv;
+
+    hc->w = hc->h = hc->level * hc->level * hc->level;
+    return config_props(outlink);
+}
+
+static const AVFilterPad haldclutsrc_outputs[] = {
+    {
+        .name          = "default",
+        .type          = AVMEDIA_TYPE_VIDEO,
+        .request_frame = request_frame,
+        .config_props  = haldclutsrc_config_props,
+    },
+    {  NULL }
+};
+
+AVFilter avfilter_vsrc_haldclutsrc = {
+    .name            = "haldclutsrc",
+    .description     = NULL_IF_CONFIG_SMALL("Provide an identity Hald CLUT."),
+    .priv_class      = &haldclutsrc_class,
+    .priv_size       = sizeof(TestSourceContext),
+    .init            = haldclutsrc_init,
+    .uninit          = uninit,
+    .query_formats   = haldclutsrc_query_formats,
+    .inputs          = NULL,
+    .outputs         = haldclutsrc_outputs,
+};
+#endif /* CONFIG_HALDCLUTSRC_FILTER */
+
 #if CONFIG_NULLSRC_FILTER
 
 #define nullsrc_options options
@@ -307,7 +444,13 @@
 
 #if CONFIG_TESTSRC_FILTER
 
-#define testsrc_options options
+static const AVOption testsrc_options[] = {
+    COMMON_OPTIONS
+    { "decimals", "set number of decimals to show", OFFSET(nb_decimals), AV_OPT_TYPE_INT, {.i64=0},  0, 17, FLAGS },
+    { "n",        "set number of decimals to show", OFFSET(nb_decimals), AV_OPT_TYPE_INT, {.i64=0},  0, 17, FLAGS },
+    { NULL }
+};
+
 AVFILTER_DEFINE_CLASS(testsrc);
 
 /**
@@ -432,7 +575,7 @@
     }
 
     /* draw sliding color line */
-    p0 = p = data + frame->linesize[0] * height * 3/4;
+    p0 = p = data + frame->linesize[0] * (height * 3/4);
     grad = (256 * test->nb_frame * test->time_base.num / test->time_base.den) %
         GRADIENT_SIZE;
     rgrad = 0;
diff --git a/libavfilter/x86/Makefile b/libavfilter/x86/Makefile
index cd97347..0b19c4b 100644
--- a/libavfilter/x86/Makefile
+++ b/libavfilter/x86/Makefile
@@ -1,5 +1,6 @@
 OBJS-$(CONFIG_GRADFUN_FILTER)                += x86/vf_gradfun.o
 OBJS-$(CONFIG_HQDN3D_FILTER)                 += x86/vf_hqdn3d_init.o
+OBJS-$(CONFIG_SPP_FILTER)                    += x86/vf_spp.o
 OBJS-$(CONFIG_VOLUME_FILTER)                 += x86/af_volume_init.o
 OBJS-$(CONFIG_YADIF_FILTER)                  += x86/vf_yadif_init.o
 
diff --git a/libavfilter/x86/af_volume_init.c b/libavfilter/x86/af_volume_init.c
index beee8ca..57c7eab 100644
--- a/libavfilter/x86/af_volume_init.c
+++ b/libavfilter/x86/af_volume_init.c
@@ -17,6 +17,7 @@
  */
 
 #include "config.h"
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/samplefmt.h"
 #include "libavutil/x86/cpu.h"
@@ -32,26 +33,26 @@
 void ff_scale_samples_s32_avx(uint8_t *dst, const uint8_t *src, int len,
                               int volume);
 
-void ff_volume_init_x86(VolumeContext *vol)
+av_cold void ff_volume_init_x86(VolumeContext *vol)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
     enum AVSampleFormat sample_fmt = av_get_packed_sample_fmt(vol->sample_fmt);
 
     if (sample_fmt == AV_SAMPLE_FMT_S16) {
-        if (EXTERNAL_SSE2(mm_flags) && vol->volume_i < 32768) {
+        if (EXTERNAL_SSE2(cpu_flags) && vol->volume_i < 32768) {
             vol->scale_samples = ff_scale_samples_s16_sse2;
             vol->samples_align = 8;
         }
     } else if (sample_fmt == AV_SAMPLE_FMT_S32) {
-        if (EXTERNAL_SSE2(mm_flags)) {
+        if (EXTERNAL_SSE2(cpu_flags)) {
             vol->scale_samples = ff_scale_samples_s32_sse2;
             vol->samples_align = 4;
         }
-        if (EXTERNAL_SSSE3(mm_flags) && mm_flags & AV_CPU_FLAG_ATOM) {
+        if (EXTERNAL_SSSE3(cpu_flags) && cpu_flags & AV_CPU_FLAG_ATOM) {
             vol->scale_samples = ff_scale_samples_s32_ssse3_atom;
             vol->samples_align = 4;
         }
-        if (EXTERNAL_AVX(mm_flags)) {
+        if (EXTERNAL_AVX(cpu_flags)) {
             vol->scale_samples = ff_scale_samples_s32_avx;
             vol->samples_align = 8;
         }
diff --git a/libavfilter/x86/vf_spp.c b/libavfilter/x86/vf_spp.c
new file mode 100644
index 0000000..eb46ddc
--- /dev/null
+++ b/libavfilter/x86/vf_spp.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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.
+ */
+
+
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/mem.h"
+#include "libavutil/x86/asm.h"
+#include "libavfilter/vf_spp.h"
+
+#if HAVE_MMX_INLINE
+static void hardthresh_mmx(int16_t dst[64], const int16_t src[64],
+                           int qp, const uint8_t *permutation)
+{
+    int bias = 0; //FIXME
+    unsigned int threshold1;
+
+    threshold1 = qp * ((1<<4) - bias) - 1;
+
+#define REQUANT_CORE(dst0, dst1, dst2, dst3, src0, src1, src2, src3)    \
+    "movq " #src0 ", %%mm0      \n"                                     \
+    "movq " #src1 ", %%mm1      \n"                                     \
+    "movq " #src2 ", %%mm2      \n"                                     \
+    "movq " #src3 ", %%mm3      \n"                                     \
+    "psubw %%mm4, %%mm0         \n"                                     \
+    "psubw %%mm4, %%mm1         \n"                                     \
+    "psubw %%mm4, %%mm2         \n"                                     \
+    "psubw %%mm4, %%mm3         \n"                                     \
+    "paddusw %%mm5, %%mm0       \n"                                     \
+    "paddusw %%mm5, %%mm1       \n"                                     \
+    "paddusw %%mm5, %%mm2       \n"                                     \
+    "paddusw %%mm5, %%mm3       \n"                                     \
+    "paddw %%mm6, %%mm0         \n"                                     \
+    "paddw %%mm6, %%mm1         \n"                                     \
+    "paddw %%mm6, %%mm2         \n"                                     \
+    "paddw %%mm6, %%mm3         \n"                                     \
+    "psubusw %%mm6, %%mm0       \n"                                     \
+    "psubusw %%mm6, %%mm1       \n"                                     \
+    "psubusw %%mm6, %%mm2       \n"                                     \
+    "psubusw %%mm6, %%mm3       \n"                                     \
+    "psraw $3, %%mm0            \n"                                     \
+    "psraw $3, %%mm1            \n"                                     \
+    "psraw $3, %%mm2            \n"                                     \
+    "psraw $3, %%mm3            \n"                                     \
+                                                                        \
+    "movq %%mm0, %%mm7          \n"                                     \
+    "punpcklwd %%mm2, %%mm0     \n" /*A*/                               \
+    "punpckhwd %%mm2, %%mm7     \n" /*C*/                               \
+    "movq %%mm1, %%mm2          \n"                                     \
+    "punpcklwd %%mm3, %%mm1     \n" /*B*/                               \
+    "punpckhwd %%mm3, %%mm2     \n" /*D*/                               \
+    "movq %%mm0, %%mm3          \n"                                     \
+    "punpcklwd %%mm1, %%mm0     \n" /*A*/                               \
+    "punpckhwd %%mm7, %%mm3     \n" /*C*/                               \
+    "punpcklwd %%mm2, %%mm7     \n" /*B*/                               \
+    "punpckhwd %%mm2, %%mm1     \n" /*D*/                               \
+                                                                        \
+    "movq %%mm0, " #dst0 "      \n"                                     \
+    "movq %%mm7, " #dst1 "      \n"                                     \
+    "movq %%mm3, " #dst2 "      \n"                                     \
+    "movq %%mm1, " #dst3 "      \n"
+
+    __asm__ volatile(
+        "movd %2, %%mm4             \n"
+        "movd %3, %%mm5             \n"
+        "movd %4, %%mm6             \n"
+        "packssdw %%mm4, %%mm4      \n"
+        "packssdw %%mm5, %%mm5      \n"
+        "packssdw %%mm6, %%mm6      \n"
+        "packssdw %%mm4, %%mm4      \n"
+        "packssdw %%mm5, %%mm5      \n"
+        "packssdw %%mm6, %%mm6      \n"
+        REQUANT_CORE(  (%1),  8(%1), 16(%1), 24(%1),  (%0), 8(%0), 64(%0), 72(%0))
+        REQUANT_CORE(32(%1), 40(%1), 48(%1), 56(%1),16(%0),24(%0), 48(%0), 56(%0))
+        REQUANT_CORE(64(%1), 72(%1), 80(%1), 88(%1),32(%0),40(%0), 96(%0),104(%0))
+        REQUANT_CORE(96(%1),104(%1),112(%1),120(%1),80(%0),88(%0),112(%0),120(%0))
+        : : "r" (src), "r" (dst), "g" (threshold1+1), "g" (threshold1+5), "g" (threshold1-4) //FIXME maybe more accurate then needed?
+    );
+    dst[0] = (src[0] + 4) >> 3;
+}
+
+static void softthresh_mmx(int16_t dst[64], const int16_t src[64],
+                           int qp, const uint8_t *permutation)
+{
+    int bias = 0; //FIXME
+    unsigned int threshold1;
+
+    threshold1 = qp*((1<<4) - bias) - 1;
+
+#undef REQUANT_CORE
+#define REQUANT_CORE(dst0, dst1, dst2, dst3, src0, src1, src2, src3)    \
+    "movq " #src0 ", %%mm0      \n"                                     \
+    "movq " #src1 ", %%mm1      \n"                                     \
+    "pxor %%mm6, %%mm6          \n"                                     \
+    "pxor %%mm7, %%mm7          \n"                                     \
+    "pcmpgtw %%mm0, %%mm6       \n"                                     \
+    "pcmpgtw %%mm1, %%mm7       \n"                                     \
+    "pxor %%mm6, %%mm0          \n"                                     \
+    "pxor %%mm7, %%mm1          \n"                                     \
+    "psubusw %%mm4, %%mm0       \n"                                     \
+    "psubusw %%mm4, %%mm1       \n"                                     \
+    "pxor %%mm6, %%mm0          \n"                                     \
+    "pxor %%mm7, %%mm1          \n"                                     \
+    "movq " #src2 ", %%mm2      \n"                                     \
+    "movq " #src3 ", %%mm3      \n"                                     \
+    "pxor %%mm6, %%mm6          \n"                                     \
+    "pxor %%mm7, %%mm7          \n"                                     \
+    "pcmpgtw %%mm2, %%mm6       \n"                                     \
+    "pcmpgtw %%mm3, %%mm7       \n"                                     \
+    "pxor %%mm6, %%mm2          \n"                                     \
+    "pxor %%mm7, %%mm3          \n"                                     \
+    "psubusw %%mm4, %%mm2       \n"                                     \
+    "psubusw %%mm4, %%mm3       \n"                                     \
+    "pxor %%mm6, %%mm2          \n"                                     \
+    "pxor %%mm7, %%mm3          \n"                                     \
+                                                                        \
+    "paddsw %%mm5, %%mm0        \n"                                     \
+    "paddsw %%mm5, %%mm1        \n"                                     \
+    "paddsw %%mm5, %%mm2        \n"                                     \
+    "paddsw %%mm5, %%mm3        \n"                                     \
+    "psraw $3, %%mm0            \n"                                     \
+    "psraw $3, %%mm1            \n"                                     \
+    "psraw $3, %%mm2            \n"                                     \
+    "psraw $3, %%mm3            \n"                                     \
+                                                                        \
+    "movq %%mm0, %%mm7          \n"                                     \
+    "punpcklwd %%mm2, %%mm0     \n" /*A*/                               \
+    "punpckhwd %%mm2, %%mm7     \n" /*C*/                               \
+    "movq %%mm1, %%mm2          \n"                                     \
+    "punpcklwd %%mm3, %%mm1     \n" /*B*/                               \
+    "punpckhwd %%mm3, %%mm2     \n" /*D*/                               \
+    "movq %%mm0, %%mm3          \n"                                     \
+    "punpcklwd %%mm1, %%mm0     \n" /*A*/                               \
+    "punpckhwd %%mm7, %%mm3     \n" /*C*/                               \
+    "punpcklwd %%mm2, %%mm7     \n" /*B*/                               \
+    "punpckhwd %%mm2, %%mm1     \n" /*D*/                               \
+                                                                        \
+    "movq %%mm0, " #dst0 "      \n"                                     \
+    "movq %%mm7, " #dst1 "      \n"                                     \
+    "movq %%mm3, " #dst2 "      \n"                                     \
+    "movq %%mm1, " #dst3 "      \n"
+
+    __asm__ volatile(
+        "movd %2, %%mm4             \n"
+        "movd %3, %%mm5             \n"
+        "packssdw %%mm4, %%mm4      \n"
+        "packssdw %%mm5, %%mm5      \n"
+        "packssdw %%mm4, %%mm4      \n"
+        "packssdw %%mm5, %%mm5      \n"
+        REQUANT_CORE(  (%1),  8(%1), 16(%1), 24(%1),  (%0), 8(%0), 64(%0), 72(%0))
+        REQUANT_CORE(32(%1), 40(%1), 48(%1), 56(%1),16(%0),24(%0), 48(%0), 56(%0))
+        REQUANT_CORE(64(%1), 72(%1), 80(%1), 88(%1),32(%0),40(%0), 96(%0),104(%0))
+        REQUANT_CORE(96(%1),104(%1),112(%1),120(%1),80(%0),88(%0),112(%0),120(%0))
+        : : "r" (src), "r" (dst), "g" (threshold1), "rm" (4) //FIXME maybe more accurate then needed?
+    );
+
+    dst[0] = (src[0] + 4) >> 3;
+}
+
+static void store_slice_mmx(uint8_t *dst, const int16_t *src,
+                            int dst_stride, int src_stride,
+                            int width, int height, int log2_scale,
+                            const uint8_t dither[8][8])
+{
+    int y;
+
+    for (y = 0; y < height; y++) {
+        uint8_t *dst1 = dst;
+        const int16_t *src1 = src;
+        __asm__ volatile(
+            "movq (%3), %%mm3           \n"
+            "movq (%3), %%mm4           \n"
+            "movd %4, %%mm2             \n"
+            "pxor %%mm0, %%mm0          \n"
+            "punpcklbw %%mm0, %%mm3     \n"
+            "punpckhbw %%mm0, %%mm4     \n"
+            "psraw %%mm2, %%mm3         \n"
+            "psraw %%mm2, %%mm4         \n"
+            "movd %5, %%mm2             \n"
+            "1:                         \n"
+            "movq (%0), %%mm0           \n"
+            "movq 8(%0), %%mm1          \n"
+            "paddw %%mm3, %%mm0         \n"
+            "paddw %%mm4, %%mm1         \n"
+            "psraw %%mm2, %%mm0         \n"
+            "psraw %%mm2, %%mm1         \n"
+            "packuswb %%mm1, %%mm0      \n"
+            "movq %%mm0, (%1)           \n"
+            "add $16, %0                \n"
+            "add $8, %1                 \n"
+            "cmp %2, %1                 \n"
+            " jb 1b                     \n"
+            : "+r" (src1), "+r"(dst1)
+            : "r"(dst + width), "r"(dither[y]), "g"(log2_scale), "g"(MAX_LEVEL - log2_scale)
+        );
+        src += src_stride;
+        dst += dst_stride;
+    }
+}
+
+#endif /* HAVE_MMX_INLINE */
+
+av_cold void ff_spp_init_x86(SPPContext *s)
+{
+#if HAVE_MMX_INLINE
+    int cpu_flags = av_get_cpu_flags();
+
+    if (cpu_flags & AV_CPU_FLAG_MMX) {
+        s->store_slice = store_slice_mmx;
+        switch (s->mode) {
+        case 0: s->requantize = hardthresh_mmx; break;
+        case 1: s->requantize = softthresh_mmx; break;
+        }
+    }
+#endif
+}
diff --git a/libavfilter/x86/vf_yadif_init.c b/libavfilter/x86/vf_yadif_init.c
index 0043931..ae09bb0 100644
--- a/libavfilter/x86/vf_yadif_init.c
+++ b/libavfilter/x86/vf_yadif_init.c
@@ -23,7 +23,6 @@
 #include "libavutil/mem.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
-#include "libavcodec/x86/dsputil_mmx.h"
 #include "libavfilter/yadif.h"
 
 void ff_yadif_filter_line_mmxext(void *dst, void *prev, void *cur,
diff --git a/libavformat/4xm.c b/libavformat/4xm.c
index 1e142f5..3714297 100644
--- a/libavformat/4xm.c
+++ b/libavformat/4xm.c
@@ -57,7 +57,7 @@
 
 #define GET_LIST_HEADER() \
     fourcc_tag = avio_rl32(pb); \
-    size = avio_rl32(pb); \
+    size       = avio_rl32(pb); \
     if (fourcc_tag != LIST_TAG) \
         return AVERROR_INVALIDDATA; \
     fourcc_tag = avio_rl32(pb);
@@ -72,8 +72,6 @@
 } AudioTrack;
 
 typedef struct FourxmDemuxContext {
-    int width;
-    int height;
     int video_stream_index;
     int track_count;
     AudioTrack *tracks;
@@ -91,6 +89,107 @@
     return AVPROBE_SCORE_MAX;
 }
 
+static int parse_vtrk(AVFormatContext *s,
+                      FourxmDemuxContext *fourxm, uint8_t *buf, int size,
+                      int left)
+{
+    AVStream *st;
+    /* check that there is enough data */
+    if (size != vtrk_SIZE || left < size + 8) {
+        return AVERROR_INVALIDDATA;
+    }
+
+    /* allocate a new AVStream */
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    avpriv_set_pts_info(st, 60, 1, fourxm->fps);
+
+    fourxm->video_stream_index = st->index;
+
+    st->codec->codec_type     = AVMEDIA_TYPE_VIDEO;
+    st->codec->codec_id       = AV_CODEC_ID_4XM;
+    st->codec->extradata_size = 4;
+    st->codec->extradata      = av_malloc(4);
+    AV_WL32(st->codec->extradata, AV_RL32(buf + 16));
+    st->codec->width  = AV_RL32(buf + 36);
+    st->codec->height = AV_RL32(buf + 40);
+
+    return 0;
+}
+
+
+static int parse_strk(AVFormatContext *s,
+                      FourxmDemuxContext *fourxm, uint8_t *buf, int size,
+                      int left)
+{
+    AVStream *st;
+    int track;
+    /* check that there is enough data */
+    if (size != strk_SIZE || left < size + 8)
+        return AVERROR_INVALIDDATA;
+
+    track = AV_RL32(buf + 8);
+    if ((unsigned)track >= UINT_MAX / sizeof(AudioTrack) - 1) {
+        av_log(s, AV_LOG_ERROR, "current_track too large\n");
+        return AVERROR_INVALIDDATA;
+    }
+    if (track + 1 > fourxm->track_count) {
+        if (av_reallocp_array(&fourxm->tracks, track + 1, sizeof(AudioTrack)))
+            return AVERROR(ENOMEM);
+        memset(&fourxm->tracks[fourxm->track_count], 0,
+               sizeof(AudioTrack) * (track + 1 - fourxm->track_count));
+        fourxm->track_count = track + 1;
+    }
+    fourxm->tracks[track].adpcm       = AV_RL32(buf + 12);
+    fourxm->tracks[track].channels    = AV_RL32(buf + 36);
+    fourxm->tracks[track].sample_rate = AV_RL32(buf + 40);
+    fourxm->tracks[track].bits        = AV_RL32(buf + 44);
+    fourxm->tracks[track].audio_pts   = 0;
+
+    if (fourxm->tracks[track].channels    <= 0 ||
+        fourxm->tracks[track].sample_rate <= 0 ||
+        fourxm->tracks[track].bits        < 0) {
+        av_log(s, AV_LOG_ERROR, "audio header invalid\n");
+        return AVERROR_INVALIDDATA;
+    }
+    if (!fourxm->tracks[track].adpcm && fourxm->tracks[track].bits<8) {
+        av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    /* allocate a new AVStream */
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    st->id = track;
+    avpriv_set_pts_info(st, 60, 1, fourxm->tracks[track].sample_rate);
+
+    fourxm->tracks[track].stream_index = st->index;
+
+    st->codec->codec_type            = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_tag             = 0;
+    st->codec->channels              = fourxm->tracks[track].channels;
+    st->codec->sample_rate           = fourxm->tracks[track].sample_rate;
+    st->codec->bits_per_coded_sample = fourxm->tracks[track].bits;
+    st->codec->bit_rate              = st->codec->channels *
+                                       st->codec->sample_rate *
+                                       st->codec->bits_per_coded_sample;
+    st->codec->block_align           = st->codec->channels *
+                                       st->codec->bits_per_coded_sample;
+
+    if (fourxm->tracks[track].adpcm){
+        st->codec->codec_id = AV_CODEC_ID_ADPCM_4XM;
+    } else if (st->codec->bits_per_coded_sample == 8) {
+        st->codec->codec_id = AV_CODEC_ID_PCM_U8;
+    } else
+        st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
+
+    return 0;
+}
+
 static int fourxm_read_header(AVFormatContext *s)
 {
     AVIOContext *pb = s->pb;
@@ -100,11 +199,10 @@
     FourxmDemuxContext *fourxm = s->priv_data;
     unsigned char *header;
     int i, ret;
-    AVStream *st;
 
     fourxm->track_count = 0;
-    fourxm->tracks = NULL;
-    fourxm->fps = 1.0;
+    fourxm->tracks      = NULL;
+    fourxm->fps         = 1.0;
 
     /* skip the first 3 32-bit numbers */
     avio_skip(pb, 12);
@@ -119,7 +217,7 @@
     header = av_malloc(header_size);
     if (!header)
         return AVERROR(ENOMEM);
-    if (avio_read(pb, header, header_size) != header_size){
+    if (avio_read(pb, header, header_size) != header_size) {
         av_free(header);
         return AVERROR(EIO);
     }
@@ -127,123 +225,38 @@
     /* take the lazy approach and search for any and all vtrk and strk chunks */
     for (i = 0; i < header_size - 8; i++) {
         fourcc_tag = AV_RL32(&header[i]);
-        size = AV_RL32(&header[i + 4]);
+        size       = AV_RL32(&header[i + 4]);
         if (size > header_size - i - 8 && (fourcc_tag == vtrk_TAG || fourcc_tag == strk_TAG)) {
             av_log(s, AV_LOG_ERROR, "chunk larger than array %d>%d\n", size, header_size - i - 8);
             return AVERROR_INVALIDDATA;
         }
 
         if (fourcc_tag == std__TAG) {
-            if (header_size < i + 16) {
+            if (header_size - i < 16) {
                 av_log(s, AV_LOG_ERROR, "std TAG truncated\n");
-                return AVERROR_INVALIDDATA;
+                ret = AVERROR_INVALIDDATA;
+                goto fail;
             }
             fourxm->fps = av_int2float(AV_RL32(&header[i + 12]));
         } else if (fourcc_tag == vtrk_TAG) {
-            /* check that there is enough data */
-            if (size != vtrk_SIZE) {
-                ret= AVERROR_INVALIDDATA;
+            if ((ret = parse_vtrk(s, fourxm, header + i, size,
+                                  header_size - i)) < 0)
                 goto fail;
-            }
-            fourxm->width  = AV_RL32(&header[i + 36]);
-            fourxm->height = AV_RL32(&header[i + 40]);
-
-            /* allocate a new AVStream */
-            st = avformat_new_stream(s, NULL);
-            if (!st){
-                ret= AVERROR(ENOMEM);
-                goto fail;
-            }
-            avpriv_set_pts_info(st, 60, 1, fourxm->fps);
-
-            fourxm->video_stream_index = st->index;
-
-            st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
-            st->codec->codec_id = AV_CODEC_ID_4XM;
-            st->codec->extradata_size = 4;
-            st->codec->extradata = av_malloc(4);
-            AV_WL32(st->codec->extradata, AV_RL32(&header[i + 16]));
-            st->codec->width  = fourxm->width;
-            st->codec->height = fourxm->height;
 
             i += 8 + size;
         } else if (fourcc_tag == strk_TAG) {
-            int current_track;
-            /* check that there is enough data */
-            if (size != strk_SIZE) {
-                ret= AVERROR_INVALIDDATA;
+            if ((ret = parse_strk(s, fourxm, header + i, size,
+                                  header_size - i)) < 0)
                 goto fail;
-            }
-            current_track = AV_RL32(&header[i + 8]);
-            if((unsigned)current_track >= UINT_MAX / sizeof(AudioTrack) - 1){
-                av_log(s, AV_LOG_ERROR, "current_track too large\n");
-                ret = AVERROR_INVALIDDATA;
-                goto fail;
-            }
-            if (current_track + 1 > fourxm->track_count) {
-                fourxm->tracks = av_realloc_f(fourxm->tracks,
-                                              sizeof(AudioTrack),
-                                              current_track + 1);
-                if (!fourxm->tracks) {
-                    ret = AVERROR(ENOMEM);
-                    goto fail;
-                }
-                memset(&fourxm->tracks[fourxm->track_count], 0,
-                       sizeof(AudioTrack) * (current_track + 1 - fourxm->track_count));
-                fourxm->track_count = current_track + 1;
-            }
-            fourxm->tracks[current_track].adpcm       = AV_RL32(&header[i + 12]);
-            fourxm->tracks[current_track].channels    = AV_RL32(&header[i + 36]);
-            fourxm->tracks[current_track].sample_rate = AV_RL32(&header[i + 40]);
-            fourxm->tracks[current_track].bits        = AV_RL32(&header[i + 44]);
-            fourxm->tracks[current_track].audio_pts   = 0;
-            if(   fourxm->tracks[current_track].channels    <= 0
-               || fourxm->tracks[current_track].sample_rate <= 0
-               || fourxm->tracks[current_track].bits        <  0){
-                av_log(s, AV_LOG_ERROR, "audio header invalid\n");
-                ret = AVERROR_INVALIDDATA;
-                goto fail;
-            }
-            if(!fourxm->tracks[current_track].adpcm && fourxm->tracks[current_track].bits<8){
-                av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n");
-                ret = AVERROR_INVALIDDATA;
-                goto fail;
-            }
+
             i += 8 + size;
-
-            /* allocate a new AVStream */
-            st = avformat_new_stream(s, NULL);
-            if (!st){
-                ret= AVERROR(ENOMEM);
-                goto fail;
-            }
-
-            st->id = current_track;
-            avpriv_set_pts_info(st, 60, 1, fourxm->tracks[current_track].sample_rate);
-
-            fourxm->tracks[current_track].stream_index = st->index;
-
-            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
-            st->codec->codec_tag = 0;
-            st->codec->channels              = fourxm->tracks[current_track].channels;
-            st->codec->sample_rate           = fourxm->tracks[current_track].sample_rate;
-            st->codec->bits_per_coded_sample = fourxm->tracks[current_track].bits;
-            st->codec->bit_rate              = st->codec->channels * st->codec->sample_rate *
-                st->codec->bits_per_coded_sample;
-            st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
-            if (fourxm->tracks[current_track].adpcm){
-                st->codec->codec_id = AV_CODEC_ID_ADPCM_4XM;
-            }else if (st->codec->bits_per_coded_sample == 8){
-                st->codec->codec_id = AV_CODEC_ID_PCM_U8;
-            }else
-                st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
         }
     }
 
     /* skip over the LIST-MOVI chunk (which is where the stream should be */
     GET_LIST_HEADER();
-    if (fourcc_tag != MOVI_TAG){
-        ret= AVERROR_INVALIDDATA;
+    if (fourcc_tag != MOVI_TAG) {
+        ret = AVERROR_INVALIDDATA;
         goto fail;
     }
 
@@ -262,7 +275,7 @@
                               AVPacket *pkt)
 {
     FourxmDemuxContext *fourxm = s->priv_data;
-    AVIOContext *pb = s->pb;
+    AVIOContext *pb            = s->pb;
     unsigned int fourcc_tag;
     unsigned int size;
     int ret = 0;
@@ -272,18 +285,16 @@
     int audio_frame_count;
 
     while (!packet_read) {
-
         if ((ret = avio_read(s->pb, header, 8)) < 0)
             return ret;
         fourcc_tag = AV_RL32(&header[0]);
-        size = AV_RL32(&header[4]);
+        size       = AV_RL32(&header[4]);
         if (url_feof(pb))
             return AVERROR(EIO);
         switch (fourcc_tag) {
-
         case LIST_TAG:
             /* this is a good time to bump the video pts */
-            fourxm->video_pts ++;
+            fourxm->video_pts++;
 
             /* skip the LIST-* tag and move on to the next fourcc */
             avio_rl32(pb);
@@ -300,45 +311,43 @@
             if (size + 8 < size || av_new_packet(pkt, size + 8))
                 return AVERROR(EIO);
             pkt->stream_index = fourxm->video_stream_index;
-            pkt->pts = fourxm->video_pts;
-            pkt->pos = avio_tell(s->pb);
+            pkt->pts          = fourxm->video_pts;
+            pkt->pos          = avio_tell(s->pb);
             memcpy(pkt->data, header, 8);
             ret = avio_read(s->pb, &pkt->data[8], size);
 
-            if (ret < 0){
+            if (ret < 0) {
                 av_free_packet(pkt);
-            }else
+            } else
                 packet_read = 1;
             break;
 
         case snd__TAG:
             track_number = avio_rl32(pb);
             avio_skip(pb, 4);
-            size-=8;
+            size -= 8;
 
-            if (track_number < fourxm->track_count && fourxm->tracks[track_number].channels>0) {
-                ret= av_get_packet(s->pb, pkt, size);
-                if(ret<0)
+            if (track_number < fourxm->track_count &&
+                fourxm->tracks[track_number].channels > 0) {
+                ret = av_get_packet(s->pb, pkt, size);
+                if (ret < 0)
                     return AVERROR(EIO);
                 pkt->stream_index =
                     fourxm->tracks[track_number].stream_index;
-                pkt->pts = fourxm->tracks[track_number].audio_pts;
+                pkt->pts    = fourxm->tracks[track_number].audio_pts;
                 packet_read = 1;
 
                 /* pts accounting */
                 audio_frame_count = size;
                 if (fourxm->tracks[track_number].adpcm)
-                    audio_frame_count -=
-                        2 * (fourxm->tracks[track_number].channels);
-                audio_frame_count /=
-                      fourxm->tracks[track_number].channels;
-                if (fourxm->tracks[track_number].adpcm){
+                    audio_frame_count -= 2 * (fourxm->tracks[track_number].channels);
+                audio_frame_count /= fourxm->tracks[track_number].channels;
+                if (fourxm->tracks[track_number].adpcm) {
                     audio_frame_count *= 2;
-                }else
+                } else
                     audio_frame_count /=
-                    (fourxm->tracks[track_number].bits / 8);
+                        (fourxm->tracks[track_number].bits / 8);
                 fourxm->tracks[track_number].audio_pts += audio_frame_count;
-
             } else {
                 avio_skip(pb, size);
             }
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 470e7f3..35d49f7 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -11,6 +11,7 @@
        avio.o               \
        aviobuf.o            \
        cutils.o             \
+       format.o             \
        id3v1.o              \
        id3v2.o              \
        metadata.o           \
@@ -20,9 +21,14 @@
        riff.o               \
        sdp.o                \
        seek.o               \
+       url.o                \
        utils.o              \
 
+OBJS-$(HAVE_MSVCRT) += file_open.o
+
 OBJS-$(CONFIG_NETWORK)                   += network.o
+OBJS-$(CONFIG_RIFFDEC)                   += riffdec.o
+OBJS-$(CONFIG_RIFFENC)                   += riffenc.o
 OBJS-$(CONFIG_RTPDEC)                    += rdt.o                       \
                                             rtp.o                       \
                                             rtpdec.o                    \
@@ -50,11 +56,12 @@
 
 # muxers/demuxers
 OBJS-$(CONFIG_A64_MUXER)                 += a64.o rawenc.o
-OBJS-$(CONFIG_AAC_DEMUXER)               += aacdec.o rawdec.o
+OBJS-$(CONFIG_AAC_DEMUXER)               += aacdec.o apetag.o img2.o rawdec.o
 OBJS-$(CONFIG_AC3_DEMUXER)               += ac3dec.o rawdec.o
 OBJS-$(CONFIG_AC3_MUXER)                 += rawenc.o
 OBJS-$(CONFIG_ACT_DEMUXER)               += act.o
 OBJS-$(CONFIG_ADF_DEMUXER)               += bintext.o sauce.o
+OBJS-$(CONFIG_ADP_DEMUXER)               += adp.o
 OBJS-$(CONFIG_ADX_DEMUXER)               += adxdec.o
 OBJS-$(CONFIG_ADX_MUXER)                 += rawenc.o
 OBJS-$(CONFIG_ADTS_MUXER)                += adtsenc.o
@@ -91,6 +98,7 @@
 OBJS-$(CONFIG_BIT_DEMUXER)               += bit.o
 OBJS-$(CONFIG_BIT_MUXER)                 += bit.o
 OBJS-$(CONFIG_BMV_DEMUXER)               += bmv.o
+OBJS-$(CONFIG_BOA_DEMUXER)               += boadec.o
 OBJS-$(CONFIG_BRSTM_DEMUXER)             += brstm.o
 OBJS-$(CONFIG_C93_DEMUXER)               += c93.o vocdec.o voc.o
 OBJS-$(CONFIG_CAF_DEMUXER)               += cafdec.o caf.o mov.o mov_chan.o \
@@ -102,6 +110,8 @@
 OBJS-$(CONFIG_CDXL_DEMUXER)              += cdxl.o
 OBJS-$(CONFIG_CONCAT_DEMUXER)            += concatdec.o
 OBJS-$(CONFIG_CRC_MUXER)                 += crcenc.o
+OBJS-$(CONFIG_DATA_DEMUXER)              += rawdec.o
+OBJS-$(CONFIG_DATA_MUXER)                += rawdec.o
 OBJS-$(CONFIG_DAUD_DEMUXER)              += daud.o
 OBJS-$(CONFIG_DAUD_MUXER)                += daud.o
 OBJS-$(CONFIG_DFA_DEMUXER)               += dfa.o
@@ -128,6 +138,7 @@
 OBJS-$(CONFIG_FILMSTRIP_DEMUXER)         += filmstripdec.o
 OBJS-$(CONFIG_FILMSTRIP_MUXER)           += filmstripenc.o
 OBJS-$(CONFIG_FLAC_DEMUXER)              += flacdec.o rawdec.o \
+                                            flacdec_picture.o \
                                             oggparsevorbis.o \
                                             vorbiscomment.o
 OBJS-$(CONFIG_FLAC_MUXER)                += flacenc.o flacenc_header.o \
@@ -156,7 +167,7 @@
 OBJS-$(CONFIG_H264_DEMUXER)              += h264dec.o rawdec.o
 OBJS-$(CONFIG_H264_MUXER)                += rawenc.o
 OBJS-$(CONFIG_HLS_DEMUXER)               += hls.o
-OBJS-$(CONFIG_HLS_MUXER)                 += hlsenc.o mpegtsenc.o
+OBJS-$(CONFIG_HLS_MUXER)                 += hlsenc.o
 OBJS-$(CONFIG_ICO_DEMUXER)               += icodec.o
 OBJS-$(CONFIG_ICO_MUXER)                 += icoenc.o
 OBJS-$(CONFIG_IDCIN_DEMUXER)             += idcin.o
@@ -191,7 +202,7 @@
                                             isom.o rmsipr.o
 OBJS-$(CONFIG_MATROSKA_MUXER)            += matroskaenc.o matroska.o \
                                             isom.o avc.o \
-                                            flacenc_header.o avlanguage.o
+                                            flacenc_header.o avlanguage.o wv.o
 OBJS-$(CONFIG_MD5_MUXER)                 += md5enc.o
 OBJS-$(CONFIG_MGSTS_DEMUXER)             += mgsts.o
 OBJS-$(CONFIG_MICRODVD_DEMUXER)          += microdvddec.o subtitles.o
@@ -249,7 +260,8 @@
                                             oggparsespeex.o  \
                                             oggparsetheora.o \
                                             oggparsevorbis.o \
-                                            vorbiscomment.o
+                                            vorbiscomment.o  \
+                                            flacdec_picture.o
 OBJS-$(CONFIG_OGG_MUXER)                 += oggenc.o \
                                             vorbiscomment.o
 OBJS-$(CONFIG_OMA_DEMUXER)               += omadec.o pcm.o oma.o
@@ -304,11 +316,13 @@
 OBJS-$(CONFIG_RAWVIDEO_DEMUXER)          += rawvideodec.o
 OBJS-$(CONFIG_RAWVIDEO_MUXER)            += rawenc.o
 OBJS-$(CONFIG_REALTEXT_DEMUXER)          += realtextdec.o subtitles.o
+OBJS-$(CONFIG_REDSPARK_DEMUXER)          += redspark.o
 OBJS-$(CONFIG_RL2_DEMUXER)               += rl2.o
 OBJS-$(CONFIG_RM_DEMUXER)                += rmdec.o rm.o rmsipr.o
 OBJS-$(CONFIG_RM_MUXER)                  += rmenc.o rm.o
 OBJS-$(CONFIG_ROQ_DEMUXER)               += idroqdec.o
 OBJS-$(CONFIG_ROQ_MUXER)                 += idroqenc.o rawenc.o
+OBJS-$(CONFIG_RSD_DEMUXER)               += rsd.o
 OBJS-$(CONFIG_RSO_DEMUXER)               += rsodec.o rso.o pcm.o
 OBJS-$(CONFIG_RSO_MUXER)                 += rsoenc.o rso.o
 OBJS-$(CONFIG_RPL_DEMUXER)               += rpl.o
@@ -364,10 +378,11 @@
 OBJS-$(CONFIG_TMV_DEMUXER)               += tmv.o
 OBJS-$(CONFIG_TRUEHD_DEMUXER)            += rawdec.o
 OBJS-$(CONFIG_TRUEHD_MUXER)              += rawenc.o
-OBJS-$(CONFIG_TTA_DEMUXER)               += tta.o
+OBJS-$(CONFIG_TTA_DEMUXER)               += tta.o apetag.o img2.o
 OBJS-$(CONFIG_TTY_DEMUXER)               += tty.o sauce.o
 OBJS-$(CONFIG_TXD_DEMUXER)               += txd.o
 OBJS-$(CONFIG_VC1_DEMUXER)               += rawdec.o
+OBJS-$(CONFIG_VC1_MUXER)                 += rawenc.o
 OBJS-$(CONFIG_VC1T_DEMUXER)              += vc1test.o
 OBJS-$(CONFIG_VC1T_MUXER)                += vc1testenc.o
 OBJS-$(CONFIG_VIVO_DEMUXER)              += vivo.o
@@ -384,15 +399,16 @@
 OBJS-$(CONFIG_WC3_DEMUXER)               += wc3movie.o
 OBJS-$(CONFIG_WEBM_MUXER)                += matroskaenc.o matroska.o \
                                             isom.o avc.o \
-                                            flacenc_header.o avlanguage.o
+                                            flacenc_header.o avlanguage.o wv.o
 OBJS-$(CONFIG_WEBVTT_DEMUXER)            += webvttdec.o subtitles.o
+OBJS-$(CONFIG_WEBVTT_MUXER)              += webvttenc.o
 OBJS-$(CONFIG_WSAUD_DEMUXER)             += westwood_aud.o
 OBJS-$(CONFIG_WSVQA_DEMUXER)             += westwood_vqa.o
 OBJS-$(CONFIG_WTV_DEMUXER)               += wtvdec.o wtv.o asfdec.o asf.o asfcrypt.o \
                                             avlanguage.o mpegts.o isom.o
 OBJS-$(CONFIG_WTV_MUXER)                 += wtvenc.o wtv.o asf.o asfenc.o
-OBJS-$(CONFIG_WV_DEMUXER)                += wv.o apetag.o img2.o
-OBJS-$(CONFIG_WV_MUXER)                  += wvenc.o apetagenc.o
+OBJS-$(CONFIG_WV_DEMUXER)                += wvdec.o wv.o apetag.o img2.o
+OBJS-$(CONFIG_WV_MUXER)                  += wvenc.o wv.o apetag.o img2.o
 OBJS-$(CONFIG_XA_DEMUXER)                += xa.o
 OBJS-$(CONFIG_XBIN_DEMUXER)              += bintext.o sauce.o
 OBJS-$(CONFIG_XMV_DEMUXER)               += xmv.o
@@ -402,6 +418,7 @@
 OBJS-$(CONFIG_YUV4MPEGPIPE_DEMUXER)      += yuv4mpeg.o
 
 # external libraries
+OBJS-$(CONFIG_LIBGME_DEMUXER)            += libgme.o
 OBJS-$(CONFIG_LIBMODPLUG_DEMUXER)        += libmodplug.o
 OBJS-$(CONFIG_LIBNUT_DEMUXER)            += libnut.o
 OBJS-$(CONFIG_LIBNUT_MUXER)              += libnut.o
@@ -418,6 +435,7 @@
 OBJS-$(CONFIG_FFRTMPCRYPT_PROTOCOL)      += rtmpcrypt.o rtmpdh.o
 OBJS-$(CONFIG_FFRTMPHTTP_PROTOCOL)       += rtmphttp.o
 OBJS-$(CONFIG_FILE_PROTOCOL)             += file.o
+OBJS-$(CONFIG_FTP_PROTOCOL)              += ftp.o
 OBJS-$(CONFIG_GOPHER_PROTOCOL)           += gopher.o
 OBJS-$(CONFIG_HLS_PROTOCOL)              += hlsproto.o
 OBJS-$(CONFIG_HTTP_PROTOCOL)             += http.o httpauth.o urldecode.o
@@ -439,14 +457,16 @@
 OBJS-$(CONFIG_TCP_PROTOCOL)              += tcp.o
 OBJS-$(CONFIG_TLS_PROTOCOL)              += tls.o
 OBJS-$(CONFIG_UDP_PROTOCOL)              += udp.o
+OBJS-$(CONFIG_UNIX_PROTOCOL)             += unix.o
 
 SKIPHEADERS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpdh.h
 SKIPHEADERS-$(CONFIG_NETWORK)            += network.h rtsp.h
-TESTPROGS = noproxy                                                     \
-            seek                                                        \
+TESTPROGS = seek                                                        \
             srtp                                                        \
             url                                                         \
 
+TESTPROGS-$(CONFIG_NETWORK)              += noproxy
+
 TOOLS     = aviocat                                                     \
             ismindex                                                    \
             pktdumper                                                   \
diff --git a/libavformat/aacdec.c b/libavformat/aacdec.c
index 7c17dd0..d93e75e 100644
--- a/libavformat/aacdec.c
+++ b/libavformat/aacdec.c
@@ -25,7 +25,7 @@
 #include "internal.h"
 #include "rawdec.h"
 #include "id3v1.h"
-
+#include "apetag.h"
 
 static int adts_aac_probe(AVProbeData *p)
 {
@@ -55,9 +55,9 @@
         if(buf == buf0)
             first_frames= frames;
     }
-    if   (first_frames>=3) return AVPROBE_SCORE_MAX/2+1;
-    else if(max_frames>500)return AVPROBE_SCORE_MAX/2;
-    else if(max_frames>=3) return AVPROBE_SCORE_MAX/4;
+    if   (first_frames>=3) return AVPROBE_SCORE_EXTENSION + 1;
+    else if(max_frames>500)return AVPROBE_SCORE_EXTENSION;
+    else if(max_frames>=3) return AVPROBE_SCORE_EXTENSION / 2;
     else if(max_frames>=1) return 1;
     else                   return 0;
 }
@@ -75,6 +75,12 @@
     st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
 
     ff_id3v1_read(s);
+    if (s->pb->seekable &&
+        !av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) {
+        int64_t cur = avio_tell(s->pb);
+        ff_ape_parse_tag(s);
+        avio_seek(s->pb, cur, SEEK_SET);
+    }
 
     //LCM of all possible ADTS sample rates
     avpriv_set_pts_info(st, 64, 1, 28224000);
diff --git a/libavformat/ac3dec.c b/libavformat/ac3dec.c
index c531f8a..3db2339 100644
--- a/libavformat/ac3dec.c
+++ b/libavformat/ac3dec.c
@@ -79,9 +79,9 @@
     if(codec_id != expected_codec_id) return 0;
     // keep this in sync with mp3 probe, both need to avoid
     // issues with MPEG-files!
-    if   (first_frames>=4) return AVPROBE_SCORE_MAX/2+1;
-    else if(max_frames>200)return AVPROBE_SCORE_MAX/2;
-    else if(max_frames>=4) return AVPROBE_SCORE_MAX/4;
+    if   (first_frames>=4) return AVPROBE_SCORE_EXTENSION + 1;
+    else if(max_frames>200)return AVPROBE_SCORE_EXTENSION;
+    else if(max_frames>=4) return AVPROBE_SCORE_EXTENSION/2;
     else if(max_frames>=1) return 1;
     else                   return 0;
 }
diff --git a/libavformat/act.c b/libavformat/act.c
index 78f1d3b..3f223d5 100644
--- a/libavformat/act.c
+++ b/libavformat/act.c
@@ -42,7 +42,7 @@
         (AV_RL32(&p->buf[16]) != 16))
     return 0;
 
-    //We cant be sure that this is ACT and not regular WAV
+    //We can't be sure that this is ACT and not regular WAV
     if (p->buf_size<512)
         return 0;
 
diff --git a/libavformat/adp.c b/libavformat/adp.c
new file mode 100644
index 0000000..c5feac4
--- /dev/null
+++ b/libavformat/adp.c
@@ -0,0 +1,91 @@
+/*
+ * ADP demuxer
+ * Copyright (c) 2013 James Almer
+ *
+ * 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
+ */
+
+#include "libavutil/channel_layout.h"
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+#include "internal.h"
+
+static int adp_probe(AVProbeData *p)
+{
+    int i;
+
+    if (p->buf_size < 32)
+        return 0;
+
+    for (i = 0; i < p->buf_size - 3; i+=32)
+        if (p->buf[i] != p->buf[i+2] || p->buf[i+1] != p->buf[i+3])
+            return 0;
+
+    return p->buf_size < 260 ? 1 : AVPROBE_SCORE_MAX / 4;
+}
+
+static int adp_read_header(AVFormatContext *s)
+{
+    AVStream *st;
+
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    st->codec->codec_type     = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_id       = AV_CODEC_ID_ADPCM_DTK;
+    st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
+    st->codec->channels       = 2;
+    st->codec->sample_rate    = 48000;
+    st->start_time            = 0;
+    if (s->pb->seekable)
+        st->duration          = av_get_audio_frame_duration(st->codec, avio_size(s->pb));
+
+    avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+
+    return 0;
+}
+
+static int adp_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    int ret, size = 1024;
+
+    if (url_feof(s->pb))
+        return AVERROR_EOF;
+
+    ret = av_get_packet(s->pb, pkt, size);
+
+    if (ret != size) {
+        if (ret < 0) {
+            av_free_packet(pkt);
+            return ret;
+        }
+        av_shrink_packet(pkt, ret);
+    }
+    pkt->stream_index = 0;
+
+    return ret;
+}
+
+AVInputFormat ff_adp_demuxer = {
+    .name           = "adp",
+    .long_name      = NULL_IF_CONFIG_SMALL("ADP"),
+    .read_probe     = adp_probe,
+    .read_header    = adp_read_header,
+    .read_packet    = adp_read_packet,
+    .extensions     = "adp,dtk",
+};
diff --git a/libavformat/aiff.h b/libavformat/aiff.h
index b3ef577..c13bcc0 100644
--- a/libavformat/aiff.h
+++ b/libavformat/aiff.h
@@ -45,6 +45,7 @@
     { AV_CODEC_ID_MACE3,        MKTAG('M','A','C','3') },
     { AV_CODEC_ID_MACE6,        MKTAG('M','A','C','6') },
     { AV_CODEC_ID_GSM,          MKTAG('G','S','M',' ') },
+    { AV_CODEC_ID_ADPCM_G722,   MKTAG('G','7','2','2') },
     { AV_CODEC_ID_ADPCM_G726,   MKTAG('G','7','2','6') },
     { AV_CODEC_ID_PCM_S16BE,    MKTAG('t','w','o','s') },
     { AV_CODEC_ID_PCM_S16LE,    MKTAG('s','o','w','t') },
diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c
index 62af3dc..851091e 100644
--- a/libavformat/aiffdec.c
+++ b/libavformat/aiffdec.c
@@ -141,6 +141,7 @@
         case AV_CODEC_ID_MACE3:
             codec->block_align = 2*codec->channels;
             break;
+        case AV_CODEC_ID_ADPCM_G722:
         case AV_CODEC_ID_MACE6:
             codec->block_align = 1*codec->channels;
             break;
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 80c53f6..b3b2a3b 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -65,6 +65,7 @@
     REGISTER_MUXDEMUX(AC3,              ac3);
     REGISTER_DEMUXER (ACT,              act);
     REGISTER_DEMUXER (ADF,              adf);
+    REGISTER_DEMUXER (ADP,              adp);
     REGISTER_MUXER   (ADTS,             adts);
     REGISTER_MUXDEMUX(ADX,              adx);
     REGISTER_DEMUXER (AEA,              aea);
@@ -92,6 +93,7 @@
     REGISTER_MUXDEMUX(BIT,              bit);
     REGISTER_DEMUXER (BMV,              bmv);
     REGISTER_DEMUXER (BRSTM,            brstm);
+    REGISTER_DEMUXER (BOA,              boa);
     REGISTER_DEMUXER (C93,              c93);
     REGISTER_MUXDEMUX(CAF,              caf);
     REGISTER_MUXDEMUX(CAVSVIDEO,        cavsvideo);
@@ -99,6 +101,7 @@
     REGISTER_DEMUXER (CDXL,             cdxl);
     REGISTER_DEMUXER (CONCAT,           concat);
     REGISTER_MUXER   (CRC,              crc);
+    REGISTER_MUXDEMUX(DATA,             data);
     REGISTER_MUXDEMUX(DAUD,             daud);
     REGISTER_DEMUXER (DFA,              dfa);
     REGISTER_MUXDEMUX(DIRAC,            dirac);
@@ -230,10 +233,12 @@
     REGISTER_DEMUXER (R3D,              r3d);
     REGISTER_MUXDEMUX(RAWVIDEO,         rawvideo);
     REGISTER_DEMUXER (REALTEXT,         realtext);
+    REGISTER_DEMUXER (REDSPARK,         redspark);
     REGISTER_DEMUXER (RL2,              rl2);
     REGISTER_MUXDEMUX(RM,               rm);
     REGISTER_MUXDEMUX(ROQ,              roq);
     REGISTER_DEMUXER (RPL,              rpl);
+    REGISTER_DEMUXER (RSD,              rsd);
     REGISTER_MUXDEMUX(RSO,              rso);
     REGISTER_MUXDEMUX(RTP,              rtp);
     REGISTER_MUXDEMUX(RTSP,             rtsp);
@@ -263,7 +268,7 @@
     REGISTER_DEMUXER (SUBVIEWER,        subviewer);
     REGISTER_MUXDEMUX(SWF,              swf);
     REGISTER_DEMUXER (TAK,              tak);
-    REGISTER_MUXER   (TEE, tee);
+    REGISTER_MUXER   (TEE,              tee);
     REGISTER_DEMUXER (TEDCAPTIONS,      tedcaptions);
     REGISTER_MUXER   (TG2,              tg2);
     REGISTER_MUXER   (TGP,              tgp);
@@ -287,7 +292,7 @@
     REGISTER_MUXDEMUX(WAV,              wav);
     REGISTER_DEMUXER (WC3,              wc3);
     REGISTER_MUXER   (WEBM,             webm);
-    REGISTER_DEMUXER (WEBVTT,           webvtt);
+    REGISTER_MUXDEMUX(WEBVTT,           webvtt);
     REGISTER_DEMUXER (WSAUD,            wsaud);
     REGISTER_DEMUXER (WSVQA,            wsvqa);
     REGISTER_MUXDEMUX(WTV,              wtv);
@@ -308,6 +313,7 @@
     REGISTER_PROTOCOL(FFRTMPCRYPT,      ffrtmpcrypt);
     REGISTER_PROTOCOL(FFRTMPHTTP,       ffrtmphttp);
     REGISTER_PROTOCOL(FILE,             file);
+    REGISTER_PROTOCOL(FTP,              ftp);
     REGISTER_PROTOCOL(GOPHER,           gopher);
     REGISTER_PROTOCOL(HLS,              hls);
     REGISTER_PROTOCOL(HTTP,             http);
@@ -329,8 +335,10 @@
     REGISTER_PROTOCOL(TCP,              tcp);
     REGISTER_PROTOCOL(TLS,              tls);
     REGISTER_PROTOCOL(UDP,              udp);
+    REGISTER_PROTOCOL(UNIX,             unix);
 
     /* external libraries */
+    REGISTER_DEMUXER (LIBGME,           libgme);
     REGISTER_DEMUXER (LIBMODPLUG,       libmodplug);
     REGISTER_MUXDEMUX(LIBNUT,           libnut);
     REGISTER_DEMUXER (LIBQUVI,          libquvi);
diff --git a/libavformat/ape.c b/libavformat/ape.c
index e2b8ada..bb61a24 100644
--- a/libavformat/ape.c
+++ b/libavformat/ape.c
@@ -414,6 +414,8 @@
     AV_WL32(pkt->data    , nblocks);
     AV_WL32(pkt->data + 4, ape->frames[ape->currentframe].skip);
     ret = avio_read(s->pb, pkt->data + extra_size, ape->frames[ape->currentframe].size);
+    if (ret < 0)
+        return ret;
 
     pkt->pts = ape->frames[ape->currentframe].pts;
     pkt->stream_index = 0;
diff --git a/libavformat/apetag.c b/libavformat/apetag.c
index a445c84..ab93736 100644
--- a/libavformat/apetag.c
+++ b/libavformat/apetag.c
@@ -23,10 +23,12 @@
 #include "libavutil/intreadwrite.h"
 #include "libavutil/dict.h"
 #include "avformat.h"
+#include "avio_internal.h"
 #include "apetag.h"
 #include "internal.h"
 
 #define APE_TAG_FLAG_CONTAINS_HEADER  (1 << 31)
+#define APE_TAG_FLAG_CONTAINS_FOOTER  (1 << 30)
 #define APE_TAG_FLAG_IS_HEADER        (1 << 29)
 #define APE_TAG_FLAG_IS_BINARY        (1 << 1)
 
@@ -114,7 +116,7 @@
 int64_t ff_ape_parse_tag(AVFormatContext *s)
 {
     AVIOContext *pb = s->pb;
-    int file_size = avio_size(pb);
+    int64_t file_size = avio_size(pb);
     uint32_t val, fields, tag_bytes;
     uint8_t buf[8];
     int64_t tag_start;
@@ -167,3 +169,73 @@
 
     return tag_start;
 }
+
+static int string_is_ascii(const uint8_t *str)
+{
+    while (*str && *str >= 0x20 && *str <= 0x7e ) str++;
+    return !*str;
+}
+
+int ff_ape_write_tag(AVFormatContext *s)
+{
+    AVDictionaryEntry *e = NULL;
+    int size, ret, count = 0;
+    AVIOContext *dyn_bc = NULL;
+    uint8_t *dyn_buf = NULL;
+
+    if ((ret = avio_open_dyn_buf(&dyn_bc)) < 0)
+        goto end;
+
+    // flags
+    avio_wl32(dyn_bc, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER |
+                     APE_TAG_FLAG_IS_HEADER);
+    ffio_fill(dyn_bc, 0, 8);             // reserved
+
+    while ((e = av_dict_get(s->metadata, "", e, AV_DICT_IGNORE_SUFFIX))) {
+        int val_len;
+
+        if (!string_is_ascii(e->key)) {
+            av_log(s, AV_LOG_WARNING, "Non ASCII keys are not allowed\n");
+            continue;
+        }
+
+        val_len = strlen(e->value);
+        avio_wl32(dyn_bc, val_len);            // value length
+        avio_wl32(dyn_bc, 0);                  // item flags
+        avio_put_str(dyn_bc, e->key);          // key
+        avio_write(dyn_bc, e->value, val_len); // value
+        count++;
+    }
+    if (!count)
+        goto end;
+
+    size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
+    if (size <= 0)
+        goto end;
+    size += 20;
+
+    // header
+    avio_write(s->pb, "APETAGEX", 8);   // id
+    avio_wl32(s->pb, APE_TAG_VERSION);  // version
+    avio_wl32(s->pb, size);
+    avio_wl32(s->pb, count);
+
+    avio_write(s->pb, dyn_buf, size - 20);
+
+    // footer
+    avio_write(s->pb, "APETAGEX", 8);   // id
+    avio_wl32(s->pb, APE_TAG_VERSION);  // version
+    avio_wl32(s->pb, size);             // size
+    avio_wl32(s->pb, count);            // tag count
+
+    // flags
+    avio_wl32(s->pb, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER);
+    ffio_fill(s->pb, 0, 8);             // reserved
+
+end:
+    if (dyn_bc && !dyn_buf)
+        avio_close_dyn_buf(dyn_bc, &dyn_buf);
+    av_freep(&dyn_buf);
+
+    return ret;
+}
diff --git a/libavformat/apetag.h b/libavformat/apetag.h
index 0330c89..cf2a5f8 100644
--- a/libavformat/apetag.h
+++ b/libavformat/apetag.h
@@ -37,8 +37,8 @@
 int64_t ff_ape_parse_tag(AVFormatContext *s);
 
 /**
- * Write an APEv2 tag
+ * Write an APE tag into a file.
  */
-void ff_ape_write(AVFormatContext *s);
+int ff_ape_write_tag(AVFormatContext *s);
 
 #endif /* AVFORMAT_APETAG_H */
diff --git a/libavformat/apetagenc.c b/libavformat/apetagenc.c
deleted file mode 100644
index 42f5836..0000000
--- a/libavformat/apetagenc.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * APE tag writer
- * Copyright (c) 2012 Paul B Mahol
- *
- * 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
- */
-
-#include "libavutil/dict.h"
-#include "avio_internal.h"
-#include "avformat.h"
-#include "apetag.h"
-
-static int string_is_ascii(const uint8_t *str)
-{
-    while (*str && *str >= 0x20 && *str <= 0x7e ) str++;
-    return !*str;
-}
-
-void ff_ape_write(AVFormatContext *s)
-{
-    int64_t tag_bytes;
-    AVDictionaryEntry *t = NULL;
-    AVIOContext *pb = s->pb;
-    int tags = 0, vlen;
-
-    tag_bytes = avio_tell(s->pb);
-    while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) {
-        if (!string_is_ascii(t->key)) {
-            av_log(s, AV_LOG_WARNING, "Non ASCII keys are not allowed\n");
-            continue;
-        }
-
-        vlen = strlen(t->value);
-        avio_wl32(pb, vlen + 1);
-        avio_wl32(pb, 0); // flags
-        avio_put_str(pb, t->key);
-        avio_put_str(pb, t->value);
-        tags++;
-    }
-    tag_bytes = avio_tell(s->pb) - tag_bytes;
-
-    if (!tags)
-        return;
-
-    avio_write(pb, APE_TAG_PREAMBLE, 8);
-    avio_wl32(pb, APE_TAG_VERSION);
-    avio_wl32(pb, tag_bytes + APE_TAG_FOOTER_BYTES);
-    avio_wl32(pb, tags); // item count
-    avio_wl32(pb, 0); // global flags
-    ffio_fill(pb, 0, 8); // reserved
-}
diff --git a/libavformat/aqtitledec.c b/libavformat/aqtitledec.c
index a78fd81..810f95b 100644
--- a/libavformat/aqtitledec.c
+++ b/libavformat/aqtitledec.c
@@ -43,7 +43,7 @@
     const char *ptr = p->buf;
 
     if (sscanf(ptr, "-->> %d", &frame) == 1)
-        return AVPROBE_SCORE_MAX / 2;
+        return AVPROBE_SCORE_EXTENSION;
     return 0;
 }
 
diff --git a/libavformat/asf.h b/libavformat/asf.h
index 5ffc746..30d6c1e 100644
--- a/libavformat/asf.h
+++ b/libavformat/asf.h
@@ -39,8 +39,10 @@
     /* use for reading */
     AVPacket pkt;
     int frag_offset;
+    int packet_obj_size;
     int timestamp;
     int64_t duration;
+    int skip_to_key;
 
     int ds_span;                /* descrambling  */
     int ds_packet_size;
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c
index 1d7f26c..0d6370d 100644
--- a/libavformat/asfdec.c
+++ b/libavformat/asfdec.c
@@ -19,14 +19,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-//#define DEBUG
-
 #include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/bswap.h"
 #include "libavutil/common.h"
 #include "libavutil/dict.h"
+#include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
 #include "avformat.h"
@@ -69,7 +68,6 @@
     unsigned int packet_frag_size;
     int64_t packet_frag_timestamp;
     int packet_multi_size;
-    int packet_obj_size;
     int packet_time_delta;
     int packet_time_start;
     int64_t packet_pos;
@@ -368,14 +366,8 @@
     if (!st)
         return AVERROR(ENOMEM);
     avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
-    asf_st = av_mallocz(sizeof(ASFStream));
-    if (!asf_st)
-        return AVERROR(ENOMEM);
-    st->priv_data  = asf_st;
     start_time     = asf->hdr.preroll;
 
-    asf_st->stream_language_index = 128; // invalid stream index means no language info
-
     if (!(asf->hdr.flags & 0x01)) { // if we aren't streaming...
         int64_t fsize = avio_size(pb);
         if (fsize <= 0 || (int64_t)asf->hdr.file_size <= 0 || FFABS(fsize - (int64_t)asf->hdr.file_size) < 10000)
@@ -407,6 +399,7 @@
     st->id = avio_rl16(pb) & 0x7f; /* stream id */
     // mapping of asf ID to AV stream ID;
     asf->asfid2avid[st->id] = s->nb_streams - 1;
+    asf_st = &asf->streams[st->id];
 
     avio_rl32(pb);
 
@@ -731,6 +724,10 @@
     avio_r8(pb);
     avio_r8(pb);
     memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid));
+
+    for (i = 0; i<128; i++)
+        asf->streams[i].stream_language_index = 128; // invalid stream index means no language info
+
     for (;;) {
         uint64_t gpos = avio_tell(pb);
         ff_get_guid(pb, &g);
@@ -883,7 +880,7 @@
  * @param pb context to read data from
  * @return 0 on success, <0 on error
  */
-static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb)
+static int asf_get_packet(AVFormatContext *s, AVIOContext *pb)
 {
     ASFContext *asf = s->priv_data;
     uint32_t packet_length, padsize;
@@ -1009,10 +1006,10 @@
     if (asf->packet_replic_size >= 8) {
         int64_t end = avio_tell(pb) + asf->packet_replic_size;
         AVRational aspect;
-        asf->packet_obj_size = avio_rl32(pb);
-        if (asf->packet_obj_size >= (1 << 24) || asf->packet_obj_size <= 0) {
+        asfst->packet_obj_size = avio_rl32(pb);
+        if (asfst->packet_obj_size >= (1 << 24) || asfst->packet_obj_size <= 0) {
             av_log(s, AV_LOG_ERROR, "packet_obj_size invalid\n");
-            asf->packet_obj_size = 0;
+            asfst->packet_obj_size = 0;
             return AVERROR_INVALIDDATA;
         }
         asf->packet_frag_timestamp = avio_rl32(pb); // timestamp
@@ -1110,7 +1107,7 @@
  * @return 0 if data was stored in pkt, <0 on error or 1 if more ASF
  *          packets need to be loaded (through asf_get_packet())
  */
-static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
+static int asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
 {
     ASFContext *asf   = s->priv_data;
     ASFStream *asf_st = 0;
@@ -1141,7 +1138,7 @@
             if (asf->stream_index < 0 ||
                 s->streams[asf->stream_index]->discard >= AVDISCARD_ALL ||
                 (!asf->packet_key_frame &&
-                 s->streams[asf->stream_index]->discard >= AVDISCARD_NONKEY)) {
+                 (s->streams[asf->stream_index]->discard >= AVDISCARD_NONKEY || asf->streams[s->streams[asf->stream_index]->id].skip_to_key))) {
                 asf->packet_time_start = 0;
                 /* unhandled packet (should not happen) */
                 avio_skip(pb, asf->packet_frag_size);
@@ -1151,7 +1148,8 @@
                            asf->packet_frag_size);
                 continue;
             }
-            asf->asf_st = s->streams[asf->stream_index]->priv_data;
+            asf->asf_st = &asf->streams[s->streams[asf->stream_index]->id];
+            asf->asf_st->skip_to_key = 0;
         }
         asf_st = asf->asf_st;
         av_assert0(asf_st);
@@ -1160,37 +1158,30 @@
             // frag_offset is here used as the beginning timestamp
             asf->packet_frag_timestamp = asf->packet_time_start;
             asf->packet_time_start    += asf->packet_time_delta;
-            asf->packet_obj_size       = asf->packet_frag_size = avio_r8(pb);
+            asf_st->packet_obj_size    = asf->packet_frag_size = avio_r8(pb);
             asf->packet_size_left--;
             asf->packet_multi_size--;
-            if (asf->packet_multi_size < asf->packet_obj_size) {
+            if (asf->packet_multi_size < asf_st->packet_obj_size) {
                 asf->packet_time_start = 0;
                 avio_skip(pb, asf->packet_multi_size);
                 asf->packet_size_left -= asf->packet_multi_size;
                 continue;
             }
-            asf->packet_multi_size -= asf->packet_obj_size;
-        }
-        if (asf_st->frag_offset + asf->packet_frag_size <= asf_st->pkt.size &&
-            asf_st->frag_offset + asf->packet_frag_size > asf->packet_obj_size) {
-            av_log(s, AV_LOG_INFO, "ignoring invalid packet_obj_size (%d %d %d %d)\n",
-                   asf_st->frag_offset, asf->packet_frag_size,
-                   asf->packet_obj_size, asf_st->pkt.size);
-            asf->packet_obj_size = asf_st->pkt.size;
+            asf->packet_multi_size -= asf_st->packet_obj_size;
         }
 
-        if (asf_st->pkt.size != asf->packet_obj_size ||
+        if (asf_st->pkt.size != asf_st->packet_obj_size ||
             // FIXME is this condition sufficient?
             asf_st->frag_offset + asf->packet_frag_size > asf_st->pkt.size) {
             if (asf_st->pkt.data) {
                 av_log(s, AV_LOG_INFO,
                        "freeing incomplete packet size %d, new %d\n",
-                       asf_st->pkt.size, asf->packet_obj_size);
+                       asf_st->pkt.size, asf_st->packet_obj_size);
                 asf_st->frag_offset = 0;
                 av_free_packet(&asf_st->pkt);
             }
             /* new packet */
-            av_new_packet(&asf_st->pkt, asf->packet_obj_size);
+            av_new_packet(&asf_st->pkt, asf_st->packet_obj_size);
             asf_st->seq              = asf->packet_seq;
             asf_st->pkt.dts          = asf->packet_frag_timestamp - asf->hdr.preroll;
             asf_st->pkt.stream_index = asf->stream_index;
@@ -1211,7 +1202,7 @@
                     asf->stream_index, asf->packet_key_frame,
                     asf_st->pkt.flags & AV_PKT_FLAG_KEY,
                     s->streams[asf->stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO,
-                    asf->packet_obj_size);
+                    asf_st->packet_obj_size);
             if (s->streams[asf->stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
                 asf->packet_key_frame = 1;
             if (asf->packet_key_frame)
@@ -1310,7 +1301,9 @@
             asf_st->frag_offset         = 0;
             *pkt                        = asf_st->pkt;
 #if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
             asf_st->pkt.destruct        = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
             asf_st->pkt.buf             = 0;
             asf_st->pkt.size            = 0;
@@ -1331,9 +1324,9 @@
         int ret;
 
         /* parse cached packets, if any */
-        if ((ret = ff_asf_parse_packet(s, s->pb, pkt)) <= 0)
+        if ((ret = asf_parse_packet(s, s->pb, pkt)) <= 0)
             return ret;
-        if ((ret = ff_asf_get_packet(s, s->pb)) < 0)
+        if ((ret = asf_get_packet(s, s->pb)) < 0)
             assert(asf->packet_size_left < FRAME_HEADER_SIZE ||
                    asf->packet_segments < 1);
         asf->packet_time_start = 0;
@@ -1364,21 +1357,34 @@
     asf->packet_frag_size      = 0;
     asf->packet_frag_timestamp = 0;
     asf->packet_multi_size     = 0;
-    asf->packet_obj_size       = 0;
     asf->packet_time_delta     = 0;
     asf->packet_time_start     = 0;
 
-    for (i = 0; i < s->nb_streams; i++) {
-        asf_st = s->streams[i]->priv_data;
-        if (!asf_st)
-            continue;
+    for (i = 0; i < 128; i++) {
+        asf_st = &asf->streams[i];
         av_free_packet(&asf_st->pkt);
+        asf_st->packet_obj_size = 0;
         asf_st->frag_offset = 0;
         asf_st->seq         = 0;
     }
     asf->asf_st = NULL;
 }
 
+static void skip_to_key(AVFormatContext *s)
+{
+    ASFContext *asf = s->priv_data;
+    int i;
+
+    for (i = 0; i < 128; i++) {
+        int j = asf->asfid2avid[i];
+        ASFStream *asf_st = &asf->streams[i];
+        if (j < 0 || s->streams[j]->codec->codec_type != AVMEDIA_TYPE_VIDEO)
+            continue;
+
+        asf_st->skip_to_key = 1;
+    }
+}
+
 static int asf_read_close(AVFormatContext *s)
 {
     asf_reset_header(s);
@@ -1389,6 +1395,7 @@
 static int64_t asf_read_pts(AVFormatContext *s, int stream_index,
                             int64_t *ppos, int64_t pos_limit)
 {
+    ASFContext *asf     = s->priv_data;
     AVPacket pkt1, *pkt = &pkt1;
     ASFStream *asf_st;
     int64_t pts;
@@ -1407,6 +1414,7 @@
     if (avio_seek(s->pb, pos, SEEK_SET) < 0)
         return AV_NOPTS_VALUE;
 
+    ff_read_frame_flush(s);
     asf_reset_header(s);
     for (;;) {
         if (av_read_frame(s, pkt) < 0) {
@@ -1420,8 +1428,7 @@
         if (pkt->flags & AV_PKT_FLAG_KEY) {
             i = pkt->stream_index;
 
-            asf_st = s->streams[i]->priv_data;
-            av_assert0(asf_st);
+            asf_st = &asf->streams[s->streams[i]->id];
 
 //            assert((asf_st->packet_pos - s->data_offset) % s->packet_size == 0);
             pos = asf_st->packet_pos;
@@ -1528,6 +1535,7 @@
             if(avio_seek(s->pb, pos, SEEK_SET) < 0)
                 return -1;
             asf_reset_header(s);
+            skip_to_key(s);
             return 0;
         }
     }
@@ -1535,6 +1543,7 @@
     if (ff_seek_frame_binary(s, stream_index, pts, flags) < 0)
         return -1;
     asf_reset_header(s);
+    skip_to_key(s);
     return 0;
 }
 
diff --git a/libavformat/audiointerleave.c b/libavformat/audiointerleave.c
index 35dd8d5..2aa95f3 100644
--- a/libavformat/audiointerleave.c
+++ b/libavformat/audiointerleave.c
@@ -74,8 +74,8 @@
     return 0;
 }
 
-static int ff_interleave_new_audio_packet(AVFormatContext *s, AVPacket *pkt,
-                                   int stream_index, int flush)
+static int interleave_new_audio_packet(AVFormatContext *s, AVPacket *pkt,
+                                       int stream_index, int flush)
 {
     AVStream *st = s->streams[stream_index];
     AudioInterleaveContext *aic = st->priv_data;
@@ -134,7 +134,7 @@
         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
             AVPacket new_pkt;
             int ret;
-            while ((ret = ff_interleave_new_audio_packet(s, &new_pkt, i, flush)) > 0) {
+            while ((ret = interleave_new_audio_packet(s, &new_pkt, i, flush)) > 0) {
                 ret = ff_interleave_add_packet(s, &new_pkt, compare_ts);
                 if (ret < 0)
                     return ret;
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 80d693a..77efc61 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -337,8 +337,10 @@
     int buf_size;       /**< Size of buf except extra allocated bytes */
 } AVProbeData;
 
-#define AVPROBE_SCORE_MAX 100               ///< maximum score, half of that is used for file-extension-based detection
 #define AVPROBE_SCORE_RETRY (AVPROBE_SCORE_MAX/4)
+#define AVPROBE_SCORE_EXTENSION  50 ///< score for file extension
+#define AVPROBE_SCORE_MAX       100 ///< maximum score
+
 #define AVPROBE_PADDING_SIZE 32             ///< extra allocated bytes at the end of the probe buffer
 
 /// Demuxer will use avio_open, no opened file should be provided by the caller.
@@ -354,8 +356,8 @@
 #define AVFMT_VARIABLE_FPS  0x0400 /**< Format allows variable fps. */
 #define AVFMT_NODIMENSIONS  0x0800 /**< Format does not need width/height */
 #define AVFMT_NOSTREAMS     0x1000 /**< Format does not require any streams */
-#define AVFMT_NOBINSEARCH   0x2000 /**< Format does not allow to fallback to binary search via read_timestamp */
-#define AVFMT_NOGENSEARCH   0x4000 /**< Format does not allow to fallback to generic search */
+#define AVFMT_NOBINSEARCH   0x2000 /**< Format does not allow to fall back on binary search via read_timestamp */
+#define AVFMT_NOGENSEARCH   0x4000 /**< Format does not allow to fall back on generic search */
 #define AVFMT_NO_BYTE_SEEK  0x8000 /**< Format does not allow seeking by bytes */
 #define AVFMT_ALLOW_FLUSH  0x10000 /**< Format allows flushing. If not set, the muxer will not receive a NULL packet in the write_packet function. */
 #if LIBAVFORMAT_VERSION_MAJOR <= 54
@@ -366,6 +368,14 @@
                                    /**< Format does not require strictly
                                         increasing timestamps, but they must
                                         still be monotonic */
+#define AVFMT_TS_NEGATIVE  0x40000 /**< Format allows muxing negative
+                                        timestamps. If not set the timestamp
+                                        will be shifted in av_write_frame and
+                                        av_interleaved_write_frame so they
+                                        start from 0.
+                                        The user or muxer can override this through
+                                        AVFormatContext.avoid_negative_ts
+                                        */
 
 #define AVFMT_SEEK_TO_PTS   0x4000000 /**< Seeking is based on PTS */
 
@@ -626,6 +636,13 @@
 #define AV_DISPOSITION_ATTACHED_PIC      0x0400
 
 /**
+ * To specify text track kind (different from subtitles default).
+ */
+#define AV_DISPOSITION_CAPTIONS     0x10000
+#define AV_DISPOSITION_DESCRIPTIONS 0x20000
+#define AV_DISPOSITION_METADATA     0x40000
+
+/**
  * Options for behavior on timestamp wrap detection.
  */
 #define AV_PTS_WRAP_IGNORE      0   ///< ignore the wrap
@@ -723,19 +740,6 @@
      */
     AVPacket attached_pic;
 
-    /**
-     * Real base framerate of the stream.
-     * This is the lowest framerate with which all timestamps can be
-     * represented accurately (it is the least common multiple of all
-     * framerates in the stream). Note, this value is just a guess!
-     * For example, if the time base is 1/90000 and all frames have either
-     * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1.
-     *
-     * Code outside avformat should access this field using:
-     * av_stream_get/set_r_frame_rate(stream)
-     */
-    AVRational r_frame_rate;
-
     /*****************************************************************
      * All fields below this line are not part of the public API. They
      * may not be used outside of libavformat and can be changed and
@@ -796,16 +800,6 @@
      */
     int codec_info_nb_frames;
 
-    /**
-     * Stream Identifier
-     * This is the MPEG-TS stream identifier +1
-     * 0 means unknown
-     */
-    int stream_identifier;
-
-    int64_t interleaver_chunk_size;
-    int64_t interleaver_chunk_duration;
-
     /* av_read_frame() support */
     enum AVStreamParseType need_parsing;
     struct AVCodecParserContext *parser;
@@ -824,6 +818,29 @@
     unsigned int index_entries_allocated_size;
 
     /**
+     * Real base framerate of the stream.
+     * This is the lowest framerate with which all timestamps can be
+     * represented accurately (it is the least common multiple of all
+     * framerates in the stream). Note, this value is just a guess!
+     * For example, if the time base is 1/90000 and all frames have either
+     * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1.
+     *
+     * Code outside avformat should access this field using:
+     * av_stream_get/set_r_frame_rate(stream)
+     */
+    AVRational r_frame_rate;
+
+    /**
+     * Stream Identifier
+     * This is the MPEG-TS stream identifier +1
+     * 0 means unknown
+     */
+    int stream_identifier;
+
+    int64_t interleaver_chunk_size;
+    int64_t interleaver_chunk_duration;
+
+    /**
      * stream probing state
      * -1   -> probing finished
      *  0   -> no probing requested
@@ -1259,6 +1276,18 @@
     int raw_packet_buffer_remaining_size;
 
     /**
+     * Offset to remap timestamps to be non-negative.
+     * Expressed in timebase units.
+     * @see AVStream.mux_ts_offset
+     */
+    int64_t offset;
+
+    /**
+     * Timebase for the timestamp offset.
+     */
+    AVRational offset_timebase;
+
+    /**
      * IO repositioned flag.
      * This is set by avformat when the underlaying IO context read pointer
      * is repositioned, for example when doing byte based seeking.
@@ -1376,6 +1405,9 @@
  *
  * When muxing, should be called by the user before avformat_write_header().
  *
+ * User is required to call avcodec_close() and avformat_free_context() to
+ * clean up the allocation by avformat_new_stream().
+ *
  * @param c If non-NULL, the AVCodecContext corresponding to the new stream
  * will be initialized to use this codec. This is needed for e.g. codec-specific
  * defaults to be set, so codec should be provided if it is known.
@@ -1391,12 +1423,6 @@
  */
 
 
-#if FF_API_PKT_DUMP
-attribute_deprecated void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload);
-attribute_deprecated void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt,
-                                          int dump_payload);
-#endif
-
 #if FF_API_ALLOC_OUTPUT_CONTEXT
 /**
  * @deprecated deprecated in favor of avformat_alloc_output_context2()
@@ -1487,7 +1513,7 @@
 
 /**
  * Open an input stream and read the header. The codecs are not opened.
- * The stream must be closed with av_close_input_file().
+ * The stream must be closed with avformat_close_input().
  *
  * @param ps Pointer to user-supplied AVFormatContext (allocated by avformat_alloc_context).
  *           May be a pointer to NULL, in which case an AVFormatContext is allocated by this
@@ -1622,8 +1648,8 @@
  * information possible for decoding.
  *
  * If pkt->buf is NULL, then the packet is valid until the next
- * av_read_frame() or until av_close_input_file(). Otherwise the packet is valid
- * indefinitely. In both cases the packet must be freed with
+ * av_read_frame() or until avformat_close_input(). Otherwise the packet
+ * is valid indefinitely. In both cases the packet must be freed with
  * av_free_packet when it is no longer needed. For video, the packet contains
  * exactly one frame. For audio, it contains an integer number of frames if each
  * frame has a known fixed size (e.g. PCM or ADPCM data). If the audio frames
@@ -1667,6 +1693,7 @@
  * or if stream_index is -1, in AV_TIME_BASE units.
  * If flags contain AVSEEK_FLAG_ANY, then non-keyframes are treated as
  * keyframes (this may not be supported by all demuxers).
+ * If flags contain AVSEEK_FLAG_BACKWARD, it is ignored.
  *
  * @param stream_index index of the stream which is used as time base reference
  * @param min_ts smallest acceptable timestamp
@@ -1753,7 +1780,7 @@
  *
  * @param s Media file handle, must be allocated with avformat_alloc_context().
  *          Its oformat field must be set to the desired output format;
- *          Its pb field must be set to an already openened AVIOContext.
+ *          Its pb field must be set to an already opened AVIOContext.
  * @param options  An AVDictionary filled with AVFormatContext and muxer-private options.
  *                 On return this parameter will be destroyed and replaced with a dict containing
  *                 options that were not found. May be NULL.
diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index 3105d33..2827064 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -19,36 +19,38 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/intreadwrite.h"
-#include "libavutil/mathematics.h"
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
 #include "libavutil/bswap.h"
 #include "libavutil/opt.h"
 #include "libavutil/dict.h"
-#include "libavutil/avstring.h"
-#include "libavutil/avassert.h"
+#include "libavutil/internal.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mathematics.h"
 #include "avformat.h"
-#include "internal.h"
 #include "avi.h"
 #include "dv.h"
+#include "internal.h"
 #include "riff.h"
 
 typedef struct AVIStream {
-    int64_t frame_offset; /* current frame (video) or byte (audio) counter
-                         (used to compute the pts) */
+    int64_t frame_offset;   /* current frame (video) or byte (audio) counter
+                             * (used to compute the pts) */
     int remaining;
     int packet_size;
 
     uint32_t scale;
     uint32_t rate;
-    int sample_size; /* size of one sample (or packet) (in the rate/scale sense) in bytes */
+    int sample_size;        /* size of one sample (or packet)
+                             * (in the rate/scale sense) in bytes */
 
-    int64_t cum_len; /* temporary storage (used during seek) */
-
-    int prefix;                       ///< normally 'd'<<8 + 'c' or 'w'<<8 + 'b'
+    int64_t cum_len;        /* temporary storage (used during seek) */
+    int prefix;             /* normally 'd'<<8 + 'c' or 'w'<<8 + 'b' */
     int prefix_count;
     uint32_t pal[256];
     int has_pal;
-    int dshow_block_align;            ///< block align variable used to emulate bugs in the MS dshow demuxer
+    int dshow_block_align;  /* block align variable used to emulate bugs in
+                             * the MS dshow demuxer */
 
     AVFormatContext *sub_ctx;
     AVPacket sub_pkt;
@@ -59,9 +61,9 @@
 
 typedef struct {
     const AVClass *class;
-    int64_t  riff_end;
-    int64_t  movi_end;
-    int64_t  fsize;
+    int64_t riff_end;
+    int64_t movi_end;
+    int64_t fsize;
     int64_t io_fsize;
     int64_t movi_list;
     int64_t last_pkt_pos;
@@ -69,7 +71,7 @@
     int is_odml;
     int non_interleaved;
     int stream_index;
-    DVDemuxContext* dv_demux;
+    DVDemuxContext *dv_demux;
     int odml_depth;
     int use_odml;
 #define MAX_ODML_DEPTH 1000
@@ -92,11 +94,11 @@
 
 
 static const char avi_headers[][8] = {
-    { 'R', 'I', 'F', 'F',    'A', 'V', 'I', ' ' },
-    { 'R', 'I', 'F', 'F',    'A', 'V', 'I', 'X' },
-    { 'R', 'I', 'F', 'F',    'A', 'V', 'I', 0x19},
-    { 'O', 'N', '2', ' ',    'O', 'N', '2', 'f' },
-    { 'R', 'I', 'F', 'F',    'A', 'M', 'V', ' ' },
+    { 'R', 'I', 'F', 'F', 'A', 'V', 'I', ' '  },
+    { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 'X'  },
+    { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 0x19 },
+    { 'O', 'N', '2', ' ', 'O', 'N', '2', 'f'  },
+    { 'R', 'I', 'F', 'F', 'A', 'M', 'V', ' '  },
     { 0 }
 };
 
@@ -108,20 +110,21 @@
 static int avi_load_index(AVFormatContext *s);
 static int guess_ni_flag(AVFormatContext *s);
 
-#define print_tag(str, tag, size)                       \
-    av_dlog(NULL, "%s: tag=%c%c%c%c size=0x%x\n",       \
-           str, tag & 0xff,                             \
-           (tag >> 8) & 0xff,                           \
-           (tag >> 16) & 0xff,                          \
-           (tag >> 24) & 0xff,                          \
-           size)
+#define print_tag(str, tag, size)                        \
+    av_dlog(NULL, "%s: tag=%c%c%c%c size=0x%x\n",        \
+            str, tag & 0xff,                             \
+            (tag >> 8) & 0xff,                           \
+            (tag >> 16) & 0xff,                          \
+            (tag >> 24) & 0xff,                          \
+            size)
 
-static inline int get_duration(AVIStream *ast, int len){
-    if(ast->sample_size){
+static inline int get_duration(AVIStream *ast, int len)
+{
+    if (ast->sample_size)
         return len;
-    }else if (ast->dshow_block_align){
-        return (len + ast->dshow_block_align - 1)/ast->dshow_block_align;
-    }else
+    else if (ast->dshow_block_align)
+        return (len + ast->dshow_block_align - 1) / ast->dshow_block_align;
+    else
         return 1;
 }
 
@@ -133,164 +136,180 @@
 
     /* check RIFF header */
     avio_read(pb, header, 4);
-    avi->riff_end = avio_rl32(pb);  /* RIFF chunk size */
+    avi->riff_end  = avio_rl32(pb); /* RIFF chunk size */
     avi->riff_end += avio_tell(pb); /* RIFF chunk end */
-    avio_read(pb, header+4, 4);
+    avio_read(pb, header + 4, 4);
 
-    for(i=0; avi_headers[i][0]; i++)
-        if(!memcmp(header, avi_headers[i], 8))
+    for (i = 0; avi_headers[i][0]; i++)
+        if (!memcmp(header, avi_headers[i], 8))
             break;
-    if(!avi_headers[i][0])
+    if (!avi_headers[i][0])
         return AVERROR_INVALIDDATA;
 
-    if(header[7] == 0x19)
-        av_log(s, AV_LOG_INFO, "This file has been generated by a totally broken muxer.\n");
+    if (header[7] == 0x19)
+        av_log(s, AV_LOG_INFO,
+               "This file has been generated by a totally broken muxer.\n");
 
     return 0;
 }
 
-static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){
-    AVIContext *avi = s->priv_data;
-    AVIOContext *pb = s->pb;
-    int longs_pre_entry= avio_rl16(pb);
-    int index_sub_type = avio_r8(pb);
-    int index_type     = avio_r8(pb);
-    int entries_in_use = avio_rl32(pb);
-    int chunk_id       = avio_rl32(pb);
-    int64_t base       = avio_rl64(pb);
-    int stream_id= 10*((chunk_id&0xFF) - '0') + (((chunk_id>>8)&0xFF) - '0');
+static int read_braindead_odml_indx(AVFormatContext *s, int frame_num)
+{
+    AVIContext *avi     = s->priv_data;
+    AVIOContext *pb     = s->pb;
+    int longs_pre_entry = avio_rl16(pb);
+    int index_sub_type  = avio_r8(pb);
+    int index_type      = avio_r8(pb);
+    int entries_in_use  = avio_rl32(pb);
+    int chunk_id        = avio_rl32(pb);
+    int64_t base        = avio_rl64(pb);
+    int stream_id       = ((chunk_id      & 0xFF) - '0') * 10 +
+                          ((chunk_id >> 8 & 0xFF) - '0');
     AVStream *st;
     AVIStream *ast;
     int i;
-    int64_t last_pos= -1;
-    int64_t filesize= avi->fsize;
+    int64_t last_pos = -1;
+    int64_t filesize = avi->fsize;
 
-    av_dlog(s, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64"\n",
-            longs_pre_entry,index_type, entries_in_use, chunk_id, base);
+    av_dlog(s,
+            "longs_pre_entry:%d index_type:%d entries_in_use:%d "
+            "chunk_id:%X base:%16"PRIX64"\n",
+            longs_pre_entry,
+            index_type,
+            entries_in_use,
+            chunk_id,
+            base);
 
-    if(stream_id >= s->nb_streams || stream_id < 0)
+    if (stream_id >= s->nb_streams || stream_id < 0)
         return AVERROR_INVALIDDATA;
-    st= s->streams[stream_id];
+    st  = s->streams[stream_id];
     ast = st->priv_data;
 
-    if(index_sub_type)
+    if (index_sub_type)
         return AVERROR_INVALIDDATA;
 
     avio_rl32(pb);
 
-    if(index_type && longs_pre_entry != 2)
+    if (index_type && longs_pre_entry != 2)
         return AVERROR_INVALIDDATA;
-    if(index_type>1)
+    if (index_type > 1)
         return AVERROR_INVALIDDATA;
 
-    if(filesize > 0 && base >= filesize){
+    if (filesize > 0 && base >= filesize) {
         av_log(s, AV_LOG_ERROR, "ODML index invalid\n");
-        if(base>>32 == (base & 0xFFFFFFFF) && (base & 0xFFFFFFFF) < filesize && filesize <= 0xFFFFFFFF)
+        if (base >> 32 == (base & 0xFFFFFFFF) &&
+            (base & 0xFFFFFFFF) < filesize    &&
+            filesize <= 0xFFFFFFFF)
             base &= 0xFFFFFFFF;
         else
             return AVERROR_INVALIDDATA;
     }
 
-    for(i=0; i<entries_in_use; i++){
-        if(index_type){
-            int64_t pos= avio_rl32(pb) + base - 8;
-            int len    = avio_rl32(pb);
-            int key= len >= 0;
+    for (i = 0; i < entries_in_use; i++) {
+        if (index_type) {
+            int64_t pos = avio_rl32(pb) + base - 8;
+            int len     = avio_rl32(pb);
+            int key     = len >= 0;
             len &= 0x7FFFFFFF;
 
 #ifdef DEBUG_SEEK
             av_log(s, AV_LOG_ERROR, "pos:%"PRId64", len:%X\n", pos, len);
 #endif
-            if(url_feof(pb))
+            if (url_feof(pb))
                 return AVERROR_INVALIDDATA;
 
-            if(last_pos == pos || pos == base - 8)
-                avi->non_interleaved= 1;
-            if(last_pos != pos && (len || !ast->sample_size))
-                av_add_index_entry(st, pos, ast->cum_len, len, 0, key ? AVINDEX_KEYFRAME : 0);
+            if (last_pos == pos || pos == base - 8)
+                avi->non_interleaved = 1;
+            if (last_pos != pos && (len || !ast->sample_size))
+                av_add_index_entry(st, pos, ast->cum_len, len, 0,
+                                   key ? AVINDEX_KEYFRAME : 0);
 
             ast->cum_len += get_duration(ast, len);
-            last_pos= pos;
-        }else{
+            last_pos      = pos;
+        } else {
             int64_t offset, pos;
             int duration;
             offset = avio_rl64(pb);
             avio_rl32(pb);       /* size */
             duration = avio_rl32(pb);
 
-            if(url_feof(pb))
+            if (url_feof(pb))
                 return AVERROR_INVALIDDATA;
 
             pos = avio_tell(pb);
 
-            if(avi->odml_depth > MAX_ODML_DEPTH){
+            if (avi->odml_depth > MAX_ODML_DEPTH) {
                 av_log(s, AV_LOG_ERROR, "Too deeply nested ODML indexes\n");
                 return AVERROR_INVALIDDATA;
             }
 
-            if(avio_seek(pb, offset+8, SEEK_SET) < 0)
+            if (avio_seek(pb, offset + 8, SEEK_SET) < 0)
                 return -1;
             avi->odml_depth++;
             read_braindead_odml_indx(s, frame_num);
             avi->odml_depth--;
             frame_num += duration;
 
-            if(avio_seek(pb, pos, SEEK_SET) < 0) {
+            if (avio_seek(pb, pos, SEEK_SET) < 0) {
                 av_log(s, AV_LOG_ERROR, "Failed to restore position after reading index\n");
                 return -1;
             }
 
         }
     }
-    avi->index_loaded=2;
+    avi->index_loaded = 2;
     return 0;
 }
 
-static void clean_index(AVFormatContext *s){
+static void clean_index(AVFormatContext *s)
+{
     int i;
     int64_t j;
 
-    for(i=0; i<s->nb_streams; i++){
-        AVStream *st = s->streams[i];
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st   = s->streams[i];
         AVIStream *ast = st->priv_data;
-        int n= st->nb_index_entries;
-        int max= ast->sample_size;
+        int n          = st->nb_index_entries;
+        int max        = ast->sample_size;
         int64_t pos, size, ts;
 
-        if(n != 1 || ast->sample_size==0)
+        if (n != 1 || ast->sample_size == 0)
             continue;
 
-        while(max < 1024) max+=max;
+        while (max < 1024)
+            max += max;
 
-        pos= st->index_entries[0].pos;
-        size= st->index_entries[0].size;
-        ts= st->index_entries[0].timestamp;
+        pos  = st->index_entries[0].pos;
+        size = st->index_entries[0].size;
+        ts   = st->index_entries[0].timestamp;
 
-        for(j=0; j<size; j+=max){
-            av_add_index_entry(st, pos+j, ts+j, FFMIN(max, size-j), 0, AVINDEX_KEYFRAME);
-        }
+        for (j = 0; j < size; j += max)
+            av_add_index_entry(st, pos + j, ts + j, FFMIN(max, size - j), 0,
+                               AVINDEX_KEYFRAME);
     }
 }
 
-static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag, uint32_t size)
+static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag,
+                        uint32_t size)
 {
     AVIOContext *pb = s->pb;
-    char key[5] = {0}, *value;
+    char key[5]     = { 0 };
+    char *value;
 
     size += (size & 1);
 
     if (size == UINT_MAX)
         return AVERROR(EINVAL);
-    value = av_malloc(size+1);
+    value = av_malloc(size + 1);
     if (!value)
         return AVERROR(ENOMEM);
     avio_read(pb, value, size);
-    value[size]=0;
+    value[size] = 0;
 
     AV_WL32(key, tag);
 
     return av_dict_set(st ? &st->metadata : &s->metadata, key, value,
-                            AV_DICT_DONT_STRDUP_VAL);
+                       AV_DICT_DONT_STRDUP_VAL);
 }
 
 static const char months[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
@@ -303,10 +322,10 @@
     /* parse standard AVI date format (ie. "Mon Mar 10 15:04:43 2003") */
     if (sscanf(date, "%*3s%*[ ]%3s%*[ ]%2d%*[ ]%8s%*[ ]%4d",
                month, &day, time, &year) == 4) {
-        for (i=0; i<12; i++)
+        for (i = 0; i < 12; i++)
             if (!av_strcasecmp(month, months[i])) {
                 snprintf(buffer, sizeof(buffer), "%.4d-%.2d-%.2d %s",
-                         year, i+1, day, time);
+                         year, i + 1, day, time);
                 av_dict_set(metadata, "creation_time", buffer, 0);
             }
     } else if (date[4] == '/' && date[7] == '/') {
@@ -321,19 +340,25 @@
         uint32_t tag  = avio_rl32(s->pb);
         uint32_t size = avio_rl32(s->pb);
         switch (tag) {
-        case MKTAG('n', 'c', 't', 'g'): {  /* Nikon Tags */
+        case MKTAG('n', 'c', 't', 'g'):  /* Nikon Tags */
+        {
             uint64_t tag_end = avio_tell(s->pb) + size;
             while (avio_tell(s->pb) < tag_end) {
-                uint16_t tag  = avio_rl16(s->pb);
-                uint16_t size = avio_rl16(s->pb);
+                uint16_t tag     = avio_rl16(s->pb);
+                uint16_t size    = avio_rl16(s->pb);
                 const char *name = NULL;
-                char buffer[64] = {0};
+                char buffer[64]  = { 0 };
                 size -= avio_read(s->pb, buffer,
-                                   FFMIN(size, sizeof(buffer)-1));
+                                  FFMIN(size, sizeof(buffer) - 1));
                 switch (tag) {
-                case 0x03:  name = "maker";  break;
-                case 0x04:  name = "model";  break;
-                case 0x13:  name = "creation_time";
+                case 0x03:
+                    name = "maker";
+                    break;
+                case 0x04:
+                    name = "model";
+                    break;
+                case 0x13:
+                    name = "creation_time";
                     if (buffer[4] == ':' && buffer[7] == ':')
                         buffer[4] = buffer[7] = '-';
                     break;
@@ -360,13 +385,14 @@
     unsigned int size;
     int i;
     AVStream *st;
-    AVIStream *ast = NULL;
-    int avih_width=0, avih_height=0;
-    int amv_file_format=0;
-    uint64_t list_end = 0;
+    AVIStream *ast      = NULL;
+    int avih_width      = 0, avih_height = 0;
+    int amv_file_format = 0;
+    uint64_t list_end   = 0;
     int ret;
+    AVDictionaryEntry *dict_entry;
 
-    avi->stream_index= -1;
+    avi->stream_index = -1;
 
     ret = get_riff(s, pb);
     if (ret < 0)
@@ -375,22 +401,22 @@
     av_log(avi, AV_LOG_DEBUG, "use odml:%d\n", avi->use_odml);
 
     avi->io_fsize = avi->fsize = avio_size(pb);
-    if(avi->fsize<=0 || avi->fsize < avi->riff_end)
-        avi->fsize= avi->riff_end == 8 ? INT64_MAX : avi->riff_end;
+    if (avi->fsize <= 0 || avi->fsize < avi->riff_end)
+        avi->fsize = avi->riff_end == 8 ? INT64_MAX : avi->riff_end;
 
     /* first list tag */
     stream_index = -1;
-    codec_type = -1;
+    codec_type   = -1;
     frame_period = 0;
-    for(;;) {
+    for (;;) {
         if (url_feof(pb))
             goto fail;
-        tag = avio_rl32(pb);
+        tag  = avio_rl32(pb);
         size = avio_rl32(pb);
 
         print_tag("tag", tag, size);
 
-        switch(tag) {
+        switch (tag) {
         case MKTAG('L', 'I', 'S', 'T'):
             list_end = avio_tell(pb) + size;
             /* Ignored, except at start of video packets. */
@@ -400,21 +426,23 @@
 
             if (tag1 == MKTAG('m', 'o', 'v', 'i')) {
                 avi->movi_list = avio_tell(pb) - 4;
-                if(size) avi->movi_end = avi->movi_list + size + (size & 1);
-                else     avi->movi_end = avi->fsize;
+                if (size)
+                    avi->movi_end = avi->movi_list + size + (size & 1);
+                else
+                    avi->movi_end = avi->fsize;
                 av_dlog(NULL, "movi end=%"PRIx64"\n", avi->movi_end);
                 goto end_of_header;
-            }
-            else if (tag1 == MKTAG('I', 'N', 'F', 'O'))
+            } else if (tag1 == MKTAG('I', 'N', 'F', 'O'))
                 ff_read_riff_info(s, size - 4);
             else if (tag1 == MKTAG('n', 'c', 'd', 't'))
                 avi_read_nikon(s, list_end);
 
             break;
-        case MKTAG('I', 'D', 'I', 'T'): {
-            unsigned char date[64] = {0};
+        case MKTAG('I', 'D', 'I', 'T'):
+        {
+            unsigned char date[64] = { 0 };
             size += (size & 1);
-            size -= avio_read(pb, date, FFMIN(size, sizeof(date)-1));
+            size -= avio_read(pb, date, FFMIN(size, sizeof(date) - 1));
             avio_skip(pb, size);
             avi_metadata_creation_time(&s->metadata, date);
             break;
@@ -424,7 +452,7 @@
             avio_skip(pb, size + (size & 1));
             break;
         case MKTAG('a', 'm', 'v', 'h'):
-            amv_file_format=1;
+            amv_file_format = 1;
         case MKTAG('a', 'v', 'i', 'h'):
             /* AVI header */
             /* using frame_period is bad idea */
@@ -436,51 +464,51 @@
             avio_skip(pb, 2 * 4);
             avio_rl32(pb);
             avio_rl32(pb);
-            avih_width=avio_rl32(pb);
-            avih_height=avio_rl32(pb);
+            avih_width  = avio_rl32(pb);
+            avih_height = avio_rl32(pb);
 
             avio_skip(pb, size - 10 * 4);
             break;
         case MKTAG('s', 't', 'r', 'h'):
             /* stream header */
 
-            tag1 = avio_rl32(pb);
+            tag1    = avio_rl32(pb);
             handler = avio_rl32(pb); /* codec tag */
 
-            if(tag1 == MKTAG('p', 'a', 'd', 's')){
+            if (tag1 == MKTAG('p', 'a', 'd', 's')) {
                 avio_skip(pb, size - 8);
                 break;
-            }else{
+            } else {
                 stream_index++;
                 st = avformat_new_stream(s, NULL);
                 if (!st)
                     goto fail;
 
                 st->id = stream_index;
-                ast = av_mallocz(sizeof(AVIStream));
+                ast    = av_mallocz(sizeof(AVIStream));
                 if (!ast)
                     goto fail;
                 st->priv_data = ast;
             }
-            if(amv_file_format)
-                tag1 = stream_index ? MKTAG('a','u','d','s') : MKTAG('v','i','d','s');
+            if (amv_file_format)
+                tag1 = stream_index ? MKTAG('a', 'u', 'd', 's')
+                                    : MKTAG('v', 'i', 'd', 's');
 
             print_tag("strh", tag1, -1);
 
-            if(tag1 == MKTAG('i', 'a', 'v', 's') || tag1 == MKTAG('i', 'v', 'a', 's')){
+            if (tag1 == MKTAG('i', 'a', 'v', 's') ||
+                tag1 == MKTAG('i', 'v', 'a', 's')) {
                 int64_t dv_dur;
 
-                /*
-                 * After some consideration -- I don't think we
-                 * have to support anything but DV in type1 AVIs.
-                 */
+                /* After some consideration -- I don't think we
+                 * have to support anything but DV in type1 AVIs. */
                 if (s->nb_streams != 1)
                     goto fail;
 
                 if (handler != MKTAG('d', 'v', 's', 'd') &&
                     handler != MKTAG('d', 'v', 'h', 'd') &&
                     handler != MKTAG('d', 'v', 's', 'l'))
-                   goto fail;
+                    goto fail;
 
                 ast = s->streams[0]->priv_data;
                 av_freep(&s->streams[0]->codec->extradata);
@@ -498,46 +526,48 @@
                 s->streams[0]->priv_data = ast;
                 avio_skip(pb, 3 * 4);
                 ast->scale = avio_rl32(pb);
-                ast->rate = avio_rl32(pb);
+                ast->rate  = avio_rl32(pb);
                 avio_skip(pb, 4);  /* start time */
 
                 dv_dur = avio_rl32(pb);
                 if (ast->scale > 0 && ast->rate > 0 && dv_dur > 0) {
-                    dv_dur *= AV_TIME_BASE;
+                    dv_dur     *= AV_TIME_BASE;
                     s->duration = av_rescale(dv_dur, ast->scale, ast->rate);
                 }
-                /*
-                 * else, leave duration alone; timing estimation in utils.c
-                 *      will make a guess based on bitrate.
-                 */
+                /* else, leave duration alone; timing estimation in utils.c
+                 * will make a guess based on bitrate. */
 
                 stream_index = s->nb_streams - 1;
-                avio_skip(pb, size - 9*4);
+                avio_skip(pb, size - 9 * 4);
                 break;
             }
 
             av_assert0(stream_index < s->nb_streams);
-            st->codec->stream_codec_tag= handler;
+            st->codec->stream_codec_tag = handler;
 
             avio_rl32(pb); /* flags */
             avio_rl16(pb); /* priority */
             avio_rl16(pb); /* language */
             avio_rl32(pb); /* initial frame */
             ast->scale = avio_rl32(pb);
-            ast->rate = avio_rl32(pb);
-            if(!(ast->scale && ast->rate)){
-                av_log(s, AV_LOG_WARNING, "scale/rate is %u/%u which is invalid. (This file has been generated by broken software.)\n", ast->scale, ast->rate);
-                if(frame_period){
-                    ast->rate = 1000000;
+            ast->rate  = avio_rl32(pb);
+            if (!(ast->scale && ast->rate)) {
+                av_log(s, AV_LOG_WARNING,
+                       "scale/rate is %u/%u which is invalid. "
+                       "(This file has been generated by broken software.)\n",
+                       ast->scale,
+                       ast->rate);
+                if (frame_period) {
+                    ast->rate  = 1000000;
                     ast->scale = frame_period;
-                }else{
-                    ast->rate = 25;
+                } else {
+                    ast->rate  = 25;
                     ast->scale = 1;
                 }
             }
             avpriv_set_pts_info(st, 64, ast->scale, ast->rate);
 
-            ast->cum_len=avio_rl32(pb); /* start */
+            ast->cum_len  = avio_rl32(pb); /* start */
             st->nb_frames = avio_rl32(pb);
 
             st->start_time = 0;
@@ -548,11 +578,11 @@
                 return AVERROR_INVALIDDATA;
             }
             ast->sample_size = avio_rl32(pb); /* sample ssize */
-            ast->cum_len *= FFMAX(1, ast->sample_size);
+            ast->cum_len    *= FFMAX(1, ast->sample_size);
             av_dlog(s, "%"PRIu32" %"PRIu32" %d\n",
                     ast->rate, ast->scale, ast->sample_size);
 
-            switch(tag1) {
+            switch (tag1) {
             case MKTAG('v', 'i', 'd', 's'):
                 codec_type = AVMEDIA_TYPE_VIDEO;
 
@@ -570,14 +600,14 @@
             default:
                 av_log(s, AV_LOG_INFO, "unknown stream type %X\n", tag1);
             }
-            if(ast->sample_size == 0) {
+            if (ast->sample_size == 0) {
                 st->duration = st->nb_frames;
                 if (st->duration > 0 && avi->io_fsize > 0 && avi->riff_end > avi->io_fsize) {
                     av_log(s, AV_LOG_DEBUG, "File is truncated adjusting duration\n");
                     st->duration = av_rescale(st->duration, avi->io_fsize, avi->riff_end);
                 }
             }
-            ast->frame_offset= ast->cum_len;
+            ast->frame_offset = ast->cum_len;
             avio_skip(pb, size - 12 * 4);
             break;
         case MKTAG('s', 't', 'r', 'f'):
@@ -592,49 +622,59 @@
                 if (cur_pos < list_end)
                     size = FFMIN(size, list_end - cur_pos);
                 st = s->streams[stream_index];
-                switch(codec_type) {
+                switch (codec_type) {
                 case AVMEDIA_TYPE_VIDEO:
-                    if(amv_file_format){
-                        st->codec->width=avih_width;
-                        st->codec->height=avih_height;
+                    if (amv_file_format) {
+                        st->codec->width      = avih_width;
+                        st->codec->height     = avih_height;
                         st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
-                        st->codec->codec_id = AV_CODEC_ID_AMV;
+                        st->codec->codec_id   = AV_CODEC_ID_AMV;
                         avio_skip(pb, size);
                         break;
                     }
                     tag1 = ff_get_bmp_header(pb, st, &esize);
 
-                    if (tag1 == MKTAG('D', 'X', 'S', 'B') || tag1 == MKTAG('D','X','S','A')) {
+                    if (tag1 == MKTAG('D', 'X', 'S', 'B') ||
+                        tag1 == MKTAG('D', 'X', 'S', 'A')) {
                         st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
-                        st->codec->codec_tag = tag1;
-                        st->codec->codec_id = AV_CODEC_ID_XSUB;
+                        st->codec->codec_tag  = tag1;
+                        st->codec->codec_id   = AV_CODEC_ID_XSUB;
                         break;
                     }
 
-                    if(size > 10*4 && size<(1<<30) && size < avi->fsize){
-                        if(esize == size-1 && (esize&1)) st->codec->extradata_size= esize - 10*4;
-                        else                             st->codec->extradata_size=  size - 10*4;
-                        st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+                    if (size > 10 * 4 && size < (1 << 30) && size < avi->fsize) {
+                        if (esize == size-1 && (esize&1)) {
+                            st->codec->extradata_size = esize - 10 * 4;
+                        } else
+                            st->codec->extradata_size =  size - 10 * 4;
+                        st->codec->extradata      = av_malloc(st->codec->extradata_size +
+                                                              FF_INPUT_BUFFER_PADDING_SIZE);
                         if (!st->codec->extradata) {
-                            st->codec->extradata_size= 0;
+                            st->codec->extradata_size = 0;
                             return AVERROR(ENOMEM);
                         }
-                        avio_read(pb, st->codec->extradata, st->codec->extradata_size);
+                        avio_read(pb,
+                                  st->codec->extradata,
+                                  st->codec->extradata_size);
                     }
 
-                    if(st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly
+                    // FIXME: check if the encoder really did this correctly
+                    if (st->codec->extradata_size & 1)
                         avio_r8(pb);
 
-                    /* Extract palette from extradata if bpp <= 8. */
-                    /* This code assumes that extradata contains only palette. */
-                    /* This is true for all paletted codecs implemented in FFmpeg. */
-                    if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) {
+                    /* Extract palette from extradata if bpp <= 8.
+                     * This code assumes that extradata contains only palette.
+                     * This is true for all paletted codecs implemented in
+                     * FFmpeg. */
+                    if (st->codec->extradata_size &&
+                        (st->codec->bits_per_coded_sample <= 8)) {
                         int pal_size = (1 << st->codec->bits_per_coded_sample) << 2;
                         const uint8_t *pal_src;
 
                         pal_size = FFMIN(pal_size, st->codec->extradata_size);
-                        pal_src = st->codec->extradata + st->codec->extradata_size - pal_size;
-                        for (i = 0; i < pal_size/4; i++)
+                        pal_src  = st->codec->extradata +
+                                   st->codec->extradata_size - pal_size;
+                        for (i = 0; i < pal_size / 4; i++)
                             ast->pal[i] = 0xFFU<<24 | AV_RL32(pal_src+4*i);
                         ast->has_pal = 1;
                     }
@@ -642,17 +682,25 @@
                     print_tag("video", tag1, 0);
 
                     st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
-                    st->codec->codec_tag = tag1;
-                    st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1);
-                    st->need_parsing = AVSTREAM_PARSE_HEADERS; // This is needed to get the pict type which is necessary for generating correct pts.
+                    st->codec->codec_tag  = tag1;
+                    st->codec->codec_id   = ff_codec_get_id(ff_codec_bmp_tags,
+                                                            tag1);
+                    /* This is needed to get the pict type which is necessary
+                     * for generating correct pts. */
+                    st->need_parsing = AVSTREAM_PARSE_HEADERS;
 
-                    if(st->codec->codec_tag==0 && st->codec->height > 0 && st->codec->extradata_size < 1U<<30){
-                        st->codec->extradata_size+= 9;
-                        st->codec->extradata= av_realloc_f(st->codec->extradata, 1, st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
-                        if(st->codec->extradata)
-                            memcpy(st->codec->extradata + st->codec->extradata_size - 9, "BottomUp", 9);
+                    if (st->codec->codec_tag == 0 && st->codec->height > 0 &&
+                        st->codec->extradata_size < 1U << 30) {
+                        st->codec->extradata_size += 9;
+                        st->codec->extradata       = av_realloc_f(st->codec->extradata,
+                                                                  1,
+                                                                  st->codec->extradata_size +
+                                                                  FF_INPUT_BUFFER_PADDING_SIZE);
+                        if (st->codec->extradata)
+                            memcpy(st->codec->extradata + st->codec->extradata_size - 9,
+                                   "BottomUp", 9);
                     }
-                    st->codec->height= FFABS(st->codec->height);
+                    st->codec->height = FFABS(st->codec->height);
 
 //                    avio_skip(pb, size - 5 * 4);
                     break;
@@ -660,12 +708,19 @@
                     ret = ff_get_wav_header(pb, st->codec, size);
                     if (ret < 0)
                         return ret;
-                    ast->dshow_block_align= st->codec->block_align;
-                    if(ast->sample_size && st->codec->block_align && ast->sample_size != st->codec->block_align){
-                        av_log(s, AV_LOG_WARNING, "sample size (%d) != block align (%d)\n", ast->sample_size, st->codec->block_align);
-                        ast->sample_size= st->codec->block_align;
+                    ast->dshow_block_align = st->codec->block_align;
+                    if (ast->sample_size && st->codec->block_align &&
+                        ast->sample_size != st->codec->block_align) {
+                        av_log(s,
+                               AV_LOG_WARNING,
+                               "sample size (%d) != block align (%d)\n",
+                               ast->sample_size,
+                               st->codec->block_align);
+                        ast->sample_size = st->codec->block_align;
                     }
-                    if (size&1) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
+                    /* 2-aligned
+                     * (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
+                    if (size & 1)
                         avio_skip(pb, 1);
                     /* Force parsing as several audio frames can be in
                      * one packet and timestamps refer to packet start. */
@@ -673,24 +728,25 @@
                     /* ADTS header is in extradata, AAC without header must be
                      * stored as exact frames. Parser not needed and it will
                      * fail. */
-                    if (st->codec->codec_id == AV_CODEC_ID_AAC && st->codec->extradata_size)
+                    if (st->codec->codec_id == AV_CODEC_ID_AAC &&
+                        st->codec->extradata_size)
                         st->need_parsing = AVSTREAM_PARSE_NONE;
                     /* AVI files with Xan DPCM audio (wrongly) declare PCM
                      * audio in the header but have Axan as stream_code_tag. */
-                    if (st->codec->stream_codec_tag == AV_RL32("Axan")){
+                    if (st->codec->stream_codec_tag == AV_RL32("Axan")) {
                         st->codec->codec_id  = AV_CODEC_ID_XAN_DPCM;
                         st->codec->codec_tag = 0;
                         ast->dshow_block_align = 0;
                     }
-                    if (amv_file_format){
-                        st->codec->codec_id  = AV_CODEC_ID_ADPCM_IMA_AMV;
+                    if (amv_file_format) {
+                        st->codec->codec_id    = AV_CODEC_ID_ADPCM_IMA_AMV;
                         ast->dshow_block_align = 0;
                     }
-                    if(st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align <= 4 && ast->dshow_block_align) {
+                    if (st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align <= 4 && ast->dshow_block_align) {
                         av_log(s, AV_LOG_DEBUG, "overriding invalid dshow_block_align of %d\n", ast->dshow_block_align);
                         ast->dshow_block_align = 0;
                     }
-                    if(st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 1024 && ast->sample_size == 1024 ||
+                    if (st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 1024 && ast->sample_size == 1024 ||
                        st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 4096 && ast->sample_size == 4096 ||
                        st->codec->codec_id == AV_CODEC_ID_MP3 && ast->dshow_block_align == 1152 && ast->sample_size == 1152) {
                         av_log(s, AV_LOG_DEBUG, "overriding sample_size\n");
@@ -704,15 +760,17 @@
                     break;
                 default:
                     st->codec->codec_type = AVMEDIA_TYPE_DATA;
-                    st->codec->codec_id= AV_CODEC_ID_NONE;
-                    st->codec->codec_tag= 0;
+                    st->codec->codec_id   = AV_CODEC_ID_NONE;
+                    st->codec->codec_tag  = 0;
                     avio_skip(pb, size);
                     break;
                 }
             }
             break;
         case MKTAG('s', 't', 'r', 'd'):
-            if (stream_index >= (unsigned)s->nb_streams || s->streams[stream_index]->codec->extradata_size) {
+            if (stream_index >= (unsigned)s->nb_streams
+                || s->streams[stream_index]->codec->extradata_size
+                || s->streams[stream_index]->codec->codec_tag == MKTAG('H','2','6','4')) {
                 avio_skip(pb, size);
             } else {
                 uint64_t cur_pos = avio_tell(pb);
@@ -720,7 +778,7 @@
                     size = FFMIN(size, list_end - cur_pos);
                 st = s->streams[stream_index];
 
-                if(size<(1<<30)){
+                if (size<(1<<30)) {
                     st->codec->extradata_size= size;
                     st->codec->extradata= av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
                     if (!st->codec->extradata) {
@@ -730,19 +788,21 @@
                     avio_read(pb, st->codec->extradata, st->codec->extradata_size);
                 }
 
-                if(st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly
+                if (st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly
                     avio_r8(pb);
             }
             break;
         case MKTAG('i', 'n', 'd', 'x'):
-            i= avio_tell(pb);
-            if(pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) && avi->use_odml &&
-               read_braindead_odml_indx(s, 0) < 0 && (s->error_recognition & AV_EF_EXPLODE))
+            i = avio_tell(pb);
+            if (pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) &&
+                avi->use_odml &&
+                read_braindead_odml_indx(s, 0) < 0 &&
+                (s->error_recognition & AV_EF_EXPLODE))
                 goto fail;
-            avio_seek(pb, i+size, SEEK_SET);
+            avio_seek(pb, i + size, SEEK_SET);
             break;
         case MKTAG('v', 'p', 'r', 'p'):
-            if(stream_index < (unsigned)s->nb_streams && size > 9*4){
+            if (stream_index < (unsigned)s->nb_streams && size > 9 * 4) {
                 AVRational active, active_aspect;
 
                 st = s->streams[stream_index];
@@ -752,33 +812,35 @@
                 avio_rl32(pb);
                 avio_rl32(pb);
 
-                active_aspect.den= avio_rl16(pb);
-                active_aspect.num= avio_rl16(pb);
-                active.num       = avio_rl32(pb);
-                active.den       = avio_rl32(pb);
-                avio_rl32(pb); //nbFieldsPerFrame
+                active_aspect.den = avio_rl16(pb);
+                active_aspect.num = avio_rl16(pb);
+                active.num        = avio_rl32(pb);
+                active.den        = avio_rl32(pb);
+                avio_rl32(pb); // nbFieldsPerFrame
 
-                if(active_aspect.num && active_aspect.den && active.num && active.den){
-                    st->sample_aspect_ratio= av_div_q(active_aspect, active);
+                if (active_aspect.num && active_aspect.den &&
+                    active.num && active.den) {
+                    st->sample_aspect_ratio = av_div_q(active_aspect, active);
                     av_dlog(s, "vprp %d/%d %d/%d\n",
                             active_aspect.num, active_aspect.den,
                             active.num, active.den);
                 }
-                size -= 9*4;
+                size -= 9 * 4;
             }
             avio_skip(pb, size);
             break;
         case MKTAG('s', 't', 'r', 'n'):
-            if(s->nb_streams){
-                ret = avi_read_tag(s, s->streams[s->nb_streams-1], tag, size);
+            if (s->nb_streams) {
+                ret = avi_read_tag(s, s->streams[s->nb_streams - 1], tag, size);
                 if (ret < 0)
                     return ret;
                 break;
             }
         default:
-            if(size > 1000000){
-                av_log(s, AV_LOG_ERROR, "Something went wrong during header parsing, "
-                                        "I will ignore it and try to continue anyway.\n");
+            if (size > 1000000) {
+                av_log(s, AV_LOG_ERROR,
+                       "Something went wrong during header parsing, "
+                       "I will ignore it and try to continue anyway.\n");
                 if (s->error_recognition & AV_EF_EXPLODE)
                     goto fail;
                 avi->movi_list = avio_tell(pb) - 4;
@@ -791,32 +853,45 @@
             break;
         }
     }
- end_of_header:
+
+end_of_header:
     /* check stream number */
     if (stream_index != s->nb_streams - 1) {
-    fail:
+
+fail:
         return AVERROR_INVALIDDATA;
     }
 
-    if(!avi->index_loaded && pb->seekable)
+    if (!avi->index_loaded && pb->seekable)
         avi_load_index(s);
-    avi->index_loaded |= 1;
+    avi->index_loaded    |= 1;
     avi->non_interleaved |= guess_ni_flag(s) | (s->flags & AVFMT_FLAG_SORT_DTS);
-    for(i=0; i<s->nb_streams; i++){
+
+    dict_entry = av_dict_get(s->metadata, "ISFT", NULL, 0);
+    if (dict_entry && !strcmp(dict_entry->value, "PotEncoder"))
+        for (i = 0; i < s->nb_streams; i++) {
+            AVStream *st = s->streams[i];
+            if (   st->codec->codec_id == AV_CODEC_ID_MPEG1VIDEO
+                || st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO)
+                st->need_parsing = AVSTREAM_PARSE_FULL;
+        }
+
+    for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
-        if(st->nb_index_entries)
+        if (st->nb_index_entries)
             break;
     }
     // DV-in-AVI cannot be non-interleaved, if set this must be
     // a mis-detection.
-    if(avi->dv_demux)
-        avi->non_interleaved=0;
-    if(i==s->nb_streams && avi->non_interleaved) {
-        av_log(s, AV_LOG_WARNING, "non-interleaved AVI without index, switching to interleaved\n");
-        avi->non_interleaved=0;
+    if (avi->dv_demux)
+        avi->non_interleaved = 0;
+    if (i == s->nb_streams && avi->non_interleaved) {
+        av_log(s, AV_LOG_WARNING,
+               "Non-interleaved AVI without index, switching to interleaved\n");
+        avi->non_interleaved = 0;
     }
 
-    if(avi->non_interleaved) {
+    if (avi->non_interleaved) {
         av_log(s, AV_LOG_INFO, "non-interleaved AVI\n");
         clean_index(s);
     }
@@ -827,16 +902,17 @@
     return 0;
 }
 
-static int read_gab2_sub(AVStream *st, AVPacket *pkt) {
-    if (pkt->data && !strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data+5) == 2) {
+static int read_gab2_sub(AVStream *st, AVPacket *pkt)
+{
+    if (pkt->data && !strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data + 5) == 2) {
         uint8_t desc[256];
-        int score = AVPROBE_SCORE_MAX / 2, ret;
+        int score      = AVPROBE_SCORE_EXTENSION, ret;
         AVIStream *ast = st->priv_data;
         AVInputFormat *sub_demuxer;
         AVRational time_base;
-        AVIOContext *pb = avio_alloc_context( pkt->data + 7,
-                                              pkt->size - 7,
-                                              0, NULL, NULL, NULL, NULL);
+        AVIOContext *pb = avio_alloc_context(pkt->data + 7,
+                                             pkt->size - 7,
+                                             0, NULL, NULL, NULL, NULL);
         AVProbeData pd;
         unsigned int desc_len = avio_rl32(pb);
 
@@ -851,14 +927,15 @@
         avio_rl16(pb);   /* flags? */
         avio_rl32(pb);   /* data size */
 
-        pd = (AVProbeData) { .buf = pb->buf_ptr, .buf_size = pb->buf_end - pb->buf_ptr };
+        pd = (AVProbeData) { .buf      = pb->buf_ptr,
+                             .buf_size = pb->buf_end - pb->buf_ptr };
         if (!(sub_demuxer = av_probe_input_format2(&pd, 1, &score)))
             goto error;
 
         if (!(ast->sub_ctx = avformat_alloc_context()))
             goto error;
 
-        ast->sub_ctx->pb      = pb;
+        ast->sub_ctx->pb = pb;
         if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) {
             ff_read_packet(ast->sub_ctx, &ast->sub_pkt);
             *st->codec = *ast->sub_ctx->streams[0]->codec;
@@ -869,6 +946,7 @@
         ast->sub_buffer = pkt->data;
         memset(pkt, 0, sizeof(*pkt));
         return 1;
+
 error:
         av_freep(&pb);
     }
@@ -886,7 +964,7 @@
     next_ts = av_rescale_q(next_ast->frame_offset, next_st->time_base,
                            AV_TIME_BASE_Q);
 
-    for (i=0; i<s->nb_streams; i++) {
+    for (i = 0; i < s->nb_streams; i++) {
         st  = s->streams[i];
         ast = st->priv_data;
         if (st->discard < AVDISCARD_ALL && ast && ast->sub_pkt.data) {
@@ -899,21 +977,23 @@
     }
 
     if (sub_st) {
-        ast = sub_st->priv_data;
-        *pkt = ast->sub_pkt;
+        ast               = sub_st->priv_data;
+        *pkt              = ast->sub_pkt;
         pkt->stream_index = sub_st->index;
+
         if (ff_read_packet(ast->sub_ctx, &ast->sub_pkt) < 0)
             ast->sub_pkt.data = NULL;
     }
     return sub_st;
 }
 
-static int get_stream_idx(int *d){
-    if(    d[0] >= '0' && d[0] <= '9'
-        && d[1] >= '0' && d[1] <= '9'){
+static int get_stream_idx(int *d)
+{
+    if (d[0] >= '0' && d[0] <= '9' &&
+        d[1] >= '0' && d[1] <= '9') {
         return (d[0] - '0') * 10 + (d[1] - '0');
-    }else{
-        return 100; //invalid stream ID
+    } else {
+        return 100; // invalid stream ID
     }
 }
 
@@ -932,52 +1012,53 @@
 
 start_sync:
     memset(d, -1, sizeof(d));
-    for(i=sync=avio_tell(pb); !url_feof(pb); i++) {
+    for (i = sync = avio_tell(pb); !url_feof(pb); i++) {
         int j;
 
-        for(j=0; j<7; j++)
-            d[j]= d[j+1];
-        d[7]= avio_r8(pb);
+        for (j = 0; j < 7; j++)
+            d[j] = d[j + 1];
+        d[7] = avio_r8(pb);
 
-        size= d[4] + (d[5]<<8) + (d[6]<<16) + (d[7]<<24);
+        size = d[4] + (d[5] << 8) + (d[6] << 16) + (d[7] << 24);
 
-        n= get_stream_idx(d+2);
+        n = get_stream_idx(d + 2);
         av_dlog(s, "%X %X %X %X %X %X %X %X %"PRId64" %u %d\n",
                 d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
-        if(i*(avi->io_fsize>0) + (uint64_t)size > avi->fsize || d[0] > 127)
+        if (i*(avi->io_fsize>0) + (uint64_t)size > avi->fsize || d[0] > 127)
             continue;
 
-        //parse ix##
-        if(  (d[0] == 'i' && d[1] == 'x' && n < s->nb_streams)
-        //parse JUNK
-           ||(d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K')
-           ||(d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1')){
+        // parse ix##
+        if ((d[0] == 'i' && d[1] == 'x' && n < s->nb_streams) ||
+            // parse JUNK
+            (d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K') ||
+            (d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1')) {
             avio_skip(pb, size);
             goto start_sync;
         }
 
-        //parse stray LIST
-        if(d[0] == 'L' && d[1] == 'I' && d[2] == 'S' && d[3] == 'T'){
+        // parse stray LIST
+        if (d[0] == 'L' && d[1] == 'I' && d[2] == 'S' && d[3] == 'T') {
             avio_skip(pb, 4);
             goto start_sync;
         }
 
-        n= get_stream_idx(d);
+        n = get_stream_idx(d);
 
-        if(!((i-avi->last_pkt_pos)&1) && get_stream_idx(d+1) < s->nb_streams)
+        if (!((i - avi->last_pkt_pos) & 1) &&
+            get_stream_idx(d + 1) < s->nb_streams)
             continue;
 
-        //detect ##ix chunk and skip
-        if(d[2] == 'i' && d[3] == 'x' && n < s->nb_streams){
+        // detect ##ix chunk and skip
+        if (d[2] == 'i' && d[3] == 'x' && n < s->nb_streams) {
             avio_skip(pb, size);
             goto start_sync;
         }
 
-        //parse ##dc/##wb
-        if(n < s->nb_streams){
+        // parse ##dc/##wb
+        if (n < s->nb_streams) {
             AVStream *st;
             AVIStream *ast;
-            st = s->streams[n];
+            st  = s->streams[n];
             ast = st->priv_data;
 
             if (!ast) {
@@ -985,67 +1066,74 @@
                 continue;
             }
 
-            if(s->nb_streams>=2){
-                AVStream *st1  = s->streams[1];
-                AVIStream *ast1= st1->priv_data;
-                //workaround for broken small-file-bug402.avi
-                if(   d[2] == 'w' && d[3] == 'b'
-                   && n==0
+            if (s->nb_streams >= 2) {
+                AVStream *st1   = s->streams[1];
+                AVIStream *ast1 = st1->priv_data;
+                // workaround for broken small-file-bug402.avi
+                if (   d[2] == 'w' && d[3] == 'b'
+                   && n == 0
                    && st ->codec->codec_type == AVMEDIA_TYPE_VIDEO
                    && st1->codec->codec_type == AVMEDIA_TYPE_AUDIO
                    && ast->prefix == 'd'*256+'c'
                    && (d[2]*256+d[3] == ast1->prefix || !ast1->prefix_count)
-                  ){
-                    n=1;
-                    st = st1;
+                  ) {
+                    n   = 1;
+                    st  = st1;
                     ast = ast1;
-                    av_log(s, AV_LOG_WARNING, "Invalid stream + prefix combination, assuming audio.\n");
+                    av_log(s, AV_LOG_WARNING,
+                           "Invalid stream + prefix combination, assuming audio.\n");
                 }
             }
 
-
-            if(   (st->discard >= AVDISCARD_DEFAULT && size==0)
-               /*|| (st->discard >= AVDISCARD_NONKEY && !(pkt->flags & AV_PKT_FLAG_KEY))*/ //FIXME needs a little reordering
-               || st->discard >= AVDISCARD_ALL){
+            if (!avi->dv_demux &&
+                ((st->discard >= AVDISCARD_DEFAULT && size == 0) /* ||
+                 // FIXME: needs a little reordering
+                 (st->discard >= AVDISCARD_NONKEY &&
+                 !(pkt->flags & AV_PKT_FLAG_KEY)) */
+                || st->discard >= AVDISCARD_ALL)) {
                 if (!exit_early) {
                     ast->frame_offset += get_duration(ast, size);
+                    avio_skip(pb, size);
+                    goto start_sync;
                 }
-                avio_skip(pb, size);
-                goto start_sync;
             }
 
-            if (d[2] == 'p' && d[3] == 'c' && size<=4*256+4) {
-                int k = avio_r8(pb);
+            if (d[2] == 'p' && d[3] == 'c' && size <= 4 * 256 + 4) {
+                int k    = avio_r8(pb);
                 int last = (k + avio_r8(pb) - 1) & 0xFF;
 
-                avio_rl16(pb); //flags
+                avio_rl16(pb); // flags
 
+                // b + (g << 8) + (r << 16);
                 for (; k <= last; k++)
-                    ast->pal[k] = 0xFFU<<24 | avio_rb32(pb)>>8;// b + (g << 8) + (r << 16);
-                ast->has_pal= 1;
-                goto start_sync;
-            } else if(   ((ast->prefix_count<5 || sync+9 > i) && d[2]<128 && d[3]<128) ||
-                         d[2]*256+d[3] == ast->prefix /*||
-                         (d[2] == 'd' && d[3] == 'c') ||
-                         (d[2] == 'w' && d[3] == 'b')*/) {
+                    ast->pal[k] = 0xFFU<<24 | avio_rb32(pb)>>8;
 
+                ast->has_pal = 1;
+                goto start_sync;
+            } else if (((ast->prefix_count < 5 || sync + 9 > i) &&
+                        d[2] < 128 && d[3] < 128) ||
+                       d[2] * 256 + d[3] == ast->prefix /* ||
+                       (d[2] == 'd' && d[3] == 'c') ||
+                       (d[2] == 'w' && d[3] == 'b') */) {
                 if (exit_early)
                     return 0;
-                if(d[2]*256+d[3] == ast->prefix)
+                if (d[2] * 256 + d[3] == ast->prefix)
                     ast->prefix_count++;
-                else{
-                    ast->prefix= d[2]*256+d[3];
-                    ast->prefix_count= 0;
+                else {
+                    ast->prefix       = d[2] * 256 + d[3];
+                    ast->prefix_count = 0;
                 }
 
-                avi->stream_index= n;
-                ast->packet_size= size + 8;
-                ast->remaining= size;
+                avi->stream_index = n;
+                ast->packet_size  = size + 8;
+                ast->remaining    = size;
 
-                if(size || !ast->sample_size){
-                    uint64_t pos= avio_tell(pb) - 8;
-                    if(!st->index_entries || !st->nb_index_entries || st->index_entries[st->nb_index_entries - 1].pos < pos){
-                        av_add_index_entry(st, pos, ast->frame_offset, size, 0, AVINDEX_KEYFRAME);
+                if (size || !ast->sample_size) {
+                    uint64_t pos = avio_tell(pb) - 8;
+                    if (!st->index_entries || !st->nb_index_entries ||
+                        st->index_entries[st->nb_index_entries - 1].pos < pos) {
+                        av_add_index_entry(st, pos, ast->frame_offset, size,
+                                           0, AVINDEX_KEYFRAME);
                     }
                 }
                 return 0;
@@ -1053,7 +1141,7 @@
         }
     }
 
-    if(pb->error)
+    if (pb->error)
         return pb->error;
     return AVERROR_EOF;
 }
@@ -1064,7 +1152,7 @@
     AVIOContext *pb = s->pb;
     int err;
 #if FF_API_DESTRUCT_PACKET
-    void* dstr;
+    void *dstr;
 #endif
 
     if (CONFIG_DV_DEMUXER && avi->dv_demux) {
@@ -1073,97 +1161,106 @@
             return size;
     }
 
-    if(avi->non_interleaved){
+    if (avi->non_interleaved) {
         int best_stream_index = 0;
-        AVStream *best_st= NULL;
+        AVStream *best_st     = NULL;
         AVIStream *best_ast;
-        int64_t best_ts= INT64_MAX;
+        int64_t best_ts = INT64_MAX;
         int i;
 
-        for(i=0; i<s->nb_streams; i++){
-            AVStream *st = s->streams[i];
+        for (i = 0; i < s->nb_streams; i++) {
+            AVStream *st   = s->streams[i];
             AVIStream *ast = st->priv_data;
-            int64_t ts= ast->frame_offset;
+            int64_t ts     = ast->frame_offset;
             int64_t last_ts;
 
-            if(!st->nb_index_entries)
+            if (!st->nb_index_entries)
                 continue;
 
             last_ts = st->index_entries[st->nb_index_entries - 1].timestamp;
-            if(!ast->remaining && ts > last_ts)
+            if (!ast->remaining && ts > last_ts)
                 continue;
 
-            ts = av_rescale_q(ts, st->time_base, (AVRational){FFMAX(1, ast->sample_size), AV_TIME_BASE});
+            ts = av_rescale_q(ts, st->time_base,
+                              (AVRational) { FFMAX(1, ast->sample_size),
+                                             AV_TIME_BASE });
 
             av_dlog(s, "%"PRId64" %d/%d %"PRId64"\n", ts,
                     st->time_base.num, st->time_base.den, ast->frame_offset);
-            if(ts < best_ts){
-                best_ts= ts;
-                best_st= st;
-                best_stream_index= i;
+            if (ts < best_ts) {
+                best_ts           = ts;
+                best_st           = st;
+                best_stream_index = i;
             }
         }
-        if(!best_st)
+        if (!best_st)
             return AVERROR_EOF;
 
         best_ast = best_st->priv_data;
-        best_ts = best_ast->frame_offset;
-        if(best_ast->remaining)
-            i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
-        else{
-            i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY);
-            if(i>=0)
-                best_ast->frame_offset= best_st->index_entries[i].timestamp;
+        best_ts  = best_ast->frame_offset;
+        if (best_ast->remaining) {
+            i = av_index_search_timestamp(best_st,
+                                          best_ts,
+                                          AVSEEK_FLAG_ANY |
+                                          AVSEEK_FLAG_BACKWARD);
+        } else {
+            i = av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY);
+            if (i >= 0)
+                best_ast->frame_offset = best_st->index_entries[i].timestamp;
         }
 
-        if(i>=0){
-            int64_t pos= best_st->index_entries[i].pos;
+        if (i >= 0) {
+            int64_t pos = best_st->index_entries[i].pos;
             pos += best_ast->packet_size - best_ast->remaining;
-            if(avio_seek(s->pb, pos + 8, SEEK_SET) < 0)
+            if (avio_seek(s->pb, pos + 8, SEEK_SET) < 0)
               return AVERROR_EOF;
 
             av_assert0(best_ast->remaining <= best_ast->packet_size);
 
-            avi->stream_index= best_stream_index;
-            if(!best_ast->remaining)
-                best_ast->packet_size=
-                best_ast->remaining= best_st->index_entries[i].size;
+            avi->stream_index = best_stream_index;
+            if (!best_ast->remaining)
+                best_ast->packet_size =
+                best_ast->remaining   = best_st->index_entries[i].size;
         }
         else
           return AVERROR_EOF;
     }
 
 resync:
-    if(avi->stream_index >= 0){
-        AVStream *st= s->streams[ avi->stream_index ];
-        AVIStream *ast= st->priv_data;
+    if (avi->stream_index >= 0) {
+        AVStream *st   = s->streams[avi->stream_index];
+        AVIStream *ast = st->priv_data;
         int size, err;
 
-        if(get_subtitle_pkt(s, st, pkt))
+        if (get_subtitle_pkt(s, st, pkt))
             return 0;
 
-        if(ast->sample_size <= 1) // minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM
-            size= INT_MAX;
-        else if(ast->sample_size < 32)
+        // minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM
+        if (ast->sample_size <= 1)
+            size = INT_MAX;
+        else if (ast->sample_size < 32)
             // arbitrary multiplier to avoid tiny packets for raw PCM data
-            size= 1024*ast->sample_size;
+            size = 1024 * ast->sample_size;
         else
-            size= ast->sample_size;
+            size = ast->sample_size;
 
-        if(size > ast->remaining)
-            size= ast->remaining;
-        avi->last_pkt_pos= avio_tell(pb);
-        err= av_get_packet(pb, pkt, size);
-        if(err<0)
+        if (size > ast->remaining)
+            size = ast->remaining;
+        avi->last_pkt_pos = avio_tell(pb);
+        err               = av_get_packet(pb, pkt, size);
+        if (err < 0)
             return err;
         size = err;
 
-        if(ast->has_pal && pkt->size<(unsigned)INT_MAX/2){
+        if (ast->has_pal && pkt->size < (unsigned)INT_MAX / 2) {
             uint8_t *pal;
-            pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
-            if(!pal){
-                av_log(s, AV_LOG_ERROR, "Failed to allocate data for palette\n");
-            }else{
+            pal = av_packet_new_side_data(pkt,
+                                          AV_PKT_DATA_PALETTE,
+                                          AVPALETTE_SIZE);
+            if (!pal) {
+                av_log(s, AV_LOG_ERROR,
+                       "Failed to allocate data for palette\n");
+            } else {
                 memcpy(pal, ast->pal, AVPALETTE_SIZE);
                 ast->has_pal = 0;
             }
@@ -1172,32 +1269,44 @@
         if (CONFIG_DV_DEMUXER && avi->dv_demux) {
             AVBufferRef *avbuf = pkt->buf;
 #if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
             dstr = pkt->destruct;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
             size = avpriv_dv_produce_packet(avi->dv_demux, pkt,
-                                    pkt->data, pkt->size, pkt->pos);
+                                            pkt->data, pkt->size, pkt->pos);
 #if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
             pkt->destruct = dstr;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
-            pkt->buf = avbuf;
+            pkt->buf    = avbuf;
             pkt->flags |= AV_PKT_FLAG_KEY;
             if (size < 0)
                 av_free_packet(pkt);
-        } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
-                   && !st->codec->codec_tag && read_gab2_sub(st, pkt)) {
+        } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE &&
+                   !st->codec->codec_tag && read_gab2_sub(st, pkt)) {
             ast->frame_offset++;
             avi->stream_index = -1;
-            ast->remaining = 0;
+            ast->remaining    = 0;
             goto resync;
         } else {
             /* XXX: How to handle B-frames in AVI? */
             pkt->dts = ast->frame_offset;
 //                pkt->dts += ast->start;
-            if(ast->sample_size)
+            if (ast->sample_size)
                 pkt->dts /= ast->sample_size;
-            av_dlog(s, "dts:%"PRId64" offset:%"PRId64" %d/%d smpl_siz:%d base:%d st:%d size:%d\n",
-                    pkt->dts, ast->frame_offset, ast->scale, ast->rate,
-                    ast->sample_size, AV_TIME_BASE, avi->stream_index, size);
+            av_dlog(s,
+                    "dts:%"PRId64" offset:%"PRId64" %d/%d smpl_siz:%d "
+                    "base:%d st:%d size:%d\n",
+                    pkt->dts,
+                    ast->frame_offset,
+                    ast->scale,
+                    ast->rate,
+                    ast->sample_size,
+                    AV_TIME_BASE,
+                    avi->stream_index,
+                    size);
             pkt->stream_index = avi->stream_index;
 
             if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
@@ -1205,17 +1314,17 @@
                 int index;
                 av_assert0(st->index_entries);
 
-                index= av_index_search_timestamp(st, ast->frame_offset, 0);
-                e= &st->index_entries[index];
+                index = av_index_search_timestamp(st, ast->frame_offset, 0);
+                e     = &st->index_entries[index];
 
-                if(index >= 0 && e->timestamp == ast->frame_offset){
-                    if (index == st->nb_index_entries-1){
+                if (index >= 0 && e->timestamp == ast->frame_offset) {
+                    if (index == st->nb_index_entries-1) {
                         int key=1;
                         int i;
                         uint32_t state=-1;
-                        for(i=0; i<FFMIN(size,256); i++){
-                            if(st->codec->codec_id == AV_CODEC_ID_MPEG4){
-                                if(state == 0x1B6){
+                        for (i=0; i<FFMIN(size,256); i++) {
+                            if (st->codec->codec_id == AV_CODEC_ID_MPEG4) {
+                                if (state == 0x1B6) {
                                     key= !(pkt->data[i]&0xC0);
                                     break;
                                 }
@@ -1223,7 +1332,7 @@
                                 break;
                             state= (state<<8) + pkt->data[i];
                         }
-                        if(!key)
+                        if (!key)
                             e->flags &= ~AVINDEX_KEYFRAME;
                     }
                     if (e->flags & AVINDEX_KEYFRAME)
@@ -1235,24 +1344,24 @@
             ast->frame_offset += get_duration(ast, pkt->size);
         }
         ast->remaining -= err;
-        if(!ast->remaining){
-            avi->stream_index= -1;
-            ast->packet_size= 0;
+        if (!ast->remaining) {
+            avi->stream_index = -1;
+            ast->packet_size  = 0;
         }
 
-        if(!avi->non_interleaved && pkt->pos >= 0 && ast->seek_pos > pkt->pos){
+        if (!avi->non_interleaved && pkt->pos >= 0 && ast->seek_pos > pkt->pos) {
             av_free_packet(pkt);
             goto resync;
         }
         ast->seek_pos= 0;
 
-        if(!avi->non_interleaved && st->nb_index_entries>1 && avi->index_loaded>1){
+        if (!avi->non_interleaved && st->nb_index_entries>1 && avi->index_loaded>1) {
             int64_t dts= av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q);
 
-            if(avi->dts_max - dts > 2*AV_TIME_BASE){
+            if (avi->dts_max - dts > 2*AV_TIME_BASE) {
                 avi->non_interleaved= 1;
                 av_log(s, AV_LOG_INFO, "Switching to NI mode, due to poor interleaving\n");
-            }else if(avi->dts_max < dts)
+            }else if (avi->dts_max < dts)
                 avi->dts_max = dts;
         }
 
@@ -1265,7 +1374,7 @@
 }
 
 /* XXX: We make the implicit supposition that the positions are sorted
-   for each stream. */
+ * for each stream. */
 static int avi_read_idx1(AVFormatContext *s, int size)
 {
     AVIContext *avi = s->priv_data;
@@ -1274,8 +1383,8 @@
     AVStream *st;
     AVIStream *ast;
     unsigned int index, tag, flags, pos, len, first_packet = 1;
-    unsigned last_pos= -1;
-    unsigned last_idx= -1;
+    unsigned last_pos = -1;
+    unsigned last_idx = -1;
     int64_t idx1_pos, first_packet_pos = 0, data_offset = 0;
     int anykey = 0;
 
@@ -1284,39 +1393,38 @@
         return AVERROR_INVALIDDATA;
 
     idx1_pos = avio_tell(pb);
-    avio_seek(pb, avi->movi_list+4, SEEK_SET);
-    if (avi_sync(s, 1) == 0) {
+    avio_seek(pb, avi->movi_list + 4, SEEK_SET);
+    if (avi_sync(s, 1) == 0)
         first_packet_pos = avio_tell(pb) - 8;
-    }
     avi->stream_index = -1;
     avio_seek(pb, idx1_pos, SEEK_SET);
 
-    if (s->nb_streams == 1 && s->streams[0]->codec->codec_tag == AV_RL32("MMES")){
+    if (s->nb_streams == 1 && s->streams[0]->codec->codec_tag == AV_RL32("MMES")) {
         first_packet_pos = 0;
         data_offset = avi->movi_list;
     }
 
     /* Read the entries and sort them in each stream component. */
-    for(i = 0; i < nb_index_entries; i++) {
-        if(url_feof(pb))
+    for (i = 0; i < nb_index_entries; i++) {
+        if (url_feof(pb))
             return -1;
 
-        tag = avio_rl32(pb);
+        tag   = avio_rl32(pb);
         flags = avio_rl32(pb);
-        pos = avio_rl32(pb);
-        len = avio_rl32(pb);
+        pos   = avio_rl32(pb);
+        len   = avio_rl32(pb);
         av_dlog(s, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/",
                 i, tag, flags, pos, len);
 
-        index = ((tag & 0xff) - '0') * 10;
-        index += ((tag >> 8) & 0xff) - '0';
+        index  = ((tag      & 0xff) - '0') * 10;
+        index +=  (tag >> 8 & 0xff) - '0';
         if (index >= s->nb_streams)
             continue;
-        st = s->streams[index];
+        st  = s->streams[index];
         ast = st->priv_data;
 
-        if(first_packet && first_packet_pos && len) {
-            data_offset = first_packet_pos - pos;
+        if (first_packet && first_packet_pos && len) {
+            data_offset  = first_packet_pos - pos;
             first_packet = 0;
         }
         pos += data_offset;
@@ -1325,15 +1433,16 @@
 
         // even if we have only a single stream, we should
         // switch to non-interleaved to get correct timestamps
-        if(last_pos == pos)
-            avi->non_interleaved= 1;
-        if(last_idx != pos && len) {
-            av_add_index_entry(st, pos, ast->cum_len, len, 0, (flags&AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
+        if (last_pos == pos)
+            avi->non_interleaved = 1;
+        if (last_idx != pos && len) {
+            av_add_index_entry(st, pos, ast->cum_len, len, 0,
+                               (flags & AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
             last_idx= pos;
         }
         ast->cum_len += get_duration(ast, len);
-        last_pos= pos;
-        anykey |= flags&AVIIF_INDEX;
+        last_pos      = pos;
+        anykey       |= flags&AVIIF_INDEX;
     }
     if (!anykey) {
         for (index = 0; index < s->nb_streams; index++) {
@@ -1345,34 +1454,35 @@
     return 0;
 }
 
-static int guess_ni_flag(AVFormatContext *s){
+static int guess_ni_flag(AVFormatContext *s)
+{
     int i;
-    int64_t last_start=0;
-    int64_t first_end= INT64_MAX;
-    int64_t oldpos= avio_tell(s->pb);
+    int64_t last_start = 0;
+    int64_t first_end  = INT64_MAX;
+    int64_t oldpos     = avio_tell(s->pb);
     int *idx;
     int64_t min_pos, pos;
 
-    for(i=0; i<s->nb_streams; i++){
+    for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
-        int n= st->nb_index_entries;
+        int n        = st->nb_index_entries;
         unsigned int size;
 
-        if(n <= 0)
+        if (n <= 0)
             continue;
 
-        if(n >= 2){
-            int64_t pos= st->index_entries[0].pos;
+        if (n >= 2) {
+            int64_t pos = st->index_entries[0].pos;
             avio_seek(s->pb, pos + 4, SEEK_SET);
-            size= avio_rl32(s->pb);
-            if(pos + size > st->index_entries[1].pos)
-                last_start= INT64_MAX;
+            size = avio_rl32(s->pb);
+            if (pos + size > st->index_entries[1].pos)
+                last_start = INT64_MAX;
         }
 
-        if(st->index_entries[0].pos > last_start)
-            last_start= st->index_entries[0].pos;
-        if(st->index_entries[n-1].pos < first_end)
-            first_end= st->index_entries[n-1].pos;
+        if (st->index_entries[0].pos > last_start)
+            last_start = st->index_entries[0].pos;
+        if (st->index_entries[n - 1].pos < first_end)
+            first_end = st->index_entries[n - 1].pos;
     }
     avio_seek(s->pb, oldpos, SEEK_SET);
     if (last_start > first_end)
@@ -1384,17 +1494,18 @@
 
         for (i=0; i<s->nb_streams; i++) {
             AVStream *st = s->streams[i];
+            AVIStream *ast = st->priv_data;
             int n= st->nb_index_entries;
             while (idx[i]<n && st->index_entries[idx[i]].pos < pos)
                 idx[i]++;
             if (idx[i] < n) {
-                min_dts = FFMIN(min_dts, av_rescale_q(st->index_entries[idx[i]].timestamp, st->time_base, AV_TIME_BASE_Q));
+                min_dts = FFMIN(min_dts, av_rescale_q(st->index_entries[idx[i]].timestamp/FFMAX(ast->sample_size, 1), st->time_base, AV_TIME_BASE_Q));
                 min_pos = FFMIN(min_pos, st->index_entries[idx[i]].pos);
             }
             if (idx[i])
-                max_dts = FFMAX(max_dts, av_rescale_q(st->index_entries[idx[i]-1].timestamp, st->time_base, AV_TIME_BASE_Q));
+                max_dts = FFMAX(max_dts, av_rescale_q(st->index_entries[idx[i]-1].timestamp/FFMAX(ast->sample_size, 1), st->time_base, AV_TIME_BASE_Q));
         }
-        if(max_dts - min_dts > 2*AV_TIME_BASE) {
+        if (max_dts - min_dts > 2*AV_TIME_BASE) {
             av_free(idx);
             return 1;
         }
@@ -1408,15 +1519,15 @@
     AVIContext *avi = s->priv_data;
     AVIOContext *pb = s->pb;
     uint32_t tag, size;
-    int64_t pos= avio_tell(pb);
+    int64_t pos = avio_tell(pb);
     int64_t next;
-    int ret = -1;
+    int ret     = -1;
 
     if (avio_seek(pb, avi->movi_end, SEEK_SET) < 0)
         goto the_end; // maybe truncated file
     av_dlog(s, "movi_end=0x%"PRIx64"\n", avi->movi_end);
-    for(;;) {
-        tag = avio_rl32(pb);
+    for (;;) {
+        tag  = avio_rl32(pb);
         size = avio_rl32(pb);
         if (url_feof(pb))
             break;
@@ -1433,18 +1544,19 @@
             avi_read_idx1(s, size) >= 0) {
             avi->index_loaded=2;
             ret = 0;
-        }else if(tag == MKTAG('L', 'I', 'S', 'T')) {
+        }else if (tag == MKTAG('L', 'I', 'S', 'T')) {
             uint32_t tag1 = avio_rl32(pb);
 
             if (tag1 == MKTAG('I', 'N', 'F', 'O'))
                 ff_read_riff_info(s, size - 4);
-        }else if(!ret)
+        }else if (!ret)
             break;
 
         if (avio_seek(pb, next, SEEK_SET) < 0)
             break; // something is wrong here
     }
- the_end:
+
+the_end:
     avio_seek(pb, pos, SEEK_SET);
     return ret;
 }
@@ -1452,14 +1564,15 @@
 static void seek_subtitle(AVStream *st, AVStream *st2, int64_t timestamp)
 {
     AVIStream *ast2 = st2->priv_data;
-    int64_t ts2 = av_rescale_q(timestamp, st->time_base, st2->time_base);
+    int64_t ts2     = av_rescale_q(timestamp, st->time_base, st2->time_base);
     av_free_packet(&ast2->sub_pkt);
     if (avformat_seek_file(ast2->sub_ctx, 0, INT64_MIN, ts2, ts2, 0) >= 0 ||
         avformat_seek_file(ast2->sub_ctx, 0, ts2, ts2, INT64_MAX, 0) >= 0)
         ff_read_packet(ast2->sub_ctx, &ast2->sub_pkt);
 }
 
-static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
+static int avi_read_seek(AVFormatContext *s, int stream_index,
+                         int64_t timestamp, int flags)
 {
     AVIContext *avi = s->priv_data;
     AVStream *st;
@@ -1472,12 +1585,14 @@
         avi_load_index(s);
         avi->index_loaded |= 1;
     }
-    av_assert0(stream_index>= 0);
+    av_assert0(stream_index >= 0);
 
-    st = s->streams[stream_index];
-    ast= st->priv_data;
-    index= av_index_search_timestamp(st, timestamp * FFMAX(ast->sample_size, 1), flags);
-    if (index<0) {
+    st    = s->streams[stream_index];
+    ast   = st->priv_data;
+    index = av_index_search_timestamp(st,
+                                      timestamp * FFMAX(ast->sample_size, 1),
+                                      flags);
+    if (index < 0) {
         if (st->nb_index_entries > 0)
             av_log(s, AV_LOG_DEBUG, "Failed to find timestamp %"PRId64 " in index %"PRId64 " .. %"PRId64 "\n",
                    timestamp * FFMAX(ast->sample_size, 1),
@@ -1487,7 +1602,7 @@
     }
 
     /* find the position */
-    pos = st->index_entries[index].pos;
+    pos       = st->index_entries[index].pos;
     timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1);
 
     av_dlog(s, "XX %"PRId64" %d %"PRId64"\n",
@@ -1499,24 +1614,24 @@
         /* the av_index_search_timestamp call above.                     */
         av_assert0(stream_index == 0);
 
-        if(avio_seek(s->pb, pos, SEEK_SET) < 0)
+        if (avio_seek(s->pb, pos, SEEK_SET) < 0)
             return -1;
 
         /* Feed the DV video stream version of the timestamp to the */
         /* DV demux so it can synthesize correct timestamps.        */
         ff_dv_offset_reset(avi->dv_demux, timestamp);
 
-        avi->stream_index= -1;
+        avi->stream_index = -1;
         return 0;
     }
 
-    pos_min= pos;
-    for(i = 0; i < s->nb_streams; i++) {
-        AVStream *st2 = s->streams[i];
+    pos_min = pos;
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st2   = s->streams[i];
         AVIStream *ast2 = st2->priv_data;
 
-        ast2->packet_size=
-        ast2->remaining= 0;
+        ast2->packet_size =
+        ast2->remaining   = 0;
 
         if (ast2->sub_ctx) {
             seek_subtitle(st, st2, timestamp);
@@ -1527,17 +1642,22 @@
             continue;
 
 //        av_assert1(st2->codec->block_align);
-        av_assert0((int64_t)st2->time_base.num*ast2->rate == (int64_t)st2->time_base.den*ast2->scale);
-        index = av_index_search_timestamp(
-                st2,
-                av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
-                flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
-        if(index<0)
-            index=0;
-        ast2->seek_pos= st2->index_entries[index].pos;
-        pos_min= FFMIN(pos_min,ast2->seek_pos);
+        av_assert0((int64_t)st2->time_base.num * ast2->rate ==
+                   (int64_t)st2->time_base.den * ast2->scale);
+        index = av_index_search_timestamp(st2,
+                                          av_rescale_q(timestamp,
+                                                       st->time_base,
+                                                       st2->time_base) *
+                                          FFMAX(ast2->sample_size, 1),
+                                          flags |
+                                          AVSEEK_FLAG_BACKWARD |
+                                          (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
+        if (index < 0)
+            index = 0;
+        ast2->seek_pos = st2->index_entries[index].pos;
+        pos_min = FFMIN(pos_min,ast2->seek_pos);
     }
-    for(i = 0; i < s->nb_streams; i++) {
+    for (i = 0; i < s->nb_streams; i++) {
         AVStream *st2 = s->streams[i];
         AVIStream *ast2 = st2->priv_data;
 
@@ -1548,9 +1668,9 @@
                 st2,
                 av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
                 flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
-        if(index<0)
-            index=0;
-        while(!avi->non_interleaved && index>0 && st2->index_entries[index-1].pos >= pos_min)
+        if (index < 0)
+            index = 0;
+        while (!avi->non_interleaved && index>0 && st2->index_entries[index-1].pos >= pos_min)
             index--;
         ast2->frame_offset = st2->index_entries[index].timestamp;
     }
@@ -1560,8 +1680,8 @@
         av_log(s, AV_LOG_ERROR, "Seek failed\n");
         return -1;
     }
-    avi->stream_index= -1;
-    avi->dts_max= INT_MIN;
+    avi->stream_index = -1;
+    avi->dts_max      = INT_MIN;
     return 0;
 }
 
@@ -1570,8 +1690,8 @@
     int i;
     AVIContext *avi = s->priv_data;
 
-    for(i=0;i<s->nb_streams;i++) {
-        AVStream *st = s->streams[i];
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st   = s->streams[i];
         AVIStream *ast = st->priv_data;
         if (ast) {
             if (ast->sub_ctx) {
@@ -1593,9 +1713,9 @@
     int i;
 
     /* check file header */
-    for(i=0; avi_headers[i][0]; i++)
-        if(!memcmp(p->buf  , avi_headers[i]  , 4) &&
-           !memcmp(p->buf+8, avi_headers[i]+4, 4))
+    for (i = 0; avi_headers[i][0]; i++)
+        if (!memcmp(p->buf,     avi_headers[i],     4) &&
+            !memcmp(p->buf + 8, avi_headers[i] + 4, 4))
             return AVPROBE_SCORE_MAX;
 
     return 0;
diff --git a/libavformat/avienc.c b/libavformat/avienc.c
index f2fa9dc..3511c81 100644
--- a/libavformat/avienc.c
+++ b/libavformat/avienc.c
@@ -523,7 +523,7 @@
     int size= pkt->size;
 
     av_dlog(s, "dts:%s packet_count:%d stream_index:%d\n", av_ts2str(pkt->dts), avist->packet_count, stream_index);
-    while(enc->block_align==0 && pkt->dts != AV_NOPTS_VALUE && pkt->dts > avist->packet_count && enc->codec_id != AV_CODEC_ID_XSUB){
+    while(enc->block_align==0 && pkt->dts != AV_NOPTS_VALUE && pkt->dts > avist->packet_count && enc->codec_id != AV_CODEC_ID_XSUB && avist->packet_count){
         AVPacket empty_packet;
 
         if(pkt->dts - avist->packet_count > 60000){
diff --git a/libavformat/avio.c b/libavformat/avio.c
index f6af0cb..2c7a35e 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -241,6 +241,8 @@
             return url_alloc_for_protocol (puc, up, filename, flags, int_cb);
     }
     *puc = NULL;
+    if (!strcmp("https", proto_str))
+        av_log(NULL, AV_LOG_WARNING, "https protocol not found, recompile with openssl or gnutls enabled.\n");
     return AVERROR_PROTOCOL_NOT_FOUND;
 }
 
@@ -271,6 +273,8 @@
 
     len = 0;
     while (len < size_min) {
+        if (ff_check_interrupt(&h->interrupt_callback))
+            return AVERROR_EXIT;
         ret = transfer_func(h, buf+len, size-len);
         if (ret == AVERROR(EINTR))
             continue;
@@ -290,12 +294,10 @@
                 av_usleep(1000);
             }
         } else if (ret < 1)
-            return ret < 0 ? ret : len;
+            return (ret < 0 && ret != AVERROR_EOF) ? ret : len;
         if (ret)
            fast_retries = FFMAX(fast_retries, 2);
         len += ret;
-        if (len < size && ff_check_interrupt(&h->interrupt_callback))
-            return AVERROR_EXIT;
     }
     return len;
 }
diff --git a/libavformat/avio_internal.h b/libavformat/avio_internal.h
index cf36764..e67ba73 100644
--- a/libavformat/avio_internal.h
+++ b/libavformat/avio_internal.h
@@ -38,6 +38,23 @@
 
 
 /**
+ * Read size bytes from AVIOContext, returning a pointer.
+ * Note that the data pointed at by the returned pointer is only
+ * valid until the next call that references the same IO context.
+ * @param s IO context
+ * @param buf pointer to buffer into which to assemble the requested
+ *    data if it is not available in contiguous addresses in the
+ *    underlying buffer
+ * @param size number of bytes requested
+ * @param data address at which to store pointer: this will be a
+ *    a direct pointer into the underlying buffer if the requested
+ *    number of bytes are available at contiguous addresses, otherwise
+ *    will be a copy of buf
+ * @return number of bytes read or AVERROR
+ */
+int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data);
+
+/**
  * Read size bytes from AVIOContext into buf.
  * This reads at most 1 packet. If that is not enough fewer bytes will be
  * returned.
@@ -71,6 +88,15 @@
 /** @warning must be called before any I/O */
 int ffio_set_buf_size(AVIOContext *s, int buf_size);
 
+/**
+ * Ensures that the requested seekback buffer size will be available
+ *
+ * Will ensure that when reading sequentially up to buf_size, seeking
+ * within the current pos and pos+buf_size is possible.
+ * Once the stream position moves outside this window this gurantee is lost.
+ */
+int ffio_ensure_seekback(AVIOContext *s, int buf_size);
+
 int ffio_limit(AVIOContext *s, int size);
 
 void ffio_init_checksum(AVIOContext *s,
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index 966e0e6..3707fda 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -92,7 +92,7 @@
     s->must_flush      = 0;
     s->eof_reached     = 0;
     s->error           = 0;
-    s->seekable        = AVIO_SEEKABLE_NORMAL;
+    s->seekable        = seek ? AVIO_SEEKABLE_NORMAL : 0;
     s->max_packet_size = 0;
     s->update_checksum = NULL;
 
@@ -392,12 +392,11 @@
 
 static void fill_buffer(AVIOContext *s)
 {
-    uint8_t *dst        = !s->max_packet_size &&
-                          s->buf_end - s->buffer < s->buffer_size ?
-                          s->buf_end : s->buffer;
-    int len             = s->buffer_size - (dst - s->buffer);
     int max_buffer_size = s->max_packet_size ?
                           s->max_packet_size : IO_BUFFER_SIZE;
+    uint8_t *dst        = s->buf_end - s->buffer + max_buffer_size < s->buffer_size ?
+                          s->buf_end : s->buffer;
+    int len             = s->buffer_size - (dst - s->buffer);
 
     /* can't fill the buffer without read_packet, just set EOF if appropriate */
     if (!s->read_packet && s->buf_ptr >= s->buf_end)
@@ -416,10 +415,13 @@
 
     /* make buffer smaller in case it ended up large after probing */
     if (s->read_packet && s->buffer_size > max_buffer_size) {
-        ffio_set_buf_size(s, max_buffer_size);
+        if (dst == s->buffer) {
+            ffio_set_buf_size(s, max_buffer_size);
 
-        s->checksum_ptr = dst = s->buffer;
-        len = s->buffer_size;
+            s->checksum_ptr = dst = s->buffer;
+        }
+        av_assert0(len >= max_buffer_size);
+        len = max_buffer_size;
     }
 
     if (s->read_packet)
@@ -523,6 +525,18 @@
     return size1 - size;
 }
 
+int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data)
+{
+    if (s->buf_end - s->buf_ptr >= size && !s->write_flag) {
+        *data = s->buf_ptr;
+        s->buf_ptr += size;
+        return size;
+    } else {
+        *data = buf;
+        return avio_read(s, buf, size);
+    }
+}
+
 int ffio_read_partial(AVIOContext *s, unsigned char *buf, int size)
 {
     int len;
@@ -723,6 +737,31 @@
     return 0;
 }
 
+int ffio_ensure_seekback(AVIOContext *s, int buf_size)
+{
+    uint8_t *buffer;
+    int max_buffer_size = s->max_packet_size ?
+                          s->max_packet_size : IO_BUFFER_SIZE;
+
+    buf_size += s->buf_ptr - s->buffer + max_buffer_size;
+
+    if (buf_size < s->buffer_size || s->seekable)
+        return 0;
+    av_assert0(!s->write_flag);
+
+    buffer = av_malloc(buf_size);
+    if (!buffer)
+        return AVERROR(ENOMEM);
+
+    memcpy(buffer, s->buffer, s->buffer_size);
+    av_free(s->buffer);
+    s->buf_ptr = buffer + (s->buf_ptr - s->buffer);
+    s->buf_end = buffer + (s->buf_end - s->buffer);
+    s->buffer = buffer;
+    s->buffer_size = buf_size;
+    return 0;
+}
+
 int ffio_set_buf_size(AVIOContext *s, int buf_size)
 {
     uint8_t *buffer;
diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c
index a5a4fcc..afacf04 100644
--- a/libavformat/avisynth.c
+++ b/libavformat/avisynth.c
@@ -36,6 +36,7 @@
   #include <windows.h>
   #undef EXTERN_C
   #include "compat/avisynth/avisynth_c.h"
+  #include "compat/avisynth/avisynth_c_25.h"
   #define AVISYNTH_LIB "avisynth"
 #else
   #include <dlfcn.h>
@@ -62,19 +63,20 @@
 typedef struct {
     void *library;
 #define AVSC_DECLARE_FUNC(name) name##_func name
+    AVSC_DECLARE_FUNC(avs_bit_blt);
+    AVSC_DECLARE_FUNC(avs_clip_get_error);
     AVSC_DECLARE_FUNC(avs_create_script_environment);
     AVSC_DECLARE_FUNC(avs_delete_script_environment);
-    AVSC_DECLARE_FUNC(avs_get_error);
-    AVSC_DECLARE_FUNC(avs_clip_get_error);
-    AVSC_DECLARE_FUNC(avs_invoke);
-    AVSC_DECLARE_FUNC(avs_release_value);
-    AVSC_DECLARE_FUNC(avs_get_video_info);
-    AVSC_DECLARE_FUNC(avs_take_clip);
-    AVSC_DECLARE_FUNC(avs_release_clip);
-    AVSC_DECLARE_FUNC(avs_bit_blt);
     AVSC_DECLARE_FUNC(avs_get_audio);
+    AVSC_DECLARE_FUNC(avs_get_error);
     AVSC_DECLARE_FUNC(avs_get_frame);
+    AVSC_DECLARE_FUNC(avs_get_version);
+    AVSC_DECLARE_FUNC(avs_get_video_info);
+    AVSC_DECLARE_FUNC(avs_invoke);
+    AVSC_DECLARE_FUNC(avs_release_clip);
+    AVSC_DECLARE_FUNC(avs_release_value);
     AVSC_DECLARE_FUNC(avs_release_video_frame);
+    AVSC_DECLARE_FUNC(avs_take_clip);
 #undef AVSC_DECLARE_FUNC
 } AviSynthLibrary;
 
@@ -127,19 +129,20 @@
     if(!continue_on_fail && !avs_library->name) \
         goto fail; \
 }
+    LOAD_AVS_FUNC(avs_bit_blt, 0);
+    LOAD_AVS_FUNC(avs_clip_get_error, 0);
     LOAD_AVS_FUNC(avs_create_script_environment, 0);
     LOAD_AVS_FUNC(avs_delete_script_environment, 0);
-    LOAD_AVS_FUNC(avs_get_error, 1); // New to AviSynth 2.6
-    LOAD_AVS_FUNC(avs_clip_get_error, 0);
-    LOAD_AVS_FUNC(avs_invoke, 0);
-    LOAD_AVS_FUNC(avs_release_value, 0);
-    LOAD_AVS_FUNC(avs_get_video_info, 0);
-    LOAD_AVS_FUNC(avs_take_clip, 0);
-    LOAD_AVS_FUNC(avs_release_clip, 0);
-    LOAD_AVS_FUNC(avs_bit_blt, 0);
     LOAD_AVS_FUNC(avs_get_audio, 0);
+    LOAD_AVS_FUNC(avs_get_error, 1); // New to AviSynth 2.6
     LOAD_AVS_FUNC(avs_get_frame, 0);
+    LOAD_AVS_FUNC(avs_get_version, 0);
+    LOAD_AVS_FUNC(avs_get_video_info, 0);
+    LOAD_AVS_FUNC(avs_invoke, 0);
+    LOAD_AVS_FUNC(avs_release_clip, 0);
+    LOAD_AVS_FUNC(avs_release_value, 0);
     LOAD_AVS_FUNC(avs_release_video_frame, 0);
+    LOAD_AVS_FUNC(avs_take_clip, 0);
 #undef LOAD_AVS_FUNC
 
     atexit(avisynth_atexit_handler);
@@ -239,37 +242,37 @@
     switch (avs->vi->pixel_type) {
 #ifdef _WIN32
     case AVS_CS_YV24:
-        st->codec->pix_fmt = PIX_FMT_YUV444P;
+        st->codec->pix_fmt = AV_PIX_FMT_YUV444P;
         planar = 1;
         break;
     case AVS_CS_YV16:
-        st->codec->pix_fmt = PIX_FMT_YUV422P;
+        st->codec->pix_fmt = AV_PIX_FMT_YUV422P;
         planar = 1;
         break;
     case AVS_CS_YV411:
-        st->codec->pix_fmt = PIX_FMT_YUV411P;
+        st->codec->pix_fmt = AV_PIX_FMT_YUV411P;
         planar = 1;
         break;
     case AVS_CS_Y8:
-        st->codec->pix_fmt = PIX_FMT_GRAY8;
+        st->codec->pix_fmt = AV_PIX_FMT_GRAY8;
         planar = 2;
         break;
 #endif
     case AVS_CS_BGR24:
-        st->codec->pix_fmt = PIX_FMT_BGR24;
+        st->codec->pix_fmt = AV_PIX_FMT_BGR24;
         break;
     case AVS_CS_BGR32:
-        st->codec->pix_fmt = PIX_FMT_RGB32;
+        st->codec->pix_fmt = AV_PIX_FMT_RGB32;
         break;
     case AVS_CS_YUY2:
-        st->codec->pix_fmt = PIX_FMT_YUYV422;
+        st->codec->pix_fmt = AV_PIX_FMT_YUYV422;
         break;
     case AVS_CS_YV12:
-        st->codec->pix_fmt = PIX_FMT_YUV420P;
+        st->codec->pix_fmt = AV_PIX_FMT_YUV420P;
         planar = 1;
         break;
     case AVS_CS_I420: // Is this even used anywhere?
-        st->codec->pix_fmt = PIX_FMT_YUV420P;
+        st->codec->pix_fmt = AV_PIX_FMT_YUV420P;
         planar = 1;
         break;
     default:
@@ -355,11 +358,22 @@
     AviSynthContext *avs = (AviSynthContext *)s->priv_data;
     AVS_Value arg, val;
     int ret;
+#ifdef _WIN32
+    char filename_ansi[MAX_PATH * 4];
+    wchar_t filename_wc[MAX_PATH * 4];
+#endif
 
     if (ret = avisynth_context_create(s))
         return ret;
 
+#ifdef _WIN32
+    // Convert UTF-8 to ANSI code page
+    MultiByteToWideChar(CP_UTF8, 0, s->filename, -1, filename_wc, MAX_PATH * 4);
+    WideCharToMultiByte(CP_THREAD_ACP, 0, filename_wc, -1, filename_ansi, MAX_PATH * 4, NULL, NULL);
+    arg = avs_new_value_string(filename_ansi);
+#else
     arg = avs_new_value_string(s->filename);
+#endif
     val = avs_library->avs_invoke(avs->env, "Import", arg, 0);
     if (avs_is_error(val)) {
         av_log(s, AV_LOG_ERROR, "%s\n", avs_as_error(val));
@@ -458,9 +472,20 @@
     for (i = 0; i < avs->n_planes; i++) {
         plane = avs->planes[i];
         src_p = avs_get_read_ptr_p(frame, plane);
+        pitch = avs_get_pitch_p(frame, plane);
+
+#ifdef _WIN32
+        if (avs_library->avs_get_version(avs->clip) == 3) {
+            rowsize = avs_get_row_size_p_25(frame, plane);
+            planeheight = avs_get_height_p_25(frame, plane);
+        } else {
+            rowsize = avs_get_row_size_p(frame, plane);
+            planeheight = avs_get_height_p(frame, plane);
+        }
+#else
         rowsize = avs_get_row_size_p(frame, plane);
         planeheight = avs_get_height_p(frame, plane);
-        pitch = avs_get_pitch_p(frame, plane);
+#endif
 
         // Flip RGB video.
         if (avs_is_rgb24(avs->vi) || avs_is_rgb(avs->vi)) {
diff --git a/libavformat/avr.c b/libavformat/avr.c
index 473136e..e03f1a4 100644
--- a/libavformat/avr.c
+++ b/libavformat/avr.c
@@ -27,7 +27,7 @@
 static int avr_probe(AVProbeData *p)
 {
     if (AV_RL32(p->buf) == MKTAG('2', 'B', 'I', 'T'))
-        return AVPROBE_SCORE_MAX / 2;
+        return AVPROBE_SCORE_EXTENSION;
     return 0;
 }
 
diff --git a/libavformat/avs.c b/libavformat/avs.c
index ec9198b..7814301 100644
--- a/libavformat/avs.c
+++ b/libavformat/avs.c
@@ -50,7 +50,9 @@
 
     d = p->buf;
     if (d[0] == 'w' && d[1] == 'W' && d[2] == 0x10 && d[3] == 0)
-        return 55;
+        /* Ensure the buffer probe scores higher than the extension probe.
+         * This avoids problems with misdetection as AviSynth scripts. */
+        return AVPROBE_SCORE_EXTENSION + 5;
 
     return 0;
 }
diff --git a/libavformat/bfi.c b/libavformat/bfi.c
index a28e09a..7a4f436 100644
--- a/libavformat/bfi.c
+++ b/libavformat/bfi.c
@@ -81,6 +81,8 @@
     /*Load the palette to extradata */
     avio_skip(pb, 8);
     vstream->codec->extradata      = av_malloc(768);
+    if (!vstream->codec->extradata)
+        return AVERROR(ENOMEM);
     vstream->codec->extradata_size = 768;
     avio_read(pb, vstream->codec->extradata,
                vstream->codec->extradata_size);
diff --git a/libavformat/bit.c b/libavformat/bit.c
index 9b2246c..0be471a 100644
--- a/libavformat/bit.c
+++ b/libavformat/bit.c
@@ -44,7 +44,7 @@
             return 0;
         i+=j;
     }
-    return AVPROBE_SCORE_MAX/2;
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 static int read_header(AVFormatContext *s)
diff --git a/libavformat/boadec.c b/libavformat/boadec.c
new file mode 100644
index 0000000..45f6b39
--- /dev/null
+++ b/libavformat/boadec.c
@@ -0,0 +1,78 @@
+/*
+ * Black ops audio demuxer
+ * Copyright (c) 2013 Michael Niedermayer
+ *
+ * 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
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+
+static int probe(AVProbeData *p)
+{
+    if (p->buf_size < 2096)
+        return 0;
+    if (   AV_RL32(p->buf     ) != 1
+        || AV_RL32(p->buf +  8) > 100000
+        || AV_RL32(p->buf + 12) > 8
+        || AV_RL32(p->buf + 16) != 2096
+        ||!AV_RL32(p->buf + 21)
+        || AV_RL16(p->buf + 25) != 2096
+        || AV_RL32(p->buf + 48) % AV_RL32(p->buf + 21)
+        )
+        return 0;
+    return AVPROBE_SCORE_EXTENSION;
+}
+
+
+static int read_header(AVFormatContext *s)
+{
+    AVStream *st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_id = AV_CODEC_ID_ADPCM_MS;
+
+    avio_rl32(s->pb);
+    avio_rl32(s->pb);
+    st->codec->sample_rate = avio_rl32(s->pb);
+    st->codec->channels    = avio_rl32(s->pb);
+    s->data_offset         = avio_rl32(s->pb);
+    avio_r8(s->pb);
+    st->codec->block_align = st->codec->channels * avio_rl32(s->pb);
+
+    avio_seek(s->pb, s->data_offset, SEEK_SET);
+
+    return 0;
+}
+
+static int read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    AVStream *st = s->streams[0];
+
+    return av_get_packet(s->pb, pkt, st->codec->block_align);
+}
+
+AVInputFormat ff_boa_demuxer = {
+    .name           = "boa",
+    .long_name      = NULL_IF_CONFIG_SMALL("Black Ops Audio"),
+    .read_probe     = probe,
+    .read_header    = read_header,
+    .read_packet    = read_packet,
+    .flags          = AVFMT_GENERIC_INDEX,
+};
diff --git a/libavformat/cafenc.c b/libavformat/cafenc.c
index 11bb055..cd3a0be 100644
--- a/libavformat/cafenc.c
+++ b/libavformat/cafenc.c
@@ -86,8 +86,9 @@
         return 1152;
     case AV_CODEC_ID_AC3:
         return 1536;
-    case AV_CODEC_ID_ALAC:
     case AV_CODEC_ID_QDM2:
+        return 2048 * channels;
+    case AV_CODEC_ID_ALAC:
         return 4096;
     case AV_CODEC_ID_ADPCM_IMA_WAV:
         return (1024 - 4 * channels) * 8 / (4 * channels) + 1;
diff --git a/libavformat/cavsvideodec.c b/libavformat/cavsvideodec.c
index c035128..5ca3c80 100644
--- a/libavformat/cavsvideodec.c
+++ b/libavformat/cavsvideodec.c
@@ -61,7 +61,7 @@
         }
     }
     if(seq && seq*9<=pic*10)
-        return AVPROBE_SCORE_MAX/2;
+        return AVPROBE_SCORE_EXTENSION;
     return 0;
 }
 
diff --git a/libavformat/cdxl.c b/libavformat/cdxl.c
index 185b745..ab8a846 100644
--- a/libavformat/cdxl.c
+++ b/libavformat/cdxl.c
@@ -41,7 +41,7 @@
 
 static int cdxl_read_probe(AVProbeData *p)
 {
-    int score = AVPROBE_SCORE_MAX / 2 + 10;
+    int score = AVPROBE_SCORE_EXTENSION + 10;
 
     if (p->buf_size < CDXL_HEADER_SIZE)
         return 0;
diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c
index 5359ad1..428c749 100644
--- a/libavformat/concatdec.c
+++ b/libavformat/concatdec.c
@@ -23,6 +23,7 @@
 #include "libavutil/parseutils.h"
 #include "avformat.h"
 #include "internal.h"
+#include "url.h"
 
 typedef struct {
     char *url;
@@ -216,6 +217,8 @@
     }
     if (ret < 0)
         FAIL(ret);
+    if (!cat->nb_files)
+        FAIL(AVERROR_INVALIDDATA);
 
     for (i = 0; i < cat->nb_files; i++) {
         if (cat->files[i].start_time == AV_NOPTS_VALUE)
@@ -341,7 +344,7 @@
         return ret;
 
     ret = try_seek(avf, stream, min_ts, ts, max_ts, flags);
-    if (ret < 0 && !(flags & AVSEEK_FLAG_BACKWARD) &&
+    if (ret < 0 &&
         left < cat->nb_files - 1 &&
         cat->files[left + 1].start_time < max_ts) {
         if ((ret = open_file(avf, left + 1)) < 0)
diff --git a/libavformat/dtsdec.c b/libavformat/dtsdec.c
index 5c05758..23cbe93 100644
--- a/libavformat/dtsdec.c
+++ b/libavformat/dtsdec.c
@@ -34,6 +34,7 @@
     uint32_t state = -1;
     int markers[3] = {0};
     int sum, max;
+    int64_t diff = 0;
 
     buf = p->buf;
 
@@ -54,13 +55,17 @@
         if (state == DCA_MARKER_14B_LE)
             if ((bytestream_get_be16(&bufp) & 0xF0FF) == 0xF007)
                 markers[2]++;
+
+        if (buf - p->buf >= 4)
+            diff += FFABS(AV_RL16(buf) - AV_RL16(buf-4));
     }
     sum = markers[0] + markers[1] + markers[2];
     max = markers[1] > markers[0];
     max = markers[2] > markers[max] ? 2 : max;
     if (markers[max] > 3 && p->buf_size / markers[max] < 32*1024 &&
-        markers[max] * 4 > sum * 3)
-        return AVPROBE_SCORE_MAX/2+1;
+        markers[max] * 4 > sum * 3 &&
+        diff / p->buf_size > 200)
+        return AVPROBE_SCORE_EXTENSION + 1;
 
     return 0;
 }
diff --git a/libavformat/dv.c b/libavformat/dv.c
index a04735a..cc48f48 100644
--- a/libavformat/dv.c
+++ b/libavformat/dv.c
@@ -65,7 +65,7 @@
         shift--;
         result = (sample - (256 * shift)) << shift;
     } else {
-        shift = 0xe - shift;
+        shift  = 0xe - shift;
         result = ((sample + ((256 * shift) + 1)) << shift) - 1;
     }
 
@@ -77,19 +77,19 @@
  * a fixed offset and if pack isn't there -- fails. We might want
  * to have a fallback mechanism for complete search of missing packs.
  */
-static const uint8_t* dv_extract_pack(uint8_t* frame, enum dv_pack_type t)
+static const uint8_t *dv_extract_pack(uint8_t *frame, enum dv_pack_type t)
 {
     int offs;
 
     switch (t) {
     case dv_audio_source:
-        offs = (80*6 + 80*16*3 + 3);
+        offs = (80 * 6 + 80 * 16 * 3 + 3);
         break;
     case dv_audio_control:
-        offs = (80*6 + 80*16*4 + 3);
+        offs = (80 * 6 + 80 * 16 * 4 + 3);
         break;
     case dv_video_control:
-        offs = (80*5 + 48 + 5);
+        offs = (80 * 5 + 48 + 5);
         break;
     case dv_timecode:
         offs = (80*1 + 3 + 3);
@@ -113,29 +113,29 @@
  * 3. Audio is always returned as 16bit linear samples: 12bit nonlinear samples
  *    are converted into 16bit linear ones.
  */
-static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4],
+static int dv_extract_audio(uint8_t *frame, uint8_t *ppcm[4],
                             const DVprofile *sys)
 {
     int size, chan, i, j, d, of, smpls, freq, quant, half_ch;
     uint16_t lc, rc;
-    const uint8_t* as_pack;
+    const uint8_t *as_pack;
     uint8_t *pcm, ipcm;
 
     as_pack = dv_extract_pack(frame, dv_audio_source);
     if (!as_pack)    /* No audio ? */
         return 0;
 
-    smpls =  as_pack[1] & 0x3f;       /* samples in this frame - min. samples */
-    freq  = (as_pack[4] >> 3) & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */
-    quant =  as_pack[4] & 0x07;       /* 0 - 16bit linear, 1 - 12bit nonlinear */
+    smpls = as_pack[1]      & 0x3f; /* samples in this frame - min. samples */
+    freq  = as_pack[4] >> 3 & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */
+    quant = as_pack[4]      & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */
 
     if (quant > 1)
-        return -1; /* unsupported quantization */
+        return -1;  /* unsupported quantization */
 
     if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency))
         return AVERROR_INVALIDDATA;
 
-    size = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */
+    size    = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */
     half_ch = sys->difseg_size / 2;
 
     /* We work with 720p frames split in half, thus even frames have
@@ -169,32 +169,41 @@
             for (j = 0; j < 9; j++) {
                 for (d = 8; d < 80; d += 2) {
                     if (quant == 0) {  /* 16bit quantization */
-                        of = sys->audio_shuffle[i][j] + (d - 8) / 2 * sys->audio_stride;
-                        if (of*2 >= size)
+                        of = sys->audio_shuffle[i][j] +
+                             (d - 8) / 2 * sys->audio_stride;
+                        if (of * 2 >= size)
                             continue;
 
-                        pcm[of*2]   = frame[d+1]; // FIXME: maybe we have to admit
-                        pcm[of*2+1] = frame[d];   //        that DV is a big-endian PCM
-                        if (pcm[of*2+1] == 0x80 && pcm[of*2] == 0x00)
-                            pcm[of*2+1] = 0;
+                        /* FIXME: maybe we have to admit that DV is a
+                         * big-endian PCM */
+                        pcm[of * 2]     = frame[d + 1];
+                        pcm[of * 2 + 1] = frame[d];
+
+                        if (pcm[of * 2 + 1] == 0x80 && pcm[of * 2] == 0x00)
+                            pcm[of * 2 + 1] = 0;
                     } else {           /* 12bit quantization */
-                        lc = ((uint16_t)frame[d]   << 4) |
-                             ((uint16_t)frame[d+2] >> 4);
-                        rc = ((uint16_t)frame[d+1] << 4) |
-                             ((uint16_t)frame[d+2] & 0x0f);
+                        lc = ((uint16_t)frame[d]     << 4) |
+                             ((uint16_t)frame[d + 2] >> 4);
+                        rc = ((uint16_t)frame[d + 1] << 4) |
+                             ((uint16_t)frame[d + 2] & 0x0f);
                         lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc));
                         rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc));
 
-                        of = sys->audio_shuffle[i%half_ch][j] + (d - 8) / 3 * sys->audio_stride;
-                        if (of*2 >= size)
+                        of = sys->audio_shuffle[i % half_ch][j] +
+                             (d - 8) / 3 * sys->audio_stride;
+                        if (of * 2 >= size)
                             continue;
 
-                        pcm[of*2]   = lc & 0xff; // FIXME: maybe we have to admit
-                        pcm[of*2+1] = lc >> 8;   //        that DV is a big-endian PCM
-                        of = sys->audio_shuffle[i%half_ch+half_ch][j] +
-                            (d - 8) / 3 * sys->audio_stride;
-                        pcm[of*2]   = rc & 0xff; // FIXME: maybe we have to admit
-                        pcm[of*2+1] = rc >> 8;   //        that DV is a big-endian PCM
+                        /* FIXME: maybe we have to admit that DV is a
+                         * big-endian PCM */
+                        pcm[of * 2]     = lc & 0xff;
+                        pcm[of * 2 + 1] = lc >> 8;
+                        of = sys->audio_shuffle[i % half_ch + half_ch][j] +
+                             (d - 8) / 3 * sys->audio_stride;
+                        /* FIXME: maybe we have to admit that DV is a
+                         * big-endian PCM */
+                        pcm[of * 2]     = rc & 0xff;
+                        pcm[of * 2 + 1] = rc >> 8;
                         ++d;
                     }
                 }
@@ -207,9 +216,9 @@
     return size;
 }
 
-static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame)
+static int dv_extract_audio_info(DVDemuxContext *c, uint8_t *frame)
 {
-    const uint8_t* as_pack;
+    const uint8_t *as_pack;
     int freq, stype, smpls, quant, i, ach;
 
     as_pack = dv_extract_pack(frame, dv_audio_source);
@@ -218,10 +227,10 @@
         return 0;
     }
 
-    smpls =  as_pack[1] & 0x3f;       /* samples in this frame - min. samples */
-    freq  = (as_pack[4] >> 3) & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */
-    stype = (as_pack[3] & 0x1f);      /* 0 - 2CH, 2 - 4CH, 3 - 8CH */
-    quant =  as_pack[4] & 0x07;       /* 0 - 16bit linear, 1 - 12bit nonlinear */
+    smpls = as_pack[1]      & 0x3f; /* samples in this frame - min. samples */
+    freq  = as_pack[4] >> 3 & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */
+    stype = as_pack[3]      & 0x1f; /* 0 - 2CH, 2 - 4CH, 3 - 8CH */
+    quant = as_pack[4]      & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */
 
     if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency)) {
         av_log(c->fctx, AV_LOG_ERROR,
@@ -236,7 +245,7 @@
     }
 
     /* note: ach counts PAIRS of channels (i.e. stereo channels) */
-    ach = ((int[4]){  1,  0,  2,  4})[stype];
+    ach = ((int[4]) { 1, 0, 2, 4 })[stype];
     if (ach == 1 && quant && freq == 2)
         ach = 2;
 
@@ -256,21 +265,21 @@
             c->audio_pkt[i].stream_index = c->ast[i]->index;
             c->audio_pkt[i].flags       |= AV_PKT_FLAG_KEY;
         }
-        c->ast[i]->codec->sample_rate = dv_audio_frequency[freq];
-        c->ast[i]->codec->channels    = 2;
+        c->ast[i]->codec->sample_rate    = dv_audio_frequency[freq];
+        c->ast[i]->codec->channels       = 2;
         c->ast[i]->codec->channel_layout = AV_CH_LAYOUT_STEREO;
-        c->ast[i]->codec->bit_rate    = 2 * dv_audio_frequency[freq] * 16;
-        c->ast[i]->start_time         = 0;
+        c->ast[i]->codec->bit_rate       = 2 * dv_audio_frequency[freq] * 16;
+        c->ast[i]->start_time            = 0;
     }
     c->ach = i;
 
-    return (c->sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */;
+    return (c->sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */
 }
 
-static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame)
+static int dv_extract_video_info(DVDemuxContext *c, uint8_t *frame)
 {
-    const uint8_t* vsc_pack;
-    AVCodecContext* avctx;
+    const uint8_t *vsc_pack;
+    AVCodecContext *avctx;
     int apt, is16_9;
     int size = 0;
 
@@ -279,7 +288,7 @@
 
         avpriv_set_pts_info(c->vst, 64, c->sys->time_base.num,
                             c->sys->time_base.den);
-        avctx->time_base= c->sys->time_base;
+        avctx->time_base = c->sys->time_base;
 
         /* finding out SAR is a little bit messy */
         vsc_pack = dv_extract_pack(frame, dv_video_control);
@@ -287,7 +296,8 @@
         is16_9   = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 ||
                                  (!apt && (vsc_pack[2] & 0x07) == 0x07)));
         c->vst->sample_aspect_ratio = c->sys->sar[is16_9];
-        avctx->bit_rate = av_rescale_q(c->sys->frame_size, (AVRational){8,1},
+        avctx->bit_rate = av_rescale_q(c->sys->frame_size,
+                                       (AVRational) { 8, 1 },
                                        c->sys->time_base);
         size = c->sys->frame_size;
     }
@@ -310,11 +320,9 @@
     return 1;
 }
 
-/*
- * The following 3 functions constitute our interface to the world
- */
+/* The following 3 functions constitute our interface to the world */
 
-DVDemuxContext* avpriv_dv_init_demux(AVFormatContext *s)
+DVDemuxContext *avpriv_dv_init_demux(AVFormatContext *s)
 {
     DVDemuxContext *c;
 
@@ -344,9 +352,9 @@
 
     for (i = 0; i < c->ach; i++) {
         if (c->ast[i] && c->audio_pkt[i].size) {
-            *pkt = c->audio_pkt[i];
+            *pkt                 = c->audio_pkt[i];
             c->audio_pkt[i].size = 0;
-            size = pkt->size;
+            size                 = pkt->size;
             break;
         }
     }
@@ -355,10 +363,10 @@
 }
 
 int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
-                      uint8_t* buf, int buf_size, int64_t pos)
+                             uint8_t *buf, int buf_size, int64_t pos)
 {
     int size, i;
-    uint8_t *ppcm[4] = {0};
+    uint8_t *ppcm[4] = { 0 };
 
     if (buf_size < DV_PROFILE_BYTES ||
         !(c->sys = avpriv_dv_frame_profile(c->sys, buf, buf_size)) ||
@@ -372,7 +380,8 @@
     for (i = 0; i < c->ach; i++) {
         c->audio_pkt[i].pos  = pos;
         c->audio_pkt[i].size = size;
-        c->audio_pkt[i].pts  = c->abytes * 30000 * 8 / c->ast[i]->codec->bit_rate;
+        c->audio_pkt[i].pts  = c->abytes * 30000 * 8 /
+                               c->ast[i]->codec->bit_rate;
         ppcm[i] = c->audio_buf[i];
     }
     if (c->ach)
@@ -385,7 +394,7 @@
             c->audio_pkt[2].size = c->audio_pkt[3].size = 0;
         } else {
             c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
-            c->abytes += size;
+            c->abytes           += size;
         }
     } else {
         c->abytes += size;
@@ -407,30 +416,32 @@
 }
 
 static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c,
-                              int64_t timestamp, int flags)
+                               int64_t timestamp, int flags)
 {
     // FIXME: sys may be wrong if last dv_read_packet() failed (buffer is junk)
-    const DVprofile* sys = avpriv_dv_codec_profile(c->vst->codec);
+    const DVprofile *sys = avpriv_dv_codec_profile(c->vst->codec);
     int64_t offset;
-    int64_t size = avio_size(s->pb) - s->data_offset;
-    int64_t max_offset = ((size-1) / sys->frame_size) * sys->frame_size;
+    int64_t size       = avio_size(s->pb) - s->data_offset;
+    int64_t max_offset = ((size - 1) / sys->frame_size) * sys->frame_size;
 
     offset = sys->frame_size * timestamp;
 
-    if (size >= 0 && offset > max_offset) offset = max_offset;
-    else if (offset < 0) offset = 0;
+    if (size >= 0 && offset > max_offset)
+        offset = max_offset;
+    else if (offset < 0)
+        offset = 0;
 
     return offset + s->data_offset;
 }
 
 void ff_dv_offset_reset(DVDemuxContext *c, int64_t frame_offset)
 {
-    c->frames= frame_offset;
+    c->frames = frame_offset;
     if (c->ach) {
         if (c->sys) {
-        c->abytes= av_rescale_q(c->frames, c->sys->time_base,
-                                (AVRational){8, c->ast[0]->codec->bit_rate});
-        }else
+        c->abytes = av_rescale_q(c->frames, c->sys->time_base,
+                                 (AVRational) { 8, c->ast[0]->codec->bit_rate });
+        } else
             av_log(c->fctx, AV_LOG_ERROR, "cannot adjust audio bytes\n");
     }
     c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
@@ -442,7 +453,7 @@
  ************************************************************/
 
 typedef struct RawDVContext {
-    DVDemuxContext* dv_demux;
+    DVDemuxContext *dv_demux;
     uint8_t         buf[DV_MAX_FRAME_SIZE];
 } RawDVContext;
 
@@ -508,13 +519,17 @@
         avio_seek(s->pb, -DV_PROFILE_BYTES, SEEK_CUR) < 0)
         return AVERROR(EIO);
 
-    c->dv_demux->sys = avpriv_dv_frame_profile(c->dv_demux->sys, c->buf, DV_PROFILE_BYTES);
+    c->dv_demux->sys = avpriv_dv_frame_profile(c->dv_demux->sys,
+                                               c->buf,
+                                               DV_PROFILE_BYTES);
     if (!c->dv_demux->sys) {
-        av_log(s, AV_LOG_ERROR, "Can't determine profile of DV input stream.\n");
+        av_log(s, AV_LOG_ERROR,
+               "Can't determine profile of DV input stream.\n");
         return -1;
     }
 
-    s->bit_rate = av_rescale_q(c->dv_demux->sys->frame_size, (AVRational){8,1},
+    s->bit_rate = av_rescale_q(c->dv_demux->sys->frame_size,
+                               (AVRational) { 8, 1 },
                                c->dv_demux->sys->time_base);
 
     if (s->pb->seekable)
@@ -523,7 +538,6 @@
     return 0;
 }
 
-
 static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     int size;
@@ -546,7 +560,7 @@
 }
 
 static int dv_read_seek(AVFormatContext *s, int stream_index,
-                       int64_t timestamp, int flags)
+                        int64_t timestamp, int flags)
 {
     RawDVContext *r   = s->priv_data;
     DVDemuxContext *c = r->dv_demux;
@@ -570,7 +584,7 @@
 {
     unsigned state, marker_pos = 0;
     int i;
-    int matches = 0;
+    int matches           = 0;
     int secondary_matches = 0;
 
     if (p->buf_size < 5)
@@ -591,10 +605,13 @@
         state = (state << 8) | p->buf[i];
     }
 
-    if (matches && p->buf_size / matches < 1024*1024) {
-        if (matches > 4 || (secondary_matches >= 10 && p->buf_size / secondary_matches < 24000))
-            return AVPROBE_SCORE_MAX*3/4; // not max to avoid dv in mov to match
-        return AVPROBE_SCORE_MAX/4;
+    if (matches && p->buf_size / matches < 1024 * 1024) {
+        if (matches > 4 ||
+            (secondary_matches >= 10 &&
+             p->buf_size / secondary_matches < 24000))
+            // not max to avoid dv in mov to match
+            return AVPROBE_SCORE_MAX * 3 / 4;
+        return AVPROBE_SCORE_MAX / 4;
     }
     return 0;
 }
diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c
index dae40b1..69e4cbf 100644
--- a/libavformat/electronicarts.c
+++ b/libavformat/electronicarts.c
@@ -30,35 +30,35 @@
 #include "internal.h"
 
 #define SCHl_TAG MKTAG('S', 'C', 'H', 'l')
-#define SEAD_TAG MKTAG('S', 'E', 'A', 'D')    /* Sxxx header */
-#define SNDC_TAG MKTAG('S', 'N', 'D', 'C')    /* Sxxx data */
-#define SEND_TAG MKTAG('S', 'E', 'N', 'D')    /* Sxxx end */
-#define SHEN_TAG MKTAG('S', 'H', 'E', 'N')    /* SxEN header */
-#define SDEN_TAG MKTAG('S', 'D', 'E', 'N')    /* SxEN data */
-#define SEEN_TAG MKTAG('S', 'E', 'E', 'N')    /* SxEN end */
-#define ISNh_TAG MKTAG('1', 'S', 'N', 'h')    /* 1SNx header */
+#define SEAD_TAG MKTAG('S', 'E', 'A', 'D')  /* Sxxx header */
+#define SNDC_TAG MKTAG('S', 'N', 'D', 'C')  /* Sxxx data */
+#define SEND_TAG MKTAG('S', 'E', 'N', 'D')  /* Sxxx end */
+#define SHEN_TAG MKTAG('S', 'H', 'E', 'N')  /* SxEN header */
+#define SDEN_TAG MKTAG('S', 'D', 'E', 'N')  /* SxEN data */
+#define SEEN_TAG MKTAG('S', 'E', 'E', 'N')  /* SxEN end */
+#define ISNh_TAG MKTAG('1', 'S', 'N', 'h')  /* 1SNx header */
 #define EACS_TAG MKTAG('E', 'A', 'C', 'S')
-#define ISNd_TAG MKTAG('1', 'S', 'N', 'd')    /* 1SNx data */
-#define ISNe_TAG MKTAG('1', 'S', 'N', 'e')    /* 1SNx end */
+#define ISNd_TAG MKTAG('1', 'S', 'N', 'd')  /* 1SNx data */
+#define ISNe_TAG MKTAG('1', 'S', 'N', 'e')  /* 1SNx end */
 #define PT00_TAG MKTAG('P', 'T', 0x0, 0x0)
 #define GSTR_TAG MKTAG('G', 'S', 'T', 'R')
 #define SCDl_TAG MKTAG('S', 'C', 'D', 'l')
 #define SCEl_TAG MKTAG('S', 'C', 'E', 'l')
-#define kVGT_TAG MKTAG('k', 'V', 'G', 'T')    /* TGV i-frame */
-#define fVGT_TAG MKTAG('f', 'V', 'G', 'T')    /* TGV p-frame */
-#define mTCD_TAG MKTAG('m', 'T', 'C', 'D')    /* MDEC */
-#define MADk_TAG MKTAG('M', 'A', 'D', 'k')    /* MAD i-frame */
-#define MADm_TAG MKTAG('M', 'A', 'D', 'm')    /* MAD p-frame */
-#define MADe_TAG MKTAG('M', 'A', 'D', 'e')    /* MAD lqp-frame */
-#define MPCh_TAG MKTAG('M', 'P', 'C', 'h')    /* MPEG2 */
-#define TGQs_TAG MKTAG('T', 'G', 'Q', 's')    /* TGQ i-frame (appears in .TGQ files) */
-#define pQGT_TAG MKTAG('p', 'Q', 'G', 'T')    /* TGQ i-frame (appears in .UV files) */
-#define pIQT_TAG MKTAG('p', 'I', 'Q', 'T')    /* TQI/UV2 i-frame (.UV2/.WVE) */
+#define kVGT_TAG MKTAG('k', 'V', 'G', 'T')  /* TGV I-frame */
+#define fVGT_TAG MKTAG('f', 'V', 'G', 'T')  /* TGV P-frame */
+#define mTCD_TAG MKTAG('m', 'T', 'C', 'D')  /* MDEC */
+#define MADk_TAG MKTAG('M', 'A', 'D', 'k')  /* MAD I-frame */
+#define MADm_TAG MKTAG('M', 'A', 'D', 'm')  /* MAD P-frame */
+#define MADe_TAG MKTAG('M', 'A', 'D', 'e')  /* MAD lqp-frame */
+#define MPCh_TAG MKTAG('M', 'P', 'C', 'h')  /* MPEG-2 */
+#define TGQs_TAG MKTAG('T', 'G', 'Q', 's')  /* TGQ I-frame (appears in .TGQ files) */
+#define pQGT_TAG MKTAG('p', 'Q', 'G', 'T')  /* TGQ I-frame (appears in .UV files) */
+#define pIQT_TAG MKTAG('p', 'I', 'Q', 'T')  /* TQI/UV2 I-frame (.UV2/.WVE) */
 #define MVhd_TAG MKTAG('M', 'V', 'h', 'd')
 #define MV0K_TAG MKTAG('M', 'V', '0', 'K')
 #define MV0F_TAG MKTAG('M', 'V', '0', 'F')
-#define MVIh_TAG MKTAG('M', 'V', 'I', 'h')    /* CMV header */
-#define MVIf_TAG MKTAG('M', 'V', 'I', 'f')    /* CMV i-frame */
+#define MVIh_TAG MKTAG('M', 'V', 'I', 'h')  /* CMV header */
+#define MVIf_TAG MKTAG('M', 'V', 'I', 'f')  /* CMV I-frame */
 
 typedef struct EaDemuxContext {
     int big_endian;
@@ -78,7 +78,8 @@
     int num_samples;
 } EaDemuxContext;
 
-static uint32_t read_arbitary(AVIOContext *pb) {
+static uint32_t read_arbitrary(AVIOContext *pb)
+{
     uint8_t size, byte;
     int i;
     uint32_t word;
@@ -87,108 +88,135 @@
 
     word = 0;
     for (i = 0; i < size; i++) {
-        byte = avio_r8(pb);
+        byte   = avio_r8(pb);
         word <<= 8;
-        word |= byte;
+        word  |= byte;
     }
 
     return word;
 }
 
-/*
- * Process PT/GSTR sound header
- * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx
- */
 static int process_audio_header_elements(AVFormatContext *s)
 {
-    int inHeader = 1;
     EaDemuxContext *ea = s->priv_data;
-    AVIOContext *pb = s->pb;
+    AVIOContext    *pb = s->pb;
+    int in_header = 1;
     int compression_type = -1, revision = -1, revision2 = -1;
 
-    ea->bytes = 2;
-    ea->sample_rate = -1;
+    ea->bytes        = 2;
+    ea->sample_rate  = -1;
     ea->num_channels = 1;
 
-    while (!url_feof(pb) && inHeader) {
-        int inSubheader;
+    while (!url_feof(pb) && in_header) {
+        int in_subheader;
         uint8_t byte;
         byte = avio_r8(pb);
 
         switch (byte) {
         case 0xFD:
-            av_log (s, AV_LOG_DEBUG, "entered audio subheader\n");
-            inSubheader = 1;
-            while (!url_feof(pb) && inSubheader) {
+            av_log(s, AV_LOG_DEBUG, "entered audio subheader\n");
+            in_subheader = 1;
+            while (!url_feof(pb) && in_subheader) {
                 uint8_t subbyte;
                 subbyte = avio_r8(pb);
 
                 switch (subbyte) {
                 case 0x80:
-                    revision = read_arbitary(pb);
-                    av_log (s, AV_LOG_DEBUG, "revision (element 0x80) set to 0x%08x\n", revision);
+                    revision = read_arbitrary(pb);
+                    av_log(s, AV_LOG_DEBUG,
+                           "revision (element 0x80) set to 0x%08x\n", revision);
                     break;
                 case 0x82:
-                    ea->num_channels = read_arbitary(pb);
-                    av_log (s, AV_LOG_DEBUG, "num_channels (element 0x82) set to 0x%08x\n", ea->num_channels);
+                    ea->num_channels = read_arbitrary(pb);
+                    av_log(s, AV_LOG_DEBUG,
+                           "num_channels (element 0x82) set to 0x%08x\n",
+                           ea->num_channels);
                     break;
                 case 0x83:
-                    compression_type = read_arbitary(pb);
-                    av_log (s, AV_LOG_DEBUG, "compression_type (element 0x83) set to 0x%08x\n", compression_type);
+                    compression_type = read_arbitrary(pb);
+                    av_log(s, AV_LOG_DEBUG,
+                           "compression_type (element 0x83) set to 0x%08x\n",
+                           compression_type);
                     break;
                 case 0x84:
-                    ea->sample_rate = read_arbitary(pb);
-                    av_log (s, AV_LOG_DEBUG, "sample_rate (element 0x84) set to %i\n", ea->sample_rate);
+                    ea->sample_rate = read_arbitrary(pb);
+                    av_log(s, AV_LOG_DEBUG,
+                           "sample_rate (element 0x84) set to %i\n",
+                           ea->sample_rate);
                     break;
                 case 0x85:
-                    ea->num_samples = read_arbitary(pb);
-                    av_log (s, AV_LOG_DEBUG, "num_samples (element 0x85) set to 0x%08x\n", ea->num_samples);
+                    ea->num_samples = read_arbitrary(pb);
+                    av_log(s, AV_LOG_DEBUG,
+                           "num_samples (element 0x85) set to 0x%08x\n",
+                           ea->num_samples);
                     break;
                 case 0x8A:
-                    av_log (s, AV_LOG_DEBUG, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb));
-                    av_log (s, AV_LOG_DEBUG, "exited audio subheader\n");
-                    inSubheader = 0;
+                    av_log(s, AV_LOG_DEBUG,
+                           "element 0x%02x set to 0x%08x\n",
+                           subbyte, read_arbitrary(pb));
+                    av_log(s, AV_LOG_DEBUG, "exited audio subheader\n");
+                    in_subheader = 0;
                     break;
                 case 0xA0:
-                    revision2 = read_arbitary(pb);
-                    av_log (s, AV_LOG_DEBUG, "revision2 (element 0xA0) set to 0x%08x\n", revision2);
+                    revision2 = read_arbitrary(pb);
+                    av_log(s, AV_LOG_DEBUG,
+                           "revision2 (element 0xA0) set to 0x%08x\n",
+                           revision2);
                     break;
                 case 0xFF:
-                    av_log (s, AV_LOG_DEBUG, "end of header block reached (within audio subheader)\n");
-                    inSubheader = 0;
-                    inHeader = 0;
+                    av_log(s, AV_LOG_DEBUG,
+                           "end of header block reached (within audio subheader)\n");
+                    in_subheader = 0;
+                    in_header    = 0;
                     break;
                 default:
-                    av_log (s, AV_LOG_DEBUG, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb));
+                    av_log(s, AV_LOG_DEBUG,
+                           "element 0x%02x set to 0x%08x\n",
+                           subbyte, read_arbitrary(pb));
                     break;
                 }
             }
             break;
         case 0xFF:
-            av_log (s, AV_LOG_DEBUG, "end of header block reached\n");
-            inHeader = 0;
+            av_log(s, AV_LOG_DEBUG, "end of header block reached\n");
+            in_header = 0;
             break;
         default:
-            av_log (s, AV_LOG_DEBUG, "header element 0x%02x set to 0x%08x\n", byte, read_arbitary(pb));
+            av_log(s, AV_LOG_DEBUG,
+                   "header element 0x%02x set to 0x%08x\n",
+                   byte, read_arbitrary(pb));
             break;
         }
     }
 
     switch (compression_type) {
-    case  0: ea->audio_codec = AV_CODEC_ID_PCM_S16LE; break;
-    case  7: ea->audio_codec = AV_CODEC_ID_ADPCM_EA; break;
+    case  0:
+        ea->audio_codec = AV_CODEC_ID_PCM_S16LE;
+        break;
+    case  7:
+        ea->audio_codec = AV_CODEC_ID_ADPCM_EA;
+        break;
     case -1:
         switch (revision) {
-        case  1: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R1; break;
-        case  2: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R2; break;
-        case  3: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R3; break;
-        case -1: break;
+        case  1:
+            ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R1;
+            break;
+        case  2:
+            ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R2;
+            break;
+        case  3:
+            ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R3;
+            break;
+        case -1:
+            break;
         default:
             avpriv_request_sample(s, "stream type; revision=%i", revision);
             return 0;
         }
         switch (revision2) {
-        case  8: ea->audio_codec = AV_CODEC_ID_PCM_S16LE_PLANAR; break;
+        case  8:
+            ea->audio_codec = AV_CODEC_ID_PCM_S16LE_PLANAR;
+            break;
         case 10:
             switch (revision) {
             case -1:
@@ -199,8 +227,11 @@
                 return 0;
             }
             break;
-        case 16: ea->audio_codec = AV_CODEC_ID_MP3; break;
-        case -1: break;
+        case 16:
+            ea->audio_codec = AV_CODEC_ID_MP3;
+            break;
+        case -1:
+            break;
         default:
             ea->audio_codec = AV_CODEC_ID_NONE;
             avpriv_request_sample(s, "stream type; revision2=%i", revision2);
@@ -208,24 +239,22 @@
         }
         break;
     default:
-        avpriv_request_sample(s, "stream type; compression_type=%i", compression_type);
+        avpriv_request_sample(s,
+                              "stream type; compression_type=%i",
+                              compression_type);
         return 0;
     }
 
     if (ea->sample_rate == -1)
-        ea->sample_rate = revision==3 ? 48000 : 22050;
+        ea->sample_rate = revision == 3 ? 48000 : 22050;
 
     return 1;
 }
 
-/*
- * Process EACS sound header
- * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx
- */
-static int process_audio_header_eacs(AVFormatContext *s)
+static void process_audio_header_eacs(AVFormatContext *s)
 {
     EaDemuxContext *ea = s->priv_data;
-    AVIOContext *pb = s->pb;
+    AVIOContext *pb    = s->pb;
     int compression_type;
 
     ea->sample_rate  = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb);
@@ -237,52 +266,54 @@
     switch (compression_type) {
     case 0:
         switch (ea->bytes) {
-        case 1: ea->audio_codec = AV_CODEC_ID_PCM_S8;    break;
-        case 2: ea->audio_codec = AV_CODEC_ID_PCM_S16LE; break;
+        case 1:
+            ea->audio_codec = AV_CODEC_ID_PCM_S8;
+            break;
+        case 2:
+            ea->audio_codec = AV_CODEC_ID_PCM_S16LE;
+            break;
         }
         break;
-    case 1: ea->audio_codec = AV_CODEC_ID_PCM_MULAW; ea->bytes = 1; break;
-    case 2: ea->audio_codec = AV_CODEC_ID_ADPCM_IMA_EA_EACS; break;
+    case 1:
+        ea->audio_codec = AV_CODEC_ID_PCM_MULAW;
+        ea->bytes       = 1;
+        break;
+    case 2:
+        ea->audio_codec = AV_CODEC_ID_ADPCM_IMA_EA_EACS;
+        break;
     default:
-        avpriv_request_sample(s, "stream type; audio compression_type=%i", compression_type);
+        avpriv_request_sample(s,
+                              "stream type; audio compression_type=%i",
+                              compression_type);
     }
-
-    return 1;
 }
 
-/*
- * Process SEAD sound header
- * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx
- */
-static int process_audio_header_sead(AVFormatContext *s)
+static void process_audio_header_sead(AVFormatContext *s)
 {
     EaDemuxContext *ea = s->priv_data;
-    AVIOContext *pb = s->pb;
+    AVIOContext *pb    = s->pb;
 
     ea->sample_rate  = avio_rl32(pb);
     ea->bytes        = avio_rl32(pb);  /* 1=8-bit, 2=16-bit */
     ea->num_channels = avio_rl32(pb);
     ea->audio_codec  = AV_CODEC_ID_ADPCM_IMA_EA_SEAD;
-
-    return 1;
 }
 
-static int process_video_header_mdec(AVFormatContext *s)
+static void process_video_header_mdec(AVFormatContext *s)
 {
     EaDemuxContext *ea = s->priv_data;
-    AVIOContext *pb = s->pb;
+    AVIOContext *pb    = s->pb;
     avio_skip(pb, 4);
-    ea->width  = avio_rl16(pb);
-    ea->height = avio_rl16(pb);
-    ea->time_base = (AVRational){1,15};
+    ea->width       = avio_rl16(pb);
+    ea->height      = avio_rl16(pb);
+    ea->time_base   = (AVRational) { 1, 15 };
     ea->video_codec = AV_CODEC_ID_MDEC;
-    return 1;
 }
 
 static int process_video_header_vp6(AVFormatContext *s)
 {
     EaDemuxContext *ea = s->priv_data;
-    AVIOContext *pb = s->pb;
+    AVIOContext *pb    = s->pb;
 
     avio_skip(pb, 8);
     ea->nb_frames = avio_rl32(pb);
@@ -293,12 +324,12 @@
         av_log(s, AV_LOG_ERROR, "Timebase is invalid\n");
         return AVERROR_INVALIDDATA;
     }
-    ea->video_codec = AV_CODEC_ID_VP6;
+    ea->video_codec   = AV_CODEC_ID_VP6;
 
     return 1;
 }
 
-static int process_video_header_cmv(AVFormatContext *s)
+static void process_video_header_cmv(AVFormatContext *s)
 {
     EaDemuxContext *ea = s->priv_data;
     int fps;
@@ -306,90 +337,87 @@
     avio_skip(s->pb, 10);
     fps = avio_rl16(s->pb);
     if (fps)
-        ea->time_base = (AVRational){1, fps};
+        ea->time_base = (AVRational) { 1, fps };
     ea->video_codec = AV_CODEC_ID_CMV;
-
-    return 0;
 }
 
-/*
- * Process EA file header
- * Returns 1 if the EA file is valid and successfully opened, 0 otherwise
- */
-static int process_ea_header(AVFormatContext *s) {
+/* Process EA file header.
+ * Return 1 if the EA file is valid and successfully opened, 0 otherwise. */
+static int process_ea_header(AVFormatContext *s)
+{
     uint32_t blockid, size = 0;
     EaDemuxContext *ea = s->priv_data;
-    AVIOContext *pb = s->pb;
+    AVIOContext *pb    = s->pb;
     int i;
 
-    for (i=0; i<5 && (!ea->audio_codec || !ea->video_codec); i++) {
+    for (i = 0; i < 5 && (!ea->audio_codec || !ea->video_codec); i++) {
         unsigned int startpos = avio_tell(pb);
-        int err = 0;
+        int err               = 0;
 
         blockid = avio_rl32(pb);
-        size = avio_rl32(pb);
+        size    = avio_rl32(pb);
         if (i == 0)
             ea->big_endian = size > 0x000FFFFF;
         if (ea->big_endian)
             size = av_bswap32(size);
 
         switch (blockid) {
-            case ISNh_TAG:
-                if (avio_rl32(pb) != EACS_TAG) {
-                    avpriv_request_sample(s, "unknown 1SNh headerid");
-                    return 0;
-                }
-                err = process_audio_header_eacs(s);
-                break;
+        case ISNh_TAG:
+            if (avio_rl32(pb) != EACS_TAG) {
+                avpriv_request_sample(s, "unknown 1SNh headerid");
+                return 0;
+            }
+            process_audio_header_eacs(s);
+            break;
 
-            case SCHl_TAG :
-            case SHEN_TAG :
-                blockid = avio_rl32(pb);
-                if (blockid == GSTR_TAG) {
-                    avio_skip(pb, 4);
-                } else if ((blockid & 0xFFFF)!=PT00_TAG) {
-                    avpriv_request_sample(s, "unknown SCHl headerid");
-                    return 0;
-                }
-                err = process_audio_header_elements(s);
-                break;
+        case SCHl_TAG:
+        case SHEN_TAG:
+            blockid = avio_rl32(pb);
+            if (blockid == GSTR_TAG) {
+                avio_skip(pb, 4);
+            } else if ((blockid & 0xFFFF) != PT00_TAG) {
+                avpriv_request_sample(s, "unknown SCHl headerid");
+                return 0;
+            }
+            err = process_audio_header_elements(s);
+            break;
 
-            case SEAD_TAG:
-                err = process_audio_header_sead(s);
-                break;
+        case SEAD_TAG:
+            process_audio_header_sead(s);
+            break;
 
-            case MVIh_TAG :
-                err = process_video_header_cmv(s);
-                break;
+        case MVIh_TAG:
+            process_video_header_cmv(s);
+            break;
 
-            case kVGT_TAG:
-                ea->video_codec = AV_CODEC_ID_TGV;
-                break;
+        case kVGT_TAG:
+            ea->video_codec = AV_CODEC_ID_TGV;
+            break;
 
-            case mTCD_TAG :
-                err = process_video_header_mdec(s);
-                break;
+        case mTCD_TAG:
+            process_video_header_mdec(s);
+            break;
 
-            case MPCh_TAG:
-                ea->video_codec = AV_CODEC_ID_MPEG2VIDEO;
-                break;
+        case MPCh_TAG:
+            ea->video_codec = AV_CODEC_ID_MPEG2VIDEO;
+            break;
 
-            case pQGT_TAG:
-            case TGQs_TAG:
-                ea->video_codec = AV_CODEC_ID_TGQ;
-                break;
+        case pQGT_TAG:
+        case TGQs_TAG:
+            ea->video_codec = AV_CODEC_ID_TGQ;
+            break;
 
-            case pIQT_TAG:
-                ea->video_codec = AV_CODEC_ID_TQI;
-                break;
+        case pIQT_TAG:
+            ea->video_codec = AV_CODEC_ID_TQI;
+            break;
 
-            case MADk_TAG :
-                ea->video_codec = AV_CODEC_ID_MAD;
-                break;
+        case MADk_TAG:
+            ea->video_codec = AV_CODEC_ID_MAD;
+            break;
 
-            case MVhd_TAG :
-                err = process_video_header_vp6(s);
-                break;
+        case MVhd_TAG:
+            err = process_video_header_vp6(s);
+            break;
         }
 
         if (err < 0) {
@@ -405,7 +433,6 @@
     return 1;
 }
 
-
 static int ea_probe(AVProbeData *p)
 {
     switch (AV_RL32(&p->buf[0])) {
@@ -424,6 +451,7 @@
     }
     if (AV_RL32(&p->buf[4]) > 0xfffff && AV_RB32(&p->buf[4]) > 0xfffff)
         return 0;
+
     return AVPROBE_SCORE_MAX;
 }
 
@@ -441,34 +469,37 @@
         if (!st)
             return AVERROR(ENOMEM);
         ea->video_stream_index = st->index;
-        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
-        st->codec->codec_id = ea->video_codec;
+        st->codec->codec_type  = AVMEDIA_TYPE_VIDEO;
+        st->codec->codec_id    = ea->video_codec;
         // parsing is necessary to make FFmpeg generate correct timestamps
         if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO)
             st->need_parsing = AVSTREAM_PARSE_HEADERS;
-        st->codec->codec_tag = 0;  /* no fourcc */
-        st->codec->width = ea->width;
-        st->codec->height = ea->height;
-        st->duration = st->nb_frames = ea->nb_frames;
+        st->codec->codec_tag   = 0; /* no fourcc */
+        st->codec->width       = ea->width;
+        st->codec->height      = ea->height;
+        st->duration           = st->nb_frames = ea->nb_frames;
         if (ea->time_base.num)
             avpriv_set_pts_info(st, 64, ea->time_base.num, ea->time_base.den);
-        st->r_frame_rate =
-        st->avg_frame_rate = av_inv_q(ea->time_base);
+        st->r_frame_rate       =
+        st->avg_frame_rate     = av_inv_q(ea->time_base);
     }
 
     if (ea->audio_codec) {
         if (ea->num_channels <= 0) {
-            av_log(s, AV_LOG_WARNING, "Unsupported number of channels: %d\n", ea->num_channels);
+            av_log(s, AV_LOG_WARNING,
+                   "Unsupported number of channels: %d\n", ea->num_channels);
             ea->audio_codec = 0;
             return 1;
         }
         if (ea->sample_rate <= 0) {
-            av_log(s, AV_LOG_ERROR, "Unsupported sample rate: %d\n", ea->sample_rate);
+            av_log(s, AV_LOG_ERROR,
+                   "Unsupported sample rate: %d\n", ea->sample_rate);
             ea->audio_codec = 0;
             return 1;
         }
         if (ea->bytes <= 0) {
-            av_log(s, AV_LOG_ERROR, "Invalid number of bytes per sample: %d\n", ea->bytes);
+            av_log(s, AV_LOG_ERROR,
+                   "Invalid number of bytes per sample: %d\n", ea->bytes);
             ea->audio_codec = AV_CODEC_ID_NONE;
             return 1;
         }
@@ -478,32 +509,31 @@
         if (!st)
             return AVERROR(ENOMEM);
         avpriv_set_pts_info(st, 33, 1, ea->sample_rate);
-        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
-        st->codec->codec_id = ea->audio_codec;
-        st->codec->codec_tag = 0;  /* no tag */
-        st->codec->channels = ea->num_channels;
-        st->codec->sample_rate = ea->sample_rate;
+        st->codec->codec_type            = AVMEDIA_TYPE_AUDIO;
+        st->codec->codec_id              = ea->audio_codec;
+        st->codec->codec_tag             = 0;   /* no tag */
+        st->codec->channels              = ea->num_channels;
+        st->codec->sample_rate           = ea->sample_rate;
         st->codec->bits_per_coded_sample = ea->bytes * 8;
-        st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
-            st->codec->bits_per_coded_sample / 4;
-        st->codec->block_align = st->codec->channels*st->codec->bits_per_coded_sample;
-        ea->audio_stream_index = st->index;
-        st->start_time = 0;
+        st->codec->bit_rate              = st->codec->channels *
+                                           st->codec->sample_rate *
+                                           st->codec->bits_per_coded_sample / 4;
+        st->codec->block_align           = st->codec->channels *
+                                           st->codec->bits_per_coded_sample;
+        ea->audio_stream_index           = st->index;
+        st->start_time                   = 0;
     }
 
     return 1;
 }
 
-static int ea_read_packet(AVFormatContext *s,
-                          AVPacket *pkt)
+static int ea_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     EaDemuxContext *ea = s->priv_data;
-    AVIOContext *pb = s->pb;
-    int ret = 0;
-    int packet_read = 0;
+    AVIOContext *pb    = s->pb;
     int partial_packet = 0;
     unsigned int chunk_type, chunk_size;
-    int key = 0;
+    int ret = 0, packet_read = 0, key = 0;
     int av_uninit(num_samples);
 
     while (!packet_read || partial_packet) {
@@ -516,7 +546,7 @@
         switch (chunk_type) {
         /* audio data */
         case ISNh_TAG:
-            /* header chunk also contains data; skip over the header portion*/
+            /* header chunk also contains data; skip over the header portion */
             if (chunk_size < 32)
                 return AVERROR_INVALIDDATA;
             avio_skip(pb, 32);
@@ -576,7 +606,7 @@
         case SCEl_TAG:
         case SEND_TAG:
         case SEEN_TAG:
-            ret = AVERROR(EIO);
+            ret         = AVERROR(EIO);
             packet_read = 1;
             break;
 
@@ -590,12 +620,12 @@
         case fVGT_TAG:
         case MADm_TAG:
         case MADe_TAG:
-            avio_seek(pb, -8, SEEK_CUR);     // include chunk preamble
+            avio_seek(pb, -8, SEEK_CUR);    // include chunk preamble
             chunk_size += 8;
             goto get_video_packet;
 
         case mTCD_TAG:
-            avio_skip(pb, 8);  // skip ea dct header
+            avio_skip(pb, 8);               // skip ea DCT header
             chunk_size -= 8;
             goto get_video_packet;
 
@@ -615,8 +645,8 @@
             }
             partial_packet = chunk_type == MVIh_TAG;
             pkt->stream_index = ea->video_stream_index;
-            pkt->flags |= key;
-            packet_read = 1;
+            pkt->flags       |= key;
+            packet_read       = 1;
             break;
 
         default:
diff --git a/libavformat/ffmenc.c b/libavformat/ffmenc.c
index 522945e..eb809eb 100644
--- a/libavformat/ffmenc.c
+++ b/libavformat/ffmenc.c
@@ -277,4 +277,5 @@
     .write_header      = ffm_write_header,
     .write_packet      = ffm_write_packet,
     .write_trailer     = ffm_write_trailer,
+    .flags             = AVFMT_TS_NEGATIVE,
 };
diff --git a/libavformat/file.c b/libavformat/file.c
index e09a64b..2defc75 100644
--- a/libavformat/file.c
+++ b/libavformat/file.c
@@ -20,6 +20,7 @@
  */
 
 #include "libavutil/avstring.h"
+#include "libavutil/internal.h"
 #include "libavutil/opt.h"
 #include "avformat.h"
 #include <fcntl.h>
@@ -49,10 +50,17 @@
     const AVClass *class;
     int fd;
     int trunc;
+    int blocksize;
 } FileContext;
 
 static const AVOption file_options[] = {
     { "truncate", "Truncate existing files on write", offsetof(FileContext, trunc), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
+    { "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+    { NULL }
+};
+
+static const AVOption pipe_options[] = {
+    { "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
     { NULL }
 };
 
@@ -63,17 +71,28 @@
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
+static const AVClass pipe_class = {
+    .class_name = "pipe",
+    .item_name  = av_default_item_name,
+    .option     = pipe_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static int file_read(URLContext *h, unsigned char *buf, int size)
 {
     FileContext *c = h->priv_data;
-    int r = read(c->fd, buf, size);
+    int r;
+    size = FFMIN(size, c->blocksize);
+    r = read(c->fd, buf, size);
     return (-1 == r)?AVERROR(errno):r;
 }
 
 static int file_write(URLContext *h, const unsigned char *buf, int size)
 {
     FileContext *c = h->priv_data;
-    int r = write(c->fd, buf, size);
+    int r;
+    size = FFMIN(size, c->blocksize);
+    r = write(c->fd, buf, size);
     return (-1 == r)?AVERROR(errno):r;
 }
 
@@ -132,7 +151,7 @@
 #ifdef O_BINARY
     access |= O_BINARY;
 #endif
-    fd = open(filename, access, 0666);
+    fd = avpriv_open(filename, access, 0666);
     if (fd == -1)
         return AVERROR(errno);
     c->fd = fd;
@@ -213,6 +232,7 @@
     .url_get_file_handle = file_get_handle,
     .url_check           = file_check,
     .priv_data_size      = sizeof(FileContext),
+    .priv_data_class     = &pipe_class,
 };
 
 #endif /* CONFIG_PIPE_PROTOCOL */
diff --git a/libavformat/file_open.c b/libavformat/file_open.c
new file mode 100644
index 0000000..494a5d3
--- /dev/null
+++ b/libavformat/file_open.c
@@ -0,0 +1 @@
+#include "libavutil/file_open.c"
diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c
index d5aacfd..8384076 100644
--- a/libavformat/flacdec.c
+++ b/libavformat/flacdec.c
@@ -21,139 +21,13 @@
 
 #include "libavcodec/flac.h"
 #include "avformat.h"
-#include "id3v2.h"
+#include "flacdec.h"
 #include "internal.h"
 #include "rawdec.h"
 #include "oggdec.h"
 #include "vorbiscomment.h"
 #include "libavcodec/bytestream.h"
 
-#define RETURN_ERROR(code) do { ret = (code); goto fail; } while (0)
-
-static int parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size)
-{
-    const CodecMime *mime = ff_id3v2_mime_tags;
-    enum  AVCodecID      id = AV_CODEC_ID_NONE;
-    AVBufferRef *data = NULL;
-    uint8_t mimetype[64], *desc = NULL;
-    AVIOContext *pb = NULL;
-    AVStream *st;
-    int type, width, height;
-    int len, ret = 0;
-
-    pb = avio_alloc_context(buf, buf_size, 0, NULL, NULL, NULL, NULL);
-    if (!pb)
-        return AVERROR(ENOMEM);
-
-    /* read the picture type */
-    type      = avio_rb32(pb);
-    if (type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types) || type < 0) {
-        av_log(s, AV_LOG_ERROR, "Invalid picture type: %d.\n", type);
-        if (s->error_recognition & AV_EF_EXPLODE) {
-            RETURN_ERROR(AVERROR_INVALIDDATA);
-        }
-        type = 0;
-    }
-
-    /* picture mimetype */
-    len  = avio_rb32(pb);
-    if (len <= 0 ||
-        avio_read(pb, mimetype, FFMIN(len, sizeof(mimetype) - 1)) != len) {
-        av_log(s, AV_LOG_ERROR, "Could not read mimetype from an attached "
-               "picture.\n");
-        if (s->error_recognition & AV_EF_EXPLODE)
-            ret = AVERROR_INVALIDDATA;
-        goto fail;
-    }
-    mimetype[len] = 0;
-
-    while (mime->id != AV_CODEC_ID_NONE) {
-        if (!strncmp(mime->str, mimetype, sizeof(mimetype))) {
-            id = mime->id;
-            break;
-        }
-        mime++;
-    }
-    if (id == AV_CODEC_ID_NONE) {
-        av_log(s, AV_LOG_ERROR, "Unknown attached picture mimetype: %s.\n",
-               mimetype);
-        if (s->error_recognition & AV_EF_EXPLODE)
-            ret = AVERROR_INVALIDDATA;
-        goto fail;
-    }
-
-    /* picture description */
-    len = avio_rb32(pb);
-    if (len > 0) {
-        if (!(desc = av_malloc(len + 1))) {
-            RETURN_ERROR(AVERROR(ENOMEM));
-        }
-
-        if (avio_read(pb, desc, len) != len) {
-            av_log(s, AV_LOG_ERROR, "Error reading attached picture description.\n");
-            if (s->error_recognition & AV_EF_EXPLODE)
-                ret = AVERROR(EIO);
-            goto fail;
-        }
-        desc[len] = 0;
-    }
-
-    /* picture metadata */
-    width  = avio_rb32(pb);
-    height = avio_rb32(pb);
-    avio_skip(pb, 8);
-
-    /* picture data */
-    len = avio_rb32(pb);
-    if (len <= 0) {
-        av_log(s, AV_LOG_ERROR, "Invalid attached picture size: %d.\n", len);
-        if (s->error_recognition & AV_EF_EXPLODE)
-            ret = AVERROR_INVALIDDATA;
-        goto fail;
-    }
-    if (!(data = av_buffer_alloc(len))) {
-        RETURN_ERROR(AVERROR(ENOMEM));
-    }
-    if (avio_read(pb, data->data, len) != len) {
-        av_log(s, AV_LOG_ERROR, "Error reading attached picture data.\n");
-        if (s->error_recognition & AV_EF_EXPLODE)
-            ret = AVERROR(EIO);
-        goto fail;
-    }
-
-    st = avformat_new_stream(s, NULL);
-    if (!st) {
-        RETURN_ERROR(AVERROR(ENOMEM));
-    }
-
-    av_init_packet(&st->attached_pic);
-    st->attached_pic.buf          = data;
-    st->attached_pic.data         = data->data;
-    st->attached_pic.size         = len;
-    st->attached_pic.stream_index = st->index;
-    st->attached_pic.flags       |= AV_PKT_FLAG_KEY;
-
-    st->disposition      |= AV_DISPOSITION_ATTACHED_PIC;
-    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
-    st->codec->codec_id   = id;
-    st->codec->width      = width;
-    st->codec->height     = height;
-    av_dict_set(&st->metadata, "comment", ff_id3v2_picture_types[type], 0);
-    if (desc)
-        av_dict_set(&st->metadata, "title",   desc, AV_DICT_DONT_STRDUP_VAL);
-
-    av_freep(&pb);
-
-    return 0;
-
-fail:
-    av_buffer_unref(&data);
-    av_freep(&desc);
-    av_freep(&pb);
-    return ret;
-
-}
-
 static int flac_read_header(AVFormatContext *s)
 {
     int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0;
@@ -248,7 +122,7 @@
             }
             av_freep(&buffer);
         } else if (metadata_type == FLAC_METADATA_TYPE_PICTURE) {
-            ret = parse_picture(s, buffer, metadata_size);
+            ret = ff_flac_parse_picture(s, buffer, metadata_size);
             av_freep(&buffer);
             if (ret < 0) {
                 av_log(s, AV_LOG_ERROR, "Error parsing attached picture.\n");
@@ -280,7 +154,7 @@
 {
     if (p->buf_size < 4 || memcmp(p->buf, "fLaC", 4))
         return 0;
-    return AVPROBE_SCORE_MAX/2;
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 AVInputFormat ff_flac_demuxer = {
diff --git a/libavformat/flacdec.h b/libavformat/flacdec.h
new file mode 100644
index 0000000..dff0660
--- /dev/null
+++ b/libavformat/flacdec.h
@@ -0,0 +1,31 @@
+/*
+ * Raw FLAC demuxer
+ * Copyright (c) 2001 Fabrice Bellard
+ *
+ * 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
+ */
+
+#ifndef AVFORMAT_FLACDEC_H
+#define AVFORMAT_FLACDEC_H
+
+#include "avformat.h"
+
+#define RETURN_ERROR(code) do { ret = (code); goto fail; } while (0)
+
+int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size);
+
+#endif /* AVFORMAT_FLACDEC_H */
diff --git a/libavformat/flacdec_picture.c b/libavformat/flacdec_picture.c
new file mode 100644
index 0000000..1b0bea2
--- /dev/null
+++ b/libavformat/flacdec_picture.c
@@ -0,0 +1,150 @@
+/*
+ * Raw FLAC demuxer
+ * Copyright (c) 2001 Fabrice Bellard
+ *
+ * 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
+ */
+
+#include "libavutil/avassert.h"
+#include "avformat.h"
+#include "flacdec.h"
+#include "id3v2.h"
+#include "internal.h"
+
+int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size)
+{
+    const CodecMime *mime = ff_id3v2_mime_tags;
+    enum  AVCodecID      id = AV_CODEC_ID_NONE;
+    AVBufferRef *data = NULL;
+    uint8_t mimetype[64], *desc = NULL;
+    AVIOContext *pb = NULL;
+    AVStream *st;
+    int type, width, height;
+    int len, ret = 0;
+
+    pb = avio_alloc_context(buf, buf_size, 0, NULL, NULL, NULL, NULL);
+    if (!pb)
+        return AVERROR(ENOMEM);
+
+    /* read the picture type */
+    type      = avio_rb32(pb);
+    if (type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types) || type < 0) {
+        av_log(s, AV_LOG_ERROR, "Invalid picture type: %d.\n", type);
+        if (s->error_recognition & AV_EF_EXPLODE) {
+            RETURN_ERROR(AVERROR_INVALIDDATA);
+        }
+        type = 0;
+    }
+
+    /* picture mimetype */
+    len  = avio_rb32(pb);
+    if (len <= 0 ||
+        avio_read(pb, mimetype, FFMIN(len, sizeof(mimetype) - 1)) != len) {
+        av_log(s, AV_LOG_ERROR, "Could not read mimetype from an attached "
+               "picture.\n");
+        if (s->error_recognition & AV_EF_EXPLODE)
+            ret = AVERROR_INVALIDDATA;
+        goto fail;
+    }
+    av_assert0(len < sizeof(mimetype));
+    mimetype[len] = 0;
+
+    while (mime->id != AV_CODEC_ID_NONE) {
+        if (!strncmp(mime->str, mimetype, sizeof(mimetype))) {
+            id = mime->id;
+            break;
+        }
+        mime++;
+    }
+    if (id == AV_CODEC_ID_NONE) {
+        av_log(s, AV_LOG_ERROR, "Unknown attached picture mimetype: %s.\n",
+               mimetype);
+        if (s->error_recognition & AV_EF_EXPLODE)
+            ret = AVERROR_INVALIDDATA;
+        goto fail;
+    }
+
+    /* picture description */
+    len = avio_rb32(pb);
+    if (len > 0) {
+        if (!(desc = av_malloc(len + 1))) {
+            RETURN_ERROR(AVERROR(ENOMEM));
+        }
+
+        if (avio_read(pb, desc, len) != len) {
+            av_log(s, AV_LOG_ERROR, "Error reading attached picture description.\n");
+            if (s->error_recognition & AV_EF_EXPLODE)
+                ret = AVERROR(EIO);
+            goto fail;
+        }
+        desc[len] = 0;
+    }
+
+    /* picture metadata */
+    width  = avio_rb32(pb);
+    height = avio_rb32(pb);
+    avio_skip(pb, 8);
+
+    /* picture data */
+    len = avio_rb32(pb);
+    if (len <= 0) {
+        av_log(s, AV_LOG_ERROR, "Invalid attached picture size: %d.\n", len);
+        if (s->error_recognition & AV_EF_EXPLODE)
+            ret = AVERROR_INVALIDDATA;
+        goto fail;
+    }
+    if (!(data = av_buffer_alloc(len))) {
+        RETURN_ERROR(AVERROR(ENOMEM));
+    }
+    if (avio_read(pb, data->data, len) != len) {
+        av_log(s, AV_LOG_ERROR, "Error reading attached picture data.\n");
+        if (s->error_recognition & AV_EF_EXPLODE)
+            ret = AVERROR(EIO);
+        goto fail;
+    }
+
+    st = avformat_new_stream(s, NULL);
+    if (!st) {
+        RETURN_ERROR(AVERROR(ENOMEM));
+    }
+
+    av_init_packet(&st->attached_pic);
+    st->attached_pic.buf          = data;
+    st->attached_pic.data         = data->data;
+    st->attached_pic.size         = len;
+    st->attached_pic.stream_index = st->index;
+    st->attached_pic.flags       |= AV_PKT_FLAG_KEY;
+
+    st->disposition      |= AV_DISPOSITION_ATTACHED_PIC;
+    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+    st->codec->codec_id   = id;
+    st->codec->width      = width;
+    st->codec->height     = height;
+    av_dict_set(&st->metadata, "comment", ff_id3v2_picture_types[type], 0);
+    if (desc)
+        av_dict_set(&st->metadata, "title",   desc, AV_DICT_DONT_STRDUP_VAL);
+
+    av_freep(&pb);
+
+    return 0;
+
+fail:
+    av_buffer_unref(&data);
+    av_freep(&desc);
+    av_freep(&pb);
+    return ret;
+}
diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c
index 8c1a1bb..87e9362 100644
--- a/libavformat/flacenc.c
+++ b/libavformat/flacenc.c
@@ -21,6 +21,7 @@
 
 #include "libavcodec/flac.h"
 #include "avformat.h"
+#include "avio_internal.h"
 #include "flacenc.h"
 #include "vorbiscomment.h"
 #include "libavcodec/bytestream.h"
@@ -31,10 +32,7 @@
 {
     avio_w8(pb, last_block ? 0x81 : 0x01);
     avio_wb24(pb, n_padding_bytes);
-    while (n_padding_bytes > 0) {
-        avio_w8(pb, 0);
-        n_padding_bytes--;
-    }
+    ffio_fill(pb, 0, n_padding_bytes);
     return 0;
 }
 
diff --git a/libavformat/flic.c b/libavformat/flic.c
index 8d49116..2835cf5 100644
--- a/libavformat/flic.c
+++ b/libavformat/flic.c
@@ -80,7 +80,7 @@
         return 0;
 
 
-    return AVPROBE_SCORE_MAX;
+    return AVPROBE_SCORE_MAX - 1;
 }
 
 static int flic_read_header(AVFormatContext *s)
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 8bb56e8..e0b79bb 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -41,12 +41,12 @@
 
 typedef struct {
     const AVClass *class; ///< Class for private options.
-    int trust_metadata; ///< configure streams according onMetaData
-    int wrong_dts; ///< wrong dts due to negative cts
+    int trust_metadata;   ///< configure streams according onMetaData
+    int wrong_dts;        ///< wrong dts due to negative cts
     uint8_t *new_extradata[FLV_STREAM_TYPE_NB];
-    int      new_extradata_size[FLV_STREAM_TYPE_NB];
-    int      last_sample_rate;
-    int      last_channels;
+    int new_extradata_size[FLV_STREAM_TYPE_NB];
+    int last_sample_rate;
+    int last_channels;
     struct {
         int64_t dts;
         int64_t pos;
@@ -61,7 +61,11 @@
     const uint8_t *d;
 
     d = p->buf;
-    if (d[0] == 'F' && d[1] == 'L' && d[2] == 'V' && d[3] < 5 && d[5]==0 && AV_RB32(d+5)>8) {
+    if (d[0] == 'F' &&
+        d[1] == 'L' &&
+        d[2] == 'V' &&
+        d[3] < 5 && d[5] == 0 &&
+        AV_RB32(d + 5) > 8) {
         return AVPROBE_SCORE_MAX;
     }
     return 0;
@@ -73,7 +77,7 @@
     if (!st)
         return NULL;
     st->codec->codec_type = codec_type;
-    if(s->nb_streams>=3 ||(   s->nb_streams==2
+    if (s->nb_streams>=3 ||(   s->nb_streams==2
                            && s->streams[0]->codec->codec_type != AVMEDIA_TYPE_DATA
                            && s->streams[1]->codec->codec_type != AVMEDIA_TYPE_DATA))
         s->ctx_flags &= ~AVFMTCTX_NOHEADER;
@@ -81,10 +85,11 @@
     avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
     return st;
 }
+
 static int flv_same_audio_codec(AVCodecContext *acodec, int flags)
 {
     int bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8;
-    int flv_codecid = flags & FLV_AUDIO_CODECID_MASK;
+    int flv_codecid           = flags & FLV_AUDIO_CODECID_MASK;
     int codec_id;
 
     if (!acodec->codec_id && !acodec->codec_tag)
@@ -93,18 +98,21 @@
     if (acodec->bits_per_coded_sample != bits_per_coded_sample)
         return 0;
 
-    switch(flv_codecid) {
-        //no distinction between S16 and S8 PCM codec flags
+    switch (flv_codecid) {
+    // no distinction between S16 and S8 PCM codec flags
     case FLV_CODECID_PCM:
-        codec_id = bits_per_coded_sample == 8 ? AV_CODEC_ID_PCM_U8 :
+        codec_id = bits_per_coded_sample == 8
+                   ? AV_CODEC_ID_PCM_U8
 #if HAVE_BIGENDIAN
-                            AV_CODEC_ID_PCM_S16BE;
+                   : AV_CODEC_ID_PCM_S16BE;
 #else
-                            AV_CODEC_ID_PCM_S16LE;
+                   : AV_CODEC_ID_PCM_S16LE;
 #endif
         return codec_id == acodec->codec_id;
     case FLV_CODECID_PCM_LE:
-        codec_id = bits_per_coded_sample == 8 ? AV_CODEC_ID_PCM_U8 : AV_CODEC_ID_PCM_S16LE;
+        codec_id = bits_per_coded_sample == 8
+                   ? AV_CODEC_ID_PCM_U8
+                   : AV_CODEC_ID_PCM_S16LE;
         return codec_id == acodec->codec_id;
     case FLV_CODECID_AAC:
         return acodec->codec_id == AV_CODEC_ID_AAC;
@@ -120,57 +128,72 @@
         return acodec->codec_id == AV_CODEC_ID_NELLYMOSER;
     case FLV_CODECID_PCM_MULAW:
         return acodec->sample_rate == 8000 &&
-               acodec->codec_id == AV_CODEC_ID_PCM_MULAW;
+               acodec->codec_id    == AV_CODEC_ID_PCM_MULAW;
     case FLV_CODECID_PCM_ALAW:
-        return acodec->sample_rate = 8000 &&
-               acodec->codec_id == AV_CODEC_ID_PCM_ALAW;
+        return acodec->sample_rate == 8000 &&
+               acodec->codec_id    == AV_CODEC_ID_PCM_ALAW;
     default:
         return acodec->codec_tag == (flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
     }
 }
 
-static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream, AVCodecContext *acodec, int flv_codecid) {
-    switch(flv_codecid) {
-        //no distinction between S16 and S8 PCM codec flags
-        case FLV_CODECID_PCM:
-            acodec->codec_id = acodec->bits_per_coded_sample == 8 ? AV_CODEC_ID_PCM_U8 :
+static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream,
+                                AVCodecContext *acodec, int flv_codecid)
+{
+    switch (flv_codecid) {
+    // no distinction between S16 and S8 PCM codec flags
+    case FLV_CODECID_PCM:
+        acodec->codec_id = acodec->bits_per_coded_sample == 8
+                           ? AV_CODEC_ID_PCM_U8
 #if HAVE_BIGENDIAN
-                                AV_CODEC_ID_PCM_S16BE;
+                           : AV_CODEC_ID_PCM_S16BE;
 #else
-                                AV_CODEC_ID_PCM_S16LE;
+                           : AV_CODEC_ID_PCM_S16LE;
 #endif
-            break;
-        case FLV_CODECID_PCM_LE:
-            acodec->codec_id = acodec->bits_per_coded_sample == 8 ? AV_CODEC_ID_PCM_U8 : AV_CODEC_ID_PCM_S16LE; break;
-        case FLV_CODECID_AAC  : acodec->codec_id = AV_CODEC_ID_AAC;                                    break;
-        case FLV_CODECID_ADPCM: acodec->codec_id = AV_CODEC_ID_ADPCM_SWF;                              break;
-        case FLV_CODECID_SPEEX:
-            acodec->codec_id = AV_CODEC_ID_SPEEX;
-            acodec->sample_rate = 16000;
-            break;
-        case FLV_CODECID_MP3  : acodec->codec_id = AV_CODEC_ID_MP3      ; astream->need_parsing = AVSTREAM_PARSE_FULL; break;
-        case FLV_CODECID_NELLYMOSER_8KHZ_MONO:
-            acodec->sample_rate = 8000; //in case metadata does not otherwise declare samplerate
-            acodec->codec_id = AV_CODEC_ID_NELLYMOSER;
-            break;
-        case FLV_CODECID_NELLYMOSER_16KHZ_MONO:
-            acodec->sample_rate = 16000;
-            acodec->codec_id = AV_CODEC_ID_NELLYMOSER;
-            break;
-        case FLV_CODECID_NELLYMOSER:
-            acodec->codec_id = AV_CODEC_ID_NELLYMOSER;
-            break;
-        case FLV_CODECID_PCM_MULAW:
-            acodec->sample_rate = 8000;
-            acodec->codec_id = AV_CODEC_ID_PCM_MULAW;
-            break;
-        case FLV_CODECID_PCM_ALAW:
-            acodec->sample_rate = 8000;
-            acodec->codec_id = AV_CODEC_ID_PCM_ALAW;
-            break;
-        default:
-            av_log(s, AV_LOG_INFO, "Unsupported audio codec (%x)\n", flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
-            acodec->codec_tag = flv_codecid >> FLV_AUDIO_CODECID_OFFSET;
+        break;
+    case FLV_CODECID_PCM_LE:
+        acodec->codec_id = acodec->bits_per_coded_sample == 8
+                           ? AV_CODEC_ID_PCM_U8
+                           : AV_CODEC_ID_PCM_S16LE;
+        break;
+    case FLV_CODECID_AAC:
+        acodec->codec_id = AV_CODEC_ID_AAC;
+        break;
+    case FLV_CODECID_ADPCM:
+        acodec->codec_id = AV_CODEC_ID_ADPCM_SWF;
+        break;
+    case FLV_CODECID_SPEEX:
+        acodec->codec_id    = AV_CODEC_ID_SPEEX;
+        acodec->sample_rate = 16000;
+        break;
+    case FLV_CODECID_MP3:
+        acodec->codec_id      = AV_CODEC_ID_MP3;
+        astream->need_parsing = AVSTREAM_PARSE_FULL;
+        break;
+    case FLV_CODECID_NELLYMOSER_8KHZ_MONO:
+        // in case metadata does not otherwise declare samplerate
+        acodec->sample_rate = 8000;
+        acodec->codec_id    = AV_CODEC_ID_NELLYMOSER;
+        break;
+    case FLV_CODECID_NELLYMOSER_16KHZ_MONO:
+        acodec->sample_rate = 16000;
+        acodec->codec_id    = AV_CODEC_ID_NELLYMOSER;
+        break;
+    case FLV_CODECID_NELLYMOSER:
+        acodec->codec_id = AV_CODEC_ID_NELLYMOSER;
+        break;
+    case FLV_CODECID_PCM_MULAW:
+        acodec->sample_rate = 8000;
+        acodec->codec_id    = AV_CODEC_ID_PCM_MULAW;
+        break;
+    case FLV_CODECID_PCM_ALAW:
+        acodec->sample_rate = 8000;
+        acodec->codec_id    = AV_CODEC_ID_PCM_ALAW;
+        break;
+    default:
+        av_log(s, AV_LOG_INFO, "Unsupported audio codec (%x)\n",
+               flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
+        acodec->codec_tag = flv_codecid >> FLV_AUDIO_CODECID_OFFSET;
     }
 }
 
@@ -182,63 +205,75 @@
         return 1;
 
     switch (flv_codecid) {
-        case FLV_CODECID_H263:
-            return vcodec->codec_id == AV_CODEC_ID_FLV1;
-        case FLV_CODECID_SCREEN:
-            return vcodec->codec_id == AV_CODEC_ID_FLASHSV;
-        case FLV_CODECID_SCREEN2:
-            return vcodec->codec_id == AV_CODEC_ID_FLASHSV2;
-        case FLV_CODECID_VP6:
-            return vcodec->codec_id == AV_CODEC_ID_VP6F;
-        case FLV_CODECID_VP6A:
-            return vcodec->codec_id == AV_CODEC_ID_VP6A;
-        case FLV_CODECID_H264:
-            return vcodec->codec_id == AV_CODEC_ID_H264;
-        default:
-            return vcodec->codec_tag == flv_codecid;
+    case FLV_CODECID_H263:
+        return vcodec->codec_id == AV_CODEC_ID_FLV1;
+    case FLV_CODECID_SCREEN:
+        return vcodec->codec_id == AV_CODEC_ID_FLASHSV;
+    case FLV_CODECID_SCREEN2:
+        return vcodec->codec_id == AV_CODEC_ID_FLASHSV2;
+    case FLV_CODECID_VP6:
+        return vcodec->codec_id == AV_CODEC_ID_VP6F;
+    case FLV_CODECID_VP6A:
+        return vcodec->codec_id == AV_CODEC_ID_VP6A;
+    case FLV_CODECID_H264:
+        return vcodec->codec_id == AV_CODEC_ID_H264;
+    default:
+        return vcodec->codec_tag == flv_codecid;
     }
 }
 
-static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_codecid, int read) {
+static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
+                               int flv_codecid, int read)
+{
     AVCodecContext *vcodec = vstream->codec;
-    switch(flv_codecid) {
-        case FLV_CODECID_H263  : vcodec->codec_id = AV_CODEC_ID_FLV1   ; break;
-        case FLV_CODECID_REALH263: vcodec->codec_id = AV_CODEC_ID_H263 ; break; // Really mean it this time
-        case FLV_CODECID_SCREEN: vcodec->codec_id = AV_CODEC_ID_FLASHSV; break;
-        case FLV_CODECID_SCREEN2: vcodec->codec_id = AV_CODEC_ID_FLASHSV2; break;
-        case FLV_CODECID_VP6   : vcodec->codec_id = AV_CODEC_ID_VP6F   ;
-        case FLV_CODECID_VP6A  :
-            if(flv_codecid == FLV_CODECID_VP6A)
-                vcodec->codec_id = AV_CODEC_ID_VP6A;
-            if (read) {
-                if (vcodec->extradata_size != 1) {
-                    vcodec->extradata = av_malloc(1 + FF_INPUT_BUFFER_PADDING_SIZE);
-                    if (vcodec->extradata)
-                        vcodec->extradata_size = 1;
-                }
+    switch (flv_codecid) {
+    case FLV_CODECID_H263:
+        vcodec->codec_id = AV_CODEC_ID_FLV1;
+        break;
+    case FLV_CODECID_REALH263:
+        vcodec->codec_id = AV_CODEC_ID_H263;
+        break; // Really mean it this time
+    case FLV_CODECID_SCREEN:
+        vcodec->codec_id = AV_CODEC_ID_FLASHSV;
+        break;
+    case FLV_CODECID_SCREEN2:
+        vcodec->codec_id = AV_CODEC_ID_FLASHSV2;
+        break;
+    case FLV_CODECID_VP6:
+        vcodec->codec_id = AV_CODEC_ID_VP6F;
+    case FLV_CODECID_VP6A:
+        if (flv_codecid == FLV_CODECID_VP6A)
+            vcodec->codec_id = AV_CODEC_ID_VP6A;
+        if (read) {
+            if (vcodec->extradata_size != 1) {
+                vcodec->extradata = av_malloc(1 + FF_INPUT_BUFFER_PADDING_SIZE);
                 if (vcodec->extradata)
-                    vcodec->extradata[0] = avio_r8(s->pb);
-                else
-                    avio_skip(s->pb, 1);
+                    vcodec->extradata_size = 1;
             }
-            return 1; // 1 byte body size adjustment for flv_read_packet()
-        case FLV_CODECID_H264:
-            vcodec->codec_id = AV_CODEC_ID_H264;
-            return 3; // not 4, reading packet type will consume one byte
-        case FLV_CODECID_MPEG4:
-            vcodec->codec_id = AV_CODEC_ID_MPEG4;
-            return 3;
-        default:
-            av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid);
-            vcodec->codec_tag = flv_codecid;
+            if (vcodec->extradata)
+                vcodec->extradata[0] = avio_r8(s->pb);
+            else
+                avio_skip(s->pb, 1);
+        }
+        return 1;     // 1 byte body size adjustment for flv_read_packet()
+    case FLV_CODECID_H264:
+        vcodec->codec_id = AV_CODEC_ID_H264;
+        return 3;     // not 4, reading packet type will consume one byte
+    case FLV_CODECID_MPEG4:
+        vcodec->codec_id = AV_CODEC_ID_MPEG4;
+        return 3;
+    default:
+        av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid);
+        vcodec->codec_tag = flv_codecid;
     }
 
     return 0;
 }
 
-static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize) {
+static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize)
+{
     int length = avio_rb16(ioc);
-    if(length >= buffsize) {
+    if (length >= buffsize) {
         avio_skip(ioc, length);
         return -1;
     }
@@ -250,16 +285,18 @@
     return length;
 }
 
-static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream *vstream, int64_t max_pos) {
-    FLVContext *flv = s->priv_data;
+static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc,
+                                 AVStream *vstream, int64_t max_pos)
+{
+    FLVContext *flv       = s->priv_data;
     unsigned int timeslen = 0, fileposlen = 0, i;
     char str_val[256];
-    int64_t *times = NULL;
+    int64_t *times         = NULL;
     int64_t *filepositions = NULL;
-    int ret = AVERROR(ENOSYS);
-    int64_t initial_pos = avio_tell(ioc);
+    int ret                = AVERROR(ENOSYS);
+    int64_t initial_pos    = avio_tell(ioc);
 
-    if(vstream->nb_index_entries>0){
+    if (vstream->nb_index_entries>0) {
         av_log(s, AV_LOG_WARNING, "Skiping duplicate index\n");
         return 0;
     }
@@ -267,8 +304,9 @@
     if (s->flags & AVFMT_FLAG_IGNIDX)
         return 0;
 
-    while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
-        int64_t** current_array;
+    while (avio_tell(ioc) < max_pos - 2 &&
+           amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
+        int64_t **current_array;
         unsigned int arraylen;
 
         // Expect array object in context
@@ -276,16 +314,19 @@
             break;
 
         arraylen = avio_rb32(ioc);
-        if(arraylen>>28)
+        if (arraylen>>28)
             break;
 
-        if       (!strcmp(KEYFRAMES_TIMESTAMP_TAG , str_val) && !times){
-            current_array= &times;
-            timeslen= arraylen;
-        }else if (!strcmp(KEYFRAMES_BYTEOFFSET_TAG, str_val) && !filepositions){
-            current_array= &filepositions;
-            fileposlen= arraylen;
-        }else // unexpected metatag inside keyframes, will not use such metadata for indexing
+        if       (!strcmp(KEYFRAMES_TIMESTAMP_TAG , str_val) && !times) {
+            current_array = &times;
+            timeslen      = arraylen;
+        } else if (!strcmp(KEYFRAMES_BYTEOFFSET_TAG, str_val) &&
+                   !filepositions) {
+            current_array = &filepositions;
+            fileposlen    = arraylen;
+        } else
+            // unexpected metatag inside keyframes, will not use such
+            // metadata for indexing
             break;
 
         if (!(*current_array = av_mallocz(sizeof(**current_array) * arraylen))) {
@@ -308,12 +349,12 @@
 
     if (timeslen == fileposlen && fileposlen>1 && max_pos <= filepositions[0]) {
         for (i = 0; i < fileposlen; i++) {
-            av_add_index_entry(vstream, filepositions[i], times[i]*1000,
+            av_add_index_entry(vstream, filepositions[i], times[i] * 1000,
                                0, 0, AVINDEX_KEYFRAME);
             if (i < 2) {
                 flv->validate_index[i].pos = filepositions[i];
                 flv->validate_index[i].dts = times[i] * 1000;
-                flv->validate_count = i + 1;
+                flv->validate_count        = i + 1;
             }
         }
     } else {
@@ -328,7 +369,10 @@
     return ret;
 }
 
-static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vstream, const char *key, int64_t max_pos, int depth) {
+static int amf_parse_object(AVFormatContext *s, AVStream *astream,
+                            AVStream *vstream, const char *key,
+                            int64_t max_pos, int depth)
+{
     AVCodecContext *acodec, *vcodec;
     FLVContext *flv = s->priv_data;
     AVIOContext *ioc;
@@ -336,74 +380,85 @@
     char str_val[256];
     double num_val;
 
-    num_val = 0;
-    ioc = s->pb;
-
+    num_val  = 0;
+    ioc      = s->pb;
     amf_type = avio_r8(ioc);
 
-    switch(amf_type) {
-        case AMF_DATA_TYPE_NUMBER:
-            num_val = av_int2double(avio_rb64(ioc)); break;
-        case AMF_DATA_TYPE_BOOL:
-            num_val = avio_r8(ioc); break;
-        case AMF_DATA_TYPE_STRING:
-            if(amf_get_string(ioc, str_val, sizeof(str_val)) < 0)
-                return -1;
-            break;
-        case AMF_DATA_TYPE_OBJECT:
-            if ((vstream || astream) && ioc->seekable && key && !strcmp(KEYFRAMES_TAG, key) && depth == 1)
-                if (parse_keyframes_index(s, ioc, vstream ? vstream : astream,
-                                          max_pos) < 0)
-                    av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n");
-
-            while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
-                if (amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0)
-                    return -1; //if we couldn't skip, bomb out.
-            }
-            if(avio_r8(ioc) != AMF_END_OF_OBJECT)
-                return -1;
-            break;
-        case AMF_DATA_TYPE_NULL:
-        case AMF_DATA_TYPE_UNDEFINED:
-        case AMF_DATA_TYPE_UNSUPPORTED:
-            break; //these take up no additional space
-        case AMF_DATA_TYPE_MIXEDARRAY:
-            avio_skip(ioc, 4); //skip 32-bit max array index
-            while(avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
-                //this is the only case in which we would want a nested parse to not skip over the object
-                if(amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0)
-                    return -1;
-            }
-            if(avio_r8(ioc) != AMF_END_OF_OBJECT)
-                return -1;
-            break;
-        case AMF_DATA_TYPE_ARRAY: {
-            unsigned int arraylen, i;
-
-            arraylen = avio_rb32(ioc);
-            for(i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++) {
-                if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0)
-                    return -1; //if we couldn't skip, bomb out.
-            }
-        }
-            break;
-        case AMF_DATA_TYPE_DATE:
-            avio_skip(ioc, 8 + 2); //timestamp (double) and UTC offset (int16)
-            break;
-        default: //unsupported type, we couldn't skip
+    switch (amf_type) {
+    case AMF_DATA_TYPE_NUMBER:
+        num_val = av_int2double(avio_rb64(ioc));
+        break;
+    case AMF_DATA_TYPE_BOOL:
+        num_val = avio_r8(ioc);
+        break;
+    case AMF_DATA_TYPE_STRING:
+        if (amf_get_string(ioc, str_val, sizeof(str_val)) < 0)
             return -1;
+        break;
+    case AMF_DATA_TYPE_OBJECT:
+        if ((vstream || astream) && key &&
+            ioc->seekable &&
+            !strcmp(KEYFRAMES_TAG, key) && depth == 1)
+            if (parse_keyframes_index(s, ioc, vstream ? vstream : astream,
+                                      max_pos) < 0)
+                av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n");
+
+        while (avio_tell(ioc) < max_pos - 2 &&
+               amf_get_string(ioc, str_val, sizeof(str_val)) > 0)
+            if (amf_parse_object(s, astream, vstream, str_val, max_pos,
+                                 depth + 1) < 0)
+                return -1;     // if we couldn't skip, bomb out.
+        if (avio_r8(ioc) != AMF_END_OF_OBJECT)
+            return -1;
+        break;
+    case AMF_DATA_TYPE_NULL:
+    case AMF_DATA_TYPE_UNDEFINED:
+    case AMF_DATA_TYPE_UNSUPPORTED:
+        break;     // these take up no additional space
+    case AMF_DATA_TYPE_MIXEDARRAY:
+        avio_skip(ioc, 4);     // skip 32-bit max array index
+        while (avio_tell(ioc) < max_pos - 2 &&
+               amf_get_string(ioc, str_val, sizeof(str_val)) > 0)
+            // this is the only case in which we would want a nested
+            // parse to not skip over the object
+            if (amf_parse_object(s, astream, vstream, str_val, max_pos,
+                                 depth + 1) < 0)
+                return -1;
+        if (avio_r8(ioc) != AMF_END_OF_OBJECT)
+            return -1;
+        break;
+    case AMF_DATA_TYPE_ARRAY:
+    {
+        unsigned int arraylen, i;
+
+        arraylen = avio_rb32(ioc);
+        for (i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++)
+            if (amf_parse_object(s, NULL, NULL, NULL, max_pos,
+                                 depth + 1) < 0)
+                return -1;      // if we couldn't skip, bomb out.
+    }
+    break;
+    case AMF_DATA_TYPE_DATE:
+        avio_skip(ioc, 8 + 2);  // timestamp (double) and UTC offset (int16)
+        break;
+    default:                    // unsupported type, we couldn't skip
+        return -1;
     }
 
-    if(depth == 1 && key) { //only look for metadata values when we are not nested and key != NULL
+    // only look for metadata values when we are not nested and key != NULL
+    if (depth == 1 && key) {
         acodec = astream ? astream->codec : NULL;
         vcodec = vstream ? vstream->codec : NULL;
 
-        if (amf_type == AMF_DATA_TYPE_NUMBER || amf_type == AMF_DATA_TYPE_BOOL) {
+        if (amf_type == AMF_DATA_TYPE_NUMBER ||
+            amf_type == AMF_DATA_TYPE_BOOL) {
             if (!strcmp(key, "duration"))
                 s->duration = num_val * AV_TIME_BASE;
-            else if (!strcmp(key, "videodatarate") && vcodec && 0 <= (int)(num_val * 1024.0))
+            else if (!strcmp(key, "videodatarate") && vcodec &&
+                     0 <= (int)(num_val * 1024.0))
                 vcodec->bit_rate = num_val * 1024.0;
-            else if (!strcmp(key, "audiodatarate") && acodec && 0 <= (int)(num_val * 1024.0))
+            else if (!strcmp(key, "audiodatarate") && acodec &&
+                     0 <= (int)(num_val * 1024.0))
                 acodec->bit_rate = num_val * 1024.0;
             else if (!strcmp(key, "datastream")) {
                 AVStream *st = create_stream(s, AVMEDIA_TYPE_DATA);
@@ -413,25 +468,21 @@
             } else if (flv->trust_metadata) {
                 if (!strcmp(key, "videocodecid") && vcodec) {
                     flv_set_video_codec(s, vstream, num_val, 0);
-                } else
-                if (!strcmp(key, "audiocodecid") && acodec) {
+                } else if (!strcmp(key, "audiocodecid") && acodec) {
                     int id = ((int)num_val) << FLV_AUDIO_CODECID_OFFSET;
                     flv_set_audio_codec(s, astream, acodec, id);
-                } else
-                if (!strcmp(key, "audiosamplerate") && acodec) {
+                } else if (!strcmp(key, "audiosamplerate") && acodec) {
                     acodec->sample_rate = num_val;
                 } else if (!strcmp(key, "audiosamplesize") && acodec) {
                     acodec->bits_per_coded_sample = num_val;
                 } else if (!strcmp(key, "stereo") && acodec) {
-                    acodec->channels = num_val + 1;
+                    acodec->channels       = num_val + 1;
                     acodec->channel_layout = acodec->channels == 2 ?
                                              AV_CH_LAYOUT_STEREO :
                                              AV_CH_LAYOUT_MONO;
-                } else
-                if (!strcmp(key, "width") && vcodec) {
+                } else if (!strcmp(key, "width") && vcodec) {
                     vcodec->width = num_val;
-                } else
-                if (!strcmp(key, "height") && vcodec) {
+                } else if (!strcmp(key, "height") && vcodec) {
                     vcodec->height = num_val;
                 }
             }
@@ -456,10 +507,11 @@
             !strcmp(key, "audiocodecid"))
             return 0;
 
-        if(amf_type == AMF_DATA_TYPE_BOOL) {
-            av_strlcpy(str_val, num_val > 0 ? "true" : "false", sizeof(str_val));
+        if (amf_type == AMF_DATA_TYPE_BOOL) {
+            av_strlcpy(str_val, num_val > 0 ? "true" : "false",
+                       sizeof(str_val));
             av_dict_set(&s->metadata, key, str_val, 0);
-        } else if(amf_type == AMF_DATA_TYPE_NUMBER) {
+        } else if (amf_type == AMF_DATA_TYPE_NUMBER) {
             snprintf(str_val, sizeof(str_val), "%.f", num_val);
             av_dict_set(&s->metadata, key, str_val, 0);
         } else if (amf_type == AMF_DATA_TYPE_STRING)
@@ -469,17 +521,23 @@
     return 0;
 }
 
-static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) {
+static int flv_read_metabody(AVFormatContext *s, int64_t next_pos)
+{
     AMFDataType type;
-    AVStream *stream, *astream, *vstream, *dstream;
+    AVStream *stream, *astream, *vstream;
+    AVStream av_unused *dstream;
     AVIOContext *ioc;
     int i;
-    char buffer[11]; //only needs to hold the string "onMetaData". Anything longer is something we don't want.
+    // only needs to hold the string "onMetaData".
+    // Anything longer is something we don't want.
+    char buffer[11];
 
-    vstream = astream = dstream = NULL;
-    ioc = s->pb;
+    astream = NULL;
+    vstream = NULL;
+    dstream = NULL;
+    ioc     = s->pb;
 
-    //first object needs to be "onMetaData" string
+    // first object needs to be "onMetaData" string
     type = avio_r8(ioc);
     if (type != AMF_DATA_TYPE_STRING ||
         amf_get_string(ioc, buffer, sizeof(buffer)) < 0)
@@ -491,16 +549,20 @@
     if (strcmp(buffer, "onMetaData"))
         return -1;
 
-    //find the streams now so that amf_parse_object doesn't need to do the lookup every time it is called.
-    for(i = 0; i < s->nb_streams; i++) {
+    // find the streams now so that amf_parse_object doesn't need to do
+    // the lookup every time it is called.
+    for (i = 0; i < s->nb_streams; i++) {
         stream = s->streams[i];
-        if(stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) vstream = stream;
-        else if(stream->codec->codec_type == AVMEDIA_TYPE_AUDIO) astream = stream;
-        else if(stream->codec->codec_type == AVMEDIA_TYPE_DATA) dstream = stream;
+        if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO)
+            vstream = stream;
+        else if (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+            astream = stream;
+        else if (stream->codec->codec_type == AVMEDIA_TYPE_DATA)
+            dstream = stream;
     }
 
-    //parse the second object (we want a mixed array)
-    if(amf_parse_object(s, astream, vstream, buffer, next_pos, 0) < 0)
+    // parse the second object (we want a mixed array)
+    if (amf_parse_object(s, astream, vstream, buffer, next_pos, 0) < 0)
         return -1;
 
     return 0;
@@ -516,19 +578,19 @@
     /* FIXME: better fix needed */
     if (!flags) {
         flags = FLV_HEADER_FLAG_HASVIDEO | FLV_HEADER_FLAG_HASAUDIO;
-        av_log(s, AV_LOG_WARNING, "Broken FLV file, which says no streams present, this might fail\n");
+        av_log(s, AV_LOG_WARNING,
+               "Broken FLV file, which says no streams present, "
+               "this might fail\n");
     }
 
     s->ctx_flags |= AVFMTCTX_NOHEADER;
 
-    if(flags & FLV_HEADER_FLAG_HASVIDEO){
-        if(!create_stream(s, AVMEDIA_TYPE_VIDEO))
+    if (flags & FLV_HEADER_FLAG_HASVIDEO)
+        if (!create_stream(s, AVMEDIA_TYPE_VIDEO))
             return AVERROR(ENOMEM);
-    }
-    if(flags & FLV_HEADER_FLAG_HASAUDIO){
-        if(!create_stream(s, AVMEDIA_TYPE_AUDIO))
+    if (flags & FLV_HEADER_FLAG_HASAUDIO)
+        if (!create_stream(s, AVMEDIA_TYPE_AUDIO))
             return AVERROR(ENOMEM);
-    }
     // Flag doesn't indicate whether or not there is script-data present. Must
     // create that stream if it's encountered.
 
@@ -545,7 +607,7 @@
 {
     int i;
     FLVContext *flv = s->priv_data;
-    for(i=0; i<FLV_STREAM_TYPE_NB; i++)
+    for (i=0; i<FLV_STREAM_TYPE_NB; i++)
         av_freep(&flv->new_extradata[i]);
     return 0;
 }
@@ -565,7 +627,8 @@
                                int size)
 {
     av_free(flv->new_extradata[stream]);
-    flv->new_extradata[stream] = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
+    flv->new_extradata[stream] = av_mallocz(size +
+                                            FF_INPUT_BUFFER_PADDING_SIZE);
     if (!flv->new_extradata[stream])
         return AVERROR(ENOMEM);
     flv->new_extradata_size[stream] = size;
@@ -576,52 +639,48 @@
 static void clear_index_entries(AVFormatContext *s, int64_t pos)
 {
     int i, j, out;
-    av_log(s, AV_LOG_WARNING, "Found invalid index entries, clearing the index.\n");
+    av_log(s, AV_LOG_WARNING,
+           "Found invalid index entries, clearing the index.\n");
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
         /* Remove all index entries that point to >= pos */
         out = 0;
-        for (j = 0; j < st->nb_index_entries; j++) {
+        for (j = 0; j < st->nb_index_entries; j++)
             if (st->index_entries[j].pos < pos)
                 st->index_entries[out++] = st->index_entries[j];
-        }
         st->nb_index_entries = out;
     }
 }
 
-
 static int flv_data_packet(AVFormatContext *s, AVPacket *pkt,
                            int64_t dts, int64_t next)
 {
-    int ret = AVERROR_INVALIDDATA, i;
     AVIOContext *pb = s->pb;
-    AVStream *st = NULL;
+    AVStream *st    = NULL;
     AMFDataType type;
     char buf[20];
-    int length;
+    int ret, i, length;
 
     type = avio_r8(pb);
     if (type == AMF_DATA_TYPE_MIXEDARRAY)
         avio_seek(pb, 4, SEEK_CUR);
     else if (type != AMF_DATA_TYPE_OBJECT)
-        goto out;
+        return AVERROR_INVALIDDATA;
 
     amf_get_string(pb, buf, sizeof(buf));
     if (strcmp(buf, "type") || avio_r8(pb) != AMF_DATA_TYPE_STRING)
-        goto out;
+        return AVERROR_INVALIDDATA;
 
     amf_get_string(pb, buf, sizeof(buf));
-    //FIXME parse it as codec_id
+    // FIXME parse it as codec_id
     amf_get_string(pb, buf, sizeof(buf));
     if (strcmp(buf, "text") || avio_r8(pb) != AMF_DATA_TYPE_STRING)
-        goto out;
+        return AVERROR_INVALIDDATA;
 
     length = avio_rb16(pb);
-    ret = av_get_packet(s->pb, pkt, length);
-    if (ret < 0) {
-        ret = AVERROR(EIO);
-        goto out;
-    }
+    ret    = av_get_packet(s->pb, pkt, length);
+    if (ret < 0)
+        return AVERROR(EIO);
 
     for (i = 0; i < s->nb_streams; i++) {
         st = s->streams[i];
@@ -632,7 +691,7 @@
     if (i == s->nb_streams) {
         st = create_stream(s, AVMEDIA_TYPE_DATA);
         if (!st)
-            goto out;
+            return AVERROR_INVALIDDATA;
         st->codec->codec_id = AV_CODEC_ID_TEXT;
     }
 
@@ -641,10 +700,10 @@
     pkt->size = ret;
 
     pkt->stream_index = st->index;
-    pkt->flags |= AV_PKT_FLAG_KEY;
+    pkt->flags       |= AV_PKT_FLAG_KEY;
 
     avio_seek(s->pb, next + 4, SEEK_SET);
-out:
+
     return ret;
 }
 
@@ -653,131 +712,131 @@
     FLVContext *flv = s->priv_data;
     int ret, i, type, size, flags;
     int stream_type=-1;
-    int64_t next, pos;
+    int64_t next, pos, meta_pos;
     int64_t dts, pts = AV_NOPTS_VALUE;
     int av_uninit(channels);
     int av_uninit(sample_rate);
-    AVStream *st = NULL;
+    AVStream *st    = NULL;
 
- for(;;avio_skip(s->pb, 4)){ /* pkt size is repeated at end. skip it */
-    pos = avio_tell(s->pb);
-    type = avio_r8(s->pb);
-    size = avio_rb24(s->pb);
-    dts = avio_rb24(s->pb);
-    dts |= avio_r8(s->pb) << 24;
-    av_dlog(s, "type:%d, size:%d, dts:%"PRId64"\n", type, size, dts);
-    if (url_feof(s->pb))
-        return AVERROR_EOF;
-    avio_skip(s->pb, 3); /* stream id, always 0 */
-    flags = 0;
+    /* pkt size is repeated at end. skip it */
+    for (;; avio_skip(s->pb, 4)) {
+        pos  = avio_tell(s->pb);
+        type = avio_r8(s->pb);
+        size = avio_rb24(s->pb);
+        dts  = avio_rb24(s->pb);
+        dts |= avio_r8(s->pb) << 24;
+        av_dlog(s, "type:%d, size:%d, dts:%"PRId64"\n", type, size, dts);
+        if (url_feof(s->pb))
+            return AVERROR_EOF;
+        avio_skip(s->pb, 3); /* stream id, always 0 */
+        flags = 0;
 
-    if (flv->validate_next < flv->validate_count) {
-        int64_t validate_pos = flv->validate_index[flv->validate_next].pos;
-        if (pos == validate_pos) {
-            if (FFABS(dts - flv->validate_index[flv->validate_next].dts) <=
-                VALIDATE_INDEX_TS_THRESH) {
-                flv->validate_next++;
-            } else {
+        if (flv->validate_next < flv->validate_count) {
+            int64_t validate_pos = flv->validate_index[flv->validate_next].pos;
+            if (pos == validate_pos) {
+                if (FFABS(dts - flv->validate_index[flv->validate_next].dts) <=
+                    VALIDATE_INDEX_TS_THRESH) {
+                    flv->validate_next++;
+                } else {
+                    clear_index_entries(s, validate_pos);
+                    flv->validate_count = 0;
+                }
+            } else if (pos > validate_pos) {
                 clear_index_entries(s, validate_pos);
                 flv->validate_count = 0;
             }
-        } else if (pos > validate_pos) {
-            clear_index_entries(s, validate_pos);
-            flv->validate_count = 0;
         }
-    }
 
-    if(size == 0)
-        continue;
+        if (size == 0)
+            continue;
 
-    next= size + avio_tell(s->pb);
+        next = size + avio_tell(s->pb);
 
-    if (type == FLV_TAG_TYPE_AUDIO) {
-        stream_type=FLV_STREAM_TYPE_AUDIO;
-        flags = avio_r8(s->pb);
-        size--;
-    } else if (type == FLV_TAG_TYPE_VIDEO) {
-        stream_type=FLV_STREAM_TYPE_VIDEO;
-        flags = avio_r8(s->pb);
-        size--;
-        if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD)
-            goto skip;
-    } else if (type == FLV_TAG_TYPE_META) {
-        if (size > 13+1+4 && dts == 0) { // Header-type metadata stuff
-            flv_read_metabody(s, next);
-            goto skip;
-        } else if (dts != 0) { // Script-data "special" metadata frames - don't skip
+        if (type == FLV_TAG_TYPE_AUDIO) {
+            stream_type = FLV_STREAM_TYPE_AUDIO;
+            flags    = avio_r8(s->pb);
+            size--;
+        } else if (type == FLV_TAG_TYPE_VIDEO) {
+            stream_type = FLV_STREAM_TYPE_VIDEO;
+            flags    = avio_r8(s->pb);
+            size--;
+            if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD)
+                goto skip;
+        } else if (type == FLV_TAG_TYPE_META) {
             stream_type=FLV_STREAM_TYPE_DATA;
+            if (size > 13 + 1 + 4 && dts == 0) { // Header-type metadata stuff
+                meta_pos = avio_tell(s->pb);
+                if (flv_read_metabody(s, next) == 0) {
+                    goto skip;
+                }
+                avio_seek(s->pb, meta_pos, SEEK_SET);
+            }
         } else {
-            goto skip;
+            av_log(s, AV_LOG_DEBUG,
+                   "skipping flv packet: type %d, size %d, flags %d\n",
+                   type, size, flags);
+skip:
+            avio_seek(s->pb, next, SEEK_SET);
+            continue;
         }
-    } else {
-        av_log(s, AV_LOG_DEBUG, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags);
-    skip:
-        avio_seek(s->pb, next, SEEK_SET);
-        continue;
-    }
 
-    /* skip empty data packets */
-    if (!size)
-        continue;
+        /* skip empty data packets */
+        if (!size)
+            continue;
 
-    /* now find stream */
-    for(i=0;i<s->nb_streams;i++) {
-        st = s->streams[i];
-        if (stream_type == FLV_STREAM_TYPE_AUDIO) {
-            if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
-                (s->audio_codec_id || flv_same_audio_codec(st->codec, flags))) {
-                break;
+        /* now find stream */
+        for (i = 0; i < s->nb_streams; i++) {
+            st = s->streams[i];
+            if (stream_type == FLV_STREAM_TYPE_AUDIO) {
+                if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
+                    (s->audio_codec_id || flv_same_audio_codec(st->codec, flags)))
+                    break;
+            } else if (stream_type == FLV_STREAM_TYPE_VIDEO) {
+                if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
+                    (s->video_codec_id || flv_same_video_codec(st->codec, flags)))
+                    break;
+            } else if (stream_type == FLV_STREAM_TYPE_DATA) {
+                if (st->codec->codec_type == AVMEDIA_TYPE_DATA)
+                    break;
             }
-        } else
-        if (stream_type == FLV_STREAM_TYPE_VIDEO) {
-            if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
-                (s->video_codec_id || flv_same_video_codec(st->codec, flags))) {
-                break;
-            }
-        } else if (stream_type == FLV_STREAM_TYPE_DATA) {
-            if (st->codec->codec_type == AVMEDIA_TYPE_DATA)
-                break;
         }
-    }
-    if(i == s->nb_streams){
-        static const enum AVMediaType stream_types[] = {AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_DATA};
-        av_log(s, AV_LOG_WARNING, "Stream discovered after head already parsed\n");
-        st = create_stream(s,
-                           stream_types[stream_type]);
-        if (!st)
-            return AVERROR(ENOMEM);
+        if (i == s->nb_streams) {
+            static const enum AVMediaType stream_types[] = {AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_DATA};
+            av_log(s, AV_LOG_WARNING, "Stream discovered after head already parsed\n");
+            st = create_stream(s, stream_types[stream_type]);
+            if (!st)
+                return AVERROR(ENOMEM);
 
+        }
+        av_dlog(s, "%d %X %d \n", stream_type, flags, st->discard);
+        if (  (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || (stream_type == FLV_STREAM_TYPE_AUDIO)))
+            ||(st->discard >= AVDISCARD_BIDIR  &&  ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && (stream_type == FLV_STREAM_TYPE_VIDEO)))
+            || st->discard >= AVDISCARD_ALL
+        ) {
+            avio_seek(s->pb, next, SEEK_SET);
+            continue;
+        }
+        if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || stream_type == FLV_STREAM_TYPE_AUDIO)
+            av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME);
+        break;
     }
-    av_dlog(s, "%d %X %d \n", stream_type, flags, st->discard);
-    if(  (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || (stream_type == FLV_STREAM_TYPE_AUDIO)))
-       ||(st->discard >= AVDISCARD_BIDIR  &&  ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && (stream_type == FLV_STREAM_TYPE_VIDEO)))
-       || st->discard >= AVDISCARD_ALL
-       ){
-        avio_seek(s->pb, next, SEEK_SET);
-        continue;
-    }
-    if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || stream_type == FLV_STREAM_TYPE_AUDIO)
-        av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME);
-    break;
- }
 
-    // if not streamed and no duration from metadata then seek to end to find the duration from the timestamps
-    if(s->pb->seekable && (!s->duration || s->duration==AV_NOPTS_VALUE) && !flv->searched_for_end){
+    // if not streamed and no duration from metadata then seek to end to find
+    // the duration from the timestamps
+    if (s->pb->seekable && (!s->duration || s->duration == AV_NOPTS_VALUE) && !flv->searched_for_end) {
         int size;
-        const int64_t pos= avio_tell(s->pb);
-        int64_t fsize= avio_size(s->pb);
+        const int64_t pos   = avio_tell(s->pb);
+        int64_t fsize       = avio_size(s->pb);
 retry_duration:
-        avio_seek(s->pb, fsize-4, SEEK_SET);
-        size= avio_rb32(s->pb);
-        avio_seek(s->pb, fsize-3-size, SEEK_SET);
-        if(size == avio_rb24(s->pb) + 11){
+        avio_seek(s->pb, fsize - 4, SEEK_SET);
+        size = avio_rb32(s->pb);
+        avio_seek(s->pb, fsize - 3 - size, SEEK_SET);
+        if (size == avio_rb24(s->pb) + 11) {
             uint32_t ts = avio_rb24(s->pb);
-            ts |= avio_r8(s->pb) << 24;
-            if(ts)
+            ts         |= avio_r8(s->pb) << 24;
+            if (ts)
                 s->duration = ts * (int64_t)AV_TIME_BASE / 1000;
-            else if (fsize >= 8 && fsize - 8 >= size){
+            else if (fsize >= 8 && fsize - 8 >= size) {
                 fsize -= size+4;
                 goto retry_duration;
             }
@@ -787,29 +846,35 @@
         flv->searched_for_end = 1;
     }
 
-    if(stream_type == FLV_STREAM_TYPE_AUDIO){
+    if (stream_type == FLV_STREAM_TYPE_AUDIO) {
         int bits_per_coded_sample;
-        channels    = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1;
-        sample_rate = (44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >> FLV_AUDIO_SAMPLERATE_OFFSET) >> 3);
+        channels = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1;
+        sample_rate = 44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >>
+                                FLV_AUDIO_SAMPLERATE_OFFSET) >> 3;
         bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8;
-        if(!st->codec->channels || !st->codec->sample_rate || !st->codec->bits_per_coded_sample) {
+        if (!st->codec->channels || !st->codec->sample_rate ||
+            !st->codec->bits_per_coded_sample) {
             st->codec->channels              = channels;
-            st->codec->channel_layout        = channels == 1 ? AV_CH_LAYOUT_MONO :
-                                                               AV_CH_LAYOUT_STEREO;
+            st->codec->channel_layout        = channels == 1
+                                               ? AV_CH_LAYOUT_MONO
+                                               : AV_CH_LAYOUT_STEREO;
             st->codec->sample_rate           = sample_rate;
             st->codec->bits_per_coded_sample = bits_per_coded_sample;
         }
-        if(!st->codec->codec_id){
-            flv_set_audio_codec(s, st, st->codec, flags & FLV_AUDIO_CODECID_MASK);
-            flv->last_sample_rate = sample_rate = st->codec->sample_rate;
-            flv->last_channels    = channels    = st->codec->channels;
+        if (!st->codec->codec_id) {
+            flv_set_audio_codec(s, st, st->codec,
+                                flags & FLV_AUDIO_CODECID_MASK);
+            flv->last_sample_rate =
+            sample_rate           = st->codec->sample_rate;
+            flv->last_channels    =
+            channels              = st->codec->channels;
         } else {
             AVCodecContext ctx;
             ctx.sample_rate = sample_rate;
             flv_set_audio_codec(s, st, &ctx, flags & FLV_AUDIO_CODECID_MASK);
             sample_rate = ctx.sample_rate;
         }
-    } else if(stream_type == FLV_STREAM_TYPE_VIDEO) {
+    } else if (stream_type == FLV_STREAM_TYPE_VIDEO) {
         size -= flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK, 1);
     }
 
@@ -819,11 +884,13 @@
         int type = avio_r8(s->pb);
         size--;
         if (st->codec->codec_id == AV_CODEC_ID_H264 || st->codec->codec_id == AV_CODEC_ID_MPEG4) {
-            int32_t cts = (avio_rb24(s->pb)+0xff800000)^0xff800000; // sign extension
+            // sign extension
+            int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000;
             pts = dts + cts;
             if (cts < 0) { // dts are wrong
                 flv->wrong_dts = 1;
-                av_log(s, AV_LOG_WARNING, "negative cts, previous timestamps might be wrong\n");
+                av_log(s, AV_LOG_WARNING,
+                       "negative cts, previous timestamps might be wrong\n");
             }
             if (flv->wrong_dts)
                 dts = AV_NOPTS_VALUE;
@@ -841,7 +908,7 @@
                 MPEG4AudioConfig cfg;
                 if (avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata,
                                              st->codec->extradata_size * 8, 1) >= 0) {
-                st->codec->channels = cfg.channels;
+                st->codec->channels       = cfg.channels;
                 st->codec->channel_layout = 0;
                 if (cfg.ext_sample_rate)
                     st->codec->sample_rate = cfg.ext_sample_rate;
@@ -863,11 +930,11 @@
         goto leave;
     }
 
-    ret= av_get_packet(s->pb, pkt, size);
+    ret = av_get_packet(s->pb, pkt, size);
     if (ret < 0)
         return ret;
-    pkt->dts = dts;
-    pkt->pts = pts == AV_NOPTS_VALUE ? dts : pts;
+    pkt->dts          = dts;
+    pkt->pts          = pts == AV_NOPTS_VALUE ? dts : pts;
     pkt->stream_index = st->index;
     if (flv->new_extradata[stream_type]) {
         uint8_t *side = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
@@ -879,8 +946,9 @@
             flv->new_extradata_size[stream_type] = 0;
         }
     }
-    if (stream_type == FLV_STREAM_TYPE_AUDIO && (sample_rate != flv->last_sample_rate ||
-                     channels != flv->last_channels)) {
+    if (stream_type == FLV_STREAM_TYPE_AUDIO &&
+                    (sample_rate != flv->last_sample_rate ||
+                     channels    != flv->last_channels)) {
         flv->last_sample_rate = sample_rate;
         flv->last_channels    = channels;
         ff_add_param_change(pkt, channels, 0, sample_rate, 0, 0);
@@ -897,7 +965,7 @@
 }
 
 static int flv_read_seek(AVFormatContext *s, int stream_index,
-    int64_t ts, int flags)
+                         int64_t ts, int flags)
 {
     FLVContext *flv = s->priv_data;
     flv->validate_count = 0;
@@ -907,11 +975,11 @@
 #define OFFSET(x) offsetof(FLVContext, x)
 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
 static const AVOption options[] = {
-    { "flv_metadata", "Allocate streams according the onMetaData array",      OFFSET(trust_metadata), AV_OPT_TYPE_INT,    { .i64 = 0 }, 0, 1, VD},
+    { "flv_metadata", "Allocate streams according the onMetaData array", OFFSET(trust_metadata), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VD },
     { NULL }
 };
 
-static const AVClass class = {
+static const AVClass flv_class = {
     .class_name = "flvdec",
     .item_name  = av_default_item_name,
     .option     = options,
@@ -928,5 +996,5 @@
     .read_seek      = flv_read_seek,
     .read_close     = flv_read_close,
     .extensions     = "flv",
-    .priv_class     = &class,
+    .priv_class     = &flv_class,
 };
diff --git a/libavformat/format.c b/libavformat/format.c
new file mode 100644
index 0000000..ac9100b
--- /dev/null
+++ b/libavformat/format.c
@@ -0,0 +1,184 @@
+/*
+ * Format register and lookup
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ *
+ * 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
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "libavutil/atomic.h"
+#include "libavutil/avstring.h"
+
+/**
+ * @file
+ * Format register and lookup
+ */
+/** head of registered input format linked list */
+static AVInputFormat *first_iformat = NULL;
+/** head of registered output format linked list */
+static AVOutputFormat *first_oformat = NULL;
+
+AVInputFormat *av_iformat_next(AVInputFormat *f)
+{
+    if (f)
+        return f->next;
+    else
+        return first_iformat;
+}
+
+AVOutputFormat *av_oformat_next(AVOutputFormat *f)
+{
+    if (f)
+        return f->next;
+    else
+        return first_oformat;
+}
+
+void av_register_input_format(AVInputFormat *format)
+{
+    AVInputFormat **p = &first_iformat;
+
+    format->next = NULL;
+    while(avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format))
+        p = &(*p)->next;
+}
+
+void av_register_output_format(AVOutputFormat *format)
+{
+    AVOutputFormat **p = &first_oformat;
+
+    format->next = NULL;
+    while(avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format))
+        p = &(*p)->next;
+}
+
+int av_match_ext(const char *filename, const char *extensions)
+{
+    const char *ext, *p;
+    char ext1[32], *q;
+
+    if (!filename)
+        return 0;
+
+    ext = strrchr(filename, '.');
+    if (ext) {
+        ext++;
+        p = extensions;
+        for (;;) {
+            q = ext1;
+            while (*p != '\0' && *p != ','  && q - ext1 < sizeof(ext1) - 1)
+                *q++ = *p++;
+            *q = '\0';
+            if (!av_strcasecmp(ext1, ext))
+                return 1;
+            if (*p == '\0')
+                break;
+            p++;
+        }
+    }
+    return 0;
+}
+
+static int match_format(const char *name, const char *names)
+{
+    const char *p;
+    int len, namelen;
+
+    if (!name || !names)
+        return 0;
+
+    namelen = strlen(name);
+    while ((p = strchr(names, ','))) {
+        len = FFMAX(p - names, namelen);
+        if (!av_strncasecmp(name, names, len))
+            return 1;
+        names = p + 1;
+    }
+    return !av_strcasecmp(name, names);
+}
+
+AVOutputFormat *av_guess_format(const char *short_name, const char *filename,
+                                const char *mime_type)
+{
+    AVOutputFormat *fmt = NULL, *fmt_found;
+    int score_max, score;
+
+    /* specific test for image sequences */
+#if CONFIG_IMAGE2_MUXER
+    if (!short_name && filename &&
+        av_filename_number_test(filename) &&
+        ff_guess_image2_codec(filename) != AV_CODEC_ID_NONE) {
+        return av_guess_format("image2", NULL, NULL);
+    }
+#endif
+    /* Find the proper file type. */
+    fmt_found = NULL;
+    score_max = 0;
+    while ((fmt = av_oformat_next(fmt))) {
+        score = 0;
+        if (fmt->name && short_name && match_format(short_name, fmt->name))
+            score += 100;
+        if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
+            score += 10;
+        if (filename && fmt->extensions &&
+            av_match_ext(filename, fmt->extensions)) {
+            score += 5;
+        }
+        if (score > score_max) {
+            score_max = score;
+            fmt_found = fmt;
+        }
+    }
+    return fmt_found;
+}
+
+enum AVCodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name,
+                              const char *filename, const char *mime_type,
+                              enum AVMediaType type)
+{
+    if (!strcmp(fmt->name, "segment") || !strcmp(fmt->name, "ssegment")) {
+        fmt = av_guess_format(NULL, filename, NULL);
+    }
+
+    if (type == AVMEDIA_TYPE_VIDEO) {
+        enum AVCodecID codec_id = AV_CODEC_ID_NONE;
+
+#if CONFIG_IMAGE2_MUXER
+        if (!strcmp(fmt->name, "image2") || !strcmp(fmt->name, "image2pipe")) {
+            codec_id = ff_guess_image2_codec(filename);
+        }
+#endif
+        if (codec_id == AV_CODEC_ID_NONE)
+            codec_id = fmt->video_codec;
+        return codec_id;
+    } else if (type == AVMEDIA_TYPE_AUDIO)
+        return fmt->audio_codec;
+    else if (type == AVMEDIA_TYPE_SUBTITLE)
+        return fmt->subtitle_codec;
+    else
+        return AV_CODEC_ID_NONE;
+}
+
+AVInputFormat *av_find_input_format(const char *short_name)
+{
+    AVInputFormat *fmt = NULL;
+    while ((fmt = av_iformat_next(fmt)))
+        if (match_format(short_name, fmt->name))
+            return fmt;
+    return NULL;
+}
diff --git a/libavformat/framecrcenc.c b/libavformat/framecrcenc.c
index df0ae79..dbe49b5 100644
--- a/libavformat/framecrcenc.c
+++ b/libavformat/framecrcenc.c
@@ -34,13 +34,22 @@
     if (pkt->flags != AV_PKT_FLAG_KEY)
         av_strlcatf(buf, sizeof(buf), ", F=0x%0X", pkt->flags);
     if (pkt->side_data_elems) {
-        int i;
+        int i, j;
         av_strlcatf(buf, sizeof(buf), ", S=%d", pkt->side_data_elems);
 
         for (i=0; i<pkt->side_data_elems; i++) {
-            uint32_t side_data_crc = av_adler32_update(0,
-                                                    pkt->side_data[i].data,
-                                                    pkt->side_data[i].size);
+            uint32_t side_data_crc = 0;
+            if (HAVE_BIGENDIAN && AV_PKT_DATA_PALETTE == pkt->side_data[i].type) {
+                for (j=0; j<pkt->side_data[i].size; j++) {
+                    side_data_crc = av_adler32_update(side_data_crc,
+                                                      pkt->side_data[i].data + (j^3),
+                                                      1);
+                }
+            } else {
+                side_data_crc = av_adler32_update(0,
+                                                  pkt->side_data[i].data,
+                                                  pkt->side_data[i].size);
+            }
             av_strlcatf(buf, sizeof(buf), ", %8d, 0x%08x", pkt->side_data[i].size, side_data_crc);
         }
     }
@@ -56,5 +65,6 @@
     .video_codec       = AV_CODEC_ID_RAWVIDEO,
     .write_header      = ff_framehash_write_header,
     .write_packet      = framecrc_write_packet,
-    .flags             = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
+    .flags             = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT |
+                         AVFMT_TS_NEGATIVE,
 };
diff --git a/libavformat/ftp.c b/libavformat/ftp.c
new file mode 100644
index 0000000..1a47081
--- /dev/null
+++ b/libavformat/ftp.c
@@ -0,0 +1,721 @@
+/*
+ * Copyright (c) 2013 Lukasz Marek <lukasz.m.luki@gmail.com>
+ *
+ * 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
+ */
+
+#include "libavutil/avstring.h"
+#include "avformat.h"
+#include "internal.h"
+#include "url.h"
+#include "libavutil/opt.h"
+#include "libavutil/bprint.h"
+
+#define CONTROL_BUFFER_SIZE 1024
+#define CREDENTIALS_BUFFER_SIZE 128
+
+typedef enum {
+    UNKNOWN,
+    READY,
+    DOWNLOADING,
+    UPLOADING,
+    DISCONNECTED
+} FTPState;
+
+typedef struct {
+    const AVClass *class;
+    URLContext *conn_control;                    /**< Control connection */
+    URLContext *conn_data;                       /**< Data connection, NULL when not connected */
+    uint8_t control_buffer[CONTROL_BUFFER_SIZE]; /**< Control connection buffer */
+    uint8_t *control_buf_ptr, *control_buf_end;
+    int server_data_port;                        /**< Data connection port opened by server, -1 on error. */
+    int server_control_port;                     /**< Control connection port, default is 21 */
+    char hostname[512];                          /**< Server address. */
+    char credencials[CREDENTIALS_BUFFER_SIZE];   /**< Authentication data */
+    char path[MAX_URL_SIZE];                     /**< Path to resource on server. */
+    int64_t filesize;                            /**< Size of file on server, -1 on error. */
+    int64_t position;                            /**< Current position, calculated. */
+    int rw_timeout;                              /**< Network timeout. */
+    const char *anonymous_password;              /**< Password to be used for anonymous user. An email should be used. */
+    int write_seekable;                          /**< Control seekability, 0 = disable, 1 = enable. */
+    FTPState state;                              /**< State of data connection */
+} FTPContext;
+
+#define OFFSET(x) offsetof(FTPContext, x)
+#define D AV_OPT_FLAG_DECODING_PARAM
+#define E AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    {"timeout", "set timeout of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D|E },
+    {"ftp-write-seekable", "control seekability of connection during encoding", OFFSET(write_seekable), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, E },
+    {"ftp-anonymous-password", "password for anonymous login. E-mail address should be used.", OFFSET(anonymous_password), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D|E },
+    {NULL}
+};
+
+static const AVClass ftp_context_class = {
+    .class_name     = "ftp",
+    .item_name      = av_default_item_name,
+    .option         = options,
+    .version        = LIBAVUTIL_VERSION_INT,
+};
+
+static int ftp_getc(FTPContext *s)
+{
+    int len;
+    if (s->control_buf_ptr >= s->control_buf_end) {
+        len = ffurl_read(s->conn_control, s->control_buffer, CONTROL_BUFFER_SIZE);
+        if (len < 0) {
+            return len;
+        } else if (!len) {
+            return -1;
+        } else {
+            s->control_buf_ptr = s->control_buffer;
+            s->control_buf_end = s->control_buffer + len;
+        }
+    }
+    return *s->control_buf_ptr++;
+}
+
+static int ftp_get_line(FTPContext *s, char *line, int line_size)
+{
+    int ch;
+    char *q = line;
+
+    for (;;) {
+        ch = ftp_getc(s);
+        if (ch < 0) {
+            return ch;
+        }
+        if (ch == '\n') {
+            /* process line */
+            if (q > line && q[-1] == '\r')
+                q--;
+            *q = '\0';
+            return 0;
+        } else {
+            if ((q - line) < line_size - 1)
+                *q++ = ch;
+        }
+    }
+}
+
+/*
+ * This routine returns ftp server response code.
+ * Server may send more than one response for a certain command.
+ * First expected code is returned.
+ */
+static int ftp_status(FTPContext *s, char **line, const int response_codes[])
+{
+    int err, i, dash = 0, result = 0, code_found = 0;
+    char buf[CONTROL_BUFFER_SIZE];
+    AVBPrint line_buffer;
+
+    if (line)
+        av_bprint_init(&line_buffer, 0, AV_BPRINT_SIZE_AUTOMATIC);
+
+    while (!code_found || dash) {
+        if ((err = ftp_get_line(s, buf, sizeof(buf))) < 0) {
+            av_bprint_finalize(&line_buffer, NULL);
+            return err;
+        }
+
+        av_log(s, AV_LOG_DEBUG, "%s\n", buf);
+
+        if (strlen(buf) < 4)
+            continue;
+
+        err = 0;
+        for (i = 0; i < 3; ++i) {
+            if (buf[i] < '0' || buf[i] > '9')
+                continue;
+            err *= 10;
+            err += buf[i] - '0';
+        }
+        dash = !!(buf[3] == '-');
+
+        for (i = 0; response_codes[i]; ++i) {
+            if (err == response_codes[i]) {
+                if (line)
+                    av_bprintf(&line_buffer, "%s", buf);
+                code_found = 1;
+                result = err;
+                break;
+            }
+        }
+    }
+
+    if (line)
+        av_bprint_finalize(&line_buffer, line);
+    return result;
+}
+
+static int ftp_send_command(FTPContext *s, const char *command,
+                            const int response_codes[], char **response)
+{
+    int err;
+
+    if ((err = ffurl_write(s->conn_control, command, strlen(command))) < 0)
+        return err;
+    if (!err)
+        return -1;
+
+    /* return status */
+    if (response_codes) {
+        return ftp_status(s, response, response_codes);
+    }
+    return 0;
+}
+
+static void ftp_close_data_connection(FTPContext *s)
+{
+    ffurl_closep(&s->conn_data);
+    s->position = 0;
+    s->state = DISCONNECTED;
+}
+
+static void ftp_close_both_connections(FTPContext *s)
+{
+    ffurl_closep(&s->conn_control);
+    ftp_close_data_connection(s);
+}
+
+static int ftp_auth(FTPContext *s)
+{
+    const char *user = NULL, *pass = NULL;
+    char *end = NULL, buf[CONTROL_BUFFER_SIZE], credencials[CREDENTIALS_BUFFER_SIZE];
+    int err;
+    const int user_codes[] = {331, 230, 500, 530, 0}; /* 500, 530 are incorrect codes */
+    const int pass_codes[] = {230, 503, 530, 0}; /* 503, 530 are incorrect codes */
+
+    /* Authentication may be repeated, original string has to be saved */
+    av_strlcpy(credencials, s->credencials, sizeof(credencials));
+
+    user = av_strtok(credencials, ":", &end);
+    pass = av_strtok(end, ":", &end);
+
+    if (!user) {
+        user = "anonymous";
+        pass = s->anonymous_password ? s->anonymous_password : "nopassword";
+    }
+
+    snprintf(buf, sizeof(buf), "USER %s\r\n", user);
+    err = ftp_send_command(s, buf, user_codes, NULL);
+    if (err == 331) {
+        if (pass) {
+            snprintf(buf, sizeof(buf), "PASS %s\r\n", pass);
+            err = ftp_send_command(s, buf, pass_codes, NULL);
+        } else
+            return AVERROR(EACCES);
+    }
+    if (err != 230)
+        return AVERROR(EACCES);
+
+    return 0;
+}
+
+static int ftp_passive_mode(FTPContext *s)
+{
+    char *res = NULL, *start = NULL, *end = NULL;
+    int i;
+    const char *command = "PASV\r\n";
+    const int pasv_codes[] = {227, 501, 0}; /* 501 is incorrect code */
+
+    if (ftp_send_command(s, command, pasv_codes, &res) != 227 || !res)
+        goto fail;
+
+    for (i = 0; res[i]; ++i) {
+        if (res[i] == '(') {
+            start = res + i + 1;
+        } else if (res[i] == ')') {
+            end = res + i;
+            break;
+        }
+    }
+    if (!start || !end)
+        goto fail;
+
+    *end  = '\0';
+    /* skip ip */
+    if (!av_strtok(start, ",", &end)) goto fail;
+    if (!av_strtok(end, ",", &end)) goto fail;
+    if (!av_strtok(end, ",", &end)) goto fail;
+    if (!av_strtok(end, ",", &end)) goto fail;
+
+    /* parse port number */
+    start = av_strtok(end, ",", &end);
+    if (!start) goto fail;
+    s->server_data_port = atoi(start) * 256;
+    start = av_strtok(end, ",", &end);
+    if (!start) goto fail;
+    s->server_data_port += atoi(start);
+    av_dlog(s, "Server data port: %d\n", s->server_data_port);
+
+    av_free(res);
+    return 0;
+
+  fail:
+    av_free(res);
+    s->server_data_port = -1;
+    return AVERROR(EIO);
+}
+
+static int ftp_current_dir(FTPContext *s)
+{
+    char *res = NULL, *start = NULL, *end = NULL;
+    int i;
+    const char *command = "PWD\r\n";
+    const int pwd_codes[] = {257, 0};
+
+    if (ftp_send_command(s, command, pwd_codes, &res) != 257 || !res)
+        goto fail;
+
+    for (i = 0; res[i]; ++i) {
+        if (res[i] == '"') {
+            if (!start) {
+                start = res + i + 1;
+                continue;
+            }
+            end = res + i;
+            break;
+        }
+    }
+
+    if (!end)
+        goto fail;
+
+    if (end > res && end[-1] == '/') {
+        end[-1] = '\0';
+    } else
+        *end = '\0';
+    av_strlcpy(s->path, start, sizeof(s->path));
+
+    av_free(res);
+    return 0;
+
+  fail:
+    av_free(res);
+    return AVERROR(EIO);
+}
+
+static int ftp_file_size(FTPContext *s)
+{
+    char command[CONTROL_BUFFER_SIZE];
+    char *res = NULL;
+    const int size_codes[] = {213, 501, 550, 0}; /* 501, 550 are incorrect codes */
+
+    snprintf(command, sizeof(command), "SIZE %s\r\n", s->path);
+    if (ftp_send_command(s, command, size_codes, &res) == 213 && res) {
+        s->filesize = strtoll(&res[4], NULL, 10);
+    } else {
+        s->filesize = -1;
+        av_free(res);
+        return AVERROR(EIO);
+    }
+
+    av_free(res);
+    return 0;
+}
+
+static int ftp_retrieve(FTPContext *s)
+{
+    char command[CONTROL_BUFFER_SIZE];
+    const int retr_codes[] = {150, 550, 554, 0}; /* 550, 554 are incorrect codes */
+
+    snprintf(command, sizeof(command), "RETR %s\r\n", s->path);
+    if (ftp_send_command(s, command, retr_codes, NULL) != 150)
+        return AVERROR(EIO);
+
+    s->state = DOWNLOADING;
+
+    return 0;
+}
+
+static int ftp_store(FTPContext *s)
+{
+    char command[CONTROL_BUFFER_SIZE];
+    const int stor_codes[] = {150, 0};
+
+    snprintf(command, sizeof(command), "STOR %s\r\n", s->path);
+    if (ftp_send_command(s, command, stor_codes, NULL) != 150)
+        return AVERROR(EIO);
+
+    s->state = UPLOADING;
+
+    return 0;
+}
+
+static int ftp_type(FTPContext *s)
+{
+    const char *command = "TYPE I\r\n";
+    const int type_codes[] = {200, 500, 504, 0}; /* 500, 504 are incorrect codes */
+
+    if (ftp_send_command(s, command, type_codes, NULL) != 200)
+        return AVERROR(EIO);
+
+    return 0;
+}
+
+static int ftp_restart(FTPContext *s, int64_t pos)
+{
+    char command[CONTROL_BUFFER_SIZE];
+    const int rest_codes[] = {350, 500, 501, 0}; /* 500, 501 are incorrect codes */
+
+    snprintf(command, sizeof(command), "REST %"PRId64"\r\n", pos);
+    if (ftp_send_command(s, command, rest_codes, NULL) != 350)
+        return AVERROR(EIO);
+
+    return 0;
+}
+
+static int ftp_connect_control_connection(URLContext *h)
+{
+    char buf[CONTROL_BUFFER_SIZE], opts_format[20], *response = NULL;
+    int err;
+    AVDictionary *opts = NULL;
+    FTPContext *s = h->priv_data;
+    const int connect_codes[] = {220, 0};
+
+    if (!s->conn_control) {
+        ff_url_join(buf, sizeof(buf), "tcp", NULL,
+                    s->hostname, s->server_control_port, NULL);
+        if (s->rw_timeout != -1) {
+            snprintf(opts_format, sizeof(opts_format), "%d", s->rw_timeout);
+            av_dict_set(&opts, "timeout", opts_format, 0);
+        } /* if option is not given, don't pass it and let tcp use its own default */
+        err = ffurl_open(&s->conn_control, buf, AVIO_FLAG_READ_WRITE,
+                         &h->interrupt_callback, &opts);
+        av_dict_free(&opts);
+        if (err < 0) {
+            av_log(h, AV_LOG_ERROR, "Cannot open control connection\n");
+            return err;
+        }
+
+        /* check if server is ready */
+        if (ftp_status(s, ((h->flags & AVIO_FLAG_WRITE) ? &response : NULL), connect_codes) != 220) {
+            av_log(h, AV_LOG_ERROR, "FTP server not ready for new users\n");
+            return AVERROR(EACCES);
+        }
+
+        if ((h->flags & AVIO_FLAG_WRITE) && av_stristr(response, "pure-ftpd")) {
+            av_log(h, AV_LOG_WARNING, "Pure-FTPd server is used as an output protocol. It is known issue this implementation may produce incorrect content and it cannot be fixed at this moment.");
+        }
+        av_free(response);
+
+        if ((err = ftp_auth(s)) < 0) {
+            av_log(h, AV_LOG_ERROR, "FTP authentication failed\n");
+            return err;
+        }
+
+        if ((err = ftp_type(s)) < 0) {
+            av_dlog(h, "Set content type failed\n");
+            return err;
+        }
+    }
+    return 0;
+}
+
+static int ftp_connect_data_connection(URLContext *h)
+{
+    int err;
+    char buf[CONTROL_BUFFER_SIZE], opts_format[20];
+    AVDictionary *opts = NULL;
+    FTPContext *s = h->priv_data;
+
+    if (!s->conn_data) {
+        /* Enter passive mode */
+        if ((err = ftp_passive_mode(s)) < 0) {
+            av_dlog(h, "Set passive mode failed\n");
+            return err;
+        }
+        /* Open data connection */
+        ff_url_join(buf, sizeof(buf), "tcp", NULL, s->hostname, s->server_data_port, NULL);
+        if (s->rw_timeout != -1) {
+            snprintf(opts_format, sizeof(opts_format), "%d", s->rw_timeout);
+            av_dict_set(&opts, "timeout", opts_format, 0);
+        } /* if option is not given, don't pass it and let tcp use its own default */
+        err = ffurl_open(&s->conn_data, buf, h->flags,
+                         &h->interrupt_callback, &opts);
+        av_dict_free(&opts);
+        if (err < 0)
+            return err;
+
+        if (s->position)
+            if ((err = ftp_restart(s, s->position)) < 0)
+                return err;
+    }
+    s->state = READY;
+    return 0;
+}
+
+static int ftp_abort(URLContext *h)
+{
+    const char *command = "ABOR\r\n";
+    int err;
+    const int abor_codes[] = {225, 226, 0};
+    FTPContext *s = h->priv_data;
+
+    /* According to RCF 959:
+       "ABOR command tells the server to abort the previous FTP
+       service command and any associated transfer of data."
+
+       There are FTP server implementations that don't response
+       to any commands during data transfer in passive mode (including ABOR).
+
+       This implementation closes data connection by force.
+    */
+
+    if (ftp_send_command(s, command, NULL, NULL) < 0) {
+        ftp_close_both_connections(s);
+        if ((err = ftp_connect_control_connection(h)) < 0) {
+            av_log(h, AV_LOG_ERROR, "Reconnect failed.\n");
+            return err;
+        }
+    } else {
+        ftp_close_data_connection(s);
+    }
+
+    if (ftp_status(s, NULL, abor_codes) < 225) {
+        /* wu-ftpd also closes control connection after data connection closing */
+        ffurl_closep(&s->conn_control);
+        if ((err = ftp_connect_control_connection(h)) < 0) {
+            av_log(h, AV_LOG_ERROR, "Reconnect failed.\n");
+            return err;
+        }
+    }
+
+    return 0;
+}
+
+static int ftp_open(URLContext *h, const char *url, int flags)
+{
+    char proto[10], path[MAX_URL_SIZE];
+    int err;
+    FTPContext *s = h->priv_data;
+
+    av_dlog(h, "ftp protocol open\n");
+
+    s->state = DISCONNECTED;
+    s->filesize = -1;
+    s->position = 0;
+
+    av_url_split(proto, sizeof(proto),
+                 s->credencials, sizeof(s->credencials),
+                 s->hostname, sizeof(s->hostname),
+                 &s->server_control_port,
+                 path, sizeof(path),
+                 url);
+
+    if (s->server_control_port < 0 || s->server_control_port > 65535)
+        s->server_control_port = 21;
+
+    if ((err = ftp_connect_control_connection(h)) < 0)
+        goto fail;
+
+    if ((err = ftp_current_dir(s)) < 0)
+        goto fail;
+    av_strlcat(s->path, path, sizeof(s->path));
+
+    if (ftp_restart(s, 0) < 0) {
+        h->is_streamed = 1;
+    } else {
+        if (ftp_file_size(s) < 0 && flags & AVIO_FLAG_READ)
+            h->is_streamed = 1;
+        if (s->write_seekable != 1 && flags & AVIO_FLAG_WRITE)
+            h->is_streamed = 1;
+    }
+
+    return 0;
+
+  fail:
+    av_log(h, AV_LOG_ERROR, "FTP open failed\n");
+    ffurl_closep(&s->conn_control);
+    ffurl_closep(&s->conn_data);
+    return err;
+}
+
+static int64_t ftp_seek(URLContext *h, int64_t pos, int whence)
+{
+    FTPContext *s = h->priv_data;
+    int err;
+    int64_t new_pos, fake_pos;
+
+    av_dlog(h, "ftp protocol seek %"PRId64" %d\n", pos, whence);
+
+    switch(whence) {
+    case AVSEEK_SIZE:
+        return s->filesize;
+    case SEEK_SET:
+        new_pos = pos;
+        break;
+    case SEEK_CUR:
+        new_pos = s->position + pos;
+        break;
+    case SEEK_END:
+        if (s->filesize < 0)
+            return AVERROR(EIO);
+        new_pos = s->filesize + pos;
+        break;
+    default:
+        return AVERROR(EINVAL);
+    }
+
+    if  (h->is_streamed)
+        return AVERROR(EIO);
+
+    /* XXX: Simulate behaviour of lseek in file protocol, which could be treated as a reference */
+    new_pos = FFMAX(0, new_pos);
+    fake_pos = s->filesize != -1 ? FFMIN(new_pos, s->filesize) : new_pos;
+
+    if (fake_pos != s->position) {
+        if ((err = ftp_abort(h)) < 0)
+            return err;
+        s->position = fake_pos;
+    }
+    return new_pos;
+}
+
+static int ftp_read(URLContext *h, unsigned char *buf, int size)
+{
+    FTPContext *s = h->priv_data;
+    int read, err, retry_done = 0;
+
+    av_dlog(h, "ftp protocol read %d bytes\n", size);
+  retry:
+    if (s->state == DISCONNECTED) {
+        /* optimization */
+        if (s->position >= s->filesize)
+            return 0;
+        if ((err = ftp_connect_data_connection(h)) < 0)
+            return err;
+    }
+    if (s->state == READY) {
+        if (s->position >= s->filesize)
+            return 0;
+        if ((err = ftp_retrieve(s)) < 0)
+            return err;
+    }
+    if (s->conn_data && s->state == DOWNLOADING) {
+        read = ffurl_read(s->conn_data, buf, size);
+        if (read >= 0) {
+            s->position += read;
+            if (s->position >= s->filesize) {
+                /* server will terminate, but keep current position to avoid madness */
+                /* save position to restart from it */
+                int64_t pos = s->position;
+                if (ftp_abort(h) < 0) {
+                    s->position = pos;
+                    return AVERROR(EIO);
+                }
+                s->position = pos;
+            }
+        }
+        if (read <= 0 && s->position < s->filesize && !h->is_streamed) {
+            /* Server closed connection. Probably due to inactivity */
+            int64_t pos = s->position;
+            av_log(h, AV_LOG_INFO, "Reconnect to FTP server.\n");
+            if ((err = ftp_abort(h)) < 0)
+                return err;
+            if ((err = ftp_seek(h, pos, SEEK_SET)) < 0) {
+                av_log(h, AV_LOG_ERROR, "Position cannot be restored.\n");
+                return err;
+            }
+            if (!retry_done) {
+                retry_done = 1;
+                goto retry;
+            }
+        }
+        return read;
+    }
+
+    av_log(h, AV_LOG_DEBUG, "FTP read failed\n");
+    return AVERROR(EIO);
+}
+
+static int ftp_write(URLContext *h, const unsigned char *buf, int size)
+{
+    int err;
+    FTPContext *s = h->priv_data;
+    int written;
+
+    av_dlog(h, "ftp protocol write %d bytes\n", size);
+
+    if (s->state == DISCONNECTED) {
+        if ((err = ftp_connect_data_connection(h)) < 0)
+            return err;
+    }
+    if (s->state == READY) {
+        if ((err = ftp_store(s)) < 0)
+            return err;
+    }
+    if (s->conn_data && s->state == UPLOADING) {
+        written = ffurl_write(s->conn_data, buf, size);
+        if (written > 0) {
+            s->position += written;
+            s->filesize = FFMAX(s->filesize, s->position);
+        }
+        return written;
+    }
+
+    av_log(h, AV_LOG_ERROR, "FTP write failed\n");
+    return AVERROR(EIO);
+}
+
+static int ftp_close(URLContext *h)
+{
+    av_dlog(h, "ftp protocol close\n");
+
+    ftp_close_both_connections(h->priv_data);
+
+    return 0;
+}
+
+static int ftp_get_file_handle(URLContext *h)
+{
+    FTPContext *s = h->priv_data;
+
+    av_dlog(h, "ftp protocol get_file_handle\n");
+
+    if (s->conn_data)
+        return ffurl_get_file_handle(s->conn_data);
+
+    return AVERROR(EIO);
+}
+
+static int ftp_shutdown(URLContext *h, int flags)
+{
+    FTPContext *s = h->priv_data;
+
+    av_dlog(h, "ftp protocol shutdown\n");
+
+    if (s->conn_data)
+        return ffurl_shutdown(s->conn_data, flags);
+
+    return AVERROR(EIO);
+}
+
+URLProtocol ff_ftp_protocol = {
+    .name                = "ftp",
+    .url_open            = ftp_open,
+    .url_read            = ftp_read,
+    .url_write           = ftp_write,
+    .url_seek            = ftp_seek,
+    .url_close           = ftp_close,
+    .url_get_file_handle = ftp_get_file_handle,
+    .url_shutdown        = ftp_shutdown,
+    .priv_data_size      = sizeof(FTPContext),
+    .priv_data_class     = &ftp_context_class,
+    .flags               = URL_PROTOCOL_FLAG_NETWORK,
+};
diff --git a/libavformat/g723_1.c b/libavformat/g723_1.c
index 8d35f88..4f3ce8f 100644
--- a/libavformat/g723_1.c
+++ b/libavformat/g723_1.c
@@ -24,13 +24,14 @@
  * G.723.1 demuxer
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/channel_layout.h"
 #include "avformat.h"
 #include "internal.h"
 
 static const uint8_t frame_size[4] = { 24, 20, 4, 1 };
 
-static int g723_1_init(AVFormatContext *s)
+static av_cold int g723_1_init(AVFormatContext *s)
 {
     AVStream *st;
 
diff --git a/libavformat/gif.c b/libavformat/gif.c
index d459bd6..f6e7625 100644
--- a/libavformat/gif.c
+++ b/libavformat/gif.c
@@ -52,21 +52,24 @@
         avio_w8(pb, 0); /* aspect ratio */
     }
 
-    /* "NETSCAPE EXTENSION" for looped animation GIF */
-    avio_w8(pb, 0x21); /* GIF Extension code */
-    avio_w8(pb, 0xff); /* Application Extension Label */
-    avio_w8(pb, 0x0b); /* Length of Application Block */
-    avio_write(pb, "NETSCAPE2.0", sizeof("NETSCAPE2.0") - 1);
-    avio_w8(pb, 0x03); /* Length of Data Sub-Block */
-    avio_w8(pb, 0x01);
-    avio_wl16(pb, (uint16_t)loop_count);
-    avio_w8(pb, 0x00); /* Data Sub-block Terminator */
+
+    if (loop_count >= 0 ) {
+        /* "NETSCAPE EXTENSION" for looped animation GIF */
+        avio_w8(pb, 0x21); /* GIF Extension code */
+        avio_w8(pb, 0xff); /* Application Extension Label */
+        avio_w8(pb, 0x0b); /* Length of Application Block */
+        avio_write(pb, "NETSCAPE2.0", sizeof("NETSCAPE2.0") - 1);
+        avio_w8(pb, 0x03); /* Length of Data Sub-Block */
+        avio_w8(pb, 0x01);
+        avio_wl16(pb, (uint16_t)loop_count);
+        avio_w8(pb, 0x00); /* Data Sub-block Terminator */
+    }
 
     return 0;
 }
 
 typedef struct {
-    AVClass *class;         /** Class for private options. */
+    AVClass *class;
     int loop;
     int last_delay;
     AVPacket *prev_pkt;
@@ -189,8 +192,8 @@
 #define OFFSET(x) offsetof(GIFContext, x)
 #define ENC AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-    { "loop", "Number of times to loop the output.", OFFSET(loop),
-      AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 65535, ENC },
+    { "loop", "Number of times to loop the output: -1 - no loop, 0 - infinite loop", OFFSET(loop),
+      AV_OPT_TYPE_INT, { .i64 = 0 }, -1, 65535, ENC },
     { "final_delay", "Force delay (in ms) after the last frame", OFFSET(last_delay),
       AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 65535, ENC },
     { NULL },
diff --git a/libavformat/gsmdec.c b/libavformat/gsmdec.c
index 9899266..a51822a 100644
--- a/libavformat/gsmdec.c
+++ b/libavformat/gsmdec.c
@@ -80,7 +80,7 @@
     { NULL },
 };
 
-static const AVClass class = {
+static const AVClass gsm_class = {
     .class_name = "gsm demuxer",
     .item_name  = av_default_item_name,
     .option     = options,
@@ -96,5 +96,5 @@
     .flags          = AVFMT_GENERIC_INDEX,
     .extensions     = "gsm",
     .raw_codec_id   = AV_CODEC_ID_GSM,
-    .priv_class     = &class,
+    .priv_class     = &gsm_class,
 };
diff --git a/libavformat/gxf.c b/libavformat/gxf.c
index 86e6291..e15d06a 100644
--- a/libavformat/gxf.c
+++ b/libavformat/gxf.c
@@ -116,12 +116,10 @@
             st->codec->codec_id = AV_CODEC_ID_MJPEG;
             break;
         case 13:
-        case 15:
-            st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
-            st->codec->codec_id = AV_CODEC_ID_DVVIDEO;
-            break;
         case 14:
+        case 15:
         case 16:
+        case 25:
             st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
             st->codec->codec_id = AV_CODEC_ID_DVVIDEO;
             break;
@@ -165,6 +163,12 @@
             st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
             st->codec->sample_rate = 48000;
             break;
+        case 26: /* AVCi50 / AVCi100 (AVC Intra) */
+        case 29: /* AVCHD */
+            st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+            st->codec->codec_id = CODEC_ID_H264;
+            st->need_parsing = AVSTREAM_PARSE_HEADERS;
+            break;
         // timecode tracks:
         case 7:
         case 8:
@@ -172,6 +176,10 @@
             st->codec->codec_type = AVMEDIA_TYPE_DATA;
             st->codec->codec_id = AV_CODEC_ID_NONE;
             break;
+        case 30:
+            st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+            st->codec->codec_id = AV_CODEC_ID_DNXHD;
+            break;
         default:
             st->codec->codec_type = AVMEDIA_TYPE_UNKNOWN;
             st->codec->codec_id = AV_CODEC_ID_NONE;
diff --git a/libavformat/gxfenc.c b/libavformat/gxfenc.c
index 9322f7b..57bb26c 100644
--- a/libavformat/gxfenc.c
+++ b/libavformat/gxfenc.c
@@ -217,12 +217,27 @@
     return size + 3;
 }
 
+static int gxf_write_dv_auxiliary(AVIOContext *pb, AVStream *st)
+{
+    int64_t track_aux_data = 0;
+
+    avio_w8(pb, TRACK_AUX);
+    avio_w8(pb, 8);
+    if (st->codec->pix_fmt == AV_PIX_FMT_YUV420P)
+        track_aux_data |= 0x01;     /* marks stream as DVCAM instead of DVPRO */
+    track_aux_data |= 0x40000000;   /* aux data is valid */
+    avio_wl64(pb, track_aux_data);
+    return 8;
+}
+
 static int gxf_write_timecode_auxiliary(AVIOContext *pb, GXFContext *gxf)
 {
     uint32_t timecode = GXF_TIMECODE(gxf->tc.color, gxf->tc.drop,
                                      gxf->tc.hh, gxf->tc.mm,
                                      gxf->tc.ss, gxf->tc.ff);
 
+    avio_w8(pb, TRACK_AUX);
+    avio_w8(pb, 8);
     avio_wl32(pb, timecode);
     /* reserved */
     avio_wl32(pb, 0);
@@ -234,7 +249,6 @@
     GXFContext *gxf = s->priv_data;
     AVIOContext *pb = s->pb;
     int64_t pos;
-    int mpeg = sc->track_type == 4 || sc->track_type == 9;
 
     /* track description section */
     avio_w8(pb, sc->media_type + 0x80);
@@ -250,13 +264,21 @@
     avio_wb16(pb, sc->media_info);
     avio_w8(pb, 0);
 
-    if (!mpeg) {
-        /* auxiliary information */
-        avio_w8(pb, TRACK_AUX);
-        avio_w8(pb, 8);
-        if (sc->track_type == 3)
+    switch (sc->track_type) {
+        case 3:     /* timecode */
             gxf_write_timecode_auxiliary(pb, gxf);
-        else
+            break;
+        case 4:     /* MPEG2 */
+        case 9:     /* MPEG1 */
+            gxf_write_mpeg_auxiliary(pb, s->streams[index]);
+            break;
+        case 5:     /* DV25 */
+        case 6:     /* DV50 */
+            gxf_write_dv_auxiliary(pb, s->streams[index]);
+            break;
+        default:
+            avio_w8(pb, TRACK_AUX);
+            avio_w8(pb, 8);
             avio_wl64(pb, 0);
     }
 
@@ -265,9 +287,6 @@
     avio_w8(pb, 4);
     avio_wb32(pb, 0);
 
-    if (mpeg)
-        gxf_write_mpeg_auxiliary(pb, s->streams[index]);
-
     /* frame rate */
     avio_w8(pb, TRACK_FPS);
     avio_w8(pb, 4);
@@ -534,13 +553,20 @@
     return 32;
 }
 
-static int gxf_write_umf_media_dv(AVIOContext *pb, GXFStreamContext *sc)
+static int gxf_write_umf_media_dv(AVIOContext *pb, GXFStreamContext *sc, AVStream *st)
 {
-    int i;
+    int dv_umf_data = 0;
 
-    for (i = 0; i < 8; i++) {
-        avio_wb32(pb, 0);
-    }
+    if (st->codec->pix_fmt == AV_PIX_FMT_YUV420P)
+        dv_umf_data |= 0x20; /* marks as DVCAM instead of DVPRO */
+    avio_wl32(pb, dv_umf_data);
+    avio_wl32(pb, 0);
+    avio_wl32(pb, 0);
+    avio_wl32(pb, 0);
+    avio_wl32(pb, 0);
+    avio_wl32(pb, 0);
+    avio_wl32(pb, 0);
+    avio_wl32(pb, 0);
     return 32;
 }
 
@@ -604,7 +630,7 @@
                 gxf_write_umf_media_audio(pb, sc);
                 break;
             case AV_CODEC_ID_DVVIDEO:
-                gxf_write_umf_media_dv(pb, sc);
+                gxf_write_umf_media_dv(pb, sc, st);
                 break;
             }
         }
diff --git a/libavformat/h261dec.c b/libavformat/h261dec.c
index 1b254d6..8d882ae 100644
--- a/libavformat/h261dec.c
+++ b/libavformat/h261dec.c
@@ -33,7 +33,7 @@
     int src_fmt=0;
     GetBitContext gb;
 
-    init_get_bits(&gb, p->buf, p->buf_size*8);
+    init_get_bits8(&gb, p->buf, p->buf_size);
 
     for(i=0; i<p->buf_size*8; i++){
         if ((code & 0x01ff0000) || !(code & 0xff00)) {
@@ -56,9 +56,9 @@
         }
     }
     if(valid_psc > 2*invalid_psc + 6){
-        return 50;
+        return AVPROBE_SCORE_EXTENSION;
     }else if(valid_psc > 2*invalid_psc + 2)
-        return 25;
+        return AVPROBE_SCORE_EXTENSION / 2;
     return 0;
 }
 
diff --git a/libavformat/h263dec.c b/libavformat/h263dec.c
index 667fdbd..e6e0345 100644
--- a/libavformat/h263dec.c
+++ b/libavformat/h263dec.c
@@ -56,9 +56,9 @@
         }
     }
     if(valid_psc > 2*invalid_psc + 2*res_change + 3){
-        return 50;
+        return AVPROBE_SCORE_EXTENSION;
     }else if(valid_psc > 2*invalid_psc)
-        return 25;
+        return AVPROBE_SCORE_EXTENSION / 2;
     return 0;
 }
 
diff --git a/libavformat/h264dec.c b/libavformat/h264dec.c
index 9c67ab9..5de582b 100644
--- a/libavformat/h264dec.c
+++ b/libavformat/h264dec.c
@@ -63,7 +63,7 @@
         }
     }
     if(sps && pps && (idr||sli>3) && res<(sps+pps+idr))
-        return AVPROBE_SCORE_MAX/2+1; // +1 for .mpg
+        return AVPROBE_SCORE_EXTENSION + 1; // 1 more than .mpg
     return 0;
 }
 
diff --git a/libavformat/hls.c b/libavformat/hls.c
index 7de6059..8554b7e 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -56,7 +56,7 @@
 };
 
 struct segment {
-    int duration;
+    int64_t duration;
     char url[MAX_URL_SIZE];
     char key[MAX_URL_SIZE];
     enum KeyType key_type;
@@ -81,7 +81,7 @@
     int stream_offset;
 
     int finished;
-    int target_duration;
+    int64_t target_duration;
     int start_seq_no;
     int n_segments;
     struct segment **segments;
@@ -206,7 +206,8 @@
 static int parse_playlist(HLSContext *c, const char *url,
                           struct variant *var, AVIOContext *in)
 {
-    int ret = 0, duration = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
+    int ret = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
+    int64_t duration = 0;
     enum KeyType key_type = KEY_NONE;
     uint8_t iv[16] = "";
     int has_iv = 0;
@@ -218,7 +219,7 @@
     if (!in) {
         AVDictionary *opts = NULL;
         close_in = 1;
-        /* Some HLS servers dont like being sent the range header */
+        /* Some HLS servers don't like being sent the range header */
         av_dict_set(&opts, "seekable", "0", 0);
 
         // broker prior HTTP options that should be consistent across requests
@@ -271,7 +272,7 @@
                     goto fail;
                 }
             }
-            var->target_duration = atoi(ptr);
+            var->target_duration = atoi(ptr) * AV_TIME_BASE;
         } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
             if (!var) {
                 var = new_variant(c, 0, url, NULL);
@@ -286,7 +287,7 @@
                 var->finished = 1;
         } else if (av_strstart(line, "#EXTINF:", &ptr)) {
             is_segment = 1;
-            duration   = atoi(ptr);
+            duration   = atof(ptr) * AV_TIME_BASE;
         } else if (av_strstart(line, "#", NULL)) {
             continue;
         } else if (line[0]) {
@@ -413,7 +414,6 @@
         int64_t reload_interval = v->n_segments > 0 ?
                                   v->segments[v->n_segments - 1]->duration :
                                   v->target_duration;
-        reload_interval *= 1000000;
 
 reload:
         if (!v->finished &&
@@ -423,7 +423,7 @@
             /* If we need to reload the playlist again below (if
              * there's still no more segments), switch to a reload
              * interval of half the target duration. */
-            reload_interval = v->target_duration * 500000LL;
+            reload_interval = v->target_duration / 2;
         }
         if (v->cur_seq_no < v->start_seq_no) {
             av_log(NULL, AV_LOG_WARNING,
@@ -457,7 +457,8 @@
     c->end_of_segment = 1;
     c->cur_seq_no = v->cur_seq_no;
 
-    if (v->ctx && v->ctx->nb_streams && v->parent->nb_streams >= v->stream_offset + v->ctx->nb_streams) {
+    if (v->ctx && v->ctx->nb_streams &&
+        v->parent->nb_streams >= v->stream_offset + v->ctx->nb_streams) {
         v->needed = 0;
         for (i = v->stream_offset; i < v->stream_offset + v->ctx->nb_streams;
              i++) {
@@ -526,7 +527,7 @@
         int64_t duration = 0;
         for (i = 0; i < c->variants[0]->n_segments; i++)
             duration += c->variants[0]->segments[i]->duration;
-        s->duration = duration * AV_TIME_BASE;
+        s->duration = duration;
     }
 
     /* Open the demuxer for each variant */
@@ -534,7 +535,8 @@
         struct variant *v = c->variants[i];
         AVInputFormat *in_fmt = NULL;
         char bitrate_str[20];
-        AVProgram *program = NULL;
+        AVProgram *program;
+
         if (v->n_segments == 0)
             continue;
 
@@ -570,18 +572,17 @@
             goto fail;
         }
         v->ctx->pb       = &v->pb;
+        v->stream_offset = stream_offset;
         ret = avformat_open_input(&v->ctx, v->segments[0]->url, in_fmt, NULL);
         if (ret < 0)
             goto fail;
 
-        v->stream_offset = stream_offset;
         v->ctx->ctx_flags &= ~AVFMTCTX_NOHEADER;
         ret = avformat_find_stream_info(v->ctx, NULL);
         if (ret < 0)
             goto fail;
         snprintf(bitrate_str, sizeof(bitrate_str), "%d", v->bandwidth);
 
-        /* Create new AVprogram for variant i */
         program = av_new_program(s, i);
         if (!program)
             goto fail;
@@ -678,8 +679,11 @@
                     reset_packet(&var->pkt);
                     break;
                 } else {
-                    if (c->first_timestamp == AV_NOPTS_VALUE)
-                        c->first_timestamp = var->pkt.dts;
+                    if (c->first_timestamp == AV_NOPTS_VALUE &&
+                        var->pkt.dts       != AV_NOPTS_VALUE)
+                        c->first_timestamp = av_rescale_q(var->pkt.dts,
+                            var->ctx->streams[var->pkt.stream_index]->time_base,
+                            AV_TIME_BASE_Q);
                 }
 
                 if (c->seek_timestamp == AV_NOPTS_VALUE)
@@ -699,24 +703,34 @@
                     c->seek_timestamp = AV_NOPTS_VALUE;
                     break;
                 }
+                av_free_packet(&var->pkt);
+                reset_packet(&var->pkt);
             }
         }
-        /* Check if this stream has the packet with the lowest dts */
+        /* Check if this stream still is on an earlier segment number, or
+         * has the packet with the lowest dts */
         if (var->pkt.data) {
-            if(minvariant < 0) {
+            struct variant *minvar = c->variants[minvariant];
+            if (minvariant < 0 || var->cur_seq_no < minvar->cur_seq_no) {
                 minvariant = i;
-            } else {
-                struct variant *minvar = c->variants[minvariant];
-                int64_t dts    =    var->pkt.dts;
-                int64_t mindts = minvar->pkt.dts;
-                AVStream *st   =    var->ctx->streams[   var->pkt.stream_index];
-                AVStream *minst= minvar->ctx->streams[minvar->pkt.stream_index];
+            } else if (var->cur_seq_no == minvar->cur_seq_no) {
+                int64_t dts     =    var->pkt.dts;
+                int64_t mindts  = minvar->pkt.dts;
+                AVStream *st    =    var->ctx->streams[var->pkt.stream_index];
+                AVStream *minst = minvar->ctx->streams[minvar->pkt.stream_index];
 
-                if(   st->start_time != AV_NOPTS_VALUE)    dts -=    st->start_time;
-                if(minst->start_time != AV_NOPTS_VALUE) mindts -= minst->start_time;
-
-                if (av_compare_ts(dts, st->time_base, mindts, minst->time_base) < 0)
+                if (dts == AV_NOPTS_VALUE) {
                     minvariant = i;
+                } else if (mindts != AV_NOPTS_VALUE) {
+                    if (st->start_time    != AV_NOPTS_VALUE)
+                        dts    -= st->start_time;
+                    if (minst->start_time != AV_NOPTS_VALUE)
+                        mindts -= minst->start_time;
+
+                    if (av_compare_ts(dts, st->time_base,
+                                      mindts, minst->time_base) < 0)
+                        minvariant = i;
+                }
             }
         }
     }
@@ -757,7 +771,7 @@
                                        s->streams[stream_index]->time_base.den,
                                        flags & AVSEEK_FLAG_BACKWARD ?
                                        AV_ROUND_DOWN : AV_ROUND_UP);
-    timestamp = av_rescale_rnd(timestamp, 1, stream_index >= 0 ?
+    timestamp = av_rescale_rnd(timestamp, AV_TIME_BASE, stream_index >= 0 ?
                                s->streams[stream_index]->time_base.den :
                                AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
                                AV_ROUND_DOWN : AV_ROUND_UP);
@@ -770,12 +784,9 @@
     for (i = 0; i < c->n_variants; i++) {
         /* Reset reading */
         struct variant *var = c->variants[i];
-        int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ? 0 :
-                      av_rescale_rnd(c->first_timestamp, 1, stream_index >= 0 ?
-                               s->streams[stream_index]->time_base.den :
-                               AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
-                               AV_ROUND_DOWN : AV_ROUND_UP);
-         if (var->input) {
+        int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ?
+                      0 : c->first_timestamp;
+        if (var->input) {
             ffurl_close(var->input);
             var->input = NULL;
         }
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 18914c0..dcd53e5 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -49,7 +49,7 @@
     int has_video;
     int64_t start_pts;
     int64_t end_pts;
-    int64_t duration;      ///< last segment duration computed so far, in seconds
+    int64_t duration;      // last segment duration computed so far, in seconds
     int nb_entries;
     ListEntry *list;
     ListEntry *end_list;
@@ -164,14 +164,12 @@
     AVFormatContext *oc = c->avf;
     int err = 0;
 
-    if (c->wrap)
-        c->number %= c->wrap;
-
     if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
-                              c->basename, c->number++) < 0) {
+                              c->basename, c->wrap ? c->number % c->wrap : c->number) < 0) {
         av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", c->basename);
         return AVERROR(EINVAL);
     }
+    c->number++;
 
     if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
                           &s->interrupt_callback, NULL)) < 0)
@@ -253,25 +251,28 @@
     AVFormatContext *oc = hls->avf;
     AVStream *st = s->streams[pkt->stream_index];
     int64_t end_pts = hls->recording_time * hls->number;
-    int ret, is_ref_pkt = 0;
+    int is_ref_pkt = 1;
+    int ret, can_split = 1;
 
     if (hls->start_pts == AV_NOPTS_VALUE) {
         hls->start_pts = pkt->pts;
         hls->end_pts   = pkt->pts;
     }
 
-    if ((hls->has_video && st->codec->codec_type == AVMEDIA_TYPE_VIDEO)      &&
-        pkt->pts != AV_NOPTS_VALUE) {
-        is_ref_pkt = 1;
+    if (hls->has_video) {
+        can_split = st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
+                    pkt->flags & AV_PKT_FLAG_KEY;
+        is_ref_pkt = st->codec->codec_type == AVMEDIA_TYPE_VIDEO;
+    }
+    if (pkt->pts == AV_NOPTS_VALUE)
+        is_ref_pkt = can_split = 0;
+
+    if (is_ref_pkt)
         hls->duration = av_rescale(pkt->pts - hls->end_pts,
                                    st->time_base.num, st->time_base.den);
-    }
 
-    if (is_ref_pkt &&
-        av_compare_ts(pkt->pts - hls->start_pts, st->time_base,
-                      end_pts, AV_TIME_BASE_Q) >= 0 &&
-        pkt->flags & AV_PKT_FLAG_KEY) {
-
+    if (can_split && av_compare_ts(pkt->pts - hls->start_pts, st->time_base,
+                                   end_pts, AV_TIME_BASE_Q) >= 0) {
         ret = append_entry(hls, hls->duration);
         if (ret)
             return ret;
diff --git a/libavformat/hlsproto.c b/libavformat/hlsproto.c
index 4e35043..f6fcbe5 100644
--- a/libavformat/hlsproto.c
+++ b/libavformat/hlsproto.c
@@ -45,7 +45,7 @@
  */
 
 struct segment {
-    int duration;
+    int64_t duration;
     char url[MAX_URL_SIZE];
 };
 
@@ -56,7 +56,7 @@
 
 typedef struct HLSContext {
     char playlisturl[MAX_URL_SIZE];
-    int target_duration;
+    int64_t target_duration;
     int start_seq_no;
     int finished;
     int n_segments;
@@ -111,7 +111,8 @@
 {
     HLSContext *s = h->priv_data;
     AVIOContext *in;
-    int ret = 0, duration = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
+    int ret = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
+    int64_t duration = 0;
     char line[1024];
     const char *ptr;
 
@@ -134,14 +135,14 @@
                                &info);
             bandwidth = atoi(info.bandwidth);
         } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
-            s->target_duration = atoi(ptr);
+            s->target_duration = atoi(ptr) * AV_TIME_BASE;
         } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
             s->start_seq_no = atoi(ptr);
         } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
             s->finished = 1;
         } else if (av_strstart(line, "#EXTINF:", &ptr)) {
             is_segment = 1;
-            duration = atoi(ptr);
+            duration = atof(ptr) * AV_TIME_BASE;
         } else if (av_strstart(line, "#", NULL)) {
             continue;
         } else if (line[0]) {
@@ -270,7 +271,6 @@
     reload_interval = s->n_segments > 0 ?
                       s->segments[s->n_segments - 1]->duration :
                       s->target_duration;
-    reload_interval *= 1000000;
 retry:
     if (!s->finished) {
         int64_t now = av_gettime();
@@ -280,7 +280,7 @@
             /* If we need to reload the playlist again below (if
              * there's still no more segments), switch to a reload
              * interval of half the target duration. */
-            reload_interval = s->target_duration * 500000LL;
+            reload_interval = s->target_duration / 2;
         }
     }
     if (s->cur_seq_no < s->start_seq_no) {
diff --git a/libavformat/http.c b/libavformat/http.c
index 7f33eca..3edddbf 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -29,6 +29,10 @@
 #include "url.h"
 #include "libavutil/opt.h"
 
+#if CONFIG_ZLIB
+#include <zlib.h>
+#endif
+
 /* XXX: POST protocol is not completely implemented because ffmpeg uses
    only a subset of it. */
 
@@ -49,6 +53,8 @@
     char *content_type;
     char *user_agent;
     int64_t off, filesize;
+    int icy_data_read;      ///< how much data was read since last ICY metadata packet
+    int icy_metaint;        ///< after how many bytes of read data a new metadata packet will be found
     char location[MAX_URL_SIZE];
     HTTPAuthState auth_state;
     HTTPAuthState proxy_auth_state;
@@ -65,12 +71,20 @@
     int rw_timeout;
     char *mime_type;
     char *cookies;          ///< holds newline (\n) delimited Set-Cookie header field values (without the "Set-Cookie: " field name)
+    int icy;
+    char *icy_metadata_headers;
+    char *icy_metadata_packet;
+#if CONFIG_ZLIB
+    int compressed;
+    z_stream inflate_stream;
+    uint8_t *inflate_buffer;
+#endif
 } HTTPContext;
 
 #define OFFSET(x) offsetof(HTTPContext, x)
 #define D AV_OPT_FLAG_DECODING_PARAM
 #define E AV_OPT_FLAG_ENCODING_PARAM
-#define DEFAULT_USER_AGENT "Mozilla/5.0 Lavf/" AV_STRINGIFY(LIBAVFORMAT_VERSION)
+#define DEFAULT_USER_AGENT "Lavf/" AV_STRINGIFY(LIBAVFORMAT_VERSION)
 static const AVOption options[] = {
 {"seekable", "control seekability of connection", OFFSET(seekable), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, D },
 {"chunked_post", "use chunked transfer-encoding for posts", OFFSET(chunked_post), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E },
@@ -82,6 +96,9 @@
 {"timeout", "set timeout of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D|E },
 {"mime_type", "set MIME type", OFFSET(mime_type), AV_OPT_TYPE_STRING, {0}, 0, 0, 0 },
 {"cookies", "set cookies to be sent in applicable future requests, use newline delimited Set-Cookie HTTP field value syntax", OFFSET(cookies), AV_OPT_TYPE_STRING, {0}, 0, 0, 0 },
+{"icy", "request ICY metadata", OFFSET(icy), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, D },
+{"icy_metadata_headers", "return ICY metadata headers", OFFSET(icy_metadata_headers), AV_OPT_TYPE_STRING, {0}, 0, 0, 0 },
+{"icy_metadata_packet", "return current ICY metadata packet", OFFSET(icy_metadata_packet), AV_OPT_TYPE_STRING, {0}, 0, 0, 0 },
 {NULL}
 };
 #define HTTP_CLASS(flavor)\
@@ -218,6 +235,7 @@
     HTTPContext *s = h->priv_data;
 
     s->off = 0;
+    s->icy_data_read = 0;
     av_strlcpy(s->location, uri, sizeof(s->location));
 
     return http_open_cnx(h);
@@ -289,6 +307,7 @@
 {
     HTTPContext *s = h->priv_data;
     char *tag, *p, *end;
+    char redirected_location[MAX_URL_SIZE];
 
     /* end of header */
     if (line[0] == '\0') {
@@ -328,7 +347,8 @@
         while (av_isspace(*p))
             p++;
         if (!av_strcasecmp(tag, "Location")) {
-            av_strlcpy(s->location, p, sizeof(s->location));
+            ff_make_absolute_url(redirected_location, sizeof(redirected_location), s->location, p);
+            av_strlcpy(s->location, redirected_location, sizeof(s->location));
             *new_location = 1;
         } else if (!av_strcasecmp (tag, "Content-Length") && s->filesize == -1) {
             s->filesize = strtoll(p, NULL, 10);
@@ -375,6 +395,41 @@
                 snprintf(s->cookies, str_size, "%s\n%s", tmp, p);
                 av_free(tmp);
             }
+        } else if (!av_strcasecmp (tag, "Icy-MetaInt")) {
+            s->icy_metaint = strtoll(p, NULL, 10);
+        } else if (!av_strncasecmp(tag, "Icy-", 4)) {
+            // Concat all Icy- header lines
+            char *buf = av_asprintf("%s%s: %s\n",
+                s->icy_metadata_headers ? s->icy_metadata_headers : "", tag, p);
+            if (!buf)
+                return AVERROR(ENOMEM);
+            av_freep(&s->icy_metadata_headers);
+            s->icy_metadata_headers = buf;
+        } else if (!av_strcasecmp (tag, "Content-Encoding")) {
+            if (!av_strncasecmp(p, "gzip", 4) || !av_strncasecmp(p, "deflate", 7)) {
+#if CONFIG_ZLIB
+                s->compressed = 1;
+                inflateEnd(&s->inflate_stream);
+                if (inflateInit2(&s->inflate_stream, 32 + 15) != Z_OK) {
+                    av_log(h, AV_LOG_WARNING, "Error during zlib initialisation: %s\n",
+                           s->inflate_stream.msg);
+                    return AVERROR(ENOSYS);
+                }
+                if (zlibCompileFlags() & (1 << 17)) {
+                    av_log(h, AV_LOG_WARNING, "Your zlib was compiled without gzip support.\n");
+                    return AVERROR(ENOSYS);
+                }
+#else
+                av_log(h, AV_LOG_WARNING, "Compressed (%s) content, need zlib with gzip support\n", p);
+                return AVERROR(ENOSYS);
+#endif
+            } else if (!av_strncasecmp(p, "identity", 8)) {
+                // The normal, no-encoding case (although servers shouldn't include
+                // the header at all if this is the case).
+            } else {
+                av_log(h, AV_LOG_WARNING, "Unknown content coding: %s\n", p);
+                return AVERROR(ENOSYS);
+            }
         }
     }
     return 1;
@@ -421,6 +476,8 @@
                 cvalue = av_strdup(param);
             }
         }
+        if (!cdomain)
+            cdomain = av_strdup(domain);
 
         // ensure all of the necessary values are valid
         if (!cdomain || !cpath || !cvalue) {
@@ -578,6 +635,10 @@
             av_free(cookies);
         }
     }
+    if (!has_header(s->headers, "\r\nIcy-MetaData: ") && s->icy) {
+        len += av_strlcatf(headers + len, sizeof(headers) - len,
+                           "Icy-MetaData: %d\r\n", 1);
+    }
 
     /* now add in custom headers */
     if (s->headers)
@@ -611,6 +672,7 @@
     s->buf_end = s->buffer;
     s->line_count = 0;
     s->off = 0;
+    s->icy_data_read = 0;
     s->filesize = -1;
     s->willclose = 0;
     s->end_chunked_post = 0;
@@ -650,12 +712,45 @@
     }
     if (len > 0) {
         s->off += len;
+        s->icy_data_read += len;
         if (s->chunksize > 0)
             s->chunksize -= len;
     }
     return len;
 }
 
+#if CONFIG_ZLIB
+#define DECOMPRESS_BUF_SIZE (256 * 1024)
+static int http_buf_read_compressed(URLContext *h, uint8_t *buf, int size)
+{
+    HTTPContext *s = h->priv_data;
+    int ret;
+
+    if (!s->inflate_buffer) {
+        s->inflate_buffer = av_malloc(DECOMPRESS_BUF_SIZE);
+        if (!s->inflate_buffer)
+            return AVERROR(ENOMEM);
+    }
+
+    if (s->inflate_stream.avail_in == 0) {
+        int read = http_buf_read(h, s->inflate_buffer, DECOMPRESS_BUF_SIZE);
+        if (read <= 0)
+            return read;
+        s->inflate_stream.next_in  = s->inflate_buffer;
+        s->inflate_stream.avail_in = read;
+    }
+
+    s->inflate_stream.avail_out = size;
+    s->inflate_stream.next_out  = buf;
+
+    ret = inflate(&s->inflate_stream, Z_SYNC_FLUSH);
+    if (ret != Z_OK && ret != Z_STREAM_END)
+        av_log(h, AV_LOG_WARNING, "inflate return value: %d, %s\n", ret, s->inflate_stream.msg);
+
+    return size - s->inflate_stream.avail_out;
+}
+#endif
+
 static int http_read(URLContext *h, uint8_t *buf, int size)
 {
     HTTPContext *s = h->priv_data;
@@ -691,6 +786,36 @@
         }
         size = FFMIN(size, s->chunksize);
     }
+    if (s->icy_metaint > 0) {
+        int remaining = s->icy_metaint - s->icy_data_read; /* until next metadata packet */
+        if (!remaining) {
+            // The metadata packet is variable sized. It has a 1 byte header
+            // which sets the length of the packet (divided by 16). If it's 0,
+            // the metadata doesn't change. After the packet, icy_metaint bytes
+            // of normal data follow.
+            int ch = http_getc(s);
+            if (ch < 0)
+                return ch;
+            if (ch > 0) {
+                char data[255 * 16 + 1];
+                int n;
+                int ret;
+                ch *= 16;
+                for (n = 0; n < ch; n++)
+                    data[n] = http_getc(s);
+                data[ch + 1] = 0;
+                if ((ret = av_opt_set(s, "icy_metadata_packet", data, 0)) < 0)
+                    return ret;
+            }
+            s->icy_data_read = 0;
+            remaining = s->icy_metaint;
+        }
+        size = FFMIN(size, remaining);
+    }
+#if CONFIG_ZLIB
+    if (s->compressed)
+        return http_buf_read_compressed(h, buf, size);
+#endif
     return http_buf_read(h, buf, size);
 }
 
@@ -742,6 +867,11 @@
     int ret = 0;
     HTTPContext *s = h->priv_data;
 
+#if CONFIG_ZLIB
+    inflateEnd(&s->inflate_stream);
+    av_freep(&s->inflate_buffer);
+#endif
+
     if (!s->end_chunked_post) {
         /* Close the write direction by sending the end of chunked encoding. */
         ret = http_shutdown(h, h->flags);
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index 3567bbc..4bc76a3 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -32,72 +32,71 @@
 #include <zlib.h>
 #endif
 
-#include "id3v2.h"
-#include "id3v1.h"
 #include "libavutil/avstring.h"
-#include "libavutil/intreadwrite.h"
 #include "libavutil/dict.h"
+#include "libavutil/intreadwrite.h"
 #include "avio_internal.h"
 #include "internal.h"
+#include "id3v1.h"
+#include "id3v2.h"
 
 const AVMetadataConv ff_id3v2_34_metadata_conv[] = {
-    { "TALB", "album"},
-    { "TCOM", "composer"},
-    { "TCON", "genre"},
-    { "TCOP", "copyright"},
-    { "TENC", "encoded_by"},
-    { "TIT2", "title"},
-    { "TLAN", "language"},
-    { "TPE1", "artist"},
-    { "TPE2", "album_artist"},
-    { "TPE3", "performer"},
-    { "TPOS", "disc"},
-    { "TPUB", "publisher"},
-    { "TRCK", "track"},
-    { "TSSE", "encoder"},
+    { "TALB", "album"        },
+    { "TCOM", "composer"     },
+    { "TCON", "genre"        },
+    { "TCOP", "copyright"    },
+    { "TENC", "encoded_by"   },
+    { "TIT2", "title"        },
+    { "TLAN", "language"     },
+    { "TPE1", "artist"       },
+    { "TPE2", "album_artist" },
+    { "TPE3", "performer"    },
+    { "TPOS", "disc"         },
+    { "TPUB", "publisher"    },
+    { "TRCK", "track"        },
+    { "TSSE", "encoder"      },
     { 0 }
 };
 
 const AVMetadataConv ff_id3v2_4_metadata_conv[] = {
-    { "TDRL", "date"},
-    { "TDRC", "date"},
-    { "TDEN", "creation_time"},
-    { "TSOA", "album-sort"},
-    { "TSOP", "artist-sort"},
-    { "TSOT", "title-sort"},
+    { "TDRL", "date"          },
+    { "TDRC", "date"          },
+    { "TDEN", "creation_time" },
+    { "TSOA", "album-sort"    },
+    { "TSOP", "artist-sort"   },
+    { "TSOT", "title-sort"    },
     { 0 }
 };
 
 static const AVMetadataConv id3v2_2_metadata_conv[] = {
-    { "TAL",  "album"},
-    { "TCO",  "genre"},
-    { "TT2",  "title"},
-    { "TEN",  "encoded_by"},
-    { "TP1",  "artist"},
-    { "TP2",  "album_artist"},
-    { "TP3",  "performer"},
-    { "TRK",  "track"},
+    { "TAL", "album"        },
+    { "TCO", "genre"        },
+    { "TT2", "title"        },
+    { "TEN", "encoded_by"   },
+    { "TP1", "artist"       },
+    { "TP2", "album_artist" },
+    { "TP3", "performer"    },
+    { "TRK", "track"        },
     { 0 }
 };
 
-
 const char ff_id3v2_tags[][4] = {
-   "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDLY", "TENC", "TEXT",
-   "TFLT", "TIT1", "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMED",
-   "TOAL", "TOFN", "TOLY", "TOPE", "TOWN", "TPE1", "TPE2", "TPE3",
-   "TPE4", "TPOS", "TPUB", "TRCK", "TRSN", "TRSO", "TSRC", "TSSE",
-   { 0 },
+    "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDLY", "TENC", "TEXT",
+    "TFLT", "TIT1", "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMED",
+    "TOAL", "TOFN", "TOLY", "TOPE", "TOWN", "TPE1", "TPE2", "TPE3",
+    "TPE4", "TPOS", "TPUB", "TRCK", "TRSN", "TRSO", "TSRC", "TSSE",
+    { 0 },
 };
 
 const char ff_id3v2_4_tags[][4] = {
-   "TDEN", "TDOR", "TDRC", "TDRL", "TDTG", "TIPL", "TMCL", "TMOO",
-   "TPRO", "TSOA", "TSOP", "TSOT", "TSST",
-   { 0 },
+    "TDEN", "TDOR", "TDRC", "TDRL", "TDTG", "TIPL", "TMCL", "TMOO",
+    "TPRO", "TSOA", "TSOP", "TSOT", "TSST",
+    { 0 },
 };
 
 const char ff_id3v2_3_tags[][4] = {
-   "TDAT", "TIME", "TORY", "TRDA", "TSIZ", "TYER",
-   { 0 },
+    "TDAT", "TIME", "TORY", "TRDA", "TSIZ", "TYER",
+    { 0 },
 };
 
 const char *ff_id3v2_picture_types[21] = {
@@ -125,36 +124,36 @@
 };
 
 const CodecMime ff_id3v2_mime_tags[] = {
-    {"image/gif" , AV_CODEC_ID_GIF},
-    {"image/jpeg", AV_CODEC_ID_MJPEG},
-    {"image/jpg",  AV_CODEC_ID_MJPEG},
-    {"image/png" , AV_CODEC_ID_PNG},
-    {"image/tiff", AV_CODEC_ID_TIFF},
-    {"image/bmp",  AV_CODEC_ID_BMP},
-    {"JPG",        AV_CODEC_ID_MJPEG}, /* ID3v2.2  */
-    {"PNG" ,       AV_CODEC_ID_PNG},   /* ID3v2.2  */
-    {"",           AV_CODEC_ID_NONE},
+    { "image/gif",  AV_CODEC_ID_GIF   },
+    { "image/jpeg", AV_CODEC_ID_MJPEG },
+    { "image/jpg",  AV_CODEC_ID_MJPEG },
+    { "image/png",  AV_CODEC_ID_PNG   },
+    { "image/tiff", AV_CODEC_ID_TIFF  },
+    { "image/bmp",  AV_CODEC_ID_BMP   },
+    { "JPG",        AV_CODEC_ID_MJPEG }, /* ID3v2.2  */
+    { "PNG",        AV_CODEC_ID_PNG   }, /* ID3v2.2  */
+    { "",           AV_CODEC_ID_NONE  },
 };
 
-int ff_id3v2_match(const uint8_t *buf, const char * magic)
+int ff_id3v2_match(const uint8_t *buf, const char *magic)
 {
     return  buf[0]         == magic[0] &&
             buf[1]         == magic[1] &&
             buf[2]         == magic[2] &&
-            buf[3]         != 0xff &&
-            buf[4]         != 0xff &&
-           (buf[6] & 0x80) ==    0 &&
-           (buf[7] & 0x80) ==    0 &&
-           (buf[8] & 0x80) ==    0 &&
-           (buf[9] & 0x80) ==    0;
+            buf[3]         != 0xff     &&
+            buf[4]         != 0xff     &&
+           (buf[6] & 0x80) == 0        &&
+           (buf[7] & 0x80) == 0        &&
+           (buf[8] & 0x80) == 0        &&
+           (buf[9] & 0x80) == 0;
 }
 
-int ff_id3v2_tag_len(const uint8_t * buf)
+int ff_id3v2_tag_len(const uint8_t *buf)
 {
     int len = ((buf[6] & 0x7f) << 21) +
               ((buf[7] & 0x7f) << 14) +
               ((buf[8] & 0x7f) << 7) +
-               (buf[9] & 0x7f) +
+              (buf[9] & 0x7f) +
               ID3v2_HEADER_SIZE;
     if (buf[5] & 0x10)
         len += ID3v2_HEADER_SIZE;
@@ -210,7 +209,6 @@
     }
 
     switch (encoding) {
-
     case ID3v2_ENCODING_ISO8859:
         while (left && ch) {
             ch = avio_r8(pb);
@@ -246,7 +244,7 @@
             PUT_UTF8(ch, tmp, avio_w8(dynbuf, tmp);)
         }
         if (left < 0)
-            left += 2; /* did not read last char from pb */
+            left += 2;  /* did not read last char from pb */
         break;
 
     case ID3v2_ENCODING_UTF8:
@@ -272,7 +270,8 @@
 /**
  * Parse a text tag.
  */
-static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, const char *key)
+static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen,
+                      AVDictionary **metadata, const char *key)
 {
     uint8_t *dst;
     int encoding, dict_flags = AV_DICT_DONT_OVERWRITE | AV_DICT_DONT_STRDUP_VAL;
@@ -289,9 +288,9 @@
         return;
     }
 
-    if (!(strcmp(key, "TCON") && strcmp(key, "TCO"))
-        && (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1)
-        && genre <= ID3v1_GENRE_MAX) {
+    if (!(strcmp(key, "TCON") && strcmp(key, "TCO"))                         &&
+        (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1) &&
+        genre <= ID3v1_GENRE_MAX) {
         av_freep(&dst);
         dst = av_strdup(ff_id3v1_genre_str[genre]);
     } else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) {
@@ -307,16 +306,17 @@
         av_freep(&dst);
 
     if (dst)
-        av_dict_set(&s->metadata, key, dst, dict_flags);
+        av_dict_set(metadata, key, dst, dict_flags);
 }
 
 /**
  * Parse GEOB tag into a ID3v2ExtraMetaGEOB struct.
  */
-static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag, ID3v2ExtraMeta **extra_meta)
+static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen,
+                         char *tag, ID3v2ExtraMeta **extra_meta)
 {
     ID3v2ExtraMetaGEOB *geob_data = NULL;
-    ID3v2ExtraMeta *new_extra = NULL;
+    ID3v2ExtraMeta *new_extra     = NULL;
     char encoding;
     unsigned int len;
 
@@ -325,13 +325,15 @@
 
     geob_data = av_mallocz(sizeof(ID3v2ExtraMetaGEOB));
     if (!geob_data) {
-        av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n", sizeof(ID3v2ExtraMetaGEOB));
+        av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n",
+               sizeof(ID3v2ExtraMetaGEOB));
         return;
     }
 
     new_extra = av_mallocz(sizeof(ID3v2ExtraMeta));
     if (!new_extra) {
-        av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n", sizeof(ID3v2ExtraMeta));
+        av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n",
+               sizeof(ID3v2ExtraMeta));
         goto fail;
     }
 
@@ -340,18 +342,19 @@
     taglen--;
 
     /* read MIME type (always ISO-8859) */
-    if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &geob_data->mime_type, &taglen) < 0
-        || taglen <= 0)
+    if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &geob_data->mime_type,
+                   &taglen) < 0 ||
+        taglen <= 0)
         goto fail;
 
     /* read file name */
-    if (decode_str(s, pb, encoding, &geob_data->file_name, &taglen) < 0
-        || taglen <= 0)
+    if (decode_str(s, pb, encoding, &geob_data->file_name, &taglen) < 0 ||
+        taglen <= 0)
         goto fail;
 
     /* read content description */
-    if (decode_str(s, pb, encoding, &geob_data->description, &taglen) < 0
-        || taglen < 0)
+    if (decode_str(s, pb, encoding, &geob_data->description, &taglen) < 0 ||
+        taglen < 0)
         goto fail;
 
     if (taglen) {
@@ -362,18 +365,19 @@
             goto fail;
         }
         if ((len = avio_read(pb, geob_data->data, taglen)) < taglen)
-            av_log(s, AV_LOG_WARNING, "Error reading GEOB frame, data truncated.\n");
+            av_log(s, AV_LOG_WARNING,
+                   "Error reading GEOB frame, data truncated.\n");
         geob_data->datasize = len;
     } else {
-        geob_data->data = NULL;
+        geob_data->data     = NULL;
         geob_data->datasize = 0;
     }
 
     /* add data to the list */
-    new_extra->tag = "GEOB";
+    new_extra->tag  = "GEOB";
     new_extra->data = geob_data;
     new_extra->next = *extra_meta;
-    *extra_meta = new_extra;
+    *extra_meta     = new_extra;
 
     return;
 
@@ -386,11 +390,12 @@
 
 static int is_number(const char *str)
 {
-    while (*str >= '0' && *str <= '9') str++;
+    while (*str >= '0' && *str <= '9')
+        str++;
     return !*str;
 }
 
-static AVDictionaryEntry* get_date_tag(AVDictionary *m, const char *tag)
+static AVDictionaryEntry *get_date_tag(AVDictionary *m, const char *tag)
 {
     AVDictionaryEntry *t;
     if ((t = av_dict_get(m, tag, NULL, AV_DICT_MATCH_CASE)) &&
@@ -402,28 +407,29 @@
 static void merge_date(AVDictionary **m)
 {
     AVDictionaryEntry *t;
-    char date[17] = {0};      // YYYY-MM-DD hh:mm
+    char date[17] = { 0 };      // YYYY-MM-DD hh:mm
 
     if (!(t = get_date_tag(*m, "TYER")) &&
         !(t = get_date_tag(*m, "TYE")))
         return;
     av_strlcpy(date, t->value, 5);
     av_dict_set(m, "TYER", NULL, 0);
-    av_dict_set(m, "TYE",  NULL, 0);
+    av_dict_set(m, "TYE", NULL, 0);
 
     if (!(t = get_date_tag(*m, "TDAT")) &&
         !(t = get_date_tag(*m, "TDA")))
         goto finish;
     snprintf(date + 4, sizeof(date) - 4, "-%.2s-%.2s", t->value + 2, t->value);
     av_dict_set(m, "TDAT", NULL, 0);
-    av_dict_set(m, "TDA",  NULL, 0);
+    av_dict_set(m, "TDA", NULL, 0);
 
     if (!(t = get_date_tag(*m, "TIME")) &&
         !(t = get_date_tag(*m, "TIM")))
         goto finish;
-    snprintf(date + 10, sizeof(date) - 10, " %.2s:%.2s", t->value, t->value + 2);
+    snprintf(date + 10, sizeof(date) - 10,
+             " %.2s:%.2s", t->value, t->value + 2);
     av_dict_set(m, "TIME", NULL, 0);
-    av_dict_set(m, "TIM",  NULL, 0);
+    av_dict_set(m, "TIM", NULL, 0);
 
 finish:
     if (date[0])
@@ -438,15 +444,16 @@
     av_freep(&apic);
 }
 
-static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag, ID3v2ExtraMeta **extra_meta)
+static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen,
+                      char *tag, ID3v2ExtraMeta **extra_meta)
 {
     int enc, pic_type;
-    char             mimetype[64];
-    const CodecMime     *mime = ff_id3v2_mime_tags;
-    enum AVCodecID           id = AV_CODEC_ID_NONE;
-    ID3v2ExtraMetaAPIC  *apic = NULL;
+    char mimetype[64];
+    const CodecMime *mime     = ff_id3v2_mime_tags;
+    enum AVCodecID id         = AV_CODEC_ID_NONE;
+    ID3v2ExtraMetaAPIC *apic  = NULL;
     ID3v2ExtraMeta *new_extra = NULL;
-    int64_t               end = avio_tell(pb) + taglen;
+    int64_t end               = avio_tell(pb) + taglen;
 
     if (taglen <= 4)
         goto fail;
@@ -469,7 +476,8 @@
         mime++;
     }
     if (id == AV_CODEC_ID_NONE) {
-        av_log(s, AV_LOG_WARNING, "Unknown attached picture mimetype: %s, skipping.\n", mimetype);
+        av_log(s, AV_LOG_WARNING,
+               "Unknown attached picture mimetype: %s, skipping.\n", mimetype);
         goto fail;
     }
     apic->id = id;
@@ -478,14 +486,16 @@
     pic_type = avio_r8(pb);
     taglen--;
     if (pic_type < 0 || pic_type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types)) {
-        av_log(s, AV_LOG_WARNING, "Unknown attached picture type %d.\n", pic_type);
+        av_log(s, AV_LOG_WARNING, "Unknown attached picture type %d.\n",
+               pic_type);
         pic_type = 0;
     }
     apic->type = ff_id3v2_picture_types[pic_type];
 
     /* description and picture data */
     if (decode_str(s, pb, enc, &apic->description, &taglen) < 0) {
-        av_log(s, AV_LOG_ERROR, "Error decoding attached picture description.\n");
+        av_log(s, AV_LOG_ERROR,
+               "Error decoding attached picture description.\n");
         goto fail;
     }
 
@@ -494,10 +504,10 @@
         goto fail;
     memset(apic->buf->data + taglen, 0, FF_INPUT_BUFFER_PADDING_SIZE);
 
-    new_extra->tag    = "APIC";
-    new_extra->data   = apic;
-    new_extra->next   = *extra_meta;
-    *extra_meta       = new_extra;
+    new_extra->tag  = "APIC";
+    new_extra->data = apic;
+    new_extra->next = *extra_meta;
+    *extra_meta     = new_extra;
 
     return;
 
@@ -508,47 +518,65 @@
     avio_seek(pb, end, SEEK_SET);
 }
 
-static void read_chapter(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag, ID3v2ExtraMeta **extra_meta)
+static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, char *ttag, ID3v2ExtraMeta **extra_meta)
 {
     AVRational time_base = {1, 1000};
-    char title[1024];
     uint32_t start, end;
+    AVChapter *chapter;
+    uint8_t *dst = NULL;
+    int taglen;
+    char tag[5];
 
-    taglen -= avio_get_str(pb, taglen, title, sizeof(title));
-    if (taglen < 16)
+    if (decode_str(s, pb, 0, &dst, &len) < 0)
+        return;
+    if (len < 16)
         return;
 
     start = avio_rb32(pb);
     end   = avio_rb32(pb);
-    taglen -= 27;
-    if (taglen > 0) {
-        char tag[4];
+    avio_skip(pb, 8);
 
-        avio_skip(pb, 8);
-        avio_read(pb, tag, 4);
-        if (!memcmp(tag, "TIT2", 4)) {
-            taglen = FFMIN(taglen, avio_rb32(pb));
-            if (taglen < 0)
-                return;
-            avio_skip(pb, 3);
-            avio_get_str(pb, taglen, title, sizeof(title));
-        }
+    chapter = avpriv_new_chapter(s, s->nb_chapters + 1, time_base, start, end, dst);
+    if (!chapter) {
+        av_free(dst);
+        return;
     }
 
-    avpriv_new_chapter(s, s->nb_chapters + 1, time_base, start, end, title);
+    len -= 16;
+    while (len > 10) {
+        avio_read(pb, tag, 4);
+        tag[4] = 0;
+        taglen = avio_rb32(pb);
+        avio_skip(pb, 2);
+        len -= 10;
+        if (taglen < 0 || taglen > len) {
+            av_free(dst);
+            return;
+        }
+        if (tag[0] == 'T')
+            read_ttag(s, pb, taglen, &chapter->metadata, tag);
+        else
+            avio_skip(pb, taglen);
+        len -= taglen;
+    }
+
+    ff_metadata_conv(&chapter->metadata, NULL, ff_id3v2_34_metadata_conv);
+    ff_metadata_conv(&chapter->metadata, NULL, ff_id3v2_4_metadata_conv);
+    av_free(dst);
 }
 
 typedef struct ID3v2EMFunc {
     const char *tag3;
     const char *tag4;
-    void (*read)(AVFormatContext*, AVIOContext*, int, char*, ID3v2ExtraMeta **);
+    void (*read)(AVFormatContext *, AVIOContext *, int, char *,
+                 ID3v2ExtraMeta **);
     void (*free)(void *obj);
 } ID3v2EMFunc;
 
 static const ID3v2EMFunc id3v2_extra_meta_funcs[] = {
     { "GEO", "GEOB", read_geobtag, free_geobtag },
-    { "PIC", "APIC", read_apic,    free_apic },
-    { "CHAP","CHAP", read_chapter, NULL },
+    { "PIC", "APIC", read_apic,    free_apic    },
+    { "CHAP","CHAP", read_chapter, NULL         },
     { NULL }
 };
 
@@ -571,7 +599,8 @@
     return NULL;
 }
 
-static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags, ID3v2ExtraMeta **extra_meta)
+static void id3v2_parse(AVFormatContext *s, int len, uint8_t version,
+                        uint8_t flags, ID3v2ExtraMeta **extra_meta)
 {
     int isv34, unsync;
     unsigned tlen;
@@ -582,7 +611,7 @@
     AVIOContext pb;
     AVIOContext *pbx;
     unsigned char *buffer = NULL;
-    int buffer_size = 0;
+    int buffer_size       = 0;
     const ID3v2EMFunc *extra_func = NULL;
     unsigned char *uncompressed_buffer = NULL;
     int uncompressed_buffer_size = 0;
@@ -595,13 +624,13 @@
             reason = "compression";
             goto error;
         }
-        isv34 = 0;
+        isv34     = 0;
         taghdrlen = 6;
         break;
 
     case 3:
     case 4:
-        isv34 = 1;
+        isv34     = 1;
         taghdrlen = 10;
         break;
 
@@ -615,7 +644,8 @@
     if (isv34 && flags & 0x40) { /* Extended header present, just skip over it */
         int extlen = get_size(s->pb, 4);
         if (version == 4)
-            extlen -= 4;     // in v2.4 the length includes the length field we just read
+            /* In v2.4 the length includes the length field we just read. */
+            extlen -= 4;
 
         if (extlen < 0) {
             reason = "invalid extended header length";
@@ -631,24 +661,24 @@
 
     while (len >= taghdrlen) {
         unsigned int tflags = 0;
-        int tunsync = 0;
-        int tcomp = 0;
-        int tencr = 0;
+        int tunsync         = 0;
+        int tcomp           = 0;
+        int tencr           = 0;
         unsigned long dlen;
 
         if (isv34) {
             avio_read(s->pb, tag, 4);
             tag[4] = 0;
-            if(version==3){
+            if (version == 3) {
                 tlen = avio_rb32(s->pb);
-            }else
+            } else
                 tlen = get_size(s->pb, 4);
-            tflags = avio_rb16(s->pb);
+            tflags  = avio_rb16(s->pb);
             tunsync = tflags & ID3v2_FLAG_UNSYNCH;
         } else {
             avio_read(s->pb, tag, 3);
             tag[3] = 0;
-            tlen = avio_rb24(s->pb);
+            tlen   = avio_rb24(s->pb);
         }
         if (tlen > (1<<28))
             break;
@@ -661,7 +691,8 @@
 
         if (!tlen) {
             if (tag[0])
-                av_log(s, AV_LOG_DEBUG, "Invalid empty frame %s, skipping.\n", tag);
+                av_log(s, AV_LOG_DEBUG, "Invalid empty frame %s, skipping.\n",
+                       tag);
             continue;
         }
 
@@ -689,7 +720,9 @@
             av_log(s, AV_LOG_WARNING, "Skipping %s ID3v2 frame %s.\n", type, tag);
             avio_skip(s->pb, tlen);
         /* check for text tag or supported special meta tag */
-        } else if (tag[0] == 'T' || (extra_meta && (extra_func = get_extra_meta_func(tag, isv34)))) {
+        } else if (tag[0] == 'T' ||
+                   (extra_meta &&
+                    (extra_func = get_extra_meta_func(tag, isv34)))) {
             pbx = s->pb;
 
             if (unsync || tunsync || tcomp) {
@@ -704,16 +737,19 @@
                 uint8_t *b;
 
                 b = buffer;
-                while (avio_tell(s->pb) < end && b - buffer < tlen) {
+                while (avio_tell(s->pb) < end && b - buffer < tlen && !s->pb->eof_reached) {
                     *b++ = avio_r8(s->pb);
-                    if (*(b - 1) == 0xff && avio_tell(s->pb) < end - 1 && b - buffer < tlen) {
+                    if (*(b - 1) == 0xff && avio_tell(s->pb) < end - 1 &&
+                        b - buffer < tlen &&
+                        !s->pb->eof_reached ) {
                         uint8_t val = avio_r8(s->pb);
                         *b++ = val ? val : avio_r8(s->pb);
                     }
                 }
-                ffio_init_context(&pb, buffer, b - buffer, 0, NULL, NULL, NULL, NULL);
+                ffio_init_context(&pb, buffer, b - buffer, 0, NULL, NULL, NULL,
+                                  NULL);
                 tlen = b - buffer;
-                pbx = &pb; // read from sync buffer
+                pbx  = &pb; // read from sync buffer
             }
 
 #if CONFIG_ZLIB
@@ -749,12 +785,11 @@
 #endif
             if (tag[0] == 'T')
                 /* parse text tag */
-                read_ttag(s, pbx, tlen, tag);
+                read_ttag(s, pbx, tlen, &s->metadata, tag);
             else
                 /* parse special meta tag */
                 extra_func->read(s, pbx, tlen, tag, extra_meta);
-        }
-        else if (!tag[0]) {
+        } else if (!tag[0]) {
             if (tag[1])
                 av_log(s, AV_LOG_WARNING, "invalid frame id, assuming padding\n");
             avio_skip(s->pb, tlen);
@@ -765,23 +800,26 @@
         avio_seek(s->pb, next, SEEK_SET);
     }
 
-    if (version == 4 && flags & 0x10) /* Footer preset, always 10 bytes, skip over it */
+    /* Footer preset, always 10 bytes, skip over it */
+    if (version == 4 && flags & 0x10)
         end += 10;
 
-  error:
+error:
     if (reason)
-        av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n", version, reason);
+        av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n",
+               version, reason);
     avio_seek(s->pb, end, SEEK_SET);
     av_free(buffer);
     av_free(uncompressed_buffer);
     return;
 }
 
-void ff_id3v2_read(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra_meta)
+void ff_id3v2_read(AVFormatContext *s, const char *magic,
+                   ID3v2ExtraMeta **extra_meta)
 {
     int len, ret;
     uint8_t buf[ID3v2_HEADER_SIZE];
-    int     found_header;
+    int found_header;
     int64_t off;
 
     do {
@@ -799,7 +837,7 @@
                   ((buf[7] & 0x7f) << 14) |
                   ((buf[8] & 0x7f) << 7) |
                    (buf[9] & 0x7f);
-            ff_id3v2_parse(s, len, buf[3], buf[5], extra_meta);
+            id3v2_parse(s, len, buf[3], buf[5], extra_meta);
         } else {
             avio_seek(s->pb, off, SEEK_SET);
         }
diff --git a/libavformat/id3v2enc.c b/libavformat/id3v2enc.c
index a10d679..6052244 100644
--- a/libavformat/id3v2enc.c
+++ b/libavformat/id3v2enc.c
@@ -26,8 +26,11 @@
 #include "libavutil/intreadwrite.h"
 #include "avformat.h"
 #include "avio.h"
+#include "avio_internal.h"
 #include "id3v2.h"
 
+#define PADDING_BYTES 10
+
 static void id3v2_put_size(AVIOContext *pb, int size)
 {
     avio_w8(pb, size >> 21 & 0x7f);
@@ -162,33 +165,31 @@
     avio_wb32(pb, 0);
 }
 
-int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3)
+static int write_metadata(AVIOContext *pb, AVDictionary **metadata,
+                          ID3v2EncContext *id3, int enc)
 {
     AVDictionaryEntry *t = NULL;
-    int enc = id3->version == 3 ? ID3v2_ENCODING_UTF16BOM :
-                                  ID3v2_ENCODING_UTF8;
+    int ret;
 
-    ff_metadata_conv(&s->metadata, ff_id3v2_34_metadata_conv, NULL);
+    ff_metadata_conv(metadata, ff_id3v2_34_metadata_conv, NULL);
     if (id3->version == 3)
-        id3v2_3_metadata_split_date(&s->metadata);
+        id3v2_3_metadata_split_date(metadata);
     else if (id3->version == 4)
-        ff_metadata_conv(&s->metadata, ff_id3v2_4_metadata_conv, NULL);
+        ff_metadata_conv(metadata, ff_id3v2_4_metadata_conv, NULL);
 
-    while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) {
-        int ret;
-
-        if ((ret = id3v2_check_write_tag(id3, s->pb, t, ff_id3v2_tags, enc)) > 0) {
+    while ((t = av_dict_get(*metadata, "", t, AV_DICT_IGNORE_SUFFIX))) {
+        if ((ret = id3v2_check_write_tag(id3, pb, t, ff_id3v2_tags, enc)) > 0) {
             id3->len += ret;
             continue;
         }
-        if ((ret = id3v2_check_write_tag(id3, s->pb, t, id3->version == 3 ?
-                                               ff_id3v2_3_tags : ff_id3v2_4_tags, enc)) > 0) {
+        if ((ret = id3v2_check_write_tag(id3, pb, t, id3->version == 3 ?
+                                         ff_id3v2_3_tags : ff_id3v2_4_tags, enc)) > 0) {
             id3->len += ret;
             continue;
         }
 
         /* unknown tag, write as TXXX frame */
-        if ((ret = id3v2_put_ttag(id3, s->pb, t->key, t->value, MKBETAG('T', 'X', 'X', 'X'), enc)) < 0)
+        if ((ret = id3v2_put_ttag(id3, pb, t->key, t->value, MKBETAG('T', 'X', 'X', 'X'), enc)) < 0)
             return ret;
         id3->len += ret;
     }
@@ -196,6 +197,64 @@
     return 0;
 }
 
+static int write_chapter(AVFormatContext *s, ID3v2EncContext *id3, int id, int enc)
+{
+    const AVRational time_base = {1, 1000};
+    AVChapter *ch = s->chapters[id];
+    uint8_t *dyn_buf = NULL;
+    AVIOContext *dyn_bc = NULL;
+    char name[123];
+    int len, start, end, ret;
+
+    if ((ret = avio_open_dyn_buf(&dyn_bc)) < 0)
+        goto fail;
+
+    start = av_rescale_q(ch->start, ch->time_base, time_base);
+    end   = av_rescale_q(ch->end,   ch->time_base, time_base);
+
+    snprintf(name, 122, "ch%d", id);
+    id3->len += avio_put_str(dyn_bc, name);
+    avio_wb32(dyn_bc, start);
+    avio_wb32(dyn_bc, end);
+    avio_wb32(dyn_bc, 0xFFFFFFFFu);
+    avio_wb32(dyn_bc, 0xFFFFFFFFu);
+
+    if ((ret = write_metadata(dyn_bc, &ch->metadata, id3, enc)) < 0)
+        goto fail;
+
+    len = avio_close_dyn_buf(dyn_bc, &dyn_buf);
+    id3->len += 16 + ID3v2_HEADER_SIZE;
+
+    avio_wb32(s->pb, MKBETAG('C', 'H', 'A', 'P'));
+    avio_wb32(s->pb, len);
+    avio_wb16(s->pb, 0);
+    avio_write(s->pb, dyn_buf, len);
+
+fail:
+    if (dyn_bc && !dyn_buf)
+        avio_close_dyn_buf(dyn_bc, &dyn_buf);
+    av_freep(&dyn_buf);
+
+    return ret;
+}
+
+int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3)
+{
+    int enc = id3->version == 3 ? ID3v2_ENCODING_UTF16BOM :
+                                  ID3v2_ENCODING_UTF8;
+    int i, ret;
+
+    if ((ret = write_metadata(s->pb, &s->metadata, id3, enc)) < 0)
+        return ret;
+
+    for (i = 0; i < s->nb_chapters; i++) {
+        if ((ret = write_chapter(s, id3, i, enc)) < 0)
+            return ret;
+    }
+
+    return 0;
+}
+
 int ff_id3v2_write_apic(AVFormatContext *s, ID3v2EncContext *id3, AVPacket *pkt)
 {
     AVStream *st = s->streams[pkt->stream_index];
@@ -236,6 +295,10 @@
     if ((e = av_dict_get(st->metadata, "title", NULL, 0)))
         desc = e->value;
 
+    /* use UTF16 only for non-ASCII strings */
+    if (enc == ID3v2_ENCODING_UTF16BOM && string_is_ascii(desc))
+        enc = ID3v2_ENCODING_ISO8859;
+
     /* start writing */
     if (avio_open_dyn_buf(&dyn_buf) < 0)
         return AVERROR(ENOMEM);
@@ -263,7 +326,15 @@
 
 void ff_id3v2_finish(ID3v2EncContext *id3, AVIOContext *pb)
 {
-    int64_t cur_pos = avio_tell(pb);
+    int64_t cur_pos;
+
+    /* adding an arbitrary amount of padding bytes at the end of the
+     * ID3 metadata fixes cover art display for some software (iTunes,
+     * Traktor, Serato, Torq) */
+    ffio_fill(pb, 0, PADDING_BYTES);
+    id3->len += PADDING_BYTES;
+
+    cur_pos = avio_tell(pb);
     avio_seek(pb, id3->size_pos, SEEK_SET);
     id3v2_put_size(pb, id3->len);
     avio_seek(pb, cur_pos, SEEK_SET);
diff --git a/libavformat/idcin.c b/libavformat/idcin.c
index 2a8af40..85d538c 100644
--- a/libavformat/idcin.c
+++ b/libavformat/idcin.c
@@ -93,7 +93,7 @@
 
 static int idcin_probe(AVProbeData *p)
 {
-    unsigned int number;
+    unsigned int number, sample_rate;
 
     /*
      * This is what you could call a "probabilistic" file check: id CIN
@@ -122,22 +122,22 @@
        return 0;
 
     /* check the audio sample rate */
-    number = AV_RL32(&p->buf[8]);
-    if ((number != 0) && ((number < 8000) | (number > 48000)))
+    sample_rate = AV_RL32(&p->buf[8]);
+    if (sample_rate && (sample_rate < 8000 || sample_rate > 48000))
         return 0;
 
     /* check the audio bytes/sample */
     number = AV_RL32(&p->buf[12]);
-    if (number > 2)
+    if (number > 2 || sample_rate && !number)
         return 0;
 
     /* check the audio channels */
     number = AV_RL32(&p->buf[16]);
-    if (number > 2)
+    if (number > 2 || sample_rate && !number)
         return 0;
 
-    /* return half certainly since this check is a bit sketchy */
-    return AVPROBE_SCORE_MAX / 2;
+    /* return half certainty since this check is a bit sketchy */
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 static int idcin_read_header(AVFormatContext *s)
@@ -196,8 +196,10 @@
     st->codec->height = height;
 
     /* load up the Huffman tables into extradata */
-    st->codec->extradata_size = HUFFMAN_TABLE_SIZE;
     st->codec->extradata = av_malloc(HUFFMAN_TABLE_SIZE);
+    if (!st->codec->extradata)
+        return AVERROR(ENOMEM);
+    st->codec->extradata_size = HUFFMAN_TABLE_SIZE;
     ret = avio_read(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE);
     if (ret < 0) {
         return ret;
diff --git a/libavformat/iff.c b/libavformat/iff.c
index 1efc147..edf308b 100644
--- a/libavformat/iff.c
+++ b/libavformat/iff.c
@@ -481,5 +481,5 @@
     .read_probe     = iff_probe,
     .read_header    = iff_read_header,
     .read_packet    = iff_read_packet,
-    .flags          = AVFMT_GENERIC_INDEX,
+    .flags          = AVFMT_GENERIC_INDEX | AVFMT_NO_BYTE_SEEK,
 };
diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c
index 12cf462..5163e69 100644
--- a/libavformat/img2dec.c
+++ b/libavformat/img2dec.c
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <sys/stat.h>
 #include "libavutil/avstring.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
@@ -63,6 +64,7 @@
     int start_number;
     int start_number_range;
     int frame_size;
+    int ts_from_file;
 } VideoDemuxData;
 
 static const int sizes[][2] = {
@@ -185,7 +187,7 @@
         else if (av_match_ext(p->filename, "raw") || av_match_ext(p->filename, "gif"))
             return 5;
         else
-            return AVPROBE_SCORE_MAX / 2;
+            return AVPROBE_SCORE_EXTENSION;
     }
     return 0;
 }
@@ -223,7 +225,10 @@
         st->need_parsing = AVSTREAM_PARSE_FULL;
     }
 
-    avpriv_set_pts_info(st, 60, s->framerate.den, s->framerate.num);
+    if (s->ts_from_file)
+        avpriv_set_pts_info(st, 64, 1, 1);
+    else
+        avpriv_set_pts_info(st, 64, s->framerate.den, s->framerate.num);
 
     if (s->width && s->height) {
         st->codec->width  = s->width;
@@ -267,7 +272,7 @@
             if (find_image_range(&first_index, &last_index, s->path,
                                  s->start_number, s->start_number_range) < 0) {
                 av_log(s1, AV_LOG_ERROR,
-                       "Could find no file with with path '%s' and index in the range %d-%d\n",
+                       "Could find no file with path '%s' and index in the range %d-%d\n",
                        s->path, s->start_number, s->start_number + s->start_number_range - 1);
                 return AVERROR(ENOENT);
             }
@@ -296,8 +301,10 @@
         s->img_last   = last_index;
         s->img_number = first_index;
         /* compute duration */
-        st->start_time = 0;
-        st->duration   = last_index - first_index + 1;
+        if (!s->ts_from_file) {
+            st->start_time = 0;
+            st->duration   = last_index - first_index + 1;
+        }
     }
 
     if (s1->video_codec_id) {
@@ -381,8 +388,15 @@
         return AVERROR(ENOMEM);
     pkt->stream_index = 0;
     pkt->flags       |= AV_PKT_FLAG_KEY;
-    if (!s->is_pipe)
+    if (s->ts_from_file) {
+        struct stat img_stat;
+        if (stat(filename, &img_stat))
+            return AVERROR(EIO);
+        pkt->pts = (int64_t)img_stat.st_mtime;
+        av_add_index_entry(s1->streams[0], s->img_number, pkt->pts, 0, 0, AVINDEX_KEYFRAME);
+    } else if (!s->is_pipe) {
         pkt->pts      = s->pts;
+    }
 
     pkt->size = 0;
     for (i = 0; i < 3; i++) {
@@ -420,6 +434,15 @@
 static int img_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
 {
     VideoDemuxData *s1 = s->priv_data;
+    AVStream *st = s->streams[0];
+
+    if (s1->ts_from_file) {
+        int index = av_index_search_timestamp(st, timestamp, flags);
+        if(index < 0)
+            return -1;
+        s1->img_number = st->index_entries[index].pos;
+        return 0;
+    }
 
     if (timestamp < 0 || !s1->loop && timestamp > s1->img_last - s1->img_first)
         return -1;
@@ -444,6 +467,7 @@
     { "start_number_range", "set range for looking at the first sequence number", OFFSET(start_number_range), AV_OPT_TYPE_INT, {.i64 = 5}, 1, INT_MAX, DEC },
     { "video_size",   "set video size",                      OFFSET(width),        AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0,   DEC },
     { "frame_size",   "force frame size in bytes",           OFFSET(frame_size),   AV_OPT_TYPE_INT,    {.i64 = 0   }, 0, INT_MAX, DEC },
+    { "ts_from_file", "set frame timestamp from file's one", OFFSET(ts_from_file), AV_OPT_TYPE_INT,    {.i64 = 0   }, 0, 1,       DEC },
     { NULL },
 };
 
diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c
index fb297da..11223fb 100644
--- a/libavformat/img2enc.c
+++ b/libavformat/img2enc.c
@@ -37,6 +37,7 @@
     int split_planes;       /**< use independent file for each Y, U, V plane */
     char path[1024];
     int update;
+    int use_strftime;
 } VideoMuxData;
 
 static int write_header(AVFormatContext *s)
@@ -60,7 +61,7 @@
                          && s->nb_streams == 1
                          && st->codec->codec_id == AV_CODEC_ID_RAWVIDEO
                          && desc
-                         &&(desc->flags & PIX_FMT_PLANAR)
+                         &&(desc->flags & AV_PIX_FMT_FLAG_PLANAR)
                          && desc->nb_components >= 3;
     return 0;
 }
@@ -77,6 +78,15 @@
     if (!img->is_pipe) {
         if (img->update) {
             av_strlcpy(filename, img->path, sizeof(filename));
+        } else if (img->use_strftime) {
+            time_t now0;
+            struct tm *tm;
+            time(&now0);
+            tm = localtime(&now0);
+            if (!strftime(filename, sizeof(filename), img->path, tm)) {
+                av_log(s, AV_LOG_ERROR, "Could not get frame filename with strftime\n");
+                return AVERROR(EINVAL);
+            }
         } else if (av_get_frame_filename(filename, sizeof(filename), img->path, img->img_number) < 0 &&
                    img->img_number > 1) {
             av_log(s, AV_LOG_ERROR,
@@ -101,7 +111,7 @@
 
     if (img->split_planes) {
         int ysize = codec->width * codec->height;
-        int usize = ((-codec->width)>>desc->log2_chroma_w) * ((-codec->height)>>desc->log2_chroma_h);
+        int usize = FF_CEIL_RSHIFT(codec->width, desc->log2_chroma_w) * FF_CEIL_RSHIFT(codec->height, desc->log2_chroma_h);
         if (desc->comp[0].depth_minus1 >= 8) {
             ysize *= 2;
             usize *= 2;
@@ -132,7 +142,8 @@
 static const AVOption muxoptions[] = {
     { "updatefirst",  "continuously overwrite one file", OFFSET(update),  AV_OPT_TYPE_INT, { .i64 = 0 }, 0,       1, ENC },
     { "update",       "continuously overwrite one file", OFFSET(update),  AV_OPT_TYPE_INT, { .i64 = 0 }, 0,       1, ENC },
-    { "start_number", "set first number in the sequence", OFFSET(img_number), AV_OPT_TYPE_INT,  { .i64 = 1 }, 1, INT_MAX, ENC },
+    { "start_number", "set first number in the sequence", OFFSET(img_number), AV_OPT_TYPE_INT,  { .i64 = 1 }, 0, INT_MAX, ENC },
+    { "strftime",     "use strftime for filename", OFFSET(use_strftime), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, ENC },
     { NULL },
 };
 
@@ -148,7 +159,7 @@
     .name           = "image2",
     .long_name      = NULL_IF_CONFIG_SMALL("image2 sequence"),
     .extensions     = "bmp,dpx,jls,jpeg,jpg,ljpg,pam,pbm,pcx,pgm,pgmyuv,png,"
-                      "ppm,sgi,tga,tif,tiff,jp2,j2c,xwd,sun,ras,rs,im1,im8,im24,"
+                      "ppm,sgi,tga,tif,tiff,jp2,j2c,j2k,xwd,sun,ras,rs,im1,im8,im24,"
                       "sunras,xbm,xface",
     .priv_data_size = sizeof(VideoMuxData),
     .video_codec    = AV_CODEC_ID_MJPEG,
diff --git a/libavformat/internal.h b/libavformat/internal.h
index 4d56388..1f74069 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -90,31 +90,6 @@
 uint64_t ff_ntp_time(void);
 
 /**
- * Assemble a URL string from components. This is the reverse operation
- * of av_url_split.
- *
- * Note, this requires networking to be initialized, so the caller must
- * ensure ff_network_init has been called.
- *
- * @see av_url_split
- *
- * @param str the buffer to fill with the url
- * @param size the size of the str buffer
- * @param proto the protocol identifier, if null, the separator
- *              after the identifier is left out, too
- * @param authorization an optional authorization string, may be null.
- *                      An empty string is treated the same as a null string.
- * @param hostname the host name string
- * @param port the port number, left out from the string if negative
- * @param fmt a generic format string for everything to add after the
- *            host/port, may be null
- * @return the number of characters written to the destination buffer
- */
-int ff_url_join(char *str, int size, const char *proto,
-                const char *authorization, const char *hostname,
-                int port, const char *fmt, ...) av_printf_format(7, 8);
-
-/**
  * Append the media-specific SDP fragment for the media stream c
  * to the buffer buff.
  *
@@ -240,17 +215,6 @@
  */
 void ff_reduce_index(AVFormatContext *s, int stream_index);
 
-/**
- * Convert a relative url into an absolute url, given a base url.
- *
- * @param buf the buffer where output absolute url is written
- * @param size the size of buf
- * @param base the base url, may be equal to buf.
- * @param rel the new url, which is interpreted relative to base
- */
-void ff_make_absolute_url(char *buf, int size, const char *base,
-                          const char *rel);
-
 enum AVCodecID ff_guess_image2_codec(const char *filename);
 
 /**
@@ -278,6 +242,9 @@
  */
 void ff_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp);
 
+int ff_find_last_ts(AVFormatContext *s, int stream_index, int64_t *ts, int64_t *pos,
+                    int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ));
+
 /**
  * Perform a binary search using read_timestamp().
  *
@@ -390,6 +357,4 @@
  */
 void ff_generate_avci_extradata(AVStream *st);
 
-int ff_http_match_no_proxy(const char *no_proxy, const char *hostname);
-
 #endif /* AVFORMAT_INTERNAL_H */
diff --git a/libavformat/isom.c b/libavformat/isom.c
index 4078c0d..ec37228 100644
--- a/libavformat/isom.c
+++ b/libavformat/isom.c
@@ -21,8 +21,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-//#define DEBUG
-
 #include "avformat.h"
 #include "internal.h"
 #include "isom.h"
@@ -188,6 +186,7 @@
     { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '4', 'p') }, /* MPEG2 IMX PAL 625/50 40mb/s produced by FCP */
     { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'n') }, /* MPEG2 IMX NTSC 525/60 30mb/s produced by FCP */
     { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'p') }, /* MPEG2 IMX PAL 625/50 30mb/s produced by FCP */
+    { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '1') }, /* XDCAM HD422 720p30 CBR */
     { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '4') }, /* XDCAM HD422 720p24 CBR */
     { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '5') }, /* XDCAM HD422 720p25 CBR */
     { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '9') }, /* XDCAM HD422 720p60 CBR */
@@ -244,6 +243,8 @@
     { AV_CODEC_ID_PRORES, MKTAG('a', 'p', '4', 'h') }, /* Apple ProRes 4444 */
     { AV_CODEC_ID_FLIC,   MKTAG('f', 'l', 'i', 'c') },
 
+    { AV_CODEC_ID_AIC, MKTAG('i', 'c', 'o', 'd') },
+
     { AV_CODEC_ID_NONE, 0 },
 };
 
diff --git a/libavformat/isom.h b/libavformat/isom.h
index 4154baf..b0fa453 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -110,7 +110,7 @@
     int ctts_index;
     int ctts_sample;
     unsigned int sample_size; ///< may contain value calculated from stsd or value from stsz atom
-    unsigned int alt_sample_size; ///< always contains sample size from stsz atom
+    unsigned int stsz_sample_size; ///< always contains sample size from stsz atom
     unsigned int sample_count;
     int *sample_sizes;
     int keyframe_absent;
@@ -162,6 +162,8 @@
     int use_absolute_path;
     int ignore_editlist;
     int64_t next_root_atom; ///< offset of the next root atom
+    int *bitrates;          ///< bitrates read before streams creation
+    int bitrates_count;
 } MOVContext;
 
 int ff_mp4_read_descr_len(AVIOContext *pb);
diff --git a/libavformat/jacosubdec.c b/libavformat/jacosubdec.c
index 89e7e1bf..da1afad 100644
--- a/libavformat/jacosubdec.c
+++ b/libavformat/jacosubdec.c
@@ -60,7 +60,7 @@
             ptr++;
         if (*ptr != '#' && *ptr != '\n') {
             if (timed_line(ptr))
-                return AVPROBE_SCORE_MAX/2 + 1;
+                return AVPROBE_SCORE_EXTENSION + 1;
             return 0;
         }
         ptr += strcspn(ptr, "\n") + 1;
diff --git a/libavformat/jvdec.c b/libavformat/jvdec.c
index e941492..69ac8f2 100644
--- a/libavformat/jvdec.c
+++ b/libavformat/jvdec.c
@@ -33,10 +33,10 @@
 #define JV_PREAMBLE_SIZE 5
 
 typedef struct {
-    int audio_size;    /** audio packet size (bytes) */
-    int video_size;    /** video packet size (bytes) */
-    int palette_size;  /** palette size (bytes) */
-    int video_type;    /** per-frame video compression type */
+    int audio_size;    /**< audio packet size (bytes) */
+    int video_size;    /**< video packet size (bytes) */
+    int palette_size;  /**< palette size (bytes) */
+    int video_type;    /**< per-frame video compression type */
 } JVFrame;
 
 typedef struct {
diff --git a/libavformat/latmenc.c b/libavformat/latmenc.c
index 9dfb4e4..b3430d7 100644
--- a/libavformat/latmenc.c
+++ b/libavformat/latmenc.c
@@ -124,7 +124,7 @@
 
             if (!ctx->channel_conf) {
                 GetBitContext gb;
-                init_get_bits(&gb, avctx->extradata, avctx->extradata_size * 8);
+                init_get_bits8(&gb, avctx->extradata, avctx->extradata_size);
                 skip_bits_long(&gb, ctx->off + 3);
                 avpriv_copy_pce_data(bs, &gb);
             }
diff --git a/libavformat/libgme.c b/libavformat/libgme.c
new file mode 100644
index 0000000..1ae63dc
--- /dev/null
+++ b/libavformat/libgme.c
@@ -0,0 +1,201 @@
+/*
+ * 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
+ */
+
+/**
+* @file
+* libgme demuxer
+*/
+
+#include <gme/gme.h>
+#include "libavutil/avstring.h"
+#include "libavutil/eval.h"
+#include "libavutil/opt.h"
+#include "avformat.h"
+#include "internal.h"
+
+typedef struct GMEContext {
+    const AVClass *class;
+    Music_Emu *music_emu;
+    gme_info_t *info;   ///< selected track
+
+    /* options */
+    int track_index;
+    int sample_rate;
+    int64_t max_size;
+} GMEContext;
+
+#define OFFSET(x) offsetof(GMEContext, x)
+#define A AV_OPT_FLAG_AUDIO_PARAM
+#define D AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+    {"track_index", "set track that should be played",        OFFSET(track_index), AV_OPT_TYPE_INT,   {.i64 = 0},                0,    INT_MAX,  A|D},
+    {"sample_rate", "set sample rate",                        OFFSET(sample_rate), AV_OPT_TYPE_INT,   {.i64 = 44100},            1000, 999999,   A|D},
+    {"max_size",    "set max file size supported (in bytes)", OFFSET(max_size),    AV_OPT_TYPE_INT64, {.i64 = 50 * 1024 * 1024}, 0,    SIZE_MAX, A|D},
+    {NULL}
+};
+
+static void add_meta(AVFormatContext *s, const char *name, const char *value)
+{
+    if (value && value[0])
+        av_dict_set(&s->metadata, name, value, 0);
+}
+
+static int load_metadata(AVFormatContext *s)
+{
+    GMEContext *gme = s->priv_data;
+    gme_info_t *info = gme->info;
+    char buf[30];
+
+    add_meta(s, "system",       info->system);
+    add_meta(s, "game",         info->game);
+    add_meta(s, "song",         info->song);
+    add_meta(s, "author",       info->author);
+    add_meta(s, "copyright",    info->copyright);
+    add_meta(s, "comment",      info->comment);
+    add_meta(s, "dumper",       info->dumper);
+
+    snprintf(buf, sizeof(buf), "%d", (int)gme_track_count(gme->music_emu));
+    add_meta(s, "tracks", buf);
+
+    return 0;
+}
+
+#define AUDIO_PKT_SIZE 512
+
+static int read_header_gme(AVFormatContext *s)
+{
+    AVStream *st;
+    AVIOContext *pb = s->pb;
+    GMEContext *gme = s->priv_data;
+    int64_t sz = avio_size(pb);
+    char *buf;
+    char dummy;
+
+    if (sz < 0) {
+        av_log(s, AV_LOG_WARNING, "Could not determine file size\n");
+        sz = gme->max_size;
+    } else if (gme->max_size && sz > gme->max_size) {
+        sz = gme->max_size;
+    }
+
+    buf = av_malloc(sz);
+    if (!buf)
+        return AVERROR(ENOMEM);
+    sz = avio_read(pb, buf, sz);
+
+    // Data left means our buffer (the max_size option) is too small
+    if (avio_read(pb, &dummy, 1) == 1) {
+        av_log(s, AV_LOG_ERROR, "File size is larger than max_size option "
+               "value %"PRIi64", consider increasing the max_size option\n",
+               gme->max_size);
+        return AVERROR_BUFFER_TOO_SMALL;
+    }
+
+    if (gme_open_data(buf, sz, &gme->music_emu, gme->sample_rate)) {
+        av_freep(&buf);
+        return AVERROR_INVALIDDATA;
+    }
+    av_freep(&buf);
+
+    if (gme_track_info(gme->music_emu, &gme->info, gme->track_index))
+        return AVERROR_STREAM_NOT_FOUND;
+
+    if (gme_start_track(gme->music_emu, gme->track_index))
+        return AVERROR_UNKNOWN;
+
+    load_metadata(s);
+
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+    avpriv_set_pts_info(st, 64, 1, 1000);
+    if (st->duration > 0)
+        st->duration = gme->info->length;
+    st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_id    = AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE);
+    st->codec->channels    = 2;
+    st->codec->sample_rate = gme->sample_rate;
+
+    return 0;
+}
+
+static int read_packet_gme(AVFormatContext *s, AVPacket *pkt)
+{
+    GMEContext *gme = s->priv_data;
+    int n_samples = AUDIO_PKT_SIZE / 2;
+    int ret;
+
+    if (gme_track_ended(gme->music_emu))
+        return AVERROR_EOF;
+
+    if ((ret = av_new_packet(pkt, AUDIO_PKT_SIZE)) < 0)
+        return ret;
+
+    if (gme_play(gme->music_emu, n_samples, (short *)pkt->data))
+        return AVERROR_EXTERNAL;
+    pkt->size = AUDIO_PKT_SIZE;
+
+    return 0;
+}
+
+static int read_close_gme(AVFormatContext *s)
+{
+    GMEContext *gme = s->priv_data;
+    gme_free_info(gme->info);
+    gme_delete(gme->music_emu);
+    return 0;
+}
+
+static int read_seek_gme(AVFormatContext *s, int stream_idx, int64_t ts, int flags)
+{
+    GMEContext *gme = s->priv_data;
+    if (!gme_seek(gme->music_emu, (int)ts))
+        return AVERROR_EXTERNAL;
+    return 0;
+}
+
+static int probe_gme(AVProbeData *p)
+{
+    // Reads 4 bytes - returns "" if unknown format.
+    if (gme_identify_header(p->buf)[0]) {
+        if (p->buf_size < 16384)
+            return AVPROBE_SCORE_MAX / 4 + 1;
+        else
+            return AVPROBE_SCORE_MAX / 2;
+    }
+    return 0;
+}
+
+static const AVClass class_gme = {
+    .class_name = "Game Music Emu demuxer",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_libgme_demuxer = {
+    .name           = "libgme",
+    .long_name      = NULL_IF_CONFIG_SMALL("Game Music Emu demuxer"),
+    .priv_data_size = sizeof(GMEContext),
+    .read_probe     = probe_gme,
+    .read_header    = read_header_gme,
+    .read_packet    = read_packet_gme,
+    .read_close     = read_close_gme,
+    .read_seek      = read_seek_gme,
+    .priv_class     = &class_gme,
+};
diff --git a/libavformat/libmodplug.c b/libavformat/libmodplug.c
index aa8edcc..836b7c2 100644
--- a/libavformat/libmodplug.c
+++ b/libavformat/libmodplug.c
@@ -166,14 +166,14 @@
     AVIOContext *pb = s->pb;
     ModPlug_Settings settings;
     ModPlugContext *modplug = s->priv_data;
-    int sz = avio_size(pb);
+    int64_t sz = avio_size(pb);
 
     if (sz < 0) {
         av_log(s, AV_LOG_WARNING, "Could not determine file size\n");
         sz = modplug->max_size;
     } else if (modplug->max_size && sz > modplug->max_size) {
         sz = modplug->max_size;
-        av_log(s, AV_LOG_WARNING, "Max file size reach%s, allocating %dB "
+        av_log(s, AV_LOG_WARNING, "Max file size reach%s, allocating %"PRIi64"B "
                "but demuxing is likely to fail due to incomplete buffer\n",
                sz == FF_MODPLUG_DEF_FILE_SIZE ? " (see -max_size)" : "", sz);
     }
@@ -347,6 +347,19 @@
     return 0;
 }
 
+static const char modplug_extensions[] = "669,abc,amf,ams,dbm,dmf,dsm,far,it,mdl,med,mid,mod,mt2,mtm,okt,psm,ptm,s3m,stm,ult,umx,xm,itgz,itr,itz,mdgz,mdr,mdz,s3gz,s3r,s3z,xmgz,xmr,xmz";
+
+static int modplug_probe(AVProbeData *p)
+{
+    if (av_match_ext(p->filename, modplug_extensions)) {
+        if (p->buf_size < 16384)
+            return AVPROBE_SCORE_EXTENSION/2-1;
+        else
+            return AVPROBE_SCORE_EXTENSION;
+    }
+    return 0;
+}
+
 static const AVClass modplug_class = {
     .class_name = "ModPlug demuxer",
     .item_name  = av_default_item_name,
@@ -358,11 +371,11 @@
     .name           = "libmodplug",
     .long_name      = NULL_IF_CONFIG_SMALL("ModPlug demuxer"),
     .priv_data_size = sizeof(ModPlugContext),
+    .read_probe     = modplug_probe,
     .read_header    = modplug_read_header,
     .read_packet    = modplug_read_packet,
     .read_close     = modplug_read_close,
     .read_seek      = modplug_read_seek,
-    .extensions     = "669,abc,amf,ams,dbm,dmf,dsm,far,it,mdl,med,mid,mod,mt2,mtm,okt,psm,ptm,s3m,stm,ult,umx,xm"
-                      ",itgz,itr,itz,mdgz,mdr,mdz,s3gz,s3r,s3z,xmgz,xmr,xmz", // compressed mods
+    .extensions     = modplug_extensions,
     .priv_class     = &modplug_class,
 };
diff --git a/libavformat/libquvi.c b/libavformat/libquvi.c
index fbae74c..ca71f9f 100644
--- a/libavformat/libquvi.c
+++ b/libavformat/libquvi.c
@@ -127,7 +127,7 @@
     rc = quvi_init(&q);
     if (rc != QUVI_OK)
         return AVERROR(ENOMEM);
-    score = quvi_supported(q, (char *)p->filename) == QUVI_OK ? AVPROBE_SCORE_MAX/2 : 0;
+    score = quvi_supported(q, (char *)p->filename) == QUVI_OK ? AVPROBE_SCORE_EXTENSION : 0;
     quvi_close(&q);
     return score;
 }
diff --git a/libavformat/loasdec.c b/libavformat/loasdec.c
index d3a8dbd..05ef0fe 100644
--- a/libavformat/loasdec.c
+++ b/libavformat/loasdec.c
@@ -52,9 +52,9 @@
         if(buf == buf0)
             first_frames= frames;
     }
-    if   (first_frames>=3) return AVPROBE_SCORE_MAX/2+1;
-    else if(max_frames>100)return AVPROBE_SCORE_MAX/2;
-    else if(max_frames>=3) return AVPROBE_SCORE_MAX/4;
+    if   (first_frames>=3) return AVPROBE_SCORE_EXTENSION+1;
+    else if(max_frames>100)return AVPROBE_SCORE_EXTENSION;
+    else if(max_frames>=3) return AVPROBE_SCORE_EXTENSION / 2;
     else                   return 0;
 }
 
diff --git a/libavformat/lvfdec.c b/libavformat/lvfdec.c
index f8dda58..a809c67 100644
--- a/libavformat/lvfdec.c
+++ b/libavformat/lvfdec.c
@@ -26,7 +26,7 @@
 static int lvf_probe(AVProbeData *p)
 {
     if (AV_RL32(p->buf) == MKTAG('L', 'V', 'F', 'F'))
-        return AVPROBE_SCORE_MAX / 2;
+        return AVPROBE_SCORE_EXTENSION;
     return 0;
 }
 
diff --git a/libavformat/lxfdec.c b/libavformat/lxfdec.c
index 876f988..5c61d4f 100644
--- a/libavformat/lxfdec.c
+++ b/libavformat/lxfdec.c
@@ -29,7 +29,6 @@
 #define LXF_IDENT               "LEITCH\0"
 #define LXF_IDENT_LENGTH        8
 #define LXF_SAMPLERATE          48000
-#define LXF_MAX_AUDIO_PACKET    (8008*15*4) ///< 15-channel 32-bit NTSC audio frame
 
 static const AVCodecTag lxf_tags[] = {
     { AV_CODEC_ID_MJPEG,       0 },
@@ -309,13 +308,6 @@
         return AVERROR_INVALIDDATA;
     }
 
-    //make sure the data fits in the de-planerization buffer
-    if (ast && ret > LXF_MAX_AUDIO_PACKET) {
-        av_log(s, AV_LOG_ERROR, "audio packet too large (%i > %i)\n",
-            ret, LXF_MAX_AUDIO_PACKET);
-        return AVERROR_INVALIDDATA;
-    }
-
     if ((ret2 = av_new_packet(pkt, ret)) < 0)
         return ret2;
 
diff --git a/libavformat/m4vdec.c b/libavformat/m4vdec.c
index e72fb42..c2fd4d7 100644
--- a/libavformat/m4vdec.c
+++ b/libavformat/m4vdec.c
@@ -45,7 +45,7 @@
     }
 
     if (VOP >= VISO && VOP >= VOL && VO >= VOL && VOL > 0 && res==0)
-        return VOP+VO > 3 ? AVPROBE_SCORE_MAX/2 : AVPROBE_SCORE_MAX/4;
+        return VOP+VO > 3 ? AVPROBE_SCORE_EXTENSION : AVPROBE_SCORE_EXTENSION/2;
     return 0;
 }
 
diff --git a/libavformat/matroska.c b/libavformat/matroska.c
index ee57c18..953c572 100644
--- a/libavformat/matroska.c
+++ b/libavformat/matroska.c
@@ -57,6 +57,11 @@
     {"A_VORBIS"         , AV_CODEC_ID_VORBIS},
     {"A_WAVPACK4"       , AV_CODEC_ID_WAVPACK},
 
+    {"D_WEBVTT/SUBTITLES"   , AV_CODEC_ID_WEBVTT},
+    {"D_WEBVTT/CAPTIONS"    , AV_CODEC_ID_WEBVTT},
+    {"D_WEBVTT/DESCRIPTIONS", AV_CODEC_ID_WEBVTT},
+    {"D_WEBVTT/METADATA"    , AV_CODEC_ID_WEBVTT},
+
     {"S_TEXT/UTF8"      , AV_CODEC_ID_SUBRIP},
     {"S_TEXT/UTF8"      , AV_CODEC_ID_TEXT},
     {"S_TEXT/UTF8"      , AV_CODEC_ID_SRT},
diff --git a/libavformat/matroska.h b/libavformat/matroska.h
index 8a7e10b..7cf423c 100644
--- a/libavformat/matroska.h
+++ b/libavformat/matroska.h
@@ -91,6 +91,7 @@
 #define MATROSKA_ID_CODECINFOURL 0x3B4040
 #define MATROSKA_ID_CODECDOWNLOADURL 0x26B240
 #define MATROSKA_ID_CODECDECODEALL 0xAA
+#define MATROSKA_ID_SEEKPREROLL 0x56BB
 #define MATROSKA_ID_TRACKNAME  0x536E
 #define MATROSKA_ID_TRACKLANGUAGE 0x22B59C
 #define MATROSKA_ID_TRACKFLAGENABLED 0xB9
@@ -156,6 +157,7 @@
 /* IDs in the cuetrackposition master */
 #define MATROSKA_ID_CUETRACK   0xF7
 #define MATROSKA_ID_CUECLUSTERPOSITION 0xF1
+#define MATROSKA_ID_CUERELATIVEPOSITION 0xF0
 #define MATROSKA_ID_CUEBLOCKNUMBER 0x5378
 
 /* IDs in the tags master */
@@ -195,6 +197,7 @@
 #define MATROSKA_ID_BLOCK      0xA1
 #define MATROSKA_ID_BLOCKDURATION 0x9B
 #define MATROSKA_ID_BLOCKREFERENCE 0xFB
+#define MATROSKA_ID_CODECSTATE 0xA4
 
 /* IDs in the attachments master */
 #define MATROSKA_ID_ATTACHEDFILE        0x61A7
@@ -229,6 +232,7 @@
   MATROSKA_TRACK_TYPE_LOGO     = 0x10,
   MATROSKA_TRACK_TYPE_SUBTITLE = 0x11,
   MATROSKA_TRACK_TYPE_CONTROL  = 0x20,
+  MATROSKA_TRACK_TYPE_METADATA = 0x21,
 } MatroskaTrackType;
 
 typedef enum {
@@ -261,7 +265,7 @@
  */
 
 typedef struct CodecTags{
-    char str[20];
+    char str[22];
     enum AVCodecID id;
 }CodecTags;
 
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index d17bf61..a90475d 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -570,6 +570,7 @@
     { MATROSKA_ID_SIMPLEBLOCK,    EBML_BIN,  0, offsetof(MatroskaBlock,bin) },
     { MATROSKA_ID_BLOCKDURATION,  EBML_UINT, 0, offsetof(MatroskaBlock,duration) },
     { MATROSKA_ID_BLOCKREFERENCE, EBML_UINT, 0, offsetof(MatroskaBlock,reference) },
+    { MATROSKA_ID_CODECSTATE,     EBML_NONE },
     { 1,                          EBML_UINT, 0, offsetof(MatroskaBlock,non_simple), {.u=1} },
     { 0 }
 };
@@ -633,21 +634,20 @@
     matroska->current_id = 0;
     matroska->num_levels = 0;
 
-    // seek to next position to resync from
-    if (avio_seek(pb, last_pos + 1, SEEK_SET) < 0 || avio_tell(pb) <= last_pos)
+    /* seek to next position to resync from */
+    if (avio_seek(pb, last_pos + 1, SEEK_SET) < 0)
         goto eof;
 
     id = avio_rb32(pb);
 
     // try to find a toplevel element
     while (!url_feof(pb)) {
-        if (id == MATROSKA_ID_INFO || id == MATROSKA_ID_TRACKS ||
-            id == MATROSKA_ID_CUES || id == MATROSKA_ID_TAGS ||
+        if (id == MATROSKA_ID_INFO     || id == MATROSKA_ID_TRACKS      ||
+            id == MATROSKA_ID_CUES     || id == MATROSKA_ID_TAGS        ||
             id == MATROSKA_ID_SEEKHEAD || id == MATROSKA_ID_ATTACHMENTS ||
-            id == MATROSKA_ID_CLUSTER || id == MATROSKA_ID_CHAPTERS)
-        {
-            matroska->current_id = id;
-            return 0;
+            id == MATROSKA_ID_CLUSTER  || id == MATROSKA_ID_CHAPTERS) {
+                matroska->current_id = id;
+                return 0;
         }
         id = (id << 8) | avio_r8(pb);
     }
@@ -1066,7 +1066,7 @@
     }
 
     // probably valid EBML header but no recognized doctype
-    return AVPROBE_SCORE_MAX/2;
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 static MatroskaTrack *matroska_find_track_by_num(MatroskaDemuxContext *matroska,
@@ -1572,7 +1572,8 @@
         /* Apply some sanity checks. */
         if (track->type != MATROSKA_TRACK_TYPE_VIDEO &&
             track->type != MATROSKA_TRACK_TYPE_AUDIO &&
-            track->type != MATROSKA_TRACK_TYPE_SUBTITLE) {
+            track->type != MATROSKA_TRACK_TYPE_SUBTITLE &&
+            track->type != MATROSKA_TRACK_TYPE_METADATA) {
             av_log(matroska->ctx, AV_LOG_INFO,
                    "Unknown or unsupported track type %"PRIu64"\n",
                    track->type);
@@ -1689,18 +1690,6 @@
                    && (track->codec_priv.data != NULL)) {
             fourcc = AV_RL32(track->codec_priv.data);
             codec_id = ff_codec_get_id(ff_codec_movvideo_tags, fourcc);
-        } else if (codec_id == AV_CODEC_ID_ALAC && track->codec_priv.size && track->codec_priv.size < INT_MAX - 12 - FF_INPUT_BUFFER_PADDING_SIZE) {
-            /* Only ALAC's magic cookie is stored in Matroska's track headers.
-               Create the "atom size", "tag", and "tag version" fields the
-               decoder expects manually. */
-            extradata_size = 12 + track->codec_priv.size;
-            extradata = av_mallocz(extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
-            if (extradata == NULL)
-                return AVERROR(ENOMEM);
-            AV_WB32(extradata, extradata_size);
-            memcpy(&extradata[4], "alac", 4);
-            AV_WB32(&extradata[8], 0);
-            memcpy(&extradata[12], track->codec_priv.data, track->codec_priv.size);
         } else if (codec_id == AV_CODEC_ID_PCM_S16BE) {
             switch (track->audio.bitdepth) {
             case  8:  codec_id = AV_CODEC_ID_PCM_U8;     break;
@@ -1731,6 +1720,19 @@
                 extradata_size = 5;
             } else
                 extradata_size = 2;
+        } else if (codec_id == AV_CODEC_ID_ALAC && track->codec_priv.size && track->codec_priv.size < INT_MAX - 12 - FF_INPUT_BUFFER_PADDING_SIZE) {
+            /* Only ALAC's magic cookie is stored in Matroska's track headers.
+               Create the "atom size", "tag", and "tag version" fields the
+               decoder expects manually. */
+            extradata_size = 12 + track->codec_priv.size;
+            extradata = av_mallocz(extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+            if (extradata == NULL)
+                return AVERROR(ENOMEM);
+            AV_WB32(extradata, extradata_size);
+            memcpy(&extradata[4], "alac", 4);
+            AV_WB32(&extradata[8], 0);
+            memcpy(&extradata[12], track->codec_priv.data,
+                                   track->codec_priv.size);
         } else if (codec_id == AV_CODEC_ID_TTA) {
             extradata_size = 30;
             extradata = av_mallocz(extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
@@ -1742,8 +1744,10 @@
             avio_wl16(&b, 1);
             avio_wl16(&b, track->audio.channels);
             avio_wl16(&b, track->audio.bitdepth);
+            if (track->audio.out_samplerate < 0 || track->audio.out_samplerate > INT_MAX)
+                return AVERROR_INVALIDDATA;
             avio_wl32(&b, track->audio.out_samplerate);
-            avio_wl32(&b, matroska->ctx->duration * track->audio.out_samplerate);
+            avio_wl32(&b, av_rescale((matroska->duration * matroska->time_scale), track->audio.out_samplerate, AV_TIME_BASE * 1000));
         } else if (codec_id == AV_CODEC_ID_RV10 || codec_id == AV_CODEC_ID_RV20 ||
                    codec_id == AV_CODEC_ID_RV30 || codec_id == AV_CODEC_ID_RV40) {
             extradata_offset = 26;
@@ -1771,7 +1775,7 @@
                 track->codec_priv.size = 0;
             } else {
                 if (codec_id == AV_CODEC_ID_SIPR && flavor < 4) {
-                    const int sipr_bit_rate[4] = { 6504, 8496, 5000, 16000 };
+                    static const int sipr_bit_rate[4] = { 6504, 8496, 5000, 16000 };
                     track->audio.sub_packet_size = ff_sipr_subpk_size[flavor];
                     st->codec->bit_rate = sipr_bit_rate[flavor];
                 }
@@ -1871,6 +1875,16 @@
             st->codec->bits_per_coded_sample = track->audio.bitdepth;
             if (st->codec->codec_id != AV_CODEC_ID_AAC)
             st->need_parsing = AVSTREAM_PARSE_HEADERS;
+        } else if (codec_id == AV_CODEC_ID_WEBVTT) {
+            st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+
+            if (!strcmp(track->codec_id, "D_WEBVTT/CAPTIONS")) {
+                st->disposition |= AV_DISPOSITION_CAPTIONS;
+            } else if (!strcmp(track->codec_id, "D_WEBVTT/DESCRIPTIONS")) {
+                st->disposition |= AV_DISPOSITION_DESCRIPTIONS;
+            } else if (!strcmp(track->codec_id, "D_WEBVTT/METADATA")) {
+                st->disposition |= AV_DISPOSITION_METADATA;
+            }
         } else if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE) {
             st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
 #if FF_API_ASS_SSA
@@ -2160,6 +2174,202 @@
 
     return 0;
 }
+
+/* reconstruct full wavpack blocks from mangled matroska ones */
+static int matroska_parse_wavpack(MatroskaTrack *track, uint8_t *src,
+                                  uint8_t **pdst, int *size)
+{
+    uint8_t *dst = NULL;
+    int dstlen   = 0;
+    int srclen   = *size;
+    uint32_t samples;
+    uint16_t ver;
+    int ret, offset = 0;
+
+    if (srclen < 12 || track->stream->codec->extradata_size < 2)
+        return AVERROR_INVALIDDATA;
+
+    ver = AV_RL16(track->stream->codec->extradata);
+
+    samples = AV_RL32(src);
+    src    += 4;
+    srclen -= 4;
+
+    while (srclen >= 8) {
+        int multiblock;
+        uint32_t blocksize;
+        uint8_t *tmp;
+
+        uint32_t flags = AV_RL32(src);
+        uint32_t crc   = AV_RL32(src + 4);
+        src    += 8;
+        srclen -= 8;
+
+        multiblock = (flags & 0x1800) != 0x1800;
+        if (multiblock) {
+            if (srclen < 4) {
+                ret = AVERROR_INVALIDDATA;
+                goto fail;
+            }
+            blocksize = AV_RL32(src);
+            src    += 4;
+            srclen -= 4;
+        } else
+            blocksize = srclen;
+
+        if (blocksize > srclen) {
+            ret = AVERROR_INVALIDDATA;
+            goto fail;
+        }
+
+        tmp = av_realloc(dst, dstlen + blocksize + 32);
+        if (!tmp) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+        dst     = tmp;
+        dstlen += blocksize + 32;
+
+        AV_WL32(dst + offset,      MKTAG('w', 'v', 'p', 'k')); // tag
+        AV_WL32(dst + offset + 4,  blocksize + 24);            // blocksize - 8
+        AV_WL16(dst + offset + 8,  ver);                       // version
+        AV_WL16(dst + offset + 10, 0);                         // track/index_no
+        AV_WL32(dst + offset + 12, 0);                         // total samples
+        AV_WL32(dst + offset + 16, 0);                         // block index
+        AV_WL32(dst + offset + 20, samples);                   // number of samples
+        AV_WL32(dst + offset + 24, flags);                     // flags
+        AV_WL32(dst + offset + 28, crc);                       // crc
+        memcpy (dst + offset + 32, src, blocksize);            // block data
+
+        src    += blocksize;
+        srclen -= blocksize;
+        offset += blocksize + 32;
+    }
+
+    *pdst = dst;
+    *size = dstlen;
+
+    return 0;
+
+fail:
+    av_freep(&dst);
+    return ret;
+}
+
+static int matroska_parse_webvtt(MatroskaDemuxContext *matroska,
+                                 MatroskaTrack *track,
+                                 AVStream *st,
+                                 uint8_t *data, int data_len,
+                                 uint64_t timecode,
+                                 uint64_t duration,
+                                 int64_t pos)
+{
+    AVPacket *pkt;
+    uint8_t *id, *settings, *text, *buf;
+    int id_len, settings_len, text_len;
+    uint8_t *p, *q;
+    int err;
+
+    if (data_len <= 0)
+        return AVERROR_INVALIDDATA;
+
+    p = data;
+    q = data + data_len;
+
+    id = p;
+    id_len = -1;
+    while (p < q) {
+        if (*p == '\r' || *p == '\n') {
+            id_len = p - id;
+            if (*p == '\r')
+                p++;
+            break;
+        }
+        p++;
+    }
+
+    if (p >= q || *p != '\n')
+        return AVERROR_INVALIDDATA;
+    p++;
+
+    settings = p;
+    settings_len = -1;
+    while (p < q) {
+        if (*p == '\r' || *p == '\n') {
+            settings_len = p - settings;
+            if (*p == '\r')
+                p++;
+            break;
+        }
+        p++;
+    }
+
+    if (p >= q || *p != '\n')
+        return AVERROR_INVALIDDATA;
+    p++;
+
+    text = p;
+    text_len = q - p;
+    while (text_len > 0) {
+        const int len = text_len - 1;
+        const uint8_t c = p[len];
+        if (c != '\r' && c != '\n')
+            break;
+        text_len = len;
+    }
+
+    if (text_len <= 0)
+        return AVERROR_INVALIDDATA;
+
+    pkt = av_mallocz(sizeof(*pkt));
+    err = av_new_packet(pkt, text_len);
+    if (err < 0) {
+        av_free(pkt);
+        return AVERROR(err);
+    }
+
+    memcpy(pkt->data, text, text_len);
+
+    if (id_len > 0) {
+        buf = av_packet_new_side_data(pkt,
+                                      AV_PKT_DATA_WEBVTT_IDENTIFIER,
+                                      id_len);
+        if (buf == NULL) {
+            av_free(pkt);
+            return AVERROR(ENOMEM);
+        }
+        memcpy(buf, id, id_len);
+    }
+
+    if (settings_len > 0) {
+        buf = av_packet_new_side_data(pkt,
+                                      AV_PKT_DATA_WEBVTT_SETTINGS,
+                                      settings_len);
+        if (buf == NULL) {
+            av_free(pkt);
+            return AVERROR(ENOMEM);
+        }
+        memcpy(buf, settings, settings_len);
+    }
+
+    // Do we need this for subtitles?
+    // pkt->flags = AV_PKT_FLAG_KEY;
+
+    pkt->stream_index = st->index;
+    pkt->pts = timecode;
+
+    // Do we need this for subtitles?
+    // pkt->dts = timecode;
+
+    pkt->duration = duration;
+    pkt->pos = pos;
+
+    dynarray_add(&matroska->packets, &matroska->num_packets, pkt);
+    matroska->prev_pkt = pkt;
+
+    return 0;
+}
+
 static int matroska_parse_frame(MatroskaDemuxContext *matroska,
                                 MatroskaTrack *track,
                                 AVStream *st,
@@ -2179,6 +2389,18 @@
             return res;
     }
 
+    if (st->codec->codec_id == AV_CODEC_ID_WAVPACK) {
+        uint8_t *wv_data;
+        res = matroska_parse_wavpack(track, pkt_data, &wv_data, &pkt_size);
+        if (res < 0) {
+            av_log(matroska->ctx, AV_LOG_ERROR, "Error parsing a wavpack block.\n");
+            goto fail;
+        }
+        if (pkt_data != data)
+            av_freep(&pkt_data);
+        pkt_data = wv_data;
+    }
+
     if (st->codec->codec_id == AV_CODEC_ID_PRORES)
         offset = 8;
 
@@ -2186,7 +2408,8 @@
     /* XXX: prevent data copy... */
     if (av_new_packet(pkt, pkt_size + offset) < 0) {
         av_free(pkt);
-        return AVERROR(ENOMEM);
+        res = AVERROR(ENOMEM);
+        goto fail;
     }
 
     if (st->codec->codec_id == AV_CODEC_ID_PRORES) {
@@ -2198,7 +2421,7 @@
     memcpy(pkt->data + offset, pkt_data, pkt_size);
 
     if (pkt_data != data)
-        av_free(pkt_data);
+        av_freep(&pkt_data);
 
     pkt->flags = is_keyframe;
     pkt->stream_index = st->index;
@@ -2265,6 +2488,10 @@
 #endif
 
     return 0;
+fail:
+    if (pkt_data != data)
+        av_freep(&pkt_data);
+    return res;
 }
 
 static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
@@ -2281,6 +2508,7 @@
     uint32_t *lace_size = NULL;
     int n, flags, laces = 0;
     uint64_t num;
+    int trust_default_duration = 1;
 
     if ((n = matroska_ebmlnum_uint(matroska, data, size, &num)) < 0) {
         av_log(matroska->ctx, AV_LOG_ERROR, "EBML block data error\n");
@@ -2301,7 +2529,7 @@
         return res;
     av_assert1(block_duration != AV_NOPTS_VALUE);
 
-    block_time = AV_RB16(data);
+    block_time = sign_extend(AV_RB16(data), 16);
     data += 2;
     flags = *data++;
     size -= 3;
@@ -2335,7 +2563,15 @@
     if (res)
         goto end;
 
-    if (!block_duration)
+    if (track->audio.samplerate == 8000) {
+        // If this is needed for more codecs, then add them here
+        if (st->codec->codec_id == AV_CODEC_ID_AC3) {
+            if(track->audio.samplerate != st->codec->sample_rate || !st->codec->frame_size)
+                trust_default_duration = 0;
+        }
+    }
+
+    if (!block_duration && trust_default_duration)
         block_duration = track->default_duration * laces / matroska->time_scale;
 
     if (cluster_time != (uint64_t)-1 && (block_time >= 0 || cluster_time >= -block_time))
@@ -2366,6 +2602,14 @@
             if (res)
                 goto end;
 
+        } else if (st->codec->codec_id == AV_CODEC_ID_WEBVTT) {
+            res = matroska_parse_webvtt(matroska, track, st,
+                                        data, lace_size[n],
+                                        timecode, lace_duration,
+                                        pos);
+            if (res)
+                goto end;
+
         } else {
             res = matroska_parse_frame(matroska, track, st, data, lace_size[n],
                                       timecode, lace_duration,
@@ -2441,7 +2685,6 @@
         }
     }
 
-    if (res < 0)  matroska->done = 1;
     return res;
 }
 
@@ -2530,10 +2773,11 @@
         if (tracks[i].type == MATROSKA_TRACK_TYPE_SUBTITLE
             && tracks[i].stream->discard != AVDISCARD_ALL) {
             index_sub = av_index_search_timestamp(tracks[i].stream, st->index_entries[index].timestamp, AVSEEK_FLAG_BACKWARD);
-            if (index_sub >= 0
-                && st->index_entries[index_sub].pos < st->index_entries[index_min].pos
-                && st->index_entries[index].timestamp - st->index_entries[index_sub].timestamp < 30000000000/matroska->time_scale)
-                index_min = index_sub;
+            while(index_sub >= 0
+                  && index_min >= 0
+                  && tracks[i].stream->index_entries[index_sub].pos < st->index_entries[index_min].pos
+                  && st->index_entries[index].timestamp - tracks[i].stream->index_entries[index_sub].timestamp < 30000000000/matroska->time_scale)
+                index_min--;
         }
     }
 
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 6726fd9..92df6cb 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -19,23 +19,28 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "avc.h"
 #include "avformat.h"
+#include "avio_internal.h"
+#include "avlanguage.h"
+#include "flacenc.h"
 #include "internal.h"
-#include "riff.h"
 #include "isom.h"
 #include "matroska.h"
-#include "avc.h"
-#include "flacenc.h"
-#include "avlanguage.h"
+#include "riff.h"
+#include "wv.h"
+
+#include "libavutil/avstring.h"
+#include "libavutil/dict.h"
+#include "libavutil/intfloat.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/lfg.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "libavutil/random_seed.h"
 #include "libavutil/samplefmt.h"
 #include "libavutil/sha.h"
-#include "libavutil/intreadwrite.h"
-#include "libavutil/intfloat.h"
-#include "libavutil/mathematics.h"
-#include "libavutil/random_seed.h"
-#include "libavutil/lfg.h"
-#include "libavutil/dict.h"
-#include "libavutil/avstring.h"
+
 #include "libavcodec/xiph.h"
 #include "libavcodec/mpeg4audio.h"
 
@@ -62,6 +67,7 @@
     uint64_t        pts;
     int             tracknum;
     int64_t         cluster_pos;        ///< file offset of the cluster containing the block
+    int64_t         relative_pos;       ///< relative offset from the position of the cluster containing the block
 } mkv_cuepoint;
 
 typedef struct {
@@ -79,6 +85,7 @@
 #define MODE_WEBM       0x02
 
 typedef struct MatroskaMuxContext {
+    const AVClass  *class;
     int             mode;
     AVIOContext   *dyn_bc;
     ebml_master     segment;
@@ -95,6 +102,13 @@
     AVPacket        cur_audio_pkt;
 
     int have_attachments;
+
+    int reserve_cues_space;
+    int cluster_size_limit;
+    int64_t cues_pos;
+    int64_t cluster_time_limit;
+
+    uint32_t chapter_id_offset;
 } MatroskaMuxContext;
 
 
@@ -102,13 +116,16 @@
  * offset, 4 bytes for target EBML ID */
 #define MAX_SEEKENTRY_SIZE 21
 
-/** per-cuepoint-track - 3 1-byte EBML IDs, 3 1-byte EBML sizes, 2
+/** per-cuepoint-track - 4 1-byte EBML IDs, 4 1-byte EBML sizes, 3
  * 8-byte uint max */
-#define MAX_CUETRACKPOS_SIZE 22
+#define MAX_CUETRACKPOS_SIZE 32
 
 /** per-cuepoint - 2 1-byte EBML IDs, 2 1-byte EBML sizes, 8-byte uint max */
 #define MAX_CUEPOINT_SIZE(num_tracks) 12 + MAX_CUETRACKPOS_SIZE*num_tracks
 
+/** Seek preroll value for opus */
+#define OPUS_SEEK_PREROLL 80000000
+
 
 static int ebml_id_size(unsigned int id)
 {
@@ -131,8 +148,7 @@
 {
     av_assert0(bytes <= 8);
     avio_w8(pb, 0x1ff >> bytes);
-    while (--bytes)
-        avio_w8(pb, 0xff);
+    ffio_fill(pb, 0xff, bytes - 1);
 }
 
 /**
@@ -222,8 +238,7 @@
         put_ebml_num(pb, size-1, 0);
     else
         put_ebml_num(pb, size-9, 8);
-    while(avio_tell(pb) < currentpos + size)
-        avio_w8(pb, 0);
+    ffio_fill(pb, 0, currentpos + size - avio_tell(pb));
 }
 
 static ebml_master start_ebml_master(AVIOContext *pb, unsigned int elementid, uint64_t expectedsize)
@@ -246,9 +261,7 @@
 
 static void put_xiph_size(AVIOContext *pb, int size)
 {
-    int i;
-    for (i = 0; i < size / 255; i++)
-        avio_w8(pb, 255);
+    ffio_fill(pb, 255, size / 255);
     avio_w8(pb, size % 255);
 }
 
@@ -365,7 +378,7 @@
     return cues;
 }
 
-static int mkv_add_cuepoint(mkv_cues *cues, int stream, int64_t ts, int64_t cluster_pos)
+static int mkv_add_cuepoint(mkv_cues *cues, int stream, int64_t ts, int64_t cluster_pos, int64_t relative_pos)
 {
     mkv_cuepoint *entries = cues->entries;
 
@@ -378,7 +391,8 @@
 
     entries[cues->num_entries  ].pts = ts;
     entries[cues->num_entries  ].tracknum = stream + 1;
-    entries[cues->num_entries++].cluster_pos = cluster_pos - cues->segment_offset;
+    entries[cues->num_entries  ].cluster_pos = cluster_pos - cues->segment_offset;
+    entries[cues->num_entries++].relative_pos = relative_pos;
 
     cues->entries = entries;
     return 0;
@@ -412,8 +426,9 @@
                 continue;
             tracks[tracknum].has_cue = 1;
             track_positions = start_ebml_master(pb, MATROSKA_ID_CUETRACKPOSITION, MAX_CUETRACKPOS_SIZE);
-            put_ebml_uint(pb, MATROSKA_ID_CUETRACK          , entry[j].tracknum   );
-            put_ebml_uint(pb, MATROSKA_ID_CUECLUSTERPOSITION, entry[j].cluster_pos);
+            put_ebml_uint(pb, MATROSKA_ID_CUETRACK           , entry[j].tracknum   );
+            put_ebml_uint(pb, MATROSKA_ID_CUECLUSTERPOSITION , entry[j].cluster_pos);
+            put_ebml_uint(pb, MATROSKA_ID_CUERELATIVEPOSITION, entry[j].relative_pos);
             end_ebml_master(pb, track_positions);
         }
         i += j - 1;
@@ -452,6 +467,15 @@
     return 0;
 }
 
+static int put_wv_codecpriv(AVIOContext *pb, AVCodecContext *codec)
+{
+    if (codec->extradata && codec->extradata_size == 2)
+        avio_write(pb, codec->extradata, 2);
+    else
+        avio_wl16(pb, 0x403); // fallback to the version mentioned in matroska specs
+    return 0;
+}
+
 static void get_aac_sample_rates(AVFormatContext *s, AVCodecContext *codec, int *sample_rate, int *output_sample_rate)
 {
     MPEG4AudioConfig mp4ac;
@@ -481,6 +505,8 @@
             ret = put_xiph_codecpriv(s, dyn_cp, codec);
         else if (codec->codec_id == AV_CODEC_ID_FLAC)
             ret = ff_flac_write_header(dyn_cp, codec, 1);
+        else if (codec->codec_id == AV_CODEC_ID_WAVPACK)
+            ret = put_wv_codecpriv(dyn_cp, codec);
         else if (codec->codec_id == AV_CODEC_ID_H264)
             ret = ff_isom_write_avcc(dyn_cp, codec->extradata, codec->extradata_size);
         else if (codec->codec_id == AV_CODEC_ID_ALAC) {
@@ -581,7 +607,11 @@
         if ((tag = av_dict_get(st->metadata, "title", NULL, 0)))
             put_ebml_string(pb, MATROSKA_ID_TRACKNAME, tag->value);
         tag = av_dict_get(st->metadata, "language", NULL, 0);
-        put_ebml_string(pb, MATROSKA_ID_TRACKLANGUAGE, tag ? tag->value:"und");
+        if (mkv->mode != MODE_WEBM || codec->codec_id != AV_CODEC_ID_WEBVTT) {
+            put_ebml_string(pb, MATROSKA_ID_TRACKLANGUAGE, tag ? tag->value:"und");
+        } else if (tag && tag->value) {
+            put_ebml_string(pb, MATROSKA_ID_TRACKLANGUAGE, tag->value);
+        }
 
         if (default_stream_exists) {
             put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGDEFAULT, !!(st->disposition & AV_DISPOSITION_DEFAULT));
@@ -589,20 +619,45 @@
         if (st->disposition & AV_DISPOSITION_FORCED)
             put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGFORCED, 1);
 
-        // look for a codec ID string specific to mkv to use,
-        // if none are found, use AVI codes
-        for (j = 0; ff_mkv_codec_tags[j].id != AV_CODEC_ID_NONE; j++) {
-            if (ff_mkv_codec_tags[j].id == codec->codec_id) {
-                put_ebml_string(pb, MATROSKA_ID_CODECID, ff_mkv_codec_tags[j].str);
-                native_id = 1;
-                break;
+        if (mkv->mode == MODE_WEBM && codec->codec_id == AV_CODEC_ID_WEBVTT) {
+            const char *codec_id;
+            if (st->disposition & AV_DISPOSITION_CAPTIONS) {
+                codec_id = "D_WEBVTT/CAPTIONS";
+                native_id = MATROSKA_TRACK_TYPE_SUBTITLE;
+            } else if (st->disposition & AV_DISPOSITION_DESCRIPTIONS) {
+                codec_id = "D_WEBVTT/DESCRIPTIONS";
+                native_id = MATROSKA_TRACK_TYPE_METADATA;
+            } else if (st->disposition & AV_DISPOSITION_METADATA) {
+                codec_id = "D_WEBVTT/METADATA";
+                native_id = MATROSKA_TRACK_TYPE_METADATA;
+            } else {
+                codec_id = "D_WEBVTT/SUBTITLES";
+                native_id = MATROSKA_TRACK_TYPE_SUBTITLE;
+            }
+            put_ebml_string(pb, MATROSKA_ID_CODECID, codec_id);
+        } else {
+            // look for a codec ID string specific to mkv to use,
+            // if none are found, use AVI codes
+            for (j = 0; ff_mkv_codec_tags[j].id != AV_CODEC_ID_NONE; j++) {
+                if (ff_mkv_codec_tags[j].id == codec->codec_id) {
+                    put_ebml_string(pb, MATROSKA_ID_CODECID, ff_mkv_codec_tags[j].str);
+                    native_id = 1;
+                    break;
+                }
             }
         }
 
+        if (codec->codec_id == AV_CODEC_ID_OPUS) {
+            put_ebml_uint(pb, MATROSKA_ID_SEEKPREROLL, OPUS_SEEK_PREROLL);
+        }
+
         if (mkv->mode == MODE_WEBM && !(codec->codec_id == AV_CODEC_ID_VP8 ||
-                                        codec->codec_id == AV_CODEC_ID_VORBIS)) {
+                                        codec->codec_id == AV_CODEC_ID_VP9 ||
+                                      ((codec->codec_id == AV_CODEC_ID_OPUS)&&(codec->strict_std_compliance <= FF_COMPLIANCE_EXPERIMENTAL)) ||
+                                        codec->codec_id == AV_CODEC_ID_VORBIS ||
+                                        codec->codec_id == AV_CODEC_ID_WEBVTT)) {
             av_log(s, AV_LOG_ERROR,
-                   "Only VP8 video and Vorbis audio are supported for WebM.\n");
+                   "Only VP8,VP9 video and Vorbis,Opus(experimental, use -strict -2) audio and WebVTT subtitles are supported for WebM.\n");
             return AVERROR(EINVAL);
         }
 
@@ -655,6 +710,12 @@
                         put_ebml_uint(pb, MATROSKA_ID_VIDEOSTEREOMODE, st_mode);
                 }
 
+                if ((tag = av_dict_get(st->metadata, "alpha_mode", NULL, 0)) ||
+                    (tag = av_dict_get( s->metadata, "alpha_mode", NULL, 0)) ||
+                    (codec->pix_fmt == AV_PIX_FMT_YUVA420P)) {
+                    put_ebml_uint(pb, MATROSKA_ID_VIDEOALPHAMODE, 1);
+                }
+
                 if (st->sample_aspect_ratio.num) {
                     int64_t d_width = av_rescale(codec->width, st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);
                     if (d_width > INT_MAX) {
@@ -690,18 +751,25 @@
                 break;
 
             case AVMEDIA_TYPE_SUBTITLE:
-                put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_SUBTITLE);
                 if (!native_id) {
                     av_log(s, AV_LOG_ERROR, "Subtitle codec %d is not supported.\n", codec->codec_id);
                     return AVERROR(ENOSYS);
                 }
+
+                if (mkv->mode != MODE_WEBM || codec->codec_id != AV_CODEC_ID_WEBVTT)
+                    native_id = MATROSKA_TRACK_TYPE_SUBTITLE;
+
+                put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, native_id);
                 break;
             default:
                 av_log(s, AV_LOG_ERROR, "Only audio, video, and subtitles are supported for Matroska.\n");
-                break;
+                return AVERROR(EINVAL);
         }
-        ret = mkv_write_codecprivate(s, pb, codec, native_id, qt_id);
-        if (ret < 0) return ret;
+
+        if (mkv->mode != MODE_WEBM || codec->codec_id != AV_CODEC_ID_WEBVTT) {
+            ret = mkv_write_codecprivate(s, pb, codec, native_id, qt_id);
+            if (ret < 0) return ret;
+        }
 
         end_ebml_master(pb, track);
 
@@ -736,7 +804,7 @@
         AVDictionaryEntry *t = NULL;
 
         chapteratom = start_ebml_master(pb, MATROSKA_ID_CHAPTERATOM, 0);
-        put_ebml_uint(pb, MATROSKA_ID_CHAPTERUID, c->id);
+        put_ebml_uint(pb, MATROSKA_ID_CHAPTERUID, c->id + mkv->chapter_id_offset);
         put_ebml_uint(pb, MATROSKA_ID_CHAPTERTIMESTART,
                       av_rescale_q(c->start, c->time_base, scale));
         put_ebml_uint(pb, MATROSKA_ID_CHAPTERTIMEEND,
@@ -815,14 +883,26 @@
     return 0;
 }
 
+static int mkv_check_tag(AVDictionary *m)
+{
+    AVDictionaryEntry *t = NULL;
+
+    while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX)))
+        if (av_strcasecmp(t->key, "title") && av_strcasecmp(t->key, "stereo_mode"))
+            return 1;
+
+    return 0;
+}
+
 static int mkv_write_tags(AVFormatContext *s)
 {
+    MatroskaMuxContext *mkv = s->priv_data;
     ebml_master tags = {0};
     int i, ret;
 
     ff_metadata_conv_ctx(s, ff_mkv_metadata_conv, NULL);
 
-    if (av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) {
+    if (mkv_check_tag(s->metadata)) {
         ret = mkv_write_tag(s, s->metadata, 0, 0, &tags);
         if (ret < 0) return ret;
     }
@@ -830,7 +910,7 @@
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
 
-        if (!av_dict_get(st->metadata, "", 0, AV_DICT_IGNORE_SUFFIX))
+        if (!mkv_check_tag(st->metadata))
             continue;
 
         ret = mkv_write_tag(s, st->metadata, MATROSKA_ID_TAGTARGETS_TRACKUID, i + 1, &tags);
@@ -840,10 +920,10 @@
     for (i = 0; i < s->nb_chapters; i++) {
         AVChapter *ch = s->chapters[i];
 
-        if (!av_dict_get(ch->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
+        if (!mkv_check_tag(ch->metadata))
             continue;
 
-        ret = mkv_write_tag(s, ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID, ch->id, &tags);
+        ret = mkv_write_tag(s, ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID, ch->id + mkv->chapter_id_offset, &tags);
         if (ret < 0) return ret;
     }
 
@@ -1022,6 +1102,9 @@
     ret = mkv_write_tracks(s);
     if (ret < 0) return ret;
 
+    for (i = 0; i < s->nb_chapters; i++)
+        mkv->chapter_id_offset = FFMAX(mkv->chapter_id_offset, 1LL - s->chapters[i]->id);
+
     if (mkv->mode != MODE_WEBM) {
         ret = mkv_write_chapters(s);
         if (ret < 0) return ret;
@@ -1040,11 +1123,31 @@
     if (mkv->cues == NULL)
         return AVERROR(ENOMEM);
 
+    if (pb->seekable && mkv->reserve_cues_space) {
+        mkv->cues_pos = avio_tell(pb);
+        put_ebml_void(pb, mkv->reserve_cues_space);
+    }
+
     av_init_packet(&mkv->cur_audio_pkt);
     mkv->cur_audio_pkt.size = 0;
     mkv->cluster_pos = -1;
 
     avio_flush(pb);
+
+    // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming or
+    // after 4k and on a keyframe
+    if (pb->seekable) {
+        if (mkv->cluster_time_limit < 0)
+            mkv->cluster_time_limit = 5000;
+        if (mkv->cluster_size_limit < 0)
+            mkv->cluster_size_limit = 5 * 1024 * 1024;
+    } else {
+        if (mkv->cluster_time_limit < 0)
+            mkv->cluster_time_limit = 1000;
+        if (mkv->cluster_size_limit < 0)
+            mkv->cluster_size_limit = 32 * 1024;
+    }
+
     return 0;
 }
 
@@ -1119,14 +1222,69 @@
 }
 #endif
 
+static int mkv_strip_wavpack(const uint8_t *src, uint8_t **pdst, int *size)
+{
+    uint8_t *dst;
+    int srclen = *size;
+    int offset = 0;
+    int ret;
+
+    dst = av_malloc(srclen);
+    if (!dst)
+        return AVERROR(ENOMEM);
+
+    while (srclen >= WV_HEADER_SIZE) {
+        WvHeader header;
+
+        ret = ff_wv_parse_header(&header, src);
+        if (ret < 0)
+            goto fail;
+        src    += WV_HEADER_SIZE;
+        srclen -= WV_HEADER_SIZE;
+
+        if (srclen < header.blocksize) {
+            ret = AVERROR_INVALIDDATA;
+            goto fail;
+        }
+
+        if (header.initial) {
+            AV_WL32(dst + offset, header.samples);
+            offset += 4;
+        }
+        AV_WL32(dst + offset,     header.flags);
+        AV_WL32(dst + offset + 4, header.crc);
+        offset += 8;
+
+        if (!(header.initial && header.final)) {
+            AV_WL32(dst + offset, header.blocksize);
+            offset += 4;
+        }
+
+        memcpy(dst + offset, src, header.blocksize);
+        src    += header.blocksize;
+        srclen -= header.blocksize;
+        offset += header.blocksize;
+    }
+
+    *pdst = dst;
+    *size = offset;
+
+    return 0;
+fail:
+    av_freep(&dst);
+    return ret;
+}
+
 static void mkv_write_block(AVFormatContext *s, AVIOContext *pb,
                             unsigned int blockid, AVPacket *pkt, int flags)
 {
     MatroskaMuxContext *mkv = s->priv_data;
     AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
-    uint8_t *data = NULL;
-    int offset = 0, size = pkt->size;
+    uint8_t *data = NULL, *side_data = NULL;
+    int offset = 0, size = pkt->size, side_data_size = 0;
     int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
+    uint64_t additional_id = 0;
+    ebml_master block_group, block_additions, block_more;
 
     av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, "
            "pts %" PRId64 ", dts %" PRId64 ", duration %d, flags %d\n",
@@ -1134,7 +1292,13 @@
     if (codec->codec_id == AV_CODEC_ID_H264 && codec->extradata_size > 0 &&
         (AV_RB24(codec->extradata) == 1 || AV_RB32(codec->extradata) == 1))
         ff_avc_parse_nal_units_buf(pkt->data, &data, &size);
-    else
+    else if (codec->codec_id == AV_CODEC_ID_WAVPACK) {
+        int ret = mkv_strip_wavpack(pkt->data, &data, &size);
+        if (ret < 0) {
+            av_log(s, AV_LOG_ERROR, "Error stripping a WavPack packet.\n");
+            return;
+        }
+    } else
         data = pkt->data;
 
     if (codec->codec_id == AV_CODEC_ID_PRORES) {
@@ -1144,6 +1308,20 @@
         offset = 8;
     }
 
+    side_data = av_packet_get_side_data(pkt,
+                                        AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
+                                        &side_data_size);
+    if (side_data) {
+        additional_id = AV_RB64(side_data);
+        side_data += 8;
+        side_data_size -= 8;
+    }
+
+    if (side_data_size && additional_id == 1) {
+        block_group = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, 0);
+        blockid = MATROSKA_ID_BLOCK;
+    }
+
     put_ebml_id(pb, blockid);
     put_ebml_num(pb, size+4, 0);
     avio_w8(pb, 0x80 | (pkt->stream_index + 1));     // this assumes stream_index is less than 126
@@ -1152,6 +1330,18 @@
     avio_write(pb, data + offset, size);
     if (data != pkt->data)
         av_free(data);
+
+    if (side_data_size && additional_id == 1) {
+        block_additions = start_ebml_master(pb, MATROSKA_ID_BLOCKADDITIONS, 0);
+        block_more = start_ebml_master(pb, MATROSKA_ID_BLOCKMORE, 0);
+        put_ebml_uint(pb, MATROSKA_ID_BLOCKADDID, 1);
+        put_ebml_id(pb, MATROSKA_ID_BLOCKADDITIONAL);
+        put_ebml_num(pb, side_data_size, 0);
+        avio_write(pb, side_data, side_data_size);
+        end_ebml_master(pb, block_more);
+        end_ebml_master(pb, block_additions);
+        end_ebml_master(pb, block_group);
+    }
 }
 
 static int srt_get_duration(uint8_t **buf)
@@ -1189,6 +1379,44 @@
     return duration;
 }
 
+static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
+{
+    MatroskaMuxContext *mkv = s->priv_data;
+    ebml_master blockgroup;
+    int id_size, settings_size, size;
+    uint8_t *id, *settings;
+    int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
+    const int flags = 0;
+
+    id_size = 0;
+    id = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_IDENTIFIER,
+                                 &id_size);
+
+    settings_size = 0;
+    settings = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_SETTINGS,
+                                       &settings_size);
+
+    size = id_size + 1 + settings_size + 1 + pkt->size;
+
+    av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, "
+           "pts %" PRId64 ", dts %" PRId64 ", duration %d, flags %d\n",
+           avio_tell(pb), size, pkt->pts, pkt->dts, pkt->duration, flags);
+
+    blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, mkv_blockgroup_size(size));
+
+    put_ebml_id(pb, MATROSKA_ID_BLOCK);
+    put_ebml_num(pb, size+4, 0);
+    avio_w8(pb, 0x80 | (pkt->stream_index + 1));     // this assumes stream_index is less than 126
+    avio_wb16(pb, ts - mkv->cluster_pts);
+    avio_w8(pb, flags);
+    avio_printf(pb, "%.*s\n%.*s\n%.*s", id_size, id, settings_size, settings, pkt->size, pkt->data);
+
+    put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, pkt->duration);
+    end_ebml_master(pb, blockgroup);
+
+    return pkt->duration;
+}
+
 static void mkv_flush_dynbuf(AVFormatContext *s)
 {
     MatroskaMuxContext *mkv = s->priv_data;
@@ -1213,6 +1441,7 @@
     int duration = pkt->duration;
     int ret;
     int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
+    int64_t relative_packet_pos;
 
     if (ts == AV_NOPTS_VALUE) {
         av_log(s, AV_LOG_ERROR, "Can't write packet with unknown timestamp\n");
@@ -1236,6 +1465,8 @@
         mkv->cluster_pts = FFMAX(0, ts);
     }
 
+    relative_packet_pos = avio_tell(s->pb) - mkv->cluster.pos;
+
     if (codec->codec_type != AVMEDIA_TYPE_SUBTITLE) {
         mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe << 7);
 #if FF_API_ASS_SSA
@@ -1244,6 +1475,8 @@
 #endif
     } else if (codec->codec_id == AV_CODEC_ID_SRT) {
         duration = mkv_write_srt_blocks(s, pb, pkt);
+    } else if (codec->codec_id == AV_CODEC_ID_WEBVTT) {
+        duration = mkv_write_vtt_blocks(s, pb, pkt);
     } else {
         ebml_master blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, mkv_blockgroup_size(pkt->size));
         /* For backward compatibility, prefer convergence_duration. */
@@ -1256,7 +1489,7 @@
     }
 
     if (codec->codec_type == AVMEDIA_TYPE_VIDEO && keyframe) {
-        ret = mkv_add_cuepoint(mkv->cues, pkt->stream_index, ts, mkv->cluster_pos);
+        ret = mkv_add_cuepoint(mkv->cues, pkt->stream_index, ts, mkv->cluster_pos, relative_packet_pos);
         if (ret < 0) return ret;
     }
 
@@ -1267,24 +1500,41 @@
 static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     MatroskaMuxContext *mkv = s->priv_data;
-    AVIOContext *pb = s->pb->seekable ? s->pb : mkv->dyn_bc;
-    AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
-    int ret, keyframe = !!(pkt->flags & AV_PKT_FLAG_KEY);
-    int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
-    int cluster_size = avio_tell(pb) - (s->pb->seekable ? mkv->cluster_pos : 0);
+    int codec_type          = s->streams[pkt->stream_index]->codec->codec_type;
+    int keyframe            = !!(pkt->flags & AV_PKT_FLAG_KEY);
+    int cluster_size;
+    int64_t cluster_time;
+    AVIOContext *pb;
+    int ret;
+
+    if (mkv->tracks[pkt->stream_index].write_dts)
+        cluster_time = pkt->dts - mkv->cluster_pts;
+    else
+        cluster_time = pkt->pts - mkv->cluster_pts;
 
     // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming or
     // after 4k and on a keyframe
+    if (s->pb->seekable) {
+        pb = s->pb;
+        cluster_size = avio_tell(pb) - mkv->cluster_pos;
+    } else {
+        pb = mkv->dyn_bc;
+        cluster_size = avio_tell(pb);
+    }
+
     if (mkv->cluster_pos != -1 &&
-        ((!s->pb->seekable && (cluster_size > 32*1024 || ts > mkv->cluster_pts + 1000))
-         ||                      cluster_size > 5*1024*1024 || ts > mkv->cluster_pts + 5000
-         || (codec->codec_type == AVMEDIA_TYPE_VIDEO && keyframe && cluster_size > 4*1024))) {
+        (cluster_size > mkv->cluster_size_limit ||
+         cluster_time > mkv->cluster_time_limit ||
+         (codec_type == AVMEDIA_TYPE_VIDEO && keyframe &&
+          cluster_size > 4 * 1024))) {
         av_log(s, AV_LOG_DEBUG, "Starting new cluster at offset %" PRIu64
-               " bytes, pts %" PRIu64 "\n", avio_tell(pb), ts);
+               " bytes, pts %" PRIu64 "dts %" PRIu64 "\n",
+               avio_tell(pb), pkt->pts, pkt->dts);
         end_ebml_master(pb, mkv->cluster);
         mkv->cluster_pos = -1;
         if (mkv->dyn_bc)
             mkv_flush_dynbuf(s);
+        avio_flush(s->pb);
     }
 
     // check if we have an audio packet cached
@@ -1299,15 +1549,41 @@
 
     // buffer an audio packet to ensure the packet containing the video
     // keyframe's timecode is contained in the same cluster for WebM
-    if (codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+    if (codec_type == AVMEDIA_TYPE_AUDIO) {
         mkv->cur_audio_pkt = *pkt;
-        mkv->cur_audio_pkt.buf = av_buffer_ref(pkt->buf);
-        ret = mkv->cur_audio_pkt.buf ? 0 : AVERROR(ENOMEM);
+        if (pkt->buf) {
+            mkv->cur_audio_pkt.buf = av_buffer_ref(pkt->buf);
+            ret = mkv->cur_audio_pkt.buf ? 0 : AVERROR(ENOMEM);
+        } else
+            ret = av_dup_packet(&mkv->cur_audio_pkt);
     } else
         ret = mkv_write_packet_internal(s, pkt);
     return ret;
 }
 
+static int mkv_write_flush_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    MatroskaMuxContext *mkv = s->priv_data;
+    AVIOContext *pb;
+    if (s->pb->seekable)
+        pb = s->pb;
+    else
+        pb = mkv->dyn_bc;
+    if (!pkt) {
+        if (mkv->cluster_pos != -1) {
+            av_log(s, AV_LOG_DEBUG, "Flushing cluster at offset %" PRIu64
+                   " bytes\n", avio_tell(pb));
+            end_ebml_master(pb, mkv->cluster);
+            mkv->cluster_pos = -1;
+            if (mkv->dyn_bc)
+                mkv_flush_dynbuf(s);
+            avio_flush(s->pb);
+        }
+        return 0;
+    }
+    return mkv_write_packet(s, pkt);
+}
+
 static int mkv_write_trailer(AVFormatContext *s)
 {
     MatroskaMuxContext *mkv = s->priv_data;
@@ -1334,7 +1610,28 @@
 
     if (pb->seekable) {
         if (mkv->cues->num_entries) {
-            cuespos = mkv_write_cues(pb, mkv->cues, mkv->tracks, s->nb_streams);
+            if (mkv->reserve_cues_space) {
+                int64_t cues_end;
+
+                currentpos = avio_tell(pb);
+                avio_seek(pb, mkv->cues_pos, SEEK_SET);
+
+                cuespos = mkv_write_cues(pb, mkv->cues, mkv->tracks, s->nb_streams);
+                cues_end = avio_tell(pb);
+                if (cues_end > cuespos + mkv->reserve_cues_space) {
+                    av_log(s, AV_LOG_ERROR, "Insufficient space reserved for cues: %d "
+                           "(needed: %"PRId64").\n", mkv->reserve_cues_space,
+                           cues_end - cuespos);
+                    return AVERROR(EINVAL);
+                }
+
+                if (cues_end < cuespos + mkv->reserve_cues_space)
+                    put_ebml_void(pb, mkv->reserve_cues_space - (cues_end - cuespos));
+
+                avio_seek(pb, currentpos, SEEK_SET);
+            } else {
+                cuespos = mkv_write_cues(pb, mkv->cues, mkv->tracks, s->nb_streams);
+            }
 
             ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CUES, cuespos);
             if (ret < 0) return ret;
@@ -1375,7 +1672,7 @@
     return 0;
 }
 
-const AVCodecTag additional_audio_tags[] = {
+static const AVCodecTag additional_audio_tags[] = {
     { AV_CODEC_ID_ALAC,      0XFFFFFFFF },
     { AV_CODEC_ID_EAC3,      0XFFFFFFFF },
     { AV_CODEC_ID_MLP,       0xFFFFFFFF },
@@ -1388,11 +1685,10 @@
     { AV_CODEC_ID_RA_288,    0xFFFFFFFF },
     { AV_CODEC_ID_COOK,      0xFFFFFFFF },
     { AV_CODEC_ID_TRUEHD,    0xFFFFFFFF },
-    { AV_CODEC_ID_WAVPACK,   0xFFFFFFFF },
     { AV_CODEC_ID_NONE,      0xFFFFFFFF }
 };
 
-const AVCodecTag additional_video_tags[] = {
+static const AVCodecTag additional_video_tags[] = {
     { AV_CODEC_ID_PRORES,    0xFFFFFFFF },
     { AV_CODEC_ID_RV10,      0xFFFFFFFF },
     { AV_CODEC_ID_RV20,      0xFFFFFFFF },
@@ -1402,7 +1698,23 @@
     { AV_CODEC_ID_NONE,      0xFFFFFFFF }
 };
 
+#define OFFSET(x) offsetof(MatroskaMuxContext, x)
+#define FLAGS AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    { "reserve_index_space", "Reserve a given amount of space (in bytes) at the beginning of the file for the index (cues).", OFFSET(reserve_cues_space), AV_OPT_TYPE_INT,   { .i64 = 0 },   0, INT_MAX,   FLAGS },
+    { "cluster_size_limit",  "Store at most the provided amount of bytes in a cluster. ",                                     OFFSET(cluster_size_limit), AV_OPT_TYPE_INT  , { .i64 = -1 }, -1, INT_MAX,   FLAGS },
+    { "cluster_time_limit",  "Store at most the provided number of milliseconds in a cluster.",                               OFFSET(cluster_time_limit), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, FLAGS },
+    { NULL },
+};
+
 #if CONFIG_MATROSKA_MUXER
+static const AVClass matroska_class = {
+    .class_name = "matroska muxer",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVOutputFormat ff_matroska_muxer = {
     .name              = "matroska",
     .long_name         = NULL_IF_CONFIG_SMALL("Matroska"),
@@ -1414,10 +1726,10 @@
     .video_codec       = CONFIG_LIBX264_ENCODER ?
                          AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4,
     .write_header      = mkv_write_header,
-    .write_packet      = mkv_write_packet,
+    .write_packet      = mkv_write_flush_packet,
     .write_trailer     = mkv_write_trailer,
     .flags             = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |
-                         AVFMT_TS_NONSTRICT,
+                         AVFMT_TS_NONSTRICT | AVFMT_ALLOW_FLUSH,
     .codec_tag         = (const AVCodecTag* const []){
          ff_codec_bmp_tags, ff_codec_wav_tags,
          additional_audio_tags, additional_video_tags, 0
@@ -1428,10 +1740,18 @@
     .subtitle_codec    = AV_CODEC_ID_ASS,
 #endif
     .query_codec       = mkv_query_codec,
+    .priv_class        = &matroska_class,
 };
 #endif
 
 #if CONFIG_WEBM_MUXER
+static const AVClass webm_class = {
+    .class_name = "webm muxer",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVOutputFormat ff_webm_muxer = {
     .name              = "webm",
     .long_name         = NULL_IF_CONFIG_SMALL("WebM"),
@@ -1440,18 +1760,26 @@
     .priv_data_size    = sizeof(MatroskaMuxContext),
     .audio_codec       = AV_CODEC_ID_VORBIS,
     .video_codec       = AV_CODEC_ID_VP8,
+    .subtitle_codec    = AV_CODEC_ID_WEBVTT,
     .write_header      = mkv_write_header,
-    .write_packet      = mkv_write_packet,
+    .write_packet      = mkv_write_flush_packet,
     .write_trailer     = mkv_write_trailer,
     .flags             = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |
-                         AVFMT_TS_NONSTRICT,
+                         AVFMT_TS_NONSTRICT | AVFMT_ALLOW_FLUSH,
+    .priv_class        = &webm_class,
 };
 #endif
 
 #if CONFIG_MATROSKA_AUDIO_MUXER
+static const AVClass mka_class = {
+    .class_name = "matroska audio muxer",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
 AVOutputFormat ff_matroska_audio_muxer = {
     .name              = "matroska",
-    .long_name         = NULL_IF_CONFIG_SMALL("Matroska"),
+    .long_name         = NULL_IF_CONFIG_SMALL("Matroska Audio"),
     .mime_type         = "audio/x-matroska",
     .extensions        = "mka",
     .priv_data_size    = sizeof(MatroskaMuxContext),
@@ -1459,11 +1787,13 @@
                          AV_CODEC_ID_VORBIS : AV_CODEC_ID_AC3,
     .video_codec       = AV_CODEC_ID_NONE,
     .write_header      = mkv_write_header,
-    .write_packet      = mkv_write_packet,
+    .write_packet      = mkv_write_flush_packet,
     .write_trailer     = mkv_write_trailer,
-    .flags             = AVFMT_GLOBALHEADER | AVFMT_TS_NONSTRICT,
+    .flags             = AVFMT_GLOBALHEADER | AVFMT_TS_NONSTRICT |
+                         AVFMT_ALLOW_FLUSH,
     .codec_tag         = (const AVCodecTag* const []){
         ff_codec_wav_tags, additional_audio_tags, 0
     },
+    .priv_class        = &mka_class,
 };
 #endif
diff --git a/libavformat/md5enc.c b/libavformat/md5enc.c
index 050efb1..270d9fb 100644
--- a/libavformat/md5enc.c
+++ b/libavformat/md5enc.c
@@ -19,21 +19,28 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/md5.h"
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/hash.h"
+#include "libavutil/opt.h"
 #include "avformat.h"
 #include "internal.h"
 
 struct MD5Context {
-    struct AVMD5 *md5;
+    const AVClass *avclass;
+    struct AVHashContext *hash;
+    char *hash_name;
 };
 
 static void md5_finish(struct AVFormatContext *s, char *buf)
 {
     struct MD5Context *c = s->priv_data;
-    uint8_t md5[16];
+    uint8_t md5[AV_HASH_MAX_SIZE];
     int i, offset = strlen(buf);
-    av_md5_final(c->md5, md5);
-    for (i = 0; i < sizeof(md5); i++) {
+    int len = av_hash_get_size(c->hash);
+    av_assert0(len > 0 && len <= sizeof(md5));
+    av_hash_final(c->hash, md5);
+    for (i = 0; i < len; i++) {
         snprintf(buf + offset, 3, "%02"PRIx8, md5[i]);
         offset += 2;
     }
@@ -44,32 +51,48 @@
     avio_flush(s->pb);
 }
 
+#define OFFSET(x) offsetof(struct MD5Context, x)
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption hash_options[] = {
+    { "hash", "set hash to use", OFFSET(hash_name), AV_OPT_TYPE_STRING, {.str = "md5"}, 0, 0, ENC },
+    { NULL },
+};
+
+static const AVClass md5enc_class = {
+    .class_name = "hash encoder class",
+    .item_name  = av_default_item_name,
+    .option     = hash_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 #if CONFIG_MD5_MUXER
 static int write_header(struct AVFormatContext *s)
 {
     struct MD5Context *c = s->priv_data;
-    c->md5 = av_md5_alloc();
-    if (!c->md5)
-        return AVERROR(ENOMEM);
-    av_md5_init(c->md5);
+    int res = av_hash_alloc(&c->hash, c->hash_name);
+    if (res < 0)
+        return res;
+    av_hash_init(c->hash);
     return 0;
 }
 
 static int write_packet(struct AVFormatContext *s, AVPacket *pkt)
 {
     struct MD5Context *c = s->priv_data;
-    av_md5_update(c->md5, pkt->data, pkt->size);
+    av_hash_update(c->hash, pkt->data, pkt->size);
     return 0;
 }
 
 static int write_trailer(struct AVFormatContext *s)
 {
     struct MD5Context *c = s->priv_data;
-    char buf[64] = "MD5=";
+    char buf[256];
+    av_strlcpy(buf, av_hash_get_name(c->hash), sizeof(buf) - 200);
+    av_strlcat(buf, "=", sizeof(buf) - 200);
 
     md5_finish(s, buf);
 
-    av_freep(&c->md5);
+    av_hash_freep(&c->hash);
     return 0;
 }
 
@@ -83,6 +106,7 @@
     .write_packet      = write_packet,
     .write_trailer     = write_trailer,
     .flags             = AVFMT_NOTIMESTAMPS,
+    .priv_class        = &md5enc_class,
 };
 #endif
 
@@ -90,9 +114,9 @@
 static int framemd5_write_header(struct AVFormatContext *s)
 {
     struct MD5Context *c = s->priv_data;
-    c->md5 = av_md5_alloc();
-    if (!c->md5)
-        return AVERROR(ENOMEM);
+    int res = av_hash_alloc(&c->hash, c->hash_name);
+    if (res < 0)
+        return res;
     return ff_framehash_write_header(s);
 }
 
@@ -100,8 +124,8 @@
 {
     struct MD5Context *c = s->priv_data;
     char buf[256];
-    av_md5_init(c->md5);
-    av_md5_update(c->md5, pkt->data, pkt->size);
+    av_hash_init(c->hash);
+    av_hash_update(c->hash, pkt->data, pkt->size);
 
     snprintf(buf, sizeof(buf) - 64, "%d, %10"PRId64", %10"PRId64", %8d, %8d, ",
              pkt->stream_index, pkt->dts, pkt->pts, pkt->duration, pkt->size);
@@ -112,10 +136,17 @@
 static int framemd5_write_trailer(struct AVFormatContext *s)
 {
     struct MD5Context *c = s->priv_data;
-    av_freep(&c->md5);
+    av_hash_freep(&c->hash);
     return 0;
 }
 
+static const AVClass framemd5_class = {
+    .class_name = "frame hash encoder class",
+    .item_name  = av_default_item_name,
+    .option     = hash_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVOutputFormat ff_framemd5_muxer = {
     .name              = "framemd5",
     .long_name         = NULL_IF_CONFIG_SMALL("Per-frame MD5 testing"),
@@ -125,6 +156,8 @@
     .write_header      = framemd5_write_header,
     .write_packet      = framemd5_write_packet,
     .write_trailer     = framemd5_write_trailer,
-    .flags             = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
+    .flags             = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT |
+                         AVFMT_TS_NEGATIVE,
+    .priv_class        = &framemd5_class,
 };
 #endif
diff --git a/libavformat/mm.c b/libavformat/mm.c
index 12a11ac..4315802 100644
--- a/libavformat/mm.c
+++ b/libavformat/mm.c
@@ -79,7 +79,7 @@
         return 0;
 
     /* only return half certainty since this check is a bit sketchy */
-    return AVPROBE_SCORE_MAX / 2;
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 static int read_header(AVFormatContext *s)
diff --git a/libavformat/mmf.c b/libavformat/mmf.c
index d074d7c..cb87a6d 100644
--- a/libavformat/mmf.c
+++ b/libavformat/mmf.c
@@ -21,8 +21,8 @@
 
 #include "libavutil/channel_layout.h"
 #include "avformat.h"
-#include "internal.h"
 #include "avio_internal.h"
+#include "internal.h"
 #include "pcm.h"
 #include "rawenc.h"
 #include "riff.h"
@@ -37,7 +37,7 @@
 
 static int mmf_rate(int code)
 {
-    if((code < 0) || (code > 4))
+    if ((code < 0) || (code > 4))
         return -1;
     return mmf_rates[code];
 }
@@ -46,8 +46,8 @@
 static int mmf_rate_code(int rate)
 {
     int i;
-    for(i = 0; i < 5; i++)
-        if(mmf_rates[i] == rate)
+    for (i = 0; i < 5; i++)
+        if (mmf_rates[i] == rate)
             return i;
     return -1;
 }
@@ -74,8 +74,9 @@
                           "VN:"LIBAVFORMAT_IDENT",";
 
     rate = mmf_rate_code(s->streams[0]->codec->sample_rate);
-    if(rate < 0) {
-        av_log(s, AV_LOG_ERROR, "Unsupported sample rate %d, supported are 4000, 8000, 11025, 22050 and 44100\n", s->streams[0]->codec->sample_rate);
+    if (rate < 0) {
+        av_log(s, AV_LOG_ERROR, "Unsupported sample rate %d, supported are 4000, 8000, 11025, 22050 and 44100\n",
+               s->streams[0]->codec->sample_rate);
         return AVERROR(EINVAL);
     }
 
@@ -97,6 +98,7 @@
     avio_w8(pb, 0); /* status */
     avio_w8(pb, 0); /* counts */
     end_tag_be(pb, pos);
+
     pos = ff_start_tag(pb, "OPDA");
     avio_write(pb, version, strlen(version)); /* metadata ("ST:songtitle,VN:version,...") */
     end_tag_be(pb, pos);
@@ -129,7 +131,7 @@
 /* Write a variable-length symbol */
 static void put_varlength(AVIOContext *pb, int val)
 {
-    if(val < 128)
+    if (val < 128)
         avio_w8(pb, val);
     else {
         val -= 128;
@@ -151,7 +153,7 @@
         end_tag_be(pb, mmf->atrpos);
         end_tag_be(pb, 8);
 
-        pos = avio_tell(pb);
+        pos  = avio_tell(pb);
         size = pos - mmf->awapos;
 
         /* Fill Atsq chunk */
@@ -206,11 +208,13 @@
     avio_skip(pb, 4); /* file_size */
 
     /* Skip some unused chunks that may or may not be present */
-    for(;; avio_skip(pb, size)) {
-        tag = avio_rl32(pb);
+    for (;; avio_skip(pb, size)) {
+        tag  = avio_rl32(pb);
         size = avio_rb32(pb);
-        if(tag == MKTAG('C','N','T','I')) continue;
-        if(tag == MKTAG('O','P','D','A')) continue;
+        if (tag == MKTAG('C', 'N', 'T', 'I'))
+            continue;
+        if (tag == MKTAG('O', 'P', 'D', 'A'))
+            continue;
         break;
     }
 
@@ -227,8 +231,8 @@
     avio_r8(pb); /* format type */
     avio_r8(pb); /* sequence type */
     params = avio_r8(pb); /* (channel << 7) | (format << 4) | rate */
-    rate = mmf_rate(params & 0x0f);
-    if(rate  < 0) {
+    rate   = mmf_rate(params & 0x0f);
+    if (rate < 0) {
         av_log(s, AV_LOG_ERROR, "Invalid sample rate\n");
         return AVERROR_INVALIDDATA;
     }
@@ -237,11 +241,13 @@
     avio_r8(pb); /* time base g */
 
     /* Skip some unused chunks that may or may not be present */
-    for(;; avio_skip(pb, size)) {
-        tag = avio_rl32(pb);
+    for (;; avio_skip(pb, size)) {
+        tag  = avio_rl32(pb);
         size = avio_rb32(pb);
-        if(tag == MKTAG('A','t','s','q')) continue;
-        if(tag == MKTAG('A','s','p','I')) continue;
+        if (tag == MKTAG('A', 't', 's', 'q'))
+            continue;
+        if (tag == MKTAG('A', 's', 'p', 'I'))
+            continue;
         break;
     }
 
@@ -256,13 +262,14 @@
     if (!st)
         return AVERROR(ENOMEM);
 
-    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
-    st->codec->codec_id = AV_CODEC_ID_ADPCM_YAMAHA;
-    st->codec->sample_rate = rate;
-    st->codec->channels = (params >> 7) + 1;
-    st->codec->channel_layout = params >> 7 ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
+    st->codec->codec_type            = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_id              = AV_CODEC_ID_ADPCM_YAMAHA;
+    st->codec->sample_rate           = rate;
+    st->codec->channels              = (params >> 7) + 1;
+    st->codec->channel_layout        = params >> 7 ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
     st->codec->bits_per_coded_sample = 4;
-    st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample;
+    st->codec->bit_rate              = st->codec->sample_rate *
+                                       st->codec->bits_per_coded_sample;
 
     avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
 
@@ -271,8 +278,7 @@
 
 #define MAX_SIZE 4096
 
-static int mmf_read_packet(AVFormatContext *s,
-                           AVPacket *pkt)
+static int mmf_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     MMFContext *mmf = s->priv_data;
     int64_t left, size;
@@ -303,17 +309,18 @@
     .flags          = AVFMT_GENERIC_INDEX,
 };
 #endif
+
 #if CONFIG_MMF_MUXER
 AVOutputFormat ff_mmf_muxer = {
-    .name              = "mmf",
-    .long_name         = NULL_IF_CONFIG_SMALL("Yamaha SMAF"),
-    .mime_type         = "application/vnd.smaf",
-    .extensions        = "mmf",
-    .priv_data_size    = sizeof(MMFContext),
-    .audio_codec       = AV_CODEC_ID_ADPCM_YAMAHA,
-    .video_codec       = AV_CODEC_ID_NONE,
-    .write_header      = mmf_write_header,
-    .write_packet      = ff_raw_write_packet,
-    .write_trailer     = mmf_write_trailer,
+    .name           = "mmf",
+    .long_name      = NULL_IF_CONFIG_SMALL("Yamaha SMAF"),
+    .mime_type      = "application/vnd.smaf",
+    .extensions     = "mmf",
+    .priv_data_size = sizeof(MMFContext),
+    .audio_codec    = AV_CODEC_ID_ADPCM_YAMAHA,
+    .video_codec    = AV_CODEC_ID_NONE,
+    .write_header   = mmf_write_header,
+    .write_packet   = ff_raw_write_packet,
+    .write_trailer  = mmf_write_trailer,
 };
 #endif
diff --git a/libavformat/mmsh.c b/libavformat/mmsh.c
index 86a0575..482ece4 100644
--- a/libavformat/mmsh.c
+++ b/libavformat/mmsh.c
@@ -66,9 +66,9 @@
     MMSHContext *mmsh = (MMSHContext *)h->priv_data;
     MMSContext *mms   = &mmsh->mms;
     if (mms->mms_hd)
-        ffurl_close(mms->mms_hd);
-    av_free(mms->streams);
-    av_free(mms->asf_header);
+        ffurl_closep(&mms->mms_hd);
+    av_freep(&mms->streams);
+    av_freep(&mms->asf_header);
     return 0;
 }
 
@@ -368,23 +368,26 @@
 static int64_t mmsh_read_seek(URLContext *h, int stream_index,
                         int64_t timestamp, int flags)
 {
-    MMSHContext *mmsh = h->priv_data;
-    MMSContext *mms   = &mmsh->mms;
+    MMSHContext *mmsh_old = h->priv_data;
+    MMSHContext *mmsh     = av_mallocz(sizeof(*mmsh));
     int ret;
 
-    ret= mmsh_open_internal(h, mmsh->location, 0, FFMAX(timestamp, 0), 0);
+    if (!mmsh)
+        return AVERROR(ENOMEM);
 
+    h->priv_data = mmsh;
+    ret= mmsh_open_internal(h, mmsh_old->location, 0, FFMAX(timestamp, 0), 0);
     if(ret>=0){
-        if (mms->mms_hd)
-            ffurl_close(mms->mms_hd);
-        av_freep(&mms->streams);
-        av_freep(&mms->asf_header);
+        h->priv_data = mmsh_old;
+        mmsh_close(h);
+        h->priv_data = mmsh;
+        av_free(mmsh_old);
+        mmsh->mms.asf_header_read_size = mmsh->mms.asf_header_size;
+    }else {
+        h->priv_data = mmsh_old;
         av_free(mmsh);
-        mmsh = h->priv_data;
-        mms   = &mmsh->mms;
-        mms->asf_header_read_size= mms->asf_header_size;
-    }else
-        h->priv_data= mmsh;
+    }
+
     return ret;
 }
 
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 3e48f15..ed5fb95 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -25,7 +25,6 @@
 
 #include <limits.h>
 
-//#define DEBUG
 //#define MOV_EXPORT_ALL_METADATA
 
 #include "libavutil/attributes.h"
@@ -786,6 +785,12 @@
 {
     int ret;
 
+    if (c->found_moov) {
+        av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
+        avio_skip(pb, atom.size);
+        return 0;
+    }
+
     if ((ret = mov_read_default(c, pb, atom)) < 0)
         return ret;
     /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
@@ -831,6 +836,11 @@
     st = c->fc->streams[c->fc->nb_streams-1];
     sc = st->priv_data;
 
+    if (sc->time_scale) {
+        av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     version = avio_r8(pb);
     if (version > 1) {
         avpriv_request_sample(c->fc, "Version %d", version);
@@ -878,7 +888,7 @@
     c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
     // set the AVCodecContext duration because the duration of individual tracks
     // may be inaccurate
-    if (c->time_scale > 0)
+    if (c->time_scale > 0 && !c->trex_data)
         c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
     avio_rb32(pb); /* preferred scale */
 
@@ -1015,6 +1025,36 @@
     return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
 }
 
+static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+    int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
+
+    if (!ret && c->fc->nb_streams >= 1) {
+        AVCodecContext *avctx = c->fc->streams[c->fc->nb_streams-1]->codec;
+        if (avctx->extradata_size >= 40) {
+            avctx->height = AV_RB16(&avctx->extradata[36]);
+            avctx->width  = AV_RB16(&avctx->extradata[38]);
+        }
+    }
+    return ret;
+}
+
+static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+    AVCodecContext *codec = c->fc->streams[c->fc->nb_streams-1]->codec;
+    if (codec->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
+        codec->codec_id == AV_CODEC_ID_H264 &&
+        atom.size > 11) {
+        avio_skip(pb, 10);
+        /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
+        if (avio_rb16(pb) == 0xd4d)
+            codec->width = 1440;
+        return 0;
+    }
+
+    return mov_read_avid(c, pb, atom);
+}
+
 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
     return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
@@ -1550,6 +1590,9 @@
     case AV_CODEC_ID_ADPCM_MS:
     case AV_CODEC_ID_ADPCM_IMA_WAV:
     case AV_CODEC_ID_ILBC:
+    case AV_CODEC_ID_MACE3:
+    case AV_CODEC_ID_MACE6:
+    case AV_CODEC_ID_QDM2:
         st->codec->block_align = sc->bytes_per_frame;
         break;
     case AV_CODEC_ID_ALAC:
@@ -1720,7 +1763,7 @@
         sample_size = avio_rb32(pb);
         if (!sc->sample_size) /* do not overwrite value computed in stsd */
             sc->sample_size = sample_size;
-        sc->alt_sample_size = sample_size;
+        sc->stsz_sample_size = sample_size;
         field_size = 32;
     } else {
         sample_size = 0;
@@ -1838,6 +1881,13 @@
     return 0;
 }
 
+static void mov_update_dts_shift(MOVStreamContext *sc, int duration)
+{
+    if (duration < 0) {
+        sc->dts_shift = FFMAX(sc->dts_shift, -duration);
+    }
+}
+
 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
     AVStream *st;
@@ -1880,8 +1930,8 @@
             return 0;
         }
 
-        if (duration < 0 && i+2<entries)
-            sc->dts_shift = FFMAX(sc->dts_shift, -duration);
+        if (i+2<entries)
+            mov_update_dts_shift(sc, duration);
     }
 
     sc->ctts_count = i;
@@ -1987,10 +2037,22 @@
         st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
 
         for (i = 0; i < sc->chunk_count; i++) {
+            int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
             current_offset = sc->chunk_offsets[i];
             while (stsc_index + 1 < sc->stsc_count &&
                 i + 1 == sc->stsc_data[stsc_index + 1].first)
                 stsc_index++;
+
+            if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
+                sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
+                av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
+                sc->stsz_sample_size = sc->sample_size;
+            }
+            if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
+                av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
+                sc->stsz_sample_size = sc->sample_size;
+            }
+
             for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
                 int keyframe = 0;
                 if (current_sample >= sc->sample_count) {
@@ -2017,7 +2079,7 @@
                 }
                 if (keyframe)
                     distance = 0;
-                sample_size = sc->alt_sample_size > 0 ? sc->alt_sample_size : sc->sample_sizes[current_sample];
+                sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
                 if (sc->pseudo_stream_id == -1 ||
                    sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
                     AVIndexEntry *e = &st->index_entries[st->nb_index_entries++];
@@ -2549,6 +2611,7 @@
         sc->ctts_data[sc->ctts_count].count = 1;
         sc->ctts_data[sc->ctts_count].duration = (flags & MOV_TRUN_SAMPLE_CTS) ?
                                                   avio_rb32(pb) : 0;
+        mov_update_dts_shift(sc, sc->ctts_data[sc->ctts_count].duration);
         sc->ctts_count++;
         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
             keyframe = 1;
@@ -2709,11 +2772,77 @@
     return 0;
 }
 
+static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+    int ret;
+    uint8_t uuid[16];
+    static const uint8_t uuid_isml_manifest[] = {
+        0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
+        0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
+    };
+
+    if (atom.size < sizeof(uuid) || atom.size == INT64_MAX)
+        return AVERROR_INVALIDDATA;
+
+    ret = avio_read(pb, uuid, sizeof(uuid));
+    if (ret < 0) {
+        return ret;
+    } else if (ret != sizeof(uuid)) {
+        return AVERROR_INVALIDDATA;
+    }
+    if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
+        uint8_t *buffer, *ptr;
+        char *endptr;
+        size_t len = atom.size - sizeof(uuid);
+
+        if (len < 4) {
+            return AVERROR_INVALIDDATA;
+        }
+        ret = avio_skip(pb, 4); // zeroes
+        len -= 4;
+
+        buffer = av_mallocz(len + 1);
+        if (!buffer) {
+            return AVERROR(ENOMEM);
+        }
+        ret = avio_read(pb, buffer, len);
+        if (ret < 0) {
+            av_free(buffer);
+            return ret;
+        } else if (ret != len) {
+            av_free(buffer);
+            return AVERROR_INVALIDDATA;
+        }
+
+        ptr = buffer;
+        while ((ptr = av_stristr(ptr, "systemBitrate=\"")) != NULL) {
+            ptr += sizeof("systemBitrate=\"") - 1;
+            c->bitrates_count++;
+            c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
+            if (!c->bitrates) {
+                c->bitrates_count = 0;
+                av_free(buffer);
+                return AVERROR(ENOMEM);
+            }
+            errno = 0;
+            ret = strtol(ptr, &endptr, 10);
+            if (ret < 0 || errno || *endptr != '"') {
+                c->bitrates[c->bitrates_count - 1] = 0;
+            } else {
+                c->bitrates[c->bitrates_count - 1] = ret;
+            }
+        }
+
+        av_free(buffer);
+    }
+    return 0;
+}
+
 static const MOVParseTableEntry mov_default_parse_table[] = {
 { MKTAG('A','C','L','R'), mov_read_avid },
 { MKTAG('A','P','R','G'), mov_read_avid },
 { MKTAG('A','A','L','P'), mov_read_avid },
-{ MKTAG('A','R','E','S'), mov_read_avid },
+{ MKTAG('A','R','E','S'), mov_read_ares },
 { MKTAG('a','v','s','s'), mov_read_avss },
 { MKTAG('c','h','p','l'), mov_read_chpl },
 { MKTAG('c','o','6','4'), mov_read_stco },
@@ -2772,6 +2901,8 @@
 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
 { MKTAG('d','v','c','1'), mov_read_dvc1 },
 { MKTAG('s','b','g','p'), mov_read_sbgp },
+{ MKTAG('u','u','i','d'), mov_read_uuid },
+{ MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
 { 0, NULL }
 };
 
@@ -2845,8 +2976,10 @@
             left = a.size - avio_tell(pb) + start_pos;
             if (left > 0) /* skip garbage at atom end */
                 avio_skip(pb, left);
-            else if(left < 0) {
-                av_log(c->fc, AV_LOG_DEBUG, "undoing overread of %"PRId64" in '%.4s'\n", -left, (char*)&a.type);
+            else if (left < 0) {
+                av_log(c->fc, AV_LOG_WARNING,
+                       "overread end of atom '%.4s' by %"PRId64" bytes\n",
+                       (char*)&a.type, -left);
                 avio_seek(pb, left, SEEK_CUR);
             }
         }
@@ -2887,7 +3020,7 @@
                 (AV_RB32(p->buf+offset) != 1 ||
                  offset + 12 > (unsigned int)p->buf_size ||
                  AV_RB64(p->buf+offset + 8) == 0)) {
-                score = FFMAX(score, AVPROBE_SCORE_MAX - 50);
+                score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
             } else {
                 score = AVPROBE_SCORE_MAX;
             }
@@ -2907,7 +3040,7 @@
         case MKTAG('u','u','i','d'):
         case MKTAG('p','r','f','l'):
             /* if we only find those cause probedata is too small at least rate them */
-            score  = FFMAX(score, AVPROBE_SCORE_MAX - 50);
+            score  = FFMAX(score, AVPROBE_SCORE_EXTENSION);
             offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
             break;
         default:
@@ -3088,6 +3221,7 @@
     }
 
     av_freep(&mov->trex_data);
+    av_freep(&mov->bitrates);
 
     return 0;
 }
@@ -3200,6 +3334,12 @@
         }
     }
 
+    for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
+        if (mov->bitrates[i]) {
+            s->streams[i]->codec->bit_rate = mov->bitrates[i];
+        }
+    }
+
     return 0;
 }
 
@@ -3255,6 +3395,11 @@
     /* must be done just before reading, to avoid infinite loop on sample */
     sc->current_sample++;
 
+    if (mov->next_root_atom) {
+        sample->pos = FFMIN(sample->pos, mov->next_root_atom);
+        sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
+    }
+
     if (st->discard != AVDISCARD_ALL) {
         if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
             av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
@@ -3387,7 +3532,7 @@
     {NULL}
 };
 
-static const AVClass class = {
+static const AVClass mov_class = {
     .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
     .item_name  = av_default_item_name,
     .option     = options,
@@ -3403,6 +3548,6 @@
     .read_packet    = mov_read_packet,
     .read_close     = mov_read_close,
     .read_seek      = mov_read_seek,
-    .priv_class     = &class,
+    .priv_class     = &mov_class,
     .flags          = AVFMT_NO_BYTE_SEEK,
 };
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 8f3b1bc..13ffa24 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -52,7 +52,7 @@
     { "separate_moof", "Write separate moof/mdat atoms for each track", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SEPARATE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
     { "frag_custom", "Flush fragments on caller requests", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_CUSTOM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
     { "isml", "Create a live smooth streaming feed (for pushing to a publishing point)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_ISML}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
-    { "faststart", "Run a second pass to put the moov at the beginning of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FASTSTART}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+    { "faststart", "Run a second pass to put the index (moov atom) at the beginning of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FASTSTART}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
     FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
     { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
     { "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
@@ -62,6 +62,7 @@
     { "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
     { "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
     { "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
+    { "video_track_timescale", "set timescale of all video tracks", offsetof(MOVMuxContext, video_track_timescale), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
     { NULL },
 };
 
@@ -73,6 +74,8 @@
     .version    = LIBAVUTIL_VERSION_INT,\
 };
 
+static int get_moov_size(AVFormatContext *s);
+
 //FIXME support 64 bit variant with wide placeholders
 static int64_t update_size(AVIOContext *pb, int64_t pos)
 {
@@ -86,20 +89,14 @@
 
 static int supports_edts(MOVMuxContext *mov)
 {
-    // EDTS with fragments is tricky as we dont know the duration when its written
+    // EDTS with fragments is tricky as we don't know the duration when its written
     return (mov->use_editlist<0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) || mov->use_editlist>0;
 }
 
-static int is_co64_required(const MOVTrack *track)
+static int co64_required(const MOVTrack *track)
 {
-    int i;
-
-    for (i = 0; i < track->entry; i++) {
-        if (!track->cluster[i].chunkNum)
-            continue;
-        if (track->cluster[i].pos + track->data_offset > UINT32_MAX)
-            return 1;
-    }
+    if (track->entry > 0 && track->cluster[track->entry - 1].pos + track->data_offset > UINT32_MAX)
+        return 1;
     return 0;
 }
 
@@ -107,7 +104,7 @@
 static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track)
 {
     int i;
-    int mode64 = is_co64_required(track); // use 32 bit size variant if possible
+    int mode64 = co64_required(track); // use 32 bit size variant if possible
     int64_t pos = avio_tell(pb);
     avio_wb32(pb, 0); /* size */
     if (mode64)
@@ -116,10 +113,10 @@
         ffio_wfourcc(pb, "stco");
     avio_wb32(pb, 0); /* version & flags */
     avio_wb32(pb, track->chunkCount); /* entry count */
-    for (i=0; i<track->entry; i++) {
-        if(!track->cluster[i].chunkNum)
+    for (i = 0; i < track->entry; i++) {
+        if (!track->cluster[i].chunkNum)
             continue;
-        if(mode64 == 1)
+        if (mode64 == 1)
             avio_wb64(pb, track->cluster[i].pos + track->data_offset);
         else
             avio_wb32(pb, track->cluster[i].pos + track->data_offset);
@@ -138,27 +135,25 @@
     ffio_wfourcc(pb, "stsz");
     avio_wb32(pb, 0); /* version & flags */
 
-    for (i=0; i<track->entry; i++) {
-        tst = track->cluster[i].size/track->cluster[i].entries;
-        if(oldtst != -1 && tst != oldtst) {
+    for (i = 0; i < track->entry; i++) {
+        tst = track->cluster[i].size / track->cluster[i].entries;
+        if (oldtst != -1 && tst != oldtst)
             equalChunks = 0;
-        }
         oldtst = tst;
         entries += track->cluster[i].entries;
     }
     if (equalChunks && track->entry) {
-        int sSize = track->entry ? track->cluster[0].size/track->cluster[0].entries : 0;
+        int sSize = track->entry ? track->cluster[0].size / track->cluster[0].entries : 0;
         sSize = FFMAX(1, sSize); // adpcm mono case could make sSize == 0
         avio_wb32(pb, sSize); // sample size
         avio_wb32(pb, entries); // sample count
-    }
-    else {
+    } else {
         avio_wb32(pb, 0); // sample size
         avio_wb32(pb, entries); // sample count
-        for (i=0; i<track->entry; i++) {
-            for (j=0; j<track->cluster[i].entries; j++) {
+        for (i = 0; i < track->entry; i++) {
+            for (j = 0; j < track->cluster[i].entries; j++) {
                 avio_wb32(pb, track->cluster[i].size /
-                         track->cluster[i].entries);
+                          track->cluster[i].entries);
             }
         }
     }
@@ -177,9 +172,8 @@
     avio_wb32(pb, 0); // version & flags
     entryPos = avio_tell(pb);
     avio_wb32(pb, track->chunkCount); // entry count
-    for (i=0; i<track->entry; i++) {
-        if (oldval != track->cluster[i].samples_in_chunk && track->cluster[i].chunkNum)
-        {
+    for (i = 0; i < track->entry; i++) {
+        if (oldval != track->cluster[i].samples_in_chunk && track->cluster[i].chunkNum) {
             avio_wb32(pb, track->cluster[i].chunkNum); // first chunk
             avio_wb32(pb, track->cluster[i].samples_in_chunk); // samples per chunk
             avio_wb32(pb, 0x1); // sample description index
@@ -206,9 +200,9 @@
     avio_wb32(pb, 0); // version & flags
     entryPos = avio_tell(pb);
     avio_wb32(pb, track->entry); // entry count
-    for (i=0; i<track->entry; i++) {
+    for (i = 0; i < track->entry; i++) {
         if (track->cluster[i].flags & flag) {
-            avio_wb32(pb, i+1);
+            avio_wb32(pb, i + 1);
             index++;
         }
     }
@@ -268,7 +262,7 @@
     put_bits(&pbc, 3, bsmod);
     put_bits(&pbc, 3, acmod);
     put_bits(&pbc, 1, lfeon);
-    put_bits(&pbc, 5, frmsizecod>>1); // bit_rate_code
+    put_bits(&pbc, 5, frmsizecod >> 1); // bit_rate_code
     put_bits(&pbc, 5, 0); // reserved
 
     flush_put_bits(&pbc);
@@ -307,8 +301,8 @@
 {
     int i = 3;
     avio_w8(pb, tag);
-    for(; i>0; i--)
-        avio_w8(pb, (size>>(7*i)) | 0x80);
+    for (; i > 0; i--)
+        avio_w8(pb, (size >> (7 * i)) | 0x80);
     avio_w8(pb, size & 0x7F);
 }
 
@@ -351,7 +345,7 @@
 
     // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
     // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
-    if(track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
+    if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
         avio_w8(pb, 0x15); // flags (= Audiostream)
     else
         avio_w8(pb, 0x11); // flags (= Visualstream)
@@ -707,7 +701,7 @@
         avio_wb16(pb, 0); /* Reserved */
     }
 
-    if(version == 1) { /* SoundDescription V1 extended info */
+    if (version == 1) { /* SoundDescription V1 extended info */
         if (mov_pcm_le_gt16(track->enc->codec_id) ||
             mov_pcm_be_gt16(track->enc->codec_id))
             avio_wb32(pb, 1); /*  must be 1 for  uncompressed formats */
@@ -718,24 +712,24 @@
         avio_wb32(pb, 2); /* Bytes per sample */
     }
 
-    if(track->mode == MODE_MOV &&
-       (track->enc->codec_id == AV_CODEC_ID_AAC ||
-        track->enc->codec_id == AV_CODEC_ID_AC3 ||
-        track->enc->codec_id == AV_CODEC_ID_AMR_NB ||
-        track->enc->codec_id == AV_CODEC_ID_ALAC ||
-        track->enc->codec_id == AV_CODEC_ID_ADPCM_MS ||
-        track->enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
-        track->enc->codec_id == AV_CODEC_ID_QDM2 ||
-        (mov_pcm_le_gt16(track->enc->codec_id) && version==1) ||
-        (mov_pcm_be_gt16(track->enc->codec_id) && version==1)))
+    if (track->mode == MODE_MOV &&
+        (track->enc->codec_id == AV_CODEC_ID_AAC           ||
+         track->enc->codec_id == AV_CODEC_ID_AC3           ||
+         track->enc->codec_id == AV_CODEC_ID_AMR_NB        ||
+         track->enc->codec_id == AV_CODEC_ID_ALAC          ||
+         track->enc->codec_id == AV_CODEC_ID_ADPCM_MS      ||
+         track->enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
+         track->enc->codec_id == AV_CODEC_ID_QDM2          ||
+         (mov_pcm_le_gt16(track->enc->codec_id) && version==1) ||
+         (mov_pcm_be_gt16(track->enc->codec_id) && version==1)))
         mov_write_wave_tag(pb, track);
-    else if(track->tag == MKTAG('m','p','4','a'))
+    else if (track->tag == MKTAG('m','p','4','a'))
         mov_write_esds_tag(pb, track);
-    else if(track->enc->codec_id == AV_CODEC_ID_AMR_NB)
+    else if (track->enc->codec_id == AV_CODEC_ID_AMR_NB)
         mov_write_amr_tag(pb, track);
-    else if(track->enc->codec_id == AV_CODEC_ID_AC3)
+    else if (track->enc->codec_id == AV_CODEC_ID_AC3)
         mov_write_ac3_tag(pb, track);
-    else if(track->enc->codec_id == AV_CODEC_ID_ALAC)
+    else if (track->enc->codec_id == AV_CODEC_ID_ALAC)
         mov_write_extradata_tag(pb, track);
     else if (track->enc->codec_id == AV_CODEC_ID_WMAPRO)
         mov_write_wfex_tag(pb, track);
@@ -796,7 +790,7 @@
     avio_wb32(pb, track->enc->width);
     /* values below are based on samples created with quicktime and avid codecs */
     if (track->vos_data[5] & 2) { // interlaced
-        avio_wb32(pb, track->enc->height/2);
+        avio_wb32(pb, track->enc->height / 2);
         avio_wb32(pb, 2); /* unknown */
         avio_wb32(pb, 0); /* unknown */
         avio_wb32(pb, 4); /* unknown */
@@ -830,18 +824,18 @@
     else if (track->enc->codec_id == AV_CODEC_ID_DIRAC)     tag = MKTAG('d','r','a','c');
     else if (track->enc->codec_id == AV_CODEC_ID_MOV_TEXT)  tag = MKTAG('t','x','3','g');
     else if (track->enc->codec_id == AV_CODEC_ID_VC1)       tag = MKTAG('v','c','-','1');
-    else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) tag = MKTAG('m','p','4','v');
-    else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) tag = MKTAG('m','p','4','a');
+    else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO)  tag = MKTAG('m','p','4','v');
+    else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)  tag = MKTAG('m','p','4','a');
 
     return tag;
 }
 
 static const AVCodecTag codec_ipod_tags[] = {
-    { AV_CODEC_ID_H264,   MKTAG('a','v','c','1') },
-    { AV_CODEC_ID_MPEG4,  MKTAG('m','p','4','v') },
-    { AV_CODEC_ID_AAC,    MKTAG('m','p','4','a') },
-    { AV_CODEC_ID_ALAC,   MKTAG('a','l','a','c') },
-    { AV_CODEC_ID_AC3,    MKTAG('a','c','-','3') },
+    { AV_CODEC_ID_H264,     MKTAG('a','v','c','1') },
+    { AV_CODEC_ID_MPEG4,    MKTAG('m','p','4','v') },
+    { AV_CODEC_ID_AAC,      MKTAG('m','p','4','a') },
+    { AV_CODEC_ID_ALAC,     MKTAG('a','l','a','c') },
+    { AV_CODEC_ID_AC3,      MKTAG('a','c','-','3') },
     { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
     { AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
     { AV_CODEC_ID_NONE, 0 },
@@ -853,8 +847,8 @@
 
     // keep original tag for subs, ipod supports both formats
     if (!(track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE &&
-        (tag == MKTAG('t','x','3','g') ||
-         tag == MKTAG('t','e','x','t'))))
+          (tag == MKTAG('t', 'x', '3', 'g') ||
+           tag == MKTAG('t', 'e', 'x', 't'))))
         tag = ff_codec_get_tag(codec_ipod_tags, track->enc->codec_id);
 
     if (!av_match_ext(s->filename, "m4a") && !av_match_ext(s->filename, "m4v"))
@@ -871,16 +865,16 @@
     if (track->enc->width == 720) { /* SD */
         if (track->enc->height == 480) { /* NTSC */
             if  (track->enc->pix_fmt == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n');
-            else                                         tag = MKTAG('d','v','c',' ');
+            else                                            tag = MKTAG('d','v','c',' ');
        }else if (track->enc->pix_fmt == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p');
         else if (track->enc->pix_fmt == AV_PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
-        else                                             tag = MKTAG('d','v','p','p');
+        else                                                tag = MKTAG('d','v','p','p');
     } else if (track->enc->height == 720) { /* HD 720 line */
-        if  (track->enc->time_base.den == 50)            tag = MKTAG('d','v','h','q');
-        else                                             tag = MKTAG('d','v','h','p');
+        if  (track->enc->time_base.den == 50)               tag = MKTAG('d','v','h','q');
+        else                                                tag = MKTAG('d','v','h','p');
     } else if (track->enc->height == 1080) { /* HD 1080 line */
-        if  (track->enc->time_base.den == 25)            tag = MKTAG('d','v','h','5');
-        else                                             tag = MKTAG('d','v','h','6');
+        if  (track->enc->time_base.den == 25)               tag = MKTAG('d','v','h','5');
+        else                                                tag = MKTAG('d','v','h','6');
     } else {
         av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n");
         return 0;
@@ -967,12 +961,12 @@
 }
 
 static const AVCodecTag codec_3gp_tags[] = {
-    { AV_CODEC_ID_H263,   MKTAG('s','2','6','3') },
-    { AV_CODEC_ID_H264,   MKTAG('a','v','c','1') },
-    { AV_CODEC_ID_MPEG4,  MKTAG('m','p','4','v') },
-    { AV_CODEC_ID_AAC,    MKTAG('m','p','4','a') },
-    { AV_CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
-    { AV_CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
+    { AV_CODEC_ID_H263,     MKTAG('s','2','6','3') },
+    { AV_CODEC_ID_H264,     MKTAG('a','v','c','1') },
+    { AV_CODEC_ID_MPEG4,    MKTAG('m','p','4','v') },
+    { AV_CODEC_ID_AAC,      MKTAG('m','p','4','a') },
+    { AV_CODEC_ID_AMR_NB,   MKTAG('s','a','m','r') },
+    { AV_CODEC_ID_AMR_WB,   MKTAG('s','a','w','b') },
     { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
     { AV_CODEC_ID_NONE, 0 },
 };
@@ -1083,7 +1077,7 @@
     avio_wb16(pb, 0); /* Codec stream revision (=0) */
     if (track->mode == MODE_MOV) {
         ffio_wfourcc(pb, "FFMP"); /* Vendor */
-        if(track->enc->codec_id == AV_CODEC_ID_RAWVIDEO) {
+        if (track->enc->codec_id == AV_CODEC_ID_RAWVIDEO) {
             avio_wb32(pb, 0); /* Temporal Quality */
             avio_wb32(pb, 0x400); /* Spatial Quality = lossless*/
         } else {
@@ -1104,7 +1098,7 @@
 
     /* FIXME not sure, ISO 14496-1 draft where it shall be set to 0 */
     if (track->mode == MODE_MOV && track->enc->codec && track->enc->codec->name)
-        av_strlcpy(compressor_name,track->enc->codec->name,32);
+        av_strlcpy(compressor_name, track->enc->codec->name, 32);
     avio_w8(pb, strlen(compressor_name));
     avio_write(pb, compressor_name, 31);
 
@@ -1113,19 +1107,19 @@
     else
         avio_wb16(pb, 0x18); /* Reserved */
     avio_wb16(pb, 0xffff); /* Reserved */
-    if(track->tag == MKTAG('m','p','4','v'))
+    if (track->tag == MKTAG('m','p','4','v'))
         mov_write_esds_tag(pb, track);
-    else if(track->enc->codec_id == AV_CODEC_ID_H263)
+    else if (track->enc->codec_id == AV_CODEC_ID_H263)
         mov_write_d263_tag(pb);
-    else if(track->enc->codec_id == AV_CODEC_ID_AVUI ||
+    else if (track->enc->codec_id == AV_CODEC_ID_AVUI ||
             track->enc->codec_id == AV_CODEC_ID_SVQ3) {
         mov_write_extradata_tag(pb, track);
         avio_wb32(pb, 0);
-    } else if(track->enc->codec_id == AV_CODEC_ID_DNXHD)
+    } else if (track->enc->codec_id == AV_CODEC_ID_DNXHD)
         mov_write_avid_tag(pb, track);
-    else if(track->enc->codec_id == AV_CODEC_ID_H264) {
+    else if (track->enc->codec_id == AV_CODEC_ID_H264) {
         mov_write_avcc_tag(pb, track);
-        if(track->mode == MODE_IPOD)
+        if (track->mode == MODE_IPOD)
             mov_write_uuid_tag_ipod(pb);
     } else if (track->enc->codec_id == AV_CODEC_ID_VC1 && track->vos_len > 0)
         mov_write_dvc1_tag(pb, track);
@@ -1221,7 +1215,7 @@
     ctts_entries = av_malloc((track->entry + 1) * sizeof(*ctts_entries)); /* worst case */
     ctts_entries[0].count = 1;
     ctts_entries[0].duration = track->cluster[0].cts;
-    for (i=1; i<track->entry; i++) {
+    for (i = 1; i < track->entry; i++) {
         if (track->cluster[i].cts == ctts_entries[entries].duration) {
             ctts_entries[entries].count++; /* compress */
         } else {
@@ -1236,7 +1230,7 @@
     ffio_wfourcc(pb, "ctts");
     avio_wb32(pb, 0); /* version & flags */
     avio_wb32(pb, entries); /* entry count */
-    for (i=0; i<entries; i++) {
+    for (i = 0; i < entries; i++) {
         avio_wb32(pb, ctts_entries[i].count);
         avio_wb32(pb, ctts_entries[i].duration);
     }
@@ -1261,7 +1255,7 @@
         stts_entries = track->entry ?
                        av_malloc(track->entry * sizeof(*stts_entries)) : /* worst case */
                        NULL;
-        for (i=0; i<track->entry; i++) {
+        for (i = 0; i < track->entry; i++) {
             int duration = get_cluster_duration(track, i);
             if (i && duration == stts_entries[entries].duration) {
                 stts_entries[entries].count++; /* compress */
@@ -1278,7 +1272,7 @@
     ffio_wfourcc(pb, "stts");
     avio_wb32(pb, 0); /* version & flags */
     avio_wb32(pb, entries); /* entry count */
-    for (i=0; i<entries; i++) {
+    for (i = 0; i < entries; i++) {
         avio_wb32(pb, stts_entries[i].count);
         avio_wb32(pb, stts_entries[i].duration);
     }
@@ -1432,18 +1426,18 @@
     const char *hdlr, *descr = NULL, *hdlr_type = NULL;
     int64_t pos = avio_tell(pb);
 
-    if (!track) { /* no media --> data handler */
-        hdlr = "dhlr";
-        hdlr_type = "url ";
-        descr = "DataHandler";
-    } else {
+    hdlr      = "dhlr";
+    hdlr_type = "url ";
+    descr     = "DataHandler";
+
+    if (track) {
         hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
         if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
             hdlr_type = "vide";
-            descr = "VideoHandler";
+            descr     = "VideoHandler";
         } else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) {
             hdlr_type = "soun";
-            descr = "SoundHandler";
+            descr     = "SoundHandler";
         } else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
             if (track->tag == MKTAG('c','6','0','8')) {
                 hdlr_type = "clcp";
@@ -1453,16 +1447,20 @@
             else                                      hdlr_type = "text";
             descr = "SubtitleHandler";
             }
+        } else if (track->enc->codec_tag == MKTAG('r','t','p',' ')) {
+            hdlr_type = "hint";
+            descr     = "HintHandler";
         } else if (track->enc->codec_tag == MKTAG('t','m','c','d')) {
             hdlr_type = "tmcd";
             descr = "TimeCodeHandler";
-        } else if (track->enc->codec_tag == MKTAG('r','t','p',' ')) {
-            hdlr_type = "hint";
-            descr = "HintHandler";
         } else {
-            hdlr = "dhlr";
-            hdlr_type = "url ";
-            descr = "DataHandler";
+            char tag_buf[32];
+            av_get_codec_tag_string(tag_buf, sizeof(tag_buf),
+                                    track->enc->codec_tag);
+
+            av_log(track->enc, AV_LOG_WARNING,
+                   "Unknown hldr_type for %s / 0x%04X, writing dummy values\n",
+                   tag_buf, track->enc->codec_tag);
         }
     }
 
@@ -1471,9 +1469,9 @@
     avio_wb32(pb, 0); /* Version & flags */
     avio_write(pb, hdlr, 4); /* handler */
     ffio_wfourcc(pb, hdlr_type); /* handler type */
-    avio_wb32(pb ,0); /* reserved */
-    avio_wb32(pb ,0); /* reserved */
-    avio_wb32(pb ,0); /* reserved */
+    avio_wb32(pb, 0); /* reserved */
+    avio_wb32(pb, 0); /* reserved */
+    avio_wb32(pb, 0); /* reserved */
     if (!track || track->mode == MODE_MOV)
         avio_w8(pb, strlen(descr)); /* pascal string */
     avio_write(pb, descr, strlen(descr)); /* handler description */
@@ -1502,7 +1500,7 @@
     int64_t pos = avio_tell(pb);
     avio_wb32(pb, 0); /* size */
     ffio_wfourcc(pb, "minf");
-    if(track->enc->codec_type == AVMEDIA_TYPE_VIDEO)
+    if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO)
         mov_write_vmhd_tag(pb);
     else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
         mov_write_smhd_tag(pb);
@@ -1550,11 +1548,11 @@
     avio_wb16(pb, track->language); /* language */
     avio_wb16(pb, 0); /* reserved (quality) */
 
-    if(version!=0 && track->mode == MODE_MOV){
+    if (version != 0 && track->mode == MODE_MOV) {
         av_log(NULL, AV_LOG_ERROR,
-            "FATAL error, file duration too long for timebase, this file will not be\n"
-            "playable with quicktime. Choose a different timebase or a different\n"
-            "container format\n");
+               "FATAL error, file duration too long for timebase, this file will not be\n"
+               "playable with quicktime. Choose a different timebase or a different\n"
+               "container format\n");
     }
 
     return 32;
@@ -1622,7 +1620,7 @@
     avio_wb16(pb, 0); /* layer */
     avio_wb16(pb, st ? st->codec->codec_type : 0); /* alternate group) */
     /* Volume, only for audio */
-    if(track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
+    if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
         avio_wb16(pb, 0x0100);
     else
         avio_wb16(pb, 0);
@@ -1643,20 +1641,19 @@
         write_matrix(pb,  1,  0,  0,  1, 0, 0);
     }
     /* Track width and height, for visual only */
-    if(st && (track->enc->codec_type == AVMEDIA_TYPE_VIDEO ||
-              track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
-        if(track->mode == MODE_MOV) {
+    if (st && (track->enc->codec_type == AVMEDIA_TYPE_VIDEO ||
+               track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
+        if (track->mode == MODE_MOV) {
             avio_wb32(pb, track->enc->width << 16);
             avio_wb32(pb, track->height << 16);
         } else {
             double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
-            if(!sample_aspect_ratio || track->height != track->enc->height)
+            if (!sample_aspect_ratio || track->height != track->enc->height)
                 sample_aspect_ratio = 1;
-            avio_wb32(pb, sample_aspect_ratio * track->enc->width*0x10000);
-            avio_wb32(pb, track->height*0x10000);
+            avio_wb32(pb, sample_aspect_ratio * track->enc->width * 0x10000);
+            avio_wb32(pb, track->height * 0x10000);
         }
-    }
-    else {
+    } else {
         avio_wb32(pb, 0);
         avio_wb32(pb, 0);
     }
@@ -1777,7 +1774,6 @@
 
 static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
 {
-
     AVFormatContext *ctx = track->rtp_ctx;
     char buf[1000] = "";
     int len;
@@ -1810,14 +1806,14 @@
         mov_write_tref_tag(pb, track);
     mov_write_mdia_tag(pb, track);
     if (track->mode == MODE_PSP)
-        mov_write_uuid_tag_psp(pb,track);  // PSP Movies require this uuid box
+        mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
     if (track->tag == MKTAG('r','t','p',' '))
         mov_write_udta_sdp(pb, track);
     if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO && track->mode == MODE_MOV) {
         double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
         if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio)
             mov_write_tapt_tag(pb, track);
-    };
+    }
     return update_size(pb, pos);
 }
 
@@ -1828,7 +1824,7 @@
     int audio_profile = mov->iods_audio_profile;
     int video_profile = mov->iods_video_profile;
     for (i = 0; i < mov->nb_streams; i++) {
-        if(mov->tracks[i].entry > 0) {
+        if (mov->tracks[i].entry > 0) {
             has_audio |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_AUDIO;
             has_video |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_VIDEO;
         }
@@ -1880,8 +1876,8 @@
     int64_t max_track_len_temp, max_track_len = 0;
     int version;
 
-    for (i=0; i<mov->nb_streams; i++) {
-        if(mov->tracks[i].entry > 0) {
+    for (i = 0; i < mov->nb_streams; i++) {
+        if (mov->tracks[i].entry > 0 && mov->tracks[i].timescale) {
             max_track_len_temp = av_rescale_rnd(mov->tracks[i].track_duration,
                                                 MOV_TIMESCALE,
                                                 mov->tracks[i].timescale,
@@ -1945,7 +1941,7 @@
 /* helper function to write a data tag with the specified string as data */
 static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
 {
-    if(long_style){
+    if (long_style) {
         int size = 16 + strlen(data);
         avio_wb32(pb, size); /* size */
         ffio_wfourcc(pb, "data");
@@ -1953,7 +1949,7 @@
         avio_wb32(pb, 0);
         avio_write(pb, data, strlen(data));
         return size;
-    }else{
+    } else {
         if (!lang)
             lang = ff_mov_iso639_to_lang("und", 1);
         avio_wb16(pb, strlen(data)); /* string length */
@@ -1963,7 +1959,9 @@
     }
 }
 
-static int mov_write_string_tag(AVIOContext *pb, const char *name, const char *value, int lang, int long_style){
+static int mov_write_string_tag(AVIOContext *pb, const char *name,
+                                const char *value, int lang, int long_style)
+{
     int size = 0;
     if (value && value[0]) {
         int64_t pos = avio_tell(pb);
@@ -1990,8 +1988,8 @@
     snprintf(tag2, sizeof(tag2), "%s-", tag);
     while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) {
         len2 = strlen(t2->key);
-        if (len2 == len+4 && !strcmp(t->value, t2->value)
-            && (l=ff_mov_iso639_to_lang(&t2->key[len2-3], 1)) >= 0) {
+        if (len2 == len + 4 && !strcmp(t->value, t2->value)
+            && (l = ff_mov_iso639_to_lang(&t2->key[len2 - 3], 1)) >= 0) {
             lang = l;
             break;
         }
@@ -2017,23 +2015,29 @@
     return size;
 }
 
-/* iTunes track number */
+/* iTunes track or disc number */
 static int mov_write_trkn_tag(AVIOContext *pb, MOVMuxContext *mov,
-                              AVFormatContext *s)
+                              AVFormatContext *s, int disc)
 {
-    AVDictionaryEntry *t = av_dict_get(s->metadata, "track", NULL, 0);
+    AVDictionaryEntry *t = av_dict_get(s->metadata,
+                                       disc ? "disc" : "track",
+                                       NULL, 0);
     int size = 0, track = t ? atoi(t->value) : 0;
     if (track) {
+        int tracks = 0;
+        char *slash = strchr(t->value, '/');
+        if (slash)
+            tracks = atoi(slash + 1);
         avio_wb32(pb, 32); /* size */
-        ffio_wfourcc(pb, "trkn");
-            avio_wb32(pb, 24); /* size */
-            ffio_wfourcc(pb, "data");
-            avio_wb32(pb, 0);        // 8 bytes empty
-            avio_wb32(pb, 0);
-            avio_wb16(pb, 0);        // empty
-            avio_wb16(pb, track);    // track number
-            avio_wb16(pb, 0);        // total track number
-            avio_wb16(pb, 0);        // empty
+        ffio_wfourcc(pb, disc ? "disk" : "trkn");
+        avio_wb32(pb, 24); /* size */
+        ffio_wfourcc(pb, "data");
+        avio_wb32(pb, 0);        // 8 bytes empty
+        avio_wb32(pb, 0);
+        avio_wb16(pb, 0);        // empty
+        avio_wb16(pb, track);    // track / disc number
+        avio_wb16(pb, tracks);   // total track / disc number
+        avio_wb16(pb, 0);        // empty
         size = 32;
     }
     return size;
@@ -2045,16 +2049,25 @@
 {
     AVDictionaryEntry *t = NULL;
     uint8_t num;
+    int size = 24 + len;
+
+    if (len != 1 && len != 4)
+        return -1;
 
     if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
         return 0;
     num = atoi(t->value);
 
-    avio_wb32(pb, len+8);
+    avio_wb32(pb, size);
     ffio_wfourcc(pb, name);
+    avio_wb32(pb, size - 8);
+    ffio_wfourcc(pb, "data");
+    avio_wb32(pb, 0x15);
+    avio_wb32(pb, 0);
     if (len==4) avio_wb32(pb, num);
     else        avio_w8 (pb, num);
-    return len+8;
+
+    return size;
 }
 
 /* iTunes meta data list */
@@ -2086,7 +2099,8 @@
     mov_write_int8_metadata  (s, pb, "stik",    "media_type",1);
     mov_write_int8_metadata  (s, pb, "hdvd",    "hd_video",  1);
     mov_write_int8_metadata  (s, pb, "pgap",    "gapless_playback",1);
-    mov_write_trkn_tag(pb, mov, s);
+    mov_write_trkn_tag(pb, mov, s, 0); // track number
+    mov_write_trkn_tag(pb, mov, s, 1); // disc number
     mov_write_tmpo_tag(pb, s);
     return update_size(pb, pos);
 }
@@ -2108,9 +2122,9 @@
 
 static int utf8len(const uint8_t *b)
 {
-    int len=0;
+    int len = 0;
     int val;
-    while(*b){
+    while (*b) {
         GET_UTF8(val, *b++, return -1;)
         len++;
     }
@@ -2120,7 +2134,7 @@
 static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
 {
     int val;
-    while(*b){
+    while (*b) {
         GET_UTF8(val, *b++, return -1;)
         avio_wb16(pb, val);
     }
@@ -2130,7 +2144,9 @@
 
 static uint16_t language_code(const char *str)
 {
-    return (((str[0]-0x60) & 0x1F) << 10) + (((str[1]-0x60) & 0x1F) << 5) + ((str[2]-0x60) & 0x1F);
+    return (((str[0] - 0x60) & 0x1F) << 10) +
+           (((str[1] - 0x60) & 0x1F) <<  5) +
+           (( str[2] - 0x60) & 0x1F);
 }
 
 static int mov_write_3gp_udta_tag(AVIOContext *pb, AVFormatContext *s,
@@ -2147,7 +2163,7 @@
         avio_wb16(pb, atoi(t->value));
     else {
         avio_wb16(pb, language_code("eng")); /* language */
-        avio_write(pb, t->value, strlen(t->value)+1); /* UTF8 string value */
+        avio_write(pb, t->value, strlen(t->value) + 1); /* UTF8 string value */
         if (!strcmp(tag, "albm") &&
             (t = av_dict_get(s->metadata, "track", NULL, 0)))
             avio_w8(pb, atoi(t->value));
@@ -2194,7 +2210,7 @@
         }
 
     ret = avio_open_dyn_buf(&pb_buf);
-    if(ret < 0)
+    if (ret < 0)
         return ret;
 
     if (mov->mode & MODE_3GP) {
@@ -2207,18 +2223,18 @@
         mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
         mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
     } else if (mov->mode == MODE_MOV) { // the title field breaks gtkpod with mp4 and my suspicion is that stuff is not valid in mp4
-        mov_write_string_metadata(s, pb_buf, "\251ART", "artist"     , 0);
-        mov_write_string_metadata(s, pb_buf, "\251nam", "title"      , 0);
-        mov_write_string_metadata(s, pb_buf, "\251aut", "author"     , 0);
-        mov_write_string_metadata(s, pb_buf, "\251alb", "album"      , 0);
-        mov_write_string_metadata(s, pb_buf, "\251day", "date"       , 0);
-        mov_write_string_metadata(s, pb_buf, "\251swr", "encoder"    , 0);
+        mov_write_string_metadata(s, pb_buf, "\251ART", "artist",      0);
+        mov_write_string_metadata(s, pb_buf, "\251nam", "title",       0);
+        mov_write_string_metadata(s, pb_buf, "\251aut", "author",      0);
+        mov_write_string_metadata(s, pb_buf, "\251alb", "album",       0);
+        mov_write_string_metadata(s, pb_buf, "\251day", "date",        0);
+        mov_write_string_metadata(s, pb_buf, "\251swr", "encoder",     0);
         // currently ignored by mov.c
-        mov_write_string_metadata(s, pb_buf, "\251des", "comment"    , 0);
+        mov_write_string_metadata(s, pb_buf, "\251des", "comment",     0);
         // add support for libquicktime, this atom is also actually read by mov.c
-        mov_write_string_metadata(s, pb_buf, "\251cmt", "comment"    , 0);
-        mov_write_string_metadata(s, pb_buf, "\251gen", "genre"      , 0);
-        mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright"  , 0);
+        mov_write_string_metadata(s, pb_buf, "\251cmt", "comment",     0);
+        mov_write_string_metadata(s, pb_buf, "\251gen", "genre",       0);
+        mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright",   0);
     } else {
         /* iTunes meta data */
         mov_write_meta_tag(pb_buf, mov, s);
@@ -2228,7 +2244,7 @@
         mov_write_chpl_tag(pb_buf, s);
 
     if ((size = avio_close_dyn_buf(pb_buf, &buf)) > 0) {
-        avio_wb32(pb, size+8);
+        avio_wb32(pb, size + 8);
         ffio_wfourcc(pb, "udta");
         avio_write(pb, buf, size);
     }
@@ -2238,12 +2254,12 @@
 }
 
 static void mov_write_psp_udta_tag(AVIOContext *pb,
-                                  const char *str, const char *lang, int type)
+                                   const char *str, const char *lang, int type)
 {
-    int len = utf8len(str)+1;
-    if(len<=0)
+    int len = utf8len(str) + 1;
+    if (len <= 0)
         return;
-    avio_wb16(pb, len*2+10);            /* size */
+    avio_wb16(pb, len * 2 + 10);        /* size */
     avio_wb32(pb, type);                /* type */
     avio_wb16(pb, language_code(lang)); /* language */
     avio_wb16(pb, 0x01);                /* ? */
@@ -2290,18 +2306,18 @@
 static void build_chunks(MOVTrack *trk)
 {
     int i;
-    MOVIentry *chunk= &trk->cluster[0];
+    MOVIentry *chunk = &trk->cluster[0];
     uint64_t chunkSize = chunk->size;
-    chunk->chunkNum= 1;
+    chunk->chunkNum = 1;
     if (trk->chunkCount)
         return;
-    trk->chunkCount= 1;
-    for(i=1; i<trk->entry; i++){
-        if(chunk->pos + chunkSize == trk->cluster[i].pos &&
+    trk->chunkCount = 1;
+    for (i = 1; i<trk->entry; i++){
+        if (chunk->pos + chunkSize == trk->cluster[i].pos &&
             chunkSize + trk->cluster[i].size < (1<<20)){
             chunkSize             += trk->cluster[i].size;
             chunk->samples_in_chunk += trk->cluster[i].entries;
-        }else{
+        } else {
             trk->cluster[i].chunkNum = chunk->chunkNum+1;
             chunk=&trk->cluster[i];
             chunkSize = chunk->size;
@@ -2319,21 +2335,21 @@
     avio_wb32(pb, 0); /* size placeholder*/
     ffio_wfourcc(pb, "moov");
 
-    for (i=0; i<mov->nb_streams; i++) {
+    for (i = 0; i < mov->nb_streams; i++) {
         if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
             continue;
 
-        mov->tracks[i].time = mov->time;
-        mov->tracks[i].track_id = i+1;
+        mov->tracks[i].time     = mov->time;
+        mov->tracks[i].track_id = i + 1;
 
         if (mov->tracks[i].entry)
             build_chunks(&mov->tracks[i]);
     }
 
     if (mov->chapter_track)
-        for (i=0; i<s->nb_streams; i++) {
+        for (i = 0; i < s->nb_streams; i++) {
             mov->tracks[i].tref_tag = MKTAG('c','h','a','p');
-            mov->tracks[i].tref_id = mov->tracks[mov->chapter_track].track_id;
+            mov->tracks[i].tref_id  = mov->tracks[mov->chapter_track].track_id;
         }
     for (i = 0; i < mov->nb_streams; i++) {
         if (mov->tracks[i].tag == MKTAG('r','t','p',' ')) {
@@ -2354,11 +2370,11 @@
     mov_write_mvhd_tag(pb, mov);
     if (mov->mode != MODE_MOV && !mov->iods_skip)
         mov_write_iods_tag(pb, mov);
-    for (i=0; i<mov->nb_streams; i++) {
+    for (i = 0; i < mov->nb_streams; i++) {
         if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT) {
-            if(i < s->nb_streams){
+            if (i < s->nb_streams){
                 int codec_type= s->streams[i]->codec->codec_type;
-                if(codec_type==AVMEDIA_TYPE_AUDIO || codec_type==AVMEDIA_TYPE_SUBTITLE){
+                if (codec_type==AVMEDIA_TYPE_AUDIO || codec_type==AVMEDIA_TYPE_SUBTITLE){
                     mov->tracks[i].secondary= not_first[codec_type];
                     not_first[codec_type]= 1;
                 }
@@ -2390,9 +2406,9 @@
 static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
 {
     char buf[150];
-    len = FFMIN(sizeof(buf)/2 - 1, len);
+    len = FFMIN(sizeof(buf) / 2 - 1, len);
     ff_data_to_hex(buf, value, len, 0);
-    buf[2*len] = '\0';
+    buf[2 * len] = '\0';
     avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
 }
 
@@ -2400,7 +2416,7 @@
 {
     int64_t pos = avio_tell(pb);
     int i;
-    const uint8_t uuid[] = {
+    static const uint8_t uuid[] = {
         0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
         0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
     };
@@ -2466,7 +2482,7 @@
             param_write_hex(pb, "CodecPrivateData", track->enc->extradata,
                             track->enc->extradata_size);
             param_write_int(pb, "AudioTag", ff_codec_get_tag(ff_codec_wav_tags,
-                                                track->enc->codec_id));
+                                                             track->enc->codec_id));
             param_write_int(pb, "Channels", track->enc->channels);
             param_write_int(pb, "SamplingRate", track->enc->sample_rate);
             param_write_int(pb, "BitsPerSample", 16);
@@ -2505,9 +2521,11 @@
 
     /* Don't set a default sample size, the silverlight player refuses
      * to play files with that set. Don't set a default sample duration,
-     * WMP freaks out if it is set. */
+     * WMP freaks out if it is set. Don't set a base data offset, PIFF
+     * file format says it MUST NOT be set. */
     if (track->mode == MODE_ISM)
-        flags &= ~(MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION);
+        flags &= ~(MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION |
+                   MOV_TFHD_BASE_DATA_OFFSET);
 
     avio_wb32(pb, 0); /* size placeholder */
     ffio_wfourcc(pb, "tfhd");
@@ -2591,7 +2609,7 @@
 static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
 {
     int64_t pos = avio_tell(pb);
-    const uint8_t uuid[] = {
+    static const uint8_t uuid[] = {
         0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
         0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
     };
@@ -2613,7 +2631,7 @@
 {
     int n = track->nb_frag_info - 1 - entry, i;
     int size = 8 + 16 + 4 + 1 + 16*n;
-    const uint8_t uuid[] = {
+    static const uint8_t uuid[] = {
         0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
         0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
     };
@@ -2634,11 +2652,10 @@
         avio_wb64(pb, track->frag_info[index].duration);
     }
     if (n < mov->ism_lookahead) {
-        int free_size = 16*(mov->ism_lookahead - n);
+        int free_size = 16 * (mov->ism_lookahead - n);
         avio_wb32(pb, free_size);
         ffio_wfourcc(pb, "free");
-        for (i = 0; i < free_size - 8; i++)
-            avio_w8(pb, 0);
+        ffio_fill(pb, 0, free_size - 8);
     }
 
     return 0;
@@ -2671,7 +2688,7 @@
         mov_write_tfxd_tag(pb, track);
 
         if (mov->ism_lookahead) {
-            int i, size = 16 + 4 + 1 + 16*mov->ism_lookahead;
+            int i, size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
 
             track->tfrf_offset = avio_tell(pb);
             avio_wb32(pb, 8 + size);
@@ -2805,7 +2822,7 @@
     } else if (mov->mode & MODE_3G2) {
         ffio_wfourcc(pb, has_h264 ? "3g2b"  : "3g2a");
         minor =     has_h264 ? 0x20000 : 0x10000;
-    }else if (mov->mode == MODE_PSP)
+    } else if (mov->mode == MODE_PSP)
         ffio_wfourcc(pb, "MSNV");
     else if (mov->mode == MODE_MP4)
         ffio_wfourcc(pb, "isom");
@@ -2820,7 +2837,7 @@
 
     avio_wb32(pb, minor);
 
-    if(mov->mode == MODE_MOV)
+    if (mov->mode == MODE_MOV)
         ffio_wfourcc(pb, "qt  ");
     else if (mov->mode == MODE_ISM) {
         ffio_wfourcc(pb, "piff");
@@ -2828,7 +2845,7 @@
     } else {
         ffio_wfourcc(pb, "isom");
         ffio_wfourcc(pb, "iso2");
-        if(has_h264)
+        if (has_h264)
             ffio_wfourcc(pb, "avc1");
     }
 
@@ -2848,7 +2865,7 @@
     AVCodecContext *video_codec = s->streams[0]->codec;
     AVCodecContext *audio_codec = s->streams[1]->codec;
     int audio_rate = audio_codec->sample_rate;
-    int frame_rate = ((video_codec->time_base.den) * (0x10000))/ (video_codec->time_base.num);
+    int frame_rate = ((video_codec->time_base.den) * (0x10000)) / (video_codec->time_base.num);
     int audio_kbitrate = audio_codec->bit_rate / 1000;
     int video_kbitrate = FFMIN(video_codec->bit_rate / 1000, 800 - audio_kbitrate);
 
@@ -2870,7 +2887,7 @@
     avio_wb32(pb, 0x0);  /* ? */
 
     avio_wb32(pb, 0x2c);  /* size */
-    ffio_wfourcc(pb, "APRF");/* audio */
+    ffio_wfourcc(pb, "APRF"); /* audio */
     avio_wb32(pb, 0x0);
     avio_wb32(pb, 0x2);   /* TrackID */
     ffio_wfourcc(pb, "mp4a");
@@ -2910,11 +2927,11 @@
     int i, closed_gop = 0;
 
     for (i = 0; i < pkt->size - 4; i++) {
-        c = (c<<8) + pkt->data[i];
+        c = (c << 8) + pkt->data[i];
         if (c == 0x1b8) { // gop
-            closed_gop = pkt->data[i+4]>>6 & 0x01;
+            closed_gop = pkt->data[i + 4] >> 6 & 0x01;
         } else if (c == 0x100) { // pic
-            int temp_ref = (pkt->data[i+1]<<2) | (pkt->data[i+2]>>6);
+            int temp_ref = (pkt->data[i + 1] << 2) | (pkt->data[i + 2] >> 6);
             if (!temp_ref || closed_gop) // I picture is not reordered
                 *flags = MOV_SYNC_SAMPLE;
             else
@@ -2982,21 +2999,6 @@
     }
 }
 
-static int get_moov_size(AVFormatContext *s)
-{
-    int ret;
-    uint8_t *buf;
-    AVIOContext *moov_buf;
-    MOVMuxContext *mov = s->priv_data;
-
-    if ((ret = avio_open_dyn_buf(&moov_buf)) < 0)
-        return ret;
-    mov_write_moov_tag(moov_buf, mov, s);
-    ret = avio_close_dyn_buf(moov_buf, &buf);
-    av_free(buf);
-    return ret;
-}
-
 static int mov_flush_fragment(AVFormatContext *s)
 {
     MOVMuxContext *mov = s->priv_data;
@@ -3082,9 +3084,14 @@
             MOVFragmentInfo *info;
             avio_flush(s->pb);
             track->nb_frag_info++;
-            track->frag_info = av_realloc(track->frag_info,
-                                          sizeof(*track->frag_info) *
-                                          track->nb_frag_info);
+            if (track->nb_frag_info >= track->frag_info_capacity) {
+                unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
+                if (av_reallocp_array(&track->frag_info,
+                                      new_capacity,
+                                      sizeof(*track->frag_info)))
+                    return AVERROR(ENOMEM);
+                track->frag_info_capacity = new_capacity;
+            }
             info = &track->frag_info[track->nb_frag_info - 1];
             info->offset   = avio_tell(s->pb);
             info->time     = mov->tracks[i].frag_start;
@@ -3124,7 +3131,7 @@
     MOVTrack *trk = &mov->tracks[pkt->stream_index];
     AVCodecContext *enc = trk->enc;
     unsigned int samples_in_chunk = 0;
-    int size= pkt->size;
+    int size = pkt->size;
     uint8_t *reformatted_data = NULL;
 
     if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
@@ -3168,7 +3175,7 @@
 
     /* copy extradata if it exists */
     if (trk->vos_len == 0 && enc->extradata_size > 0) {
-        trk->vos_len = enc->extradata_size;
+        trk->vos_len  = enc->extradata_size;
         trk->vos_data = av_malloc(trk->vos_len);
         memcpy(trk->vos_data, enc->extradata, trk->vos_len);
     }
@@ -3176,7 +3183,9 @@
     if (enc->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
         (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
         if (!s->streams[pkt->stream_index]->nb_frames) {
-            av_log(s, AV_LOG_ERROR, "malformated aac bitstream, use -absf aac_adtstoasc\n");
+            av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
+                   "use audio bitstream filter 'aac_adtstoasc' to fix it "
+                   "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
             return -1;
         }
         av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
@@ -3198,25 +3207,27 @@
     if ((enc->codec_id == AV_CODEC_ID_DNXHD ||
          enc->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len) {
         /* copy frame to create needed atoms */
-        trk->vos_len = size;
+        trk->vos_len  = size;
         trk->vos_data = av_malloc(size);
         if (!trk->vos_data)
             return AVERROR(ENOMEM);
         memcpy(trk->vos_data, pkt->data, size);
     }
 
-    if (!(trk->entry % MOV_INDEX_CLUSTER_SIZE)) {
-        trk->cluster = av_realloc_f(trk->cluster, sizeof(*trk->cluster), (trk->entry + MOV_INDEX_CLUSTER_SIZE));
-        if (!trk->cluster)
-            return -1;
+    if (trk->entry >= trk->cluster_capacity) {
+        unsigned new_capacity = 2 * (trk->entry + MOV_INDEX_CLUSTER_SIZE);
+        if (av_reallocp_array(&trk->cluster, new_capacity,
+                              sizeof(*trk->cluster)))
+            return AVERROR(ENOMEM);
+        trk->cluster_capacity = new_capacity;
     }
 
-    trk->cluster[trk->entry].pos = avio_tell(pb) - size;
+    trk->cluster[trk->entry].pos              = avio_tell(pb) - size;
     trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
-    trk->cluster[trk->entry].chunkNum = 0;
-    trk->cluster[trk->entry].size = size;
-    trk->cluster[trk->entry].entries = samples_in_chunk;
-    trk->cluster[trk->entry].dts = pkt->dts;
+    trk->cluster[trk->entry].chunkNum         = 0;
+    trk->cluster[trk->entry].size             = size;
+    trk->cluster[trk->entry].entries          = samples_in_chunk;
+    trk->cluster[trk->entry].dts              = pkt->dts;
     if (!trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
         /* First packet of a new fragment. We already wrote the duration
          * of the last packet of the previous fragment based on track_duration,
@@ -3238,7 +3249,7 @@
     }
     if (pkt->dts != pkt->pts)
         trk->flags |= MOV_TRACK_CTTS;
-    trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
+    trk->cluster[trk->entry].cts   = pkt->pts - pkt->dts;
     trk->cluster[trk->entry].flags = 0;
     if (enc->codec_id == AV_CODEC_ID_VC1) {
         mov_parse_vc1_frame(pkt, trk, mov->fragments);
@@ -3256,7 +3267,7 @@
     }
     trk->entry++;
     trk->sample_count += samples_in_chunk;
-    mov->mdat_size += size;
+    mov->mdat_size    += size;
 
     avio_flush(pb);
 
@@ -3275,7 +3286,8 @@
         int64_t frag_duration = 0;
         int size = pkt->size;
 
-        if (!pkt->size) return 0; /* Discard 0 sized packets */
+        if (!pkt->size)
+            return 0;             /* Discard 0 sized packets */
 
         if (trk->entry && pkt->stream_index < s->nb_streams)
             frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
@@ -3364,7 +3376,7 @@
 
 // QuickTime chapters involve an additional text track with the chapter names
 // as samples, and a tref pointing from the other tracks to the chapter one.
-static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
+static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
 {
     AVIOContext *pb;
 
@@ -3372,13 +3384,21 @@
     MOVTrack *track = &mov->tracks[tracknum];
     AVPacket pkt = { .stream_index = tracknum, .flags = AV_PKT_FLAG_KEY };
     int i, len;
+    // These properties are required to make QT recognize the chapter track
+    uint8_t chapter_properties[43] = { 0, 0, 0, 0, 0, 0, 0, 1, };
 
     track->mode = mov->mode;
     track->tag = MKTAG('t','e','x','t');
     track->timescale = MOV_TIMESCALE;
     track->enc = avcodec_alloc_context3(NULL);
     track->enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
-
+#if 0
+    track->enc->extradata = av_malloc(sizeof(chapter_properties));
+    if (track->enc->extradata == NULL)
+        return AVERROR(ENOMEM);
+    track->enc->extradata_size = sizeof(chapter_properties);
+    memcpy(track->enc->extradata, chapter_properties, sizeof(chapter_properties));
+#else
     if (avio_open_dyn_buf(&pb) >= 0) {
         int size;
         uint8_t *buf;
@@ -3422,6 +3442,7 @@
             av_free(&buf);
         }
     }
+#endif
 
     for (i = 0; i < s->nb_chapters; i++) {
         AVChapter *c = s->chapters[i];
@@ -3432,15 +3453,17 @@
         pkt.duration = end - pkt.dts;
 
         if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
-            len = strlen(t->value);
-            pkt.size = len+2;
+            len      = strlen(t->value);
+            pkt.size = len + 2;
             pkt.data = av_malloc(pkt.size);
             AV_WB16(pkt.data, len);
-            memcpy(pkt.data+2, t->value, len);
+            memcpy(pkt.data + 2, t->value, len);
             ff_mov_write_packet(s, &pkt);
             av_freep(&pkt.data);
         }
     }
+
+    return 0;
 }
 
 static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, const char *tcstr)
@@ -3504,7 +3527,8 @@
 
     /* faststart: moov at the beginning of the file, if supported */
     if (mov->flags & FF_MOV_FLAG_FASTSTART) {
-        if (mov->flags & FF_MOV_FLAG_FRAGMENT)
+        if ((mov->flags & FF_MOV_FLAG_FRAGMENT) ||
+            (s->flags & AVFMT_FLAG_CUSTOM_IO))
             mov->flags &= ~FF_MOV_FLAG_FASTSTART;
         else
             mov->reserved_moov_size = -1;
@@ -3518,7 +3542,7 @@
      * is enabled, we don't support non-seekable output at all. */
     if (!s->pb->seekable &&
         ((!(mov->flags & FF_MOV_FLAG_FRAGMENT) &&
-          !(s->oformat && !strcmp(s->oformat->name, "ismv")))
+          strcmp(s->oformat->name, "ismv"))
          || mov->ism_lookahead)) {
         av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
         return -1;
@@ -3527,27 +3551,36 @@
     /* Default mode == MP4 */
     mov->mode = MODE_MP4;
 
-    if (s->oformat != NULL) {
-        if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;
-        else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3GP|MODE_3G2;
-        else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;
-        else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;
-        else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD;
-        else if (!strcmp("ismv",s->oformat->name)) mov->mode = MODE_ISM;
-        else if (!strcmp("f4v", s->oformat->name)) mov->mode = MODE_F4V;
+    if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;
+    else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3GP|MODE_3G2;
+    else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;
+    else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;
+    else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD;
+    else if (!strcmp("ismv",s->oformat->name)) mov->mode = MODE_ISM;
+    else if (!strcmp("f4v", s->oformat->name)) mov->mode = MODE_F4V;
 
-        mov_write_ftyp_tag(pb,s);
-        if (mov->mode == MODE_PSP) {
-            if (s->nb_streams != 2) {
-                av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
-                return -1;
+    mov_write_ftyp_tag(pb,s);
+    if (mov->mode == MODE_PSP) {
+        int video_streams_nb = 0, audio_streams_nb = 0, other_streams_nb = 0;
+        for (i = 0; i < s->nb_streams; i++) {
+            AVStream *st = s->streams[i];
+            if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
+                video_streams_nb++;
+            else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+                audio_streams_nb++;
+            else
+                other_streams_nb++;
             }
-            mov_write_uuidprof_tag(pb,s);
+
+        if (video_streams_nb != 1 || audio_streams_nb != 1 || other_streams_nb) {
+            av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
+            return -1;
         }
+        mov_write_uuidprof_tag(pb, s);
     }
 
     mov->nb_streams = s->nb_streams;
-    if (mov->mode & (MODE_MOV|MODE_IPOD) && s->nb_chapters)
+    if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
         mov->chapter_track = mov->nb_streams++;
 
     if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
@@ -3588,11 +3621,13 @@
         mov->nb_streams += mov->nb_meta_tmcd;
     }
 
-    mov->tracks = av_mallocz(mov->nb_streams*sizeof(*mov->tracks));
+    // Reserve an extra stream for chapters for the case where chapters
+    // are written in the trailer
+    mov->tracks = av_mallocz((mov->nb_streams + 1) * sizeof(*mov->tracks));
     if (!mov->tracks)
         return AVERROR(ENOMEM);
 
-    for(i=0; i<s->nb_streams; i++){
+    for (i = 0; i < s->nb_streams; i++) {
         AVStream *st= s->streams[i];
         MOVTrack *track= &mov->tracks[i];
         AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
@@ -3602,7 +3637,7 @@
         if (track->language < 0)
             track->language = 0;
         track->mode = mov->mode;
-        track->tag = mov_find_codec_tag(s, track);
+        track->tag  = mov_find_codec_tag(s, track);
         if (!track->tag) {
             av_log(s, AV_LOG_ERROR, "track %d: could not find tag, "
                    "codec not currently supported in container\n", i);
@@ -3611,8 +3646,8 @@
         /* If hinting of this track is enabled by a later hint track,
          * this is updated. */
         track->hint_track = -1;
-        track->start_dts = AV_NOPTS_VALUE;
-        if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO){
+        track->start_dts  = AV_NOPTS_VALUE;
+        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
             if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
                 track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
                 track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {
@@ -3620,22 +3655,26 @@
                     av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
                     goto error;
                 }
-                track->height = track->tag>>24 == 'n' ? 486 : 576;
+                track->height = track->tag >> 24 == 'n' ? 486 : 576;
             }
-            track->timescale = st->codec->time_base.den;
-            while(track->timescale < 10000)
-                track->timescale *= 2;
+            if (mov->video_track_timescale) {
+                track->timescale = mov->video_track_timescale;
+            } else {
+                track->timescale = st->codec->time_base.den;
+                while(track->timescale < 10000)
+                    track->timescale *= 2;
+            }
             if (track->mode == MODE_MOV && track->timescale > 100000)
                 av_log(s, AV_LOG_WARNING,
                        "WARNING codec timebase is very high. If duration is too long,\n"
                        "file may not be playable by quicktime. Specify a shorter timebase\n"
                        "or choose different container.\n");
-        }else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO){
+        } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
             track->timescale = st->codec->sample_rate;
-            if(!st->codec->frame_size && !av_get_bits_per_sample(st->codec->codec_id)) {
+            if (!st->codec->frame_size && !av_get_bits_per_sample(st->codec->codec_id)) {
                 av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
                 track->audio_vbr = 1;
-            }else if(st->codec->codec_id == AV_CODEC_ID_ADPCM_MS ||
+            }else if (st->codec->codec_id == AV_CODEC_ID_ADPCM_MS ||
                      st->codec->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
                      st->codec->codec_id == AV_CODEC_ID_ILBC){
                 if (!st->codec->block_align) {
@@ -3643,20 +3682,25 @@
                     goto error;
                 }
                 track->sample_size = st->codec->block_align;
-            }else if(st->codec->frame_size > 1){ /* assume compressed audio */
+            }else if (st->codec->frame_size > 1){ /* assume compressed audio */
                 track->audio_vbr = 1;
             }else{
                 track->sample_size = (av_get_bits_per_sample(st->codec->codec_id) >> 3) * st->codec->channels;
             }
+            if (st->codec->codec_id == AV_CODEC_ID_ILBC) {
+                track->audio_vbr = 1;
+            }
             if (track->mode != MODE_MOV &&
                 track->enc->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {
                 av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not supported\n",
                        i, track->enc->sample_rate);
                 goto error;
             }
-        }else if(st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE){
+        } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
             track->timescale = st->codec->time_base.den;
-        }else{
+        } else if (st->codec->codec_type == AVMEDIA_TYPE_DATA) {
+            track->timescale = st->codec->time_base.den;
+        } else {
             track->timescale = MOV_TIMESCALE;
         }
         if (!track->height)
@@ -3686,14 +3730,17 @@
                       FF_MOV_FLAG_FRAGMENT;
     }
 
-    if(mov->reserved_moov_size){
+    if (mov->reserved_moov_size){
         mov->reserved_moov_pos= avio_tell(pb);
         if (mov->reserved_moov_size > 0)
             avio_skip(pb, mov->reserved_moov_size);
     }
 
-    if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
+    if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
+        if (mov->flags & FF_MOV_FLAG_FASTSTART)
+            mov->reserved_moov_pos = avio_tell(pb);
         mov_write_mdat_tag(pb, mov);
+    }
 
     if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
         mov->time = ff_iso8601_to_unix_time(t->value);
@@ -3709,7 +3756,8 @@
             AVStream *st = s->streams[i];
             if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
                 st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
-                ff_mov_init_hinting(s, hint_track, i);
+                if (ff_mov_init_hinting(s, hint_track, i) < 0)
+                    goto error;
                 hint_track++;
             }
         }
@@ -3749,11 +3797,26 @@
     return -1;
 }
 
-/**
+static int get_moov_size(AVFormatContext *s)
+{
+    int ret;
+    uint8_t *buf;
+    AVIOContext *moov_buf;
+    MOVMuxContext *mov = s->priv_data;
+
+    if ((ret = avio_open_dyn_buf(&moov_buf)) < 0)
+        return ret;
+    mov_write_moov_tag(moov_buf, mov, s);
+    ret = avio_close_dyn_buf(moov_buf, &buf);
+    av_free(buf);
+    return ret;
+}
+
+/*
  * This function gets the moov size if moved to the top of the file: the chunk
  * offset table can switch between stco (32-bit entries) to co64 (64-bit
- * entries) when the moov is moved to the top, so the size of the moov would
- * change. It also updates the chunk offset tables.
+ * entries) when the moov is moved to the beginning, so the size of the moov
+ * would change. It also updates the chunk offset tables.
  */
 static int compute_moov_size(AVFormatContext *s)
 {
@@ -3771,7 +3834,7 @@
     if (moov_size2 < 0)
         return moov_size2;
 
-    /* if the size changed, we just switched from stco to co64 and needs to
+    /* if the size changed, we just switched from stco to co64 and need to
      * update the offsets */
     if (moov_size2 != moov_size)
         for (i = 0; i < mov->nb_streams; i++)
@@ -3847,9 +3910,9 @@
 {
     MOVMuxContext *mov = s->priv_data;
     AVIOContext *pb = s->pb;
-    int64_t moov_pos;
     int res = 0;
     int i;
+    int64_t moov_pos;
 
     /*
      * Before actually writing the trailer, make sure that there are no
@@ -3864,9 +3927,19 @@
         }
     }
 
-    moov_pos = avio_tell(pb);
+    // If there were no chapters when the header was written, but there
+    // are chapters now, write them in the trailer.  This only works
+    // when we are not doing fragments.
+    if (!mov->chapter_track && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
+        if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters) {
+            mov->chapter_track = mov->nb_streams++;
+            mov_create_chapter_track(s, mov->chapter_track);
+        }
+    }
 
     if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
+        moov_pos = avio_tell(pb);
+
         /* Write size of mdat tag */
         if (mov->mdat_size + 8 <= UINT32_MAX) {
             avio_seek(pb, mov->mdat_pos, SEEK_SET);
@@ -3882,8 +3955,8 @@
         }
         avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_moov_pos : moov_pos, SEEK_SET);
 
-        if (mov->reserved_moov_size == -1) {
-            av_log(s, AV_LOG_INFO, "Starting second pass: moving header on top of the file\n");
+        if (mov->flags & FF_MOV_FLAG_FASTSTART) {
+            av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
             res = shift_data(s);
             if (res == 0) {
                 avio_seek(s->pb, mov->reserved_moov_pos, SEEK_SET);
@@ -3893,13 +3966,13 @@
             int64_t size;
             mov_write_moov_tag(pb, mov, s);
             size = mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_moov_pos);
-            if(size < 8){
+            if (size < 8){
                 av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
                 return -1;
             }
             avio_wb32(pb, size);
             ffio_wfourcc(pb, "free");
-            for(i=0; i<size; i++)
+            for (i = 0; i < size; i++)
                 avio_w8(pb, 0);
             avio_seek(pb, moov_pos, SEEK_SET);
         } else {
@@ -3910,10 +3983,12 @@
         mov_write_mfra_tag(pb, mov);
     }
 
-    if (mov->chapter_track)
+    if (mov->chapter_track) {
+        av_free(mov->tracks[mov->chapter_track].enc->extradata);
         av_freep(&mov->tracks[mov->chapter_track].enc);
+    }
 
-    for (i=0; i<mov->nb_streams; i++) {
+    for (i = 0; i < mov->nb_streams; i++) {
         if (mov->tracks[i].tag == MKTAG('r','t','p',' '))
             ff_mov_close_hinting(&mov->tracks[i]);
         else if (mov->tracks[i].tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd)
@@ -3933,7 +4008,6 @@
 
         if (mov->tracks[i].vos_len)
             av_free(mov->tracks[i].vos_data);
-
     }
 
     av_freep(&mov->tracks);
@@ -3954,7 +4028,7 @@
     .write_header      = mov_write_header,
     .write_packet      = mov_write_packet,
     .write_trailer     = mov_write_trailer,
-    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
     .codec_tag         = (const AVCodecTag* const []){
         ff_codec_movvideo_tags, ff_codec_movaudio_tags, 0
     },
@@ -3973,7 +4047,7 @@
     .write_header      = mov_write_header,
     .write_packet      = mov_write_packet,
     .write_trailer     = mov_write_trailer,
-    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
     .codec_tag         = (const AVCodecTag* const []){ codec_3gp_tags, 0 },
     .priv_class        = &tgp_muxer_class,
 };
@@ -3992,7 +4066,7 @@
     .write_header      = mov_write_header,
     .write_packet      = mov_write_packet,
     .write_trailer     = mov_write_trailer,
-    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
     .codec_tag         = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 },
     .priv_class        = &mp4_muxer_class,
 };
@@ -4010,7 +4084,7 @@
     .write_header      = mov_write_header,
     .write_packet      = mov_write_packet,
     .write_trailer     = mov_write_trailer,
-    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
     .codec_tag         = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 },
     .priv_class        = &psp_muxer_class,
 };
@@ -4027,7 +4101,7 @@
     .write_header      = mov_write_header,
     .write_packet      = mov_write_packet,
     .write_trailer     = mov_write_trailer,
-    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
     .codec_tag         = (const AVCodecTag* const []){ codec_3gp_tags, 0 },
     .priv_class        = &tg2_muxer_class,
 };
@@ -4045,7 +4119,7 @@
     .write_header      = mov_write_header,
     .write_packet      = mov_write_packet,
     .write_trailer     = mov_write_trailer,
-    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
     .codec_tag         = (const AVCodecTag* const []){ codec_ipod_tags, 0 },
     .priv_class        = &ipod_muxer_class,
 };
@@ -4063,7 +4137,7 @@
     .write_header      = mov_write_header,
     .write_packet      = mov_write_packet,
     .write_trailer     = mov_write_trailer,
-    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
     .codec_tag         = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 },
     .priv_class        = &ismv_muxer_class,
 };
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index a5db895..79d8fa2 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -26,7 +26,8 @@
 
 #include "avformat.h"
 
-#define MOV_INDEX_CLUSTER_SIZE 16384
+#define MOV_FRAG_INFO_ALLOC_INCREMENT 64
+#define MOV_INDEX_CLUSTER_SIZE 1024
 #define MOV_TIMESCALE 1000
 
 #define RTP_MAX_PACKET_SIZE 1450
@@ -75,7 +76,7 @@
     int64_t tfrf_offset;
 } MOVFragmentInfo;
 
-typedef struct MOVIndex {
+typedef struct MOVTrack {
     int         mode;
     int         entry;
     unsigned    timescale;
@@ -102,6 +103,7 @@
     int         vos_len;
     uint8_t     *vos_data;
     MOVIentry   *cluster;
+    unsigned    cluster_capacity;
     int         audio_vbr;
     int         height; ///< active picture (w/o VBI) height for D-10/IMX
     uint32_t    tref_tag;
@@ -129,6 +131,7 @@
 
     int         nb_frag_info;
     MOVFragmentInfo *frag_info;
+    unsigned    frag_info_capacity;
 
     struct {
         int64_t struct_offset;
@@ -153,8 +156,6 @@
 
     int flags;
     int rtp_flags;
-    int reserved_moov_size; ///< 0 for disabled, -1 for automatic, size otherwise
-    int64_t reserved_moov_pos;
 
     int iods_skip;
     int iods_video_profile;
@@ -168,6 +169,10 @@
     AVIOContext *mdat_buf;
 
     int use_editlist;
+    int video_track_timescale;
+
+    int reserved_moov_size; ///< 0 for disabled, -1 for automatic, size otherwise
+    int64_t reserved_moov_pos;
 } MOVMuxContext;
 
 #define FF_MOV_FLAG_RTP_HINT 1
diff --git a/libavformat/movenchint.c b/libavformat/movenchint.c
index cc90f0b..943680e 100644
--- a/libavformat/movenchint.c
+++ b/libavformat/movenchint.c
@@ -87,7 +87,7 @@
         if (queue->samples[i].own_data)
             av_free(queue->samples[i].data);
     av_freep(&queue->samples);
-    queue->len = 0;
+    queue->len  = 0;
     queue->size = 0;
 }
 
@@ -104,7 +104,7 @@
     if (size <= 14)
         return;
     if (!queue->samples || queue->len >= queue->size) {
-        HintSample* samples;
+        HintSample *samples;
         queue->size += 10;
         samples = av_realloc(queue->samples, sizeof(HintSample)*queue->size);
         if (!samples)
@@ -114,7 +114,7 @@
     queue->samples[queue->len].data = data;
     queue->samples[queue->len].size = size;
     queue->samples[queue->len].sample_number = sample;
-    queue->samples[queue->len].offset = 0;
+    queue->samples[queue->len].offset   = 0;
     queue->samples[queue->len].own_data = 0;
     queue->len++;
 }
@@ -128,7 +128,7 @@
     for (i = 0; i < queue->len; ) {
         HintSample *sample = &queue->samples[i];
         if (!sample->own_data) {
-            uint8_t* ptr = av_malloc(sample->size);
+            uint8_t *ptr = av_malloc(sample->size);
             if (!ptr) {
                 /* Unable to allocate memory for this one, remove it */
                 memmove(queue->samples + i, queue->samples + i + 1,
@@ -309,11 +309,11 @@
  * @param data buffer containing RTP packets
  * @param size the size of the data buffer
  * @param trk the MOVTrack for the hint track
- * @param pts pointer where the timestamp for the written RTP hint is stored
+ * @param dts pointer where the timestamp for the written RTP hint is stored
  * @return the number of RTP packets in the written hint
  */
 static int write_hint_packets(AVIOContext *out, const uint8_t *data,
-                              int size, MOVTrack *trk, int64_t *pts)
+                              int size, MOVTrack *trk, int64_t *dts)
 {
     int64_t curpos;
     int64_t count_pos, entries_pos;
@@ -328,6 +328,7 @@
         uint32_t packet_len = AV_RB32(data);
         uint16_t seq;
         uint32_t ts;
+        int32_t  ts_diff;
 
         data += 4;
         size -= 4;
@@ -344,25 +345,35 @@
             trk->max_packet_size = packet_len;
 
         seq = AV_RB16(&data[2]);
-        ts = AV_RB32(&data[4]);
+        ts  = AV_RB32(&data[4]);
 
         if (trk->prev_rtp_ts == 0)
             trk->prev_rtp_ts = ts;
         /* Unwrap the 32-bit RTP timestamp that wraps around often
          * into a not (as often) wrapping 64-bit timestamp. */
-        trk->cur_rtp_ts_unwrapped += (int32_t) (ts - trk->prev_rtp_ts);
-        trk->prev_rtp_ts = ts;
-        if (*pts == AV_NOPTS_VALUE)
-            *pts = trk->cur_rtp_ts_unwrapped;
+        ts_diff = ts - trk->prev_rtp_ts;
+        if (ts_diff > 0) {
+            trk->cur_rtp_ts_unwrapped += ts_diff;
+            trk->prev_rtp_ts = ts;
+            ts_diff = 0;
+        }
+        if (*dts == AV_NOPTS_VALUE)
+            *dts = trk->cur_rtp_ts_unwrapped;
 
         count++;
         /* RTPpacket header */
         avio_wb32(out, 0); /* relative_time */
         avio_write(out, data, 2); /* RTP header */
         avio_wb16(out, seq); /* RTPsequenceseed */
-        avio_wb16(out, 0); /* reserved + flags */
+        avio_wb16(out, ts_diff ? 4 : 0); /* reserved + flags (extra_flag) */
         entries_pos = avio_tell(out);
         avio_wb16(out, 0); /* entry count */
+        if (ts_diff) { /* if extra_flag is set */
+            avio_wb32(out, 16); /* extra_information_length */
+            avio_wb32(out, 12); /* rtpoffsetTLV box */
+            avio_write(out, "rtpo", 4);
+            avio_wb32(out, ts_diff);
+        }
 
         data += 12;
         size -= 12;
@@ -417,7 +428,7 @@
      * for next time. */
     size = avio_close_dyn_buf(rtp_ctx->pb, &buf);
     if ((ret = ffio_open_dyn_packet_buf(&rtp_ctx->pb,
-                                       RTP_MAX_PACKET_SIZE)) < 0)
+                                        RTP_MAX_PACKET_SIZE)) < 0)
         goto done;
 
     if (size <= 0)
@@ -445,8 +456,9 @@
     return ret;
 }
 
-void ff_mov_close_hinting(MOVTrack *track) {
-    AVFormatContext* rtp_ctx = track->rtp_ctx;
+void ff_mov_close_hinting(MOVTrack *track)
+{
+    AVFormatContext *rtp_ctx = track->rtp_ctx;
     uint8_t *ptr;
 
     av_freep(&track->enc);
diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
index d599c9c..472bad9 100644
--- a/libavformat/mp3dec.c
+++ b/libavformat/mp3dec.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/opt.h"
 #include "libavutil/avstring.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/dict.h"
@@ -36,10 +37,14 @@
 #define XING_TOC_COUNT 100
 
 typedef struct {
+    AVClass *class;
     int64_t filesize;
+    int64_t header_filesize;
     int xing_toc;
     int start_pad;
     int end_pad;
+    int usetoc;
+    int is_cbr;
 } MP3DecContext;
 
 /* mp3 read */
@@ -76,11 +81,11 @@
     }
     // keep this in sync with ac3 probe, both need to avoid
     // issues with MPEG-files!
-    if   (first_frames>=4) return AVPROBE_SCORE_MAX/2+1;
-    else if(max_frames>200)return AVPROBE_SCORE_MAX/2;
-    else if(max_frames>=4) return AVPROBE_SCORE_MAX/4;
+    if   (first_frames>=4) return AVPROBE_SCORE_EXTENSION + 1;
+    else if(max_frames>200)return AVPROBE_SCORE_EXTENSION;
+    else if(max_frames>=4) return AVPROBE_SCORE_EXTENSION / 2;
     else if(ff_id3v2_match(buf0, ID3v2_DEFAULT_MAGIC) && 2*ff_id3v2_tag_len(buf0) >= p->buf_size)
-                           return AVPROBE_SCORE_MAX/8;
+                           return AVPROBE_SCORE_EXTENSION / 4;
     else if(max_frames>=1) return 1;
     else                   return 0;
 //mpegps_mp3_unrecognized_format.mpg has max_frames=3
@@ -90,22 +95,24 @@
 {
     int i;
     MP3DecContext *mp3 = s->priv_data;
+    int fill_index = mp3->usetoc && duration > 0;
 
     if (!filesize &&
         !(filesize = avio_size(s->pb))) {
         av_log(s, AV_LOG_WARNING, "Cannot determine file size, skipping TOC table.\n");
-        return;
+        fill_index = 0;
     }
 
     for (i = 0; i < XING_TOC_COUNT; i++) {
         uint8_t b = avio_r8(s->pb);
-
-        av_add_index_entry(s->streams[0],
+        if (fill_index)
+            av_add_index_entry(s->streams[0],
                            av_rescale(b, filesize, 256),
                            av_rescale(i, duration, XING_TOC_COUNT),
                            0, 0, AVINDEX_KEYFRAME);
     }
-    mp3->xing_toc = 1;
+    if (fill_index)
+        mp3->xing_toc = 1;
 }
 
 /**
@@ -117,7 +124,7 @@
     uint32_t v, spf;
     unsigned frames = 0; /* Total number of frames in file */
     unsigned size = 0; /* Total number of bytes in the stream */
-    const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
+    static const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
     MPADecodeHeader c;
     int vbrtag_size = 0;
     int is_cbr;
@@ -143,7 +150,7 @@
             frames = avio_rb32(s->pb);
         if(v & XING_FLAG_SIZE)
             size = avio_rb32(s->pb);
-        if (v & XING_FLAG_TOC && frames)
+        if (v & XING_FLAG_TOC)
             read_xing_toc(s, size, av_rescale_q(frames, (AVRational){spf, c.sample_rate},
                                     st->time_base));
         if(v & 8)
@@ -185,6 +192,9 @@
     if (size && frames && !is_cbr)
         st->codec->bit_rate = av_rescale(size, 8 * c.sample_rate, frames * (int64_t)spf);
 
+    mp3->is_cbr          = is_cbr;
+    mp3->header_filesize = size;
+
     return 0;
 }
 
@@ -274,21 +284,33 @@
                     int flags)
 {
     MP3DecContext *mp3 = s->priv_data;
-    AVIndexEntry *ie;
+    AVIndexEntry *ie, ie1;
     AVStream *st = s->streams[0];
     int64_t ret  = av_index_search_timestamp(st, timestamp, flags);
     int i, j;
 
-    if (!mp3->xing_toc) {
+    if (mp3->is_cbr && st->duration > 0 && mp3->header_filesize > s->data_offset) {
+        int64_t filesize = avio_size(s->pb);
+        int64_t duration;
+        if (filesize <= s->data_offset)
+            filesize = mp3->header_filesize;
+        filesize -= s->data_offset;
+        duration = av_rescale(st->duration, filesize, mp3->header_filesize - s->data_offset);
+        ie = &ie1;
+        timestamp = av_clip64(timestamp, 0, duration);
+        ie->timestamp = timestamp;
+        ie->pos       = av_rescale(timestamp, filesize, duration) + s->data_offset;
+    } else if (mp3->xing_toc) {
+        if (ret < 0)
+            return ret;
+
+        ie = &st->index_entries[ret];
+    } else {
         st->skip_samples = timestamp <= 0 ? mp3->start_pad + 528 + 1 : 0;
 
         return -1;
     }
 
-    if (ret < 0)
-        return ret;
-
-    ie = &st->index_entries[ret];
     ret = avio_seek(s->pb, ie->pos, SEEK_SET);
     if (ret < 0)
         return ret;
@@ -316,6 +338,19 @@
     return 0;
 }
 
+static const AVOption options[] = {
+    { "usetoc", "use table of contents", offsetof(MP3DecContext, usetoc), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM},
+    { NULL },
+};
+
+static const AVClass demuxer_class = {
+    .class_name = "mp3",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+    .category   = AV_CLASS_CATEGORY_DEMUXER,
+};
+
 AVInputFormat ff_mp3_demuxer = {
     .name           = "mp3",
     .long_name      = NULL_IF_CONFIG_SMALL("MP2/3 (MPEG audio layer 2/3)"),
@@ -326,4 +361,5 @@
     .priv_data_size = sizeof(MP3DecContext),
     .flags          = AVFMT_GENERIC_INDEX,
     .extensions     = "mp2,mp3,m2a", /* XXX: use probe */
+    .priv_class     = &demuxer_class,
 };
diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c
index 73f8057..73b7eb7 100644
--- a/libavformat/mpc8.c
+++ b/libavformat/mpc8.c
@@ -92,7 +92,7 @@
         if (size < 2)
             return 0;
         if (bs + size - 2 >= bs_end)
-            return AVPROBE_SCORE_MAX / 4 - 1; //seems to be valid MPC but no header yet
+            return AVPROBE_SCORE_EXTENSION - 1; // seems to be valid MPC but no header yet
         if (header_found) {
             if (size < 11 || size > 28)
                 return 0;
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index 8f835ad..5d5b09f 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -89,14 +89,14 @@
     }
 
     if(vid+audio > invalid+1)     /* invalid VDR files nd short PES streams */
-        score= AVPROBE_SCORE_MAX/4;
+        score = AVPROBE_SCORE_EXTENSION / 2;
 
     if(sys>invalid && sys*9 <= pspack*10)
-        return (audio > 12 || vid > 3 || pspack > 2) ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg
+        return (audio > 12 || vid > 3 || pspack > 2) ? AVPROBE_SCORE_EXTENSION + 2 : AVPROBE_SCORE_EXTENSION / 2; // 1 more than .mpg
     if(pspack > invalid && (priv1+vid+audio)*10 >= pspack*9)
-        return pspack > 2 ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg
+        return pspack > 2 ? AVPROBE_SCORE_EXTENSION + 2 : AVPROBE_SCORE_EXTENSION / 2; // 1 more than .mpg
     if((!!vid ^ !!audio) && (audio > 4 || vid > 1) && !sys && !pspack && p->buf_size>2048 && vid + audio > invalid) /* PES stream */
-        return (audio > 12 || vid > 3 + 2*invalid) ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4;
+        return (audio > 12 || vid > 3 + 2*invalid) ? AVPROBE_SCORE_EXTENSION + 2 : AVPROBE_SCORE_EXTENSION / 2;
 
     //02-Penguin.flac has sys:0 priv1:0 pspack:0 vid:0 audio:1
     //mp3_misidentified_2.mp3 has sys:0 priv1:0 pspack:0 vid:0 audio:6
diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c
index b467bb5..6f6da5c 100644
--- a/libavformat/mpegenc.c
+++ b/libavformat/mpegenc.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/fifo.h"
 #include "libavutil/log.h"
 #include "libavutil/mathematics.h"
@@ -293,7 +294,7 @@
     return buf_index;
 }
 
-static int mpeg_mux_init(AVFormatContext *ctx)
+static av_cold int mpeg_mux_init(AVFormatContext *ctx)
 {
     MpegMuxContext *s = ctx->priv_data;
     int bitrate, i, mpa_id, mpv_id, mps_id, ac3_id, dts_id, lpcm_id, j;
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 85b5146..c641794 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -29,6 +29,7 @@
 #include "libavutil/avassert.h"
 #include "libavcodec/bytestream.h"
 #include "libavcodec/get_bits.h"
+#include "libavcodec/mathops.h"
 #include "avformat.h"
 #include "mpegts.h"
 #include "internal.h"
@@ -52,7 +53,7 @@
 
 typedef struct MpegTSFilter MpegTSFilter;
 
-typedef int PESCallback(MpegTSFilter *f, const uint8_t *buf, int len, int is_start, int64_t pos);
+typedef int PESCallback(MpegTSFilter *f, const uint8_t *buf, int len, int is_start, int64_t pos, int64_t cur_pcr);
 
 typedef struct MpegTSPESFilter {
     PESCallback *pes_cb;
@@ -98,7 +99,11 @@
     /** raw packet size, including FEC if present            */
     int raw_packet_size;
 
-    int pos47;
+    int size_stat[3];
+    int size_stat_count;
+#define SIZE_STAT_THRESHOLD 10
+
+    int64_t pos47_full;
 
     /** if true, all pids are analyzed to find streams       */
     int auto_guess;
@@ -106,6 +111,9 @@
     /** compute exact PCR for each transport stream packet   */
     int mpeg2ts_compute_pcr;
 
+    /** fix dvb teletext pts                                 */
+    int fix_teletext_pts;
+
     int64_t cur_pcr;    /**< used to estimate the exact PCR  */
     int pcr_incr;       /**< used to estimate the exact PCR  */
 
@@ -131,7 +139,7 @@
     int current_pid;
 };
 
-static const AVOption options[] = {
+static const AVOption mpegtsraw_options[] = {
     {"compute_pcr", "Compute exact PCR for each transport stream packet.", offsetof(MpegTSContext, mpeg2ts_compute_pcr), AV_OPT_TYPE_INT,
      {.i64 = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
     { NULL },
@@ -140,7 +148,20 @@
 static const AVClass mpegtsraw_class = {
     .class_name = "mpegtsraw demuxer",
     .item_name  = av_default_item_name,
-    .option     = options,
+    .option     = mpegtsraw_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVOption mpegts_options[] = {
+    {"fix_teletext_pts", "Try to fix pts values of dvb teletext streams.", offsetof(MpegTSContext, fix_teletext_pts), AV_OPT_TYPE_INT,
+     {.i64 = 1}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
+    { NULL },
+};
+
+static const AVClass mpegts_class = {
+    .class_name = "mpegts demuxer",
+    .item_name  = av_default_item_name,
+    .option     = mpegts_options,
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
@@ -179,6 +200,7 @@
     uint8_t header[MAX_PES_HEADER_SIZE];
     AVBufferRef *buffer;
     SLConfigDescr sl;
+    int64_t last_pcr;
 } PESContext;
 
 extern AVInputFormat ff_mpegts_demuxer;
@@ -268,6 +290,17 @@
     int i, j, k;
     int used = 0, discarded = 0;
     struct Program *p;
+
+    /* If none of the programs have .discard=AVDISCARD_ALL then there's
+     * no way we have to discard this packet
+     */
+    for (k = 0; k < ts->stream->nb_programs; k++) {
+        if (ts->stream->programs[k]->discard == AVDISCARD_ALL)
+            break;
+    }
+    if (k == ts->stream->nb_programs)
+        return 0;
+
     for(i=0; i<ts->nb_prg; i++) {
         p = &ts->prg[i];
         for(j=0; j<p->nb_pids; j++) {
@@ -808,7 +841,7 @@
 /* return non zero if a packet could be constructed */
 static int mpegts_push_data(MpegTSFilter *filter,
                             const uint8_t *buf, int buf_size, int is_start,
-                            int64_t pos)
+                            int64_t pos, int64_t pcr)
 {
     PESContext *pes = filter->u.pes_filter.opaque;
     MpegTSContext *ts = pes->ts;
@@ -818,6 +851,9 @@
     if(!ts->pkt)
         return 0;
 
+    if (pcr != -1)
+        pes->last_pcr = pcr;
+
     if (is_start) {
         if (pes->state == MPEGTS_PAYLOAD && pes->data_index > 0) {
             new_pes_packet(pes, ts->pkt);
@@ -964,6 +1000,32 @@
                     p += sl_header_bytes;
                     buf_size -= sl_header_bytes;
                 }
+                if (pes->ts->fix_teletext_pts && pes->st->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT) {
+                    AVProgram *p = NULL;
+                    while ((p = av_find_program_from_stream(pes->stream, p, pes->st->index))) {
+                        if (p->pcr_pid != -1 && p->discard != AVDISCARD_ALL) {
+                            MpegTSFilter *f = pes->ts->pids[p->pcr_pid];
+                            if (f && f->type == MPEGTS_PES) {
+                                PESContext *pcrpes = f->u.pes_filter.opaque;
+                                if (pcrpes && pcrpes->last_pcr != -1 && pcrpes->st && pcrpes->st->discard != AVDISCARD_ALL) {
+                                    // teletext packets do not always have correct timestamps,
+                                    // the standard says they should be handled after 40.6 ms at most,
+                                    // and the pcr error to this packet should be no more than 100 ms.
+                                    // TODO: we should interpolate the PCR, not just use the last one
+                                    int64_t pcr = pcrpes->last_pcr / 300;
+                                    pes->st->pts_wrap_reference = pcrpes->st->pts_wrap_reference;
+                                    pes->st->pts_wrap_behavior = pcrpes->st->pts_wrap_behavior;
+                                    if (pes->dts == AV_NOPTS_VALUE || pes->dts < pcr) {
+                                        pes->pts = pes->dts = pcr;
+                                    } else if (pes->dts > pcr + 3654 + 9000) {
+                                        pes->pts = pes->dts = pcr + 3654 + 9000;
+                                    }
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
             }
             break;
         case MPEGTS_PAYLOAD:
@@ -1020,6 +1082,7 @@
     pes->state = MPEGTS_SKIP;
     pes->pts = AV_NOPTS_VALUE;
     pes->dts = AV_NOPTS_VALUE;
+    pes->last_pcr = -1;
     tss = mpegts_open_pes_filter(ts, pid, mpegts_push_data, pes);
     if (!tss) {
         av_free(pes);
@@ -1625,12 +1688,18 @@
         if (sid == 0x0000) {
             /* NIT info */
         } else {
+            MpegTSFilter *fil = ts->pids[pmt_pid];
             program = av_new_program(ts->stream, sid);
             program->program_num = sid;
             program->pmt_pid = pmt_pid;
-            if (ts->pids[pmt_pid])
-                mpegts_close_filter(ts, ts->pids[pmt_pid]);
-            mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1);
+            if (fil)
+                if (   fil->type != MPEGTS_SECTION
+                    || fil->pid != pmt_pid
+                    || fil->u.section_filter.section_cb != pmt_cb)
+                    mpegts_close_filter(ts, ts->pids[pmt_pid]);
+
+            if (!ts->pids[pmt_pid])
+                mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1);
             add_pat_entry(ts, sid);
             add_pid_to_pmt(ts, sid, 0); //add pat pid to program
             add_pid_to_pmt(ts, sid, pmt_pid);
@@ -1726,6 +1795,9 @@
     }
 }
 
+static int parse_pcr(int64_t *ppcr_high, int *ppcr_low,
+                     const uint8_t *packet);
+
 /* handle one TS packet */
 static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
 {
@@ -1790,7 +1862,8 @@
         return 0;
 
     pos = avio_tell(ts->stream->pb);
-    ts->pos47= pos % ts->raw_packet_size;
+    av_assert0(pos >= TS_PACKET_SIZE);
+    ts->pos47_full = pos - TS_PACKET_SIZE;
 
     if (tss->type == MPEGTS_SECTION) {
         if (is_start) {
@@ -1819,15 +1892,53 @@
         }
     } else {
         int ret;
+        int64_t pcr = -1;
+        int64_t pcr_h;
+        int pcr_l;
+        if (parse_pcr(&pcr_h, &pcr_l, packet) == 0)
+            pcr = pcr_h * 300 + pcr_l;
         // Note: The position here points actually behind the current packet.
         if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start,
-                                            pos - ts->raw_packet_size)) < 0)
+                                            pos - ts->raw_packet_size, pcr)) < 0)
             return ret;
     }
 
     return 0;
 }
 
+static void reanalyze(MpegTSContext *ts) {
+    AVIOContext *pb = ts->stream->pb;
+    int64_t pos = avio_tell(pb);
+    if(pos < 0)
+        return;
+    pos -= ts->pos47_full;
+    if (pos == TS_PACKET_SIZE) {
+        ts->size_stat[0] ++;
+    } else if (pos == TS_DVHS_PACKET_SIZE) {
+        ts->size_stat[1] ++;
+    } else if (pos == TS_FEC_PACKET_SIZE) {
+        ts->size_stat[2] ++;
+    }
+
+    ts->size_stat_count ++;
+    if(ts->size_stat_count > SIZE_STAT_THRESHOLD) {
+        int newsize = 0;
+        if (ts->size_stat[0] > SIZE_STAT_THRESHOLD) {
+            newsize = TS_PACKET_SIZE;
+        } else if (ts->size_stat[1] > SIZE_STAT_THRESHOLD) {
+            newsize = TS_DVHS_PACKET_SIZE;
+        } else if (ts->size_stat[2] > SIZE_STAT_THRESHOLD) {
+            newsize = TS_FEC_PACKET_SIZE;
+        }
+        if (newsize && newsize != ts->raw_packet_size) {
+            av_log(ts->stream, AV_LOG_WARNING, "changing packet size to %d\n", newsize);
+            ts->raw_packet_size = newsize;
+        }
+        ts->size_stat_count = 0;
+        memset(ts->size_stat, 0, sizeof(ts->size_stat));
+    }
+}
+
 /* XXX: try to find a better synchro over several packets (use
    get_packet_size() ?) */
 static int mpegts_resync(AVFormatContext *s)
@@ -1841,6 +1952,7 @@
             return -1;
         if (c == 0x47) {
             avio_seek(pb, -1, SEEK_CUR);
+            reanalyze(s->priv_data);
             return 0;
         }
     }
@@ -1850,37 +1962,43 @@
 }
 
 /* return -1 if error or EOF. Return 0 if OK. */
-static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size)
+static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size, const uint8_t **data)
 {
     AVIOContext *pb = s->pb;
-    int skip, len;
+    int len;
 
     for(;;) {
-        len = avio_read(pb, buf, TS_PACKET_SIZE);
+        len = ffio_read_indirect(pb, buf, TS_PACKET_SIZE, data);
         if (len != TS_PACKET_SIZE)
             return len < 0 ? len : AVERROR_EOF;
         /* check packet sync byte */
-        if (buf[0] != 0x47) {
+        if ((*data)[0] != 0x47) {
             /* find a new packet start */
-            avio_seek(pb, -TS_PACKET_SIZE, SEEK_CUR);
+            avio_seek(pb, -raw_packet_size, SEEK_CUR);
             if (mpegts_resync(s) < 0)
                 return AVERROR(EAGAIN);
             else
                 continue;
         } else {
-            skip = raw_packet_size - TS_PACKET_SIZE;
-            if (skip > 0)
-                avio_skip(pb, skip);
             break;
         }
     }
     return 0;
 }
 
+static void finished_reading_packet(AVFormatContext *s, int raw_packet_size)
+{
+    AVIOContext *pb = s->pb;
+    int skip = raw_packet_size - TS_PACKET_SIZE;
+    if (skip > 0)
+        avio_skip(pb, skip);
+}
+
 static int handle_packets(MpegTSContext *ts, int nb_packets)
 {
     AVFormatContext *s = ts->stream;
     uint8_t packet[TS_PACKET_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
+    const uint8_t *data;
     int packet_num, ret = 0;
 
     if (avio_tell(s->pb) != ts->last_pos) {
@@ -1894,6 +2012,7 @@
                    av_buffer_unref(&pes->buffer);
                    pes->data_index = 0;
                    pes->state = MPEGTS_SKIP; /* skip until pes header */
+                   pes->last_pcr = -1;
                 }
                 ts->pids[i]->last_cc = -1;
             }
@@ -1913,10 +2032,11 @@
         if (ts->stop_parse > 0)
             break;
 
-        ret = read_packet(s, packet, ts->raw_packet_size);
+        ret = read_packet(s, packet, ts->raw_packet_size, &data);
         if (ret != 0)
             break;
-        ret = handle_packet(ts, packet);
+        ret = handle_packet(ts, data);
+        finished_reading_packet(s, ts->raw_packet_size);
         if (ret != 0)
             break;
     }
@@ -1986,6 +2106,15 @@
     return 0;
 }
 
+static void seek_back(AVFormatContext *s, AVIOContext *pb, int64_t pos) {
+
+    /* NOTE: We attempt to seek on non-seekable files as well, as the
+     * probe buffer usually is big enough. Only warn if the seek failed
+     * on files where the seek should work. */
+    if (avio_seek(pb, pos, SEEK_SET) < 0)
+        av_log(s, pb->seekable ? AV_LOG_ERROR : AV_LOG_INFO, "Unable to seek back to the start\n");
+}
+
 static int mpegts_read_header(AVFormatContext *s)
 {
     MpegTSContext *ts = s->priv_data;
@@ -1994,6 +2123,8 @@
     int len;
     int64_t pos;
 
+    ffio_ensure_seekback(pb, s->probesize);
+
     /* read the first 8192 bytes to get packet size */
     pos = avio_tell(pb);
     len = avio_read(pb, buf, sizeof(buf));
@@ -2009,11 +2140,7 @@
         /* normal demux */
 
         /* first do a scan to get all the services */
-        /* NOTE: We attempt to seek on non-seekable files as well, as the
-         * probe buffer usually is big enough. Only warn if the seek failed
-         * on files where the seek should work. */
-        if (avio_seek(pb, pos, SEEK_SET) < 0)
-            av_log(s, pb->seekable ? AV_LOG_ERROR : AV_LOG_INFO, "Unable to seek back to the start\n");
+        seek_back(s, pb, pos);
 
         mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1);
 
@@ -2033,6 +2160,7 @@
         int64_t pcrs[2], pcr_h;
         int packet_count[2];
         uint8_t packet[TS_PACKET_SIZE];
+        const uint8_t *data;
 
         /* only read packets */
 
@@ -2048,18 +2176,21 @@
         nb_pcrs = 0;
         nb_packets = 0;
         for(;;) {
-            ret = read_packet(s, packet, ts->raw_packet_size);
+            ret = read_packet(s, packet, ts->raw_packet_size, &data);
             if (ret < 0)
-                return -1;
-            pid = AV_RB16(packet + 1) & 0x1fff;
+                goto fail;
+            pid = AV_RB16(data + 1) & 0x1fff;
             if ((pcr_pid == -1 || pcr_pid == pid) &&
-                parse_pcr(&pcr_h, &pcr_l, packet) == 0) {
+                parse_pcr(&pcr_h, &pcr_l, data) == 0) {
+                finished_reading_packet(s, ts->raw_packet_size);
                 pcr_pid = pid;
                 packet_count[nb_pcrs] = nb_packets;
                 pcrs[nb_pcrs] = pcr_h * 300 + pcr_l;
                 nb_pcrs++;
                 if (nb_pcrs >= 2)
                     break;
+            } else {
+                finished_reading_packet(s, ts->raw_packet_size);
             }
             nb_packets++;
         }
@@ -2075,7 +2206,7 @@
                 st->start_time / 1000000.0, pcrs[0] / 27e6, ts->pcr_incr);
     }
 
-    avio_seek(pb, pos, SEEK_SET);
+    seek_back(s, pb, pos);
     return 0;
  fail:
     return -1;
@@ -2091,15 +2222,19 @@
     int64_t pcr_h, next_pcr_h, pos;
     int pcr_l, next_pcr_l;
     uint8_t pcr_buf[12];
+    const uint8_t *data;
 
     if (av_new_packet(pkt, TS_PACKET_SIZE) < 0)
         return AVERROR(ENOMEM);
     pkt->pos= avio_tell(s->pb);
-    ret = read_packet(s, pkt->data, ts->raw_packet_size);
+    ret = read_packet(s, pkt->data, ts->raw_packet_size, &data);
     if (ret < 0) {
         av_free_packet(pkt);
         return ret;
     }
+    if (data != pkt->data)
+        memcpy(pkt->data, data, ts->raw_packet_size);
+    finished_reading_packet(s, ts->raw_packet_size);
     if (ts->mpeg2ts_compute_pcr) {
         /* compute exact PCR for each packet */
         if (parse_pcr(&pcr_h, &pcr_l, pkt->data) == 0) {
@@ -2181,13 +2316,15 @@
     int64_t pos, timestamp;
     uint8_t buf[TS_PACKET_SIZE];
     int pcr_l, pcr_pid = ((PESContext*)s->streams[stream_index]->priv_data)->pcr_pid;
-    pos = ((*ppos  + ts->raw_packet_size - 1 - ts->pos47) / ts->raw_packet_size) * ts->raw_packet_size + ts->pos47;
+    int pos47 = ts->pos47_full % ts->raw_packet_size;
+    pos = ((*ppos  + ts->raw_packet_size - 1 - pos47) / ts->raw_packet_size) * ts->raw_packet_size + pos47;
     while(pos < pos_limit) {
         if (avio_seek(s->pb, pos, SEEK_SET) < 0)
             return AV_NOPTS_VALUE;
         if (avio_read(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
             return AV_NOPTS_VALUE;
         if (buf[0] != 0x47) {
+            avio_seek(s->pb, -TS_PACKET_SIZE, SEEK_CUR);
             if (mpegts_resync(s) < 0)
                 return AV_NOPTS_VALUE;
             pos = avio_tell(s->pb);
@@ -2209,7 +2346,8 @@
 {
     MpegTSContext *ts = s->priv_data;
     int64_t pos;
-    pos = ((*ppos  + ts->raw_packet_size - 1 - ts->pos47) / ts->raw_packet_size) * ts->raw_packet_size + ts->pos47;
+    int pos47 = ts->pos47_full % ts->raw_packet_size;
+    pos = ((*ppos  + ts->raw_packet_size - 1 - pos47) / ts->raw_packet_size) * ts->raw_packet_size + pos47;
     ff_read_frame_flush(s);
     if (avio_seek(s->pb, pos, SEEK_SET) < 0)
         return AV_NOPTS_VALUE;
@@ -2298,6 +2436,7 @@
     .read_close     = mpegts_read_close,
     .read_timestamp = mpegts_get_dts,
     .flags          = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,
+    .priv_class     = &mpegts_class,
 };
 
 AVInputFormat ff_mpegtsraw_demuxer = {
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index 0ddae65..1d51b97 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -85,6 +85,7 @@
 #define MPEGTS_FLAG_AAC_LATM        0x02
     int flags;
     int copyts;
+    int tables_version;
 } MpegTSWrite;
 
 /* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */
@@ -119,8 +120,10 @@
     // backward compatibility
     { "resend_headers", "Reemit PAT/PMT before writing the next packet",
       offsetof(MpegTSWrite, reemit_pat_pmt), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
-    { "mpegts_copyts", "dont offset dts/pts",
+    { "mpegts_copyts", "don't offset dts/pts",
       offsetof(MpegTSWrite, copyts), AV_OPT_TYPE_INT, {.i64=-1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
+    { "tables_version", "set PAT, PMT and SDT version",
+      offsetof(MpegTSWrite, tables_version), AV_OPT_TYPE_INT, {.i64=0}, 0, 31, AV_OPT_FLAG_ENCODING_PARAM},
     { NULL },
 };
 
@@ -252,7 +255,7 @@
         put16(&q, service->sid);
         put16(&q, 0xe000 | service->pmt.pid);
     }
-    mpegts_write_section1(&ts->pat, PAT_TID, ts->tsid, 0, 0, 0,
+    mpegts_write_section1(&ts->pat, PAT_TID, ts->tsid, ts->tables_version, 0, 0,
                           data, q - data);
 }
 
@@ -397,13 +400,23 @@
                 *q++ = 'c';
             }
             break;
+        case AVMEDIA_TYPE_DATA:
+            if (st->codec->codec_id == AV_CODEC_ID_SMPTE_KLV) {
+                *q++ = 0x05; /* MPEG-2 registration descriptor */
+                *q++ = 4;
+                *q++ = 'K';
+                *q++ = 'L';
+                *q++ = 'V';
+                *q++ = 'A';
+            }
+            break;
         }
 
         val = 0xf000 | (q - desc_length_ptr - 2);
         desc_length_ptr[0] = val >> 8;
         desc_length_ptr[1] = val;
     }
-    mpegts_write_section1(&service->pmt, PMT_TID, service->sid, 0, 0, 0,
+    mpegts_write_section1(&service->pmt, PMT_TID, service->sid, ts->tables_version, 0, 0,
                           data, q - data);
 }
 
@@ -458,7 +471,7 @@
         desc_list_len_ptr[0] = val >> 8;
         desc_list_len_ptr[1] = val;
     }
-    mpegts_write_section1(&ts->sdt, SDT_TID, ts->tsid, 0, 0, 0,
+    mpegts_write_section1(&ts->sdt, SDT_TID, ts->tsid, ts->tables_version, 0, 0,
                           data, q - data);
 }
 
@@ -977,8 +990,8 @@
             *q++ = len >> 8;
             *q++ = len;
             val = 0x80;
-            /* data alignment indicator is required for subtitle data */
-            if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE)
+            /* data alignment indicator is required for subtitle and data streams */
+            if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE || st->codec->codec_type == AVMEDIA_TYPE_DATA)
                 val |= 0x04;
             *q++ = val;
             *q++ = flags;
diff --git a/libavformat/mpegvideodec.c b/libavformat/mpegvideodec.c
index 471d2f4..a400978 100644
--- a/libavformat/mpegvideodec.c
+++ b/libavformat/mpegvideodec.c
@@ -63,8 +63,8 @@
         }
     }
     if(seq && seq*9<=pic*10 && pic*9<=slice*10 && !pspack && !apes && !res && slice > sicle) {
-        if(vpes) return AVPROBE_SCORE_MAX/8;
-        else     return pic>1 ? AVPROBE_SCORE_MAX/2+1 : AVPROBE_SCORE_MAX/4; // +1 for .mpg
+        if(vpes) return AVPROBE_SCORE_EXTENSION / 4;
+        else     return pic>1 ? AVPROBE_SCORE_EXTENSION + 1 : AVPROBE_SCORE_EXTENSION / 2; // +1 for .mpg
     }
     return 0;
 }
diff --git a/libavformat/mpsubdec.c b/libavformat/mpsubdec.c
index 2acafaa..6a0cefb 100644
--- a/libavformat/mpsubdec.c
+++ b/libavformat/mpsubdec.c
@@ -37,11 +37,10 @@
     const char *ptr_end = p->buf + p->buf_size;
 
     while (ptr < ptr_end) {
-        int n;
-
-        if (!memcmp(ptr, "FORMAT=TIME", 11) ||
-            sscanf(ptr, "FORMAT=%d", &n) == 1)
-            return AVPROBE_SCORE_MAX/2;
+        if (!memcmp(ptr, "FORMAT=TIME", 11))
+            return AVPROBE_SCORE_EXTENSION;
+        if (!memcmp(ptr, "FORMAT=", 7))
+            return AVPROBE_SCORE_EXTENSION / 3;
         ptr += strcspn(ptr, "\n") + 1;
     }
     return 0;
diff --git a/libavformat/mtv.c b/libavformat/mtv.c
index 6ffbb51..29c26c6 100644
--- a/libavformat/mtv.c
+++ b/libavformat/mtv.c
@@ -42,10 +42,10 @@
     unsigned int audio_br;          ///< bitrate of audio channel (mp3)
     unsigned int img_colorfmt;      ///< frame colorfmt rgb 565/555
     unsigned int img_bpp;           ///< frame bits per pixel
-    unsigned int img_width;         //
-    unsigned int img_height;        //
+    unsigned int img_width;
+    unsigned int img_height;
     unsigned int img_segment_size;  ///< size of image segment
-    unsigned int video_fps;         //
+    unsigned int video_fps;
     unsigned int full_segment_size;
 
 } MTVDemuxContext;
@@ -64,13 +64,13 @@
     if(!AV_RL16(&p->buf[52]) || !AV_RL16(&p->buf[54]))
     {
         if(!!AV_RL16(&p->buf[56]))
-            return AVPROBE_SCORE_MAX/2;
+            return AVPROBE_SCORE_EXTENSION;
         else
             return 0;
     }
 
     if(p->buf[51] != 16)
-        return AVPROBE_SCORE_MAX/4; // But we are going to assume 16bpp anyway ..
+        return AVPROBE_SCORE_EXTENSION / 2; // But we are going to assume 16bpp anyway ..
 
     return AVPROBE_SCORE_MAX;
 }
diff --git a/libavformat/mux.c b/libavformat/mux.c
index 1153ab6..aa5d5ed 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -19,8 +19,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-/* #define DEBUG */
-
 #include "avformat.h"
 #include "avio_internal.h"
 #include "internal.h"
@@ -34,6 +32,7 @@
 #include "id3v2.h"
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
+#include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/parseutils.h"
 #include "libavutil/time.h"
@@ -275,13 +274,18 @@
             if (av_cmp_q(st->sample_aspect_ratio, codec->sample_aspect_ratio)
                 && FFABS(av_q2d(st->sample_aspect_ratio) - av_q2d(codec->sample_aspect_ratio)) > 0.004*av_q2d(st->sample_aspect_ratio)
             ) {
-                av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between muxer "
-                                        "(%d/%d) and encoder layer (%d/%d)\n",
-                       st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
-                       codec->sample_aspect_ratio.num,
-                       codec->sample_aspect_ratio.den);
-                ret = AVERROR(EINVAL);
-                goto fail;
+                if (st->sample_aspect_ratio.num != 0 &&
+                    st->sample_aspect_ratio.den != 0 &&
+                    codec->sample_aspect_ratio.den != 0 &&
+                    codec->sample_aspect_ratio.den != 0) {
+                    av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between muxer "
+                           "(%d/%d) and encoder layer (%d/%d)\n",
+                           st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
+                           codec->sample_aspect_ratio.num,
+                           codec->sample_aspect_ratio.den);
+                    ret = AVERROR(EINVAL);
+                    goto fail;
+                }
             }
             break;
         }
@@ -298,12 +302,12 @@
             }
             if (codec->codec_tag) {
                 if (!validate_codec_tag(s, st)) {
-                    char tagbuf[32], cortag[32];
+                    char tagbuf[32], tagbuf2[32];
                     av_get_codec_tag_string(tagbuf, sizeof(tagbuf), codec->codec_tag);
-                    av_get_codec_tag_string(cortag, sizeof(cortag), av_codec_get_tag(s->oformat->codec_tag, codec->codec_id));
+                    av_get_codec_tag_string(tagbuf2, sizeof(tagbuf2), av_codec_get_tag(s->oformat->codec_tag, codec->codec_id));
                     av_log(s, AV_LOG_ERROR,
                            "Tag %s/0x%08x incompatible with output codec id '%d' (%s)\n",
-                           tagbuf, codec->codec_tag, codec->codec_id, cortag);
+                           tagbuf, codec->codec_tag, codec->codec_id, tagbuf2);
                     ret = AVERROR_INVALIDDATA;
                     goto fail;
                 }
@@ -398,6 +402,13 @@
     if ((ret = init_pts(s)) < 0)
         return ret;
 
+    if (s->avoid_negative_ts < 0) {
+        if (s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS)) {
+            s->avoid_negative_ts = 0;
+        } else
+            s->avoid_negative_ts = 1;
+    }
+
     return 0;
 }
 
@@ -485,13 +496,43 @@
 }
 
 /**
- * Move side data from payload to internal struct, call muxer, and restore
- * original packet.
+ * Make timestamps non negative, move side data from payload to internal struct, call muxer, and restore
+ * sidedata.
+ *
+ * FIXME: this function should NEVER get undefined pts/dts beside when the
+ * AVFMT_NOTIMESTAMPS is set.
+ * Those additional safety checks should be dropped once the correct checks
+ * are set in the callers.
  */
-static inline int split_write_packet(AVFormatContext *s, AVPacket *pkt)
+static int write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     int ret, did_split;
 
+    if (s->avoid_negative_ts > 0) {
+        AVStream *st = s->streams[pkt->stream_index];
+        int64_t offset = st->mux_ts_offset;
+
+        if (pkt->dts < 0 && pkt->dts != AV_NOPTS_VALUE && !s->offset) {
+            s->offset = -pkt->dts;
+            s->offset_timebase = st->time_base;
+        }
+
+        if (s->offset && !offset) {
+            offset = st->mux_ts_offset =
+                av_rescale_q_rnd(s->offset,
+                                 s->offset_timebase,
+                                 st->time_base,
+                                 AV_ROUND_UP);
+        }
+
+        if (pkt->dts != AV_NOPTS_VALUE)
+            pkt->dts += offset;
+        if (pkt->pts != AV_NOPTS_VALUE)
+            pkt->pts += offset;
+
+        av_assert2(pkt->dts == AV_NOPTS_VALUE || pkt->dts >= 0);
+    }
+
     did_split = av_packet_split_side_data(pkt);
     ret = s->oformat->write_packet(s, pkt);
     if (s->flush_packets && s->pb && s->pb->error >= 0)
@@ -522,7 +563,7 @@
     if (ret < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
         return ret;
 
-    ret = split_write_packet(s, pkt);
+    ret = write_packet(s, pkt);
     if (ret >= 0 && s->pb && s->pb->error < 0)
         ret = s->pb->error;
 
@@ -545,10 +586,13 @@
         return AVERROR(ENOMEM);
     this_pktl->pkt = *pkt;
 #if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
     pkt->destruct  = NULL;           // do not free original but only the copy
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
     pkt->buf       = NULL;
     av_dup_packet(&this_pktl->pkt);  // duplicate the packet if it uses non-allocated memory
+    av_copy_packet_side_data(&this_pktl->pkt, &this_pktl->pkt); // copy side data
 
     if (s->streams[pkt->stream_index]->last_in_packet_buffer) {
         next_point = &(st->last_in_packet_buffer->next);
@@ -600,7 +644,8 @@
     return 0;
 }
 
-static int ff_interleave_compare_dts(AVFormatContext *s, AVPacket *next, AVPacket *pkt)
+static int interleave_compare_dts(AVFormatContext *s, AVPacket *next,
+                                  AVPacket *pkt)
 {
     AVStream *st  = s->streams[pkt->stream_index];
     AVStream *st2 = s->streams[next->stream_index];
@@ -631,7 +676,7 @@
     int i, ret;
 
     if (pkt) {
-        ret = ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts);
+        ret = ff_interleave_add_packet(s, pkt, interleave_compare_dts);
         if (ret < 0)
             return ret;
     }
@@ -679,23 +724,6 @@
             st->last_in_packet_buffer = NULL;
         av_freep(&pktl);
 
-        if (s->avoid_negative_ts > 0) {
-            if (out->dts != AV_NOPTS_VALUE) {
-                if (!st->mux_ts_offset && out->dts < 0) {
-                    for (i = 0; i < s->nb_streams; i++) {
-                        s->streams[i]->mux_ts_offset =
-                            av_rescale_q_rnd(-out->dts,
-                                             st->time_base,
-                                             s->streams[i]->time_base,
-                                             AV_ROUND_UP);
-                    }
-                }
-                out->dts += st->mux_ts_offset;
-            }
-            if (out->pts != AV_NOPTS_VALUE)
-                out->pts += st->mux_ts_offset;
-        }
-
         return 1;
     } else {
         av_init_packet(out);
@@ -752,7 +780,7 @@
         if (ret <= 0) //FIXME cleanup needed for ret<0 ?
             return ret;
 
-        ret = split_write_packet(s, &opkt);
+        ret = write_packet(s, &opkt);
         if (ret >= 0)
             s->streams[opkt.stream_index]->nb_frames++;
 
@@ -778,7 +806,7 @@
         if (!ret)
             break;
 
-        ret = split_write_packet(s, &pkt);
+        ret = write_packet(s, &pkt);
         if (ret >= 0)
             s->streams[pkt.stream_index]->nb_frames++;
 
@@ -816,3 +844,25 @@
     s->oformat->get_output_timestamp(s, stream, dts, wall);
     return 0;
 }
+
+int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt,
+                     AVFormatContext *src)
+{
+    AVPacket local_pkt;
+
+    local_pkt = *pkt;
+    local_pkt.stream_index = dst_stream;
+    if (pkt->pts != AV_NOPTS_VALUE)
+        local_pkt.pts = av_rescale_q(pkt->pts,
+                                     src->streams[pkt->stream_index]->time_base,
+                                     dst->streams[dst_stream]->time_base);
+    if (pkt->dts != AV_NOPTS_VALUE)
+        local_pkt.dts = av_rescale_q(pkt->dts,
+                                     src->streams[pkt->stream_index]->time_base,
+                                     dst->streams[dst_stream]->time_base);
+    if (pkt->duration)
+        local_pkt.duration = av_rescale_q(pkt->duration,
+                                          src->streams[pkt->stream_index]->time_base,
+                                          dst->streams[dst_stream]->time_base);
+    return av_write_frame(dst, &local_pkt);
+}
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 286a884..29a2f56 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -43,8 +43,6 @@
  * Only tracks with associated descriptors will be decoded. "Highly Desirable" SMPTE 377M D.1
  */
 
-//#define DEBUG
-
 #include "libavutil/aes.h"
 #include "libavutil/avassert.h"
 #include "libavutil/mathematics.h"
@@ -1603,8 +1601,10 @@
         }
         if (descriptor->extradata) {
             st->codec->extradata = av_mallocz(descriptor->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
-            if (st->codec->extradata)
+            if (st->codec->extradata) {
                 memcpy(st->codec->extradata, descriptor->extradata, descriptor->extradata_size);
+                st->codec->extradata_size = descriptor->extradata_size;
+            }
         } else if(st->codec->codec_id == AV_CODEC_ID_H264) {
             ff_generate_avci_extradata(st);
         }
@@ -2210,10 +2210,8 @@
     KLVPacket klv;
     MXFContext *mxf = s->priv_data;
 
-    while (!url_feof(s->pb)) {
+    while (klv_read_packet(&klv, s->pb) == 0) {
         int ret;
-        if (klv_read_packet(&klv, s->pb) < 0)
-            return -1;
         PRINT_KEY(s, "read packet", klv.key);
         av_dlog(s, "size %"PRIu64" offset %#"PRIx64"\n", klv.length, klv.offset);
         if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) {
@@ -2298,7 +2296,7 @@
         skip:
             avio_skip(s->pb, klv.length);
     }
-    return AVERROR_EOF;
+    return url_feof(s->pb) ? AVERROR_EOF : -1;
 }
 
 static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
index ea13ee0..52cb282 100644
--- a/libavformat/mxfenc.c
+++ b/libavformat/mxfenc.c
@@ -30,8 +30,6 @@
  * SMPTE RP224: Registry of SMPTE Universal Labels
  */
 
-//#define DEBUG
-
 #include <inttypes.h>
 #include <math.h>
 #include <time.h>
@@ -44,6 +42,7 @@
 #include "libavcodec/dnxhddata.h"
 #include "audiointerleave.h"
 #include "avformat.h"
+#include "avio_internal.h"
 #include "internal.h"
 #include "mxf.h"
 #include "config.h"
@@ -1296,13 +1295,12 @@
         avio_write(s->pb, klv_fill_key, 16);
         pad -= 16 + 4;
         klv_encode_ber4_length(s->pb, pad);
-        for (; pad; pad--)
-            avio_w8(s->pb, 0);
+        ffio_fill(s->pb, 0, pad);
         av_assert1(!(avio_tell(s->pb) & (KAG_SIZE-1)));
     }
 }
 
-static void mxf_write_partition(AVFormatContext *s, int bodysid,
+static int mxf_write_partition(AVFormatContext *s, int bodysid,
                                 int indexsid,
                                 const uint8_t *key, int write_metadata)
 {
@@ -1311,6 +1309,7 @@
     int64_t header_byte_count_offset;
     unsigned index_byte_count = 0;
     uint64_t partition_offset = avio_tell(pb);
+    int err;
 
     if (!mxf->edit_unit_byte_count && mxf->edit_units_count)
         index_byte_count = 85 + 12+(s->nb_streams+1)*6 +
@@ -1325,10 +1324,11 @@
     }
 
     if (!memcmp(key, body_partition_key, 16)) {
-        mxf->body_partition_offset =
-            av_realloc(mxf->body_partition_offset,
-                       (mxf->body_partitions_count+1)*
-                       sizeof(*mxf->body_partition_offset));
+        if ((err = av_reallocp_array(&mxf->body_partition_offset, mxf->body_partitions_count + 1,
+                                     sizeof(*mxf->body_partition_offset))) < 0) {
+            mxf->body_partitions_count = 0;
+            return err;
+        }
         mxf->body_partition_offset[mxf->body_partitions_count++] = partition_offset;
     }
 
@@ -1393,6 +1393,8 @@
     }
 
     avio_flush(pb);
+
+    return 0;
 }
 
 static int mxf_parse_dnxhd_frame(AVFormatContext *s, AVStream *st,
@@ -1872,13 +1874,11 @@
         avio_write(s->pb, klv_fill_key, 16);
         pad -= 16 + 4;
         klv_encode_ber4_length(s->pb, pad);
-        for (; pad; pad--)
-            avio_w8(s->pb, 0);
+        ffio_fill(s->pb, 0, pad);
         av_assert1(!(avio_tell(s->pb) & (KAG_SIZE-1)));
     } else {
         av_log(s, AV_LOG_WARNING, "cannot fill d-10 video packet\n");
-        for (; pad > 0; pad--)
-            avio_w8(s->pb, 0);
+        ffio_fill(s->pb, 0, pad);
     }
 }
 
@@ -1921,13 +1921,14 @@
     AVStream *st = s->streams[pkt->stream_index];
     MXFStreamContext *sc = st->priv_data;
     MXFIndexEntry ie = {0};
+    int err;
 
     if (!mxf->edit_unit_byte_count && !(mxf->edit_units_count % EDIT_UNITS_PER_BODY)) {
-        mxf->index_entries = av_realloc(mxf->index_entries,
-            (mxf->edit_units_count + EDIT_UNITS_PER_BODY)*sizeof(*mxf->index_entries));
-        if (!mxf->index_entries) {
+        if ((err = av_reallocp_array(&mxf->index_entries, mxf->edit_units_count
+                                     + EDIT_UNITS_PER_BODY, sizeof(*mxf->index_entries))) < 0) {
+            mxf->edit_units_count = 0;
             av_log(s, AV_LOG_ERROR, "could not allocate index entries\n");
-            return -1;
+            return err;
         }
     }
 
@@ -1950,11 +1951,13 @@
 
     if (!mxf->header_written) {
         if (mxf->edit_unit_byte_count) {
-            mxf_write_partition(s, 1, 2, header_open_partition_key, 1);
+            if ((err = mxf_write_partition(s, 1, 2, header_open_partition_key, 1)) < 0)
+                return err;
             mxf_write_klv_fill(s);
             mxf_write_index_table_segment(s);
         } else {
-            mxf_write_partition(s, 0, 0, header_open_partition_key, 1);
+            if ((err = mxf_write_partition(s, 0, 0, header_open_partition_key, 1)) < 0)
+                return err;
         }
         mxf->header_written = 1;
     }
@@ -1964,8 +1967,8 @@
             (!mxf->edit_units_count || mxf->edit_units_count > EDIT_UNITS_PER_BODY) &&
             !(ie.flags & 0x33)) { // I frame, Gop start
             mxf_write_klv_fill(s);
-            mxf_write_partition(s, 1, 2, body_partition_key, 0);
-
+            if ((err = mxf_write_partition(s, 1, 2, body_partition_key, 0)) < 0)
+                return err;
             mxf_write_klv_fill(s);
             mxf_write_index_table_segment(s);
         }
@@ -2034,16 +2037,18 @@
 {
     MXFContext *mxf = s->priv_data;
     AVIOContext *pb = s->pb;
+    int err;
 
     mxf->duration = mxf->last_indexed_edit_unit + mxf->edit_units_count;
 
     mxf_write_klv_fill(s);
     mxf->footer_partition_offset = avio_tell(pb);
     if (mxf->edit_unit_byte_count) { // no need to repeat index
-        mxf_write_partition(s, 0, 0, footer_partition_key, 0);
+        if ((err = mxf_write_partition(s, 0, 0, footer_partition_key, 0)) < 0)
+            return err;
     } else {
-        mxf_write_partition(s, 0, 2, footer_partition_key, 0);
-
+        if ((err = mxf_write_partition(s, 0, 2, footer_partition_key, 0)) < 0)
+            return err;
         mxf_write_klv_fill(s);
         mxf_write_index_table_segment(s);
     }
@@ -2054,11 +2059,13 @@
     if (s->pb->seekable) {
         avio_seek(pb, 0, SEEK_SET);
         if (mxf->edit_unit_byte_count) {
-            mxf_write_partition(s, 1, 2, header_closed_partition_key, 1);
+            if ((err = mxf_write_partition(s, 1, 2, header_closed_partition_key, 1)) < 0)
+                return err;
             mxf_write_klv_fill(s);
             mxf_write_index_table_segment(s);
         } else {
-            mxf_write_partition(s, 0, 0, header_closed_partition_key, 1);
+            if ((err = mxf_write_partition(s, 0, 0, header_closed_partition_key, 1)) < 0)
+                return err;
         }
     }
 
diff --git a/libavformat/mxg.c b/libavformat/mxg.c
index 604be78..b2b5b86 100644
--- a/libavformat/mxg.c
+++ b/libavformat/mxg.c
@@ -20,6 +20,7 @@
  */
 
 #include "libavutil/channel_layout.h"
+#include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "libavcodec/mjpeg.h"
 #include "avformat.h"
@@ -74,7 +75,7 @@
 static uint8_t* mxg_find_startmarker(uint8_t *p, uint8_t *end)
 {
     for (; p < end - 3; p += 4) {
-        uint32_t x = *(uint32_t*)p;
+        uint32_t x = AV_RN32(p);
 
         if (x & (~(x+0x01010101)) & 0x80808080) {
             if (p[0] == 0xff) {
@@ -171,7 +172,9 @@
                 pkt->pts = pkt->dts = mxg->dts;
                 pkt->stream_index = 0;
 #if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
                 pkt->destruct = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
                 pkt->buf  = NULL;
                 pkt->size = mxg->buffer_ptr - mxg->soi_ptr;
@@ -212,7 +215,9 @@
                     pkt->pts = pkt->dts = AV_RL64(startmarker_ptr + 8);
                     pkt->stream_index = 1;
 #if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
                     pkt->destruct = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
                     pkt->buf  = NULL;
                     pkt->size = size - 14;
diff --git a/libavformat/network.c b/libavformat/network.c
index ceed719..7340961 100644
--- a/libavformat/network.c
+++ b/libavformat/network.c
@@ -18,9 +18,11 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/avutil.h"
+#include <fcntl.h>
 #include "network.h"
+#include "url.h"
 #include "libavcodec/internal.h"
+#include "libavutil/avutil.h"
 #include "libavutil/mem.h"
 #include "url.h"
 #include "libavutil/time.h"
@@ -29,9 +31,9 @@
 #if HAVE_PTHREADS
 #include <pthread.h>
 #elif HAVE_OS2THREADS
-#include "libavcodec/os2threads.h"
+#include "compat/os2threads.h"
 #else
-#include "libavcodec/w32pthreads.h"
+#include "compat/w32pthreads.h"
 #endif
 #endif
 
@@ -156,12 +158,12 @@
     int64_t wait_start = 0;
 
     while (1) {
+        if (ff_check_interrupt(int_cb))
+            return AVERROR_EXIT;
         ret = ff_network_wait_fd(fd, write);
         if (ret != AVERROR(EAGAIN))
             return ret;
-        if (ff_check_interrupt(int_cb))
-            return AVERROR_EXIT;
-        if (timeout) {
+        if (timeout > 0) {
             if (!wait_start)
                 wait_start = av_gettime();
             else if (av_gettime() - wait_start > timeout)
@@ -212,3 +214,171 @@
 
     return 0;
 }
+
+static int ff_poll_interrupt(struct pollfd *p, nfds_t nfds, int timeout,
+                             AVIOInterruptCB *cb)
+{
+    int runs = timeout / POLLING_TIME;
+    int ret = 0;
+
+    do {
+        if (ff_check_interrupt(cb))
+            return AVERROR_EXIT;
+        ret = poll(p, nfds, POLLING_TIME);
+        if (ret != 0)
+            break;
+    } while (timeout <= 0 || runs-- > 0);
+
+    if (!ret)
+        return AVERROR(ETIMEDOUT);
+    if (ret < 0)
+        return AVERROR(errno);
+    return ret;
+}
+
+int ff_socket(int af, int type, int proto)
+{
+    int fd;
+
+#ifdef SOCK_CLOEXEC
+    fd = socket(af, type | SOCK_CLOEXEC, proto);
+    if (fd == -1 && errno == EINVAL)
+#endif
+    {
+        fd = socket(af, type, proto);
+#if HAVE_FCNTL
+        if (fd != -1)
+            fcntl(fd, F_SETFD, FD_CLOEXEC);
+#endif
+    }
+    return fd;
+}
+
+int ff_listen_bind(int fd, const struct sockaddr *addr,
+                   socklen_t addrlen, int timeout, URLContext *h)
+{
+    int ret;
+    int reuse = 1;
+    struct pollfd lp = { fd, POLLIN, 0 };
+    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))) {
+        av_log(NULL, AV_LOG_WARNING, "setsockopt(SO_REUSEADDR) failed\n");
+    }
+    ret = bind(fd, addr, addrlen);
+    if (ret)
+        return ff_neterrno();
+
+    ret = listen(fd, 1);
+    if (ret)
+        return ff_neterrno();
+
+    ret = ff_poll_interrupt(&lp, 1, timeout, &h->interrupt_callback);
+    if (ret < 0)
+        return ret;
+
+    ret = accept(fd, NULL, NULL);
+    if (ret < 0)
+        return ff_neterrno();
+
+    closesocket(fd);
+
+    ff_socket_nonblock(ret, 1);
+    return ret;
+}
+
+int ff_listen_connect(int fd, const struct sockaddr *addr,
+                      socklen_t addrlen, int timeout, URLContext *h,
+                      int will_try_next)
+{
+    struct pollfd p = {fd, POLLOUT, 0};
+    int ret;
+    socklen_t optlen;
+
+    ff_socket_nonblock(fd, 1);
+
+    while ((ret = connect(fd, addr, addrlen))) {
+        ret = ff_neterrno();
+        switch (ret) {
+        case AVERROR(EINTR):
+            if (ff_check_interrupt(&h->interrupt_callback))
+                return AVERROR_EXIT;
+            continue;
+        case AVERROR(EINPROGRESS):
+        case AVERROR(EAGAIN):
+            ret = ff_poll_interrupt(&p, 1, timeout, &h->interrupt_callback);
+            if (ret < 0)
+                return ret;
+            optlen = sizeof(ret);
+            if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen))
+                ret = AVUNERROR(ff_neterrno());
+            if (ret != 0) {
+                char errbuf[100];
+                ret = AVERROR(ret);
+                av_strerror(ret, errbuf, sizeof(errbuf));
+                if (will_try_next)
+                    av_log(h, AV_LOG_WARNING,
+                           "Connection to %s failed (%s), trying next address\n",
+                           h->filename, errbuf);
+                else
+                    av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n",
+                           h->filename, errbuf);
+            }
+        default:
+            return ret;
+        }
+    }
+    return ret;
+}
+
+static int match_host_pattern(const char *pattern, const char *hostname)
+{
+    int len_p, len_h;
+    if (!strcmp(pattern, "*"))
+        return 1;
+    // Skip a possible *. at the start of the pattern
+    if (pattern[0] == '*')
+        pattern++;
+    if (pattern[0] == '.')
+        pattern++;
+    len_p = strlen(pattern);
+    len_h = strlen(hostname);
+    if (len_p > len_h)
+        return 0;
+    // Simply check if the end of hostname is equal to 'pattern'
+    if (!strcmp(pattern, &hostname[len_h - len_p])) {
+        if (len_h == len_p)
+            return 1; // Exact match
+        if (hostname[len_h - len_p - 1] == '.')
+            return 1; // The matched substring is a domain and not just a substring of a domain
+    }
+    return 0;
+}
+
+int ff_http_match_no_proxy(const char *no_proxy, const char *hostname)
+{
+    char *buf, *start;
+    int ret = 0;
+    if (!no_proxy)
+        return 0;
+    if (!hostname)
+        return 0;
+    buf = av_strdup(no_proxy);
+    if (!buf)
+        return 0;
+    start = buf;
+    while (start) {
+        char *sep, *next = NULL;
+        start += strspn(start, " ,");
+        sep = start + strcspn(start, " ,");
+        if (*sep) {
+            next = sep + 1;
+            *sep = '\0';
+        }
+        if (match_host_pattern(start, hostname)) {
+            ret = 1;
+            break;
+        }
+        start = next;
+    }
+    av_free(buf);
+    return ret;
+}
diff --git a/libavformat/network.h b/libavformat/network.h
index f8b4dee..c60e142 100644
--- a/libavformat/network.h
+++ b/libavformat/network.h
@@ -28,6 +28,7 @@
 #include "libavutil/error.h"
 #include "os_support.h"
 #include "avio.h"
+#include "url.h"
 
 #if HAVE_UNISTD_H
 #include <unistd.h>
@@ -89,7 +90,7 @@
  * @fd Socket descriptor
  * @write Set 1 to wait for socket able to be read, 0 to be written
  * @timeout Timeout interval, in microseconds. Actual precision is 100000 mcs, due to ff_network_wait_fd usage
- * @param int_cb Interrupt callback, is checked after each ff_network_wait_fd call
+ * @param int_cb Interrupt callback, is checked before each ff_network_wait_fd call
  * @return 0 if data can be read/written, AVERROR(ETIMEDOUT) if timeout expired, or negative error code
  */
 int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb);
@@ -222,4 +223,45 @@
 
 int ff_is_multicast_address(struct sockaddr *addr);
 
+#define POLLING_TIME 100 /// Time in milliseconds between interrupt check
+
+/**
+ * Bind to a file descriptor and poll for a connection.
+ *
+ * @param fd      First argument of bind().
+ * @param addr    Second argument of bind().
+ * @param addrlen Third argument of bind().
+ * @param timeout Polling timeout in milliseconds.
+ * @param h       URLContext providing interrupt check
+ *                callback and logging context.
+ * @return        A non-blocking file descriptor on success
+ *                or an AVERROR on failure.
+ */
+int ff_listen_bind(int fd, const struct sockaddr *addr,
+                   socklen_t addrlen, int timeout,
+                   URLContext *h);
+
+/**
+ * Connect to a file descriptor and poll for result.
+ *
+ * @param fd       First argument of connect(),
+ *                 will be set as non-blocking.
+ * @param addr     Second argument of connect().
+ * @param addrlen  Third argument of connect().
+ * @param timeout  Polling timeout in milliseconds.
+ * @param h        URLContext providing interrupt check
+ *                 callback and logging context.
+ * @param will_try_next Whether the caller will try to connect to another
+ *                 address for the same host name, affecting the form of
+ *                 logged errors.
+ * @return         0 on success, AVERROR on failure.
+ */
+int ff_listen_connect(int fd, const struct sockaddr *addr,
+                      socklen_t addrlen, int timeout,
+                      URLContext *h, int will_try_next);
+
+int ff_http_match_no_proxy(const char *no_proxy, const char *hostname);
+
+int ff_socket(int domain, int type, int protocol);
+
 #endif /* AVFORMAT_NETWORK_H */
diff --git a/libavformat/noproxy-test.c b/libavformat/noproxy-test.c
index a156620..4524764 100644
--- a/libavformat/noproxy-test.c
+++ b/libavformat/noproxy-test.c
@@ -18,7 +18,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "internal.h"
+#include "network.h"
 
 static void test(const char *pattern, const char *host)
 {
diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c
index e582f0f..4a749a2 100644
--- a/libavformat/nsvdec.c
+++ b/libavformat/nsvdec.c
@@ -28,10 +28,6 @@
 #include "libavutil/dict.h"
 #include "libavutil/intreadwrite.h"
 
-//#define DEBUG_DUMP_INDEX // XXX dumbdriving-271.nsv breaks with it commented!!
-#define CHECK_SUBSEQUENT_NSVS
-//#define DISABLE_AUDIO
-
 /* max bytes to crawl for trying to resync
  * stupid streaming servers don't start at chunk boundaries...
  */
@@ -370,25 +366,6 @@
 
     av_dlog(s, "NSV got index; filepos %"PRId64"\n", avio_tell(pb));
 
-#ifdef DEBUG_DUMP_INDEX
-#define V(v) ((v<0x20 || v > 127)?'.':v)
-    /* dump index */
-    av_dlog(s, "NSV %d INDEX ENTRIES:\n", table_entries);
-    av_dlog(s, "NSV [dataoffset][fileoffset]\n", table_entries);
-    for (i = 0; i < table_entries; i++) {
-        unsigned char b[8];
-        avio_seek(pb, size + nsv->nsvs_file_offset[i], SEEK_SET);
-        avio_read(pb, b, 8);
-        av_dlog(s, "NSV [0x%08lx][0x%08lx]: %02x %02x %02x %02x %02x %02x %02x %02x"
-           "%c%c%c%c%c%c%c%c\n",
-           nsv->nsvs_file_offset[i], size + nsv->nsvs_file_offset[i],
-           b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
-           V(b[0]), V(b[1]), V(b[2]), V(b[3]), V(b[4]), V(b[5]), V(b[6]), V(b[7]) );
-    }
-    //avio_seek(pb, size, SEEK_SET); /* go back to end of header */
-#undef V
-#endif
-
     avio_seek(pb, nsv->base_offset + size, SEEK_SET); /* required for dumbdriving-271.nsv (2 extra bytes) */
 
     if (url_feof(pb))
@@ -479,7 +456,6 @@
             }
         }
         if (atag != T_NONE) {
-#ifndef DISABLE_AUDIO
             st = avformat_new_stream(s, NULL);
             if (!st)
                 goto fail;
@@ -499,15 +475,12 @@
             avpriv_set_pts_info(st, 64, 1, framerate.num*1000);
             st->start_time = 0;
             st->duration = (int64_t)nsv->duration * framerate.num;
-#endif
         }
-#ifdef CHECK_SUBSEQUENT_NSVS
     } else {
         if (nsv->vtag != vtag || nsv->atag != atag || nsv->vwidth != vwidth || nsv->vheight != vwidth) {
             av_dlog(s, "NSV NSVs header values differ from the first one!!!\n");
             //return -1;
         }
-#endif /* CHECK_SUBSEQUENT_NSVS */
     }
 
     nsv->state = NSV_HAS_READ_NSVS;
@@ -786,7 +759,7 @@
     }
     /* so we'll have more luck on extension... */
     if (av_match_ext(p->filename, "nsv"))
-        return AVPROBE_SCORE_MAX/2;
+        return AVPROBE_SCORE_EXTENSION;
     /* FIXME: add mime-type check */
     return score;
 }
diff --git a/libavformat/nut.c b/libavformat/nut.c
index 2abe969..7e79979 100644
--- a/libavformat/nut.c
+++ b/libavformat/nut.c
@@ -26,125 +26,138 @@
 #include "internal.h"
 
 const AVCodecTag ff_nut_subtitle_tags[] = {
-    { AV_CODEC_ID_TEXT        , MKTAG('U', 'T', 'F', '8') },
-    { AV_CODEC_ID_SSA         , MKTAG('S', 'S', 'A',  0 ) },
-    { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('D', 'V', 'D', 'S') },
-    { AV_CODEC_ID_DVB_SUBTITLE, MKTAG('D', 'V', 'B', 'S') },
-    { AV_CODEC_ID_DVB_TELETEXT, MKTAG('D', 'V', 'B', 'T') },
-    { AV_CODEC_ID_NONE        , 0                         }
+    { AV_CODEC_ID_TEXT,             MKTAG('U', 'T', 'F', '8') },
+    { AV_CODEC_ID_SSA,              MKTAG('S', 'S', 'A',  0 ) },
+    { AV_CODEC_ID_DVD_SUBTITLE,     MKTAG('D', 'V', 'D', 'S') },
+    { AV_CODEC_ID_DVB_SUBTITLE,     MKTAG('D', 'V', 'B', 'S') },
+    { AV_CODEC_ID_DVB_TELETEXT,     MKTAG('D', 'V', 'B', 'T') },
+    { AV_CODEC_ID_NONE,             0                         }
 };
 
 const AVCodecTag ff_nut_data_tags[] = {
-    { AV_CODEC_ID_TEXT        , MKTAG('U', 'T', 'F', '8') },
-    { AV_CODEC_ID_NONE        , 0                         }
+    { AV_CODEC_ID_TEXT,             MKTAG('U', 'T', 'F', '8') },
+    { AV_CODEC_ID_NONE,             0 }
 };
 
 const AVCodecTag ff_nut_video_tags[] = {
-    { AV_CODEC_ID_VP9,      MKTAG('V', 'P', '9', '0') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 15 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 15 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(15 , 'B', 'G', 'R') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(15 , 'R', 'G', 'B') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 'B', 'G', 'R') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 'R', 'G', 'B') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 12 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 12 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 'B', 'G', 'R') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 'R', 'G', 'B') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 'A') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B',  0 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 'A') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R',  0 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'B', 'G', 'R') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG( 0 , 'B', 'G', 'R') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'R', 'G', 'B') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG( 0 , 'R', 'G', 'B') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 24 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 24 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '1', '1', 'P') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '2', '2', 'P') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '2', '2', 'P') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '0', 'P') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '0', 'P') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '4', 'P') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '4', 'P') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', '1', 'W', '0') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', '0', 'W', '1') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R',  8 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B',  8 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R',  4 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B',  4 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', '4', 'B', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', '4', 'B', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 48 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 48 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(48 , 'B', 'G', 'R') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(48 , 'R', 'G', 'B') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'R', 'A', 64 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'B', 'A', 64 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(64 , 'B', 'R', 'A') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(64 , 'R', 'B', 'A') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 10 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 11 , '3', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 10 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 10 , '3', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3',  0 , 10 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(10 ,  0 , '3', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 12 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 11 , '3', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 12 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 10 , '3', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3',  0 , 12 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(12 ,  0 , '3', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 14 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(14 , 11 , '3', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 14 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(14 , 10 , '3', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3',  0 , 14 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(14 ,  0 , '3', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1',  0 , 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 ,  0 , '1', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 11 , '3', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 10 , '3', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3',  0 , 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 ,  0 , '3', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11 ,  8 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10 ,  8 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4',  0 ,  8 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '2',  0 ,  8 ) },
+    { AV_CODEC_ID_VP9,              MKTAG('V', 'P', '9', '0') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', 'G', 'B', 15 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', 'G', 'R', 15 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', 'G', 'B', 16 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', 'G', 'R', 16 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(15 , 'B', 'G', 'R') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(15 , 'R', 'G', 'B') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16 , 'B', 'G', 'R') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16 , 'R', 'G', 'B') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', 'G', 'B', 12 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', 'G', 'R', 12 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(12 , 'B', 'G', 'R') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(12 , 'R', 'G', 'B') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', 'G', 'B', 'A') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', 'G', 'B',  0 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', 'G', 'R', 'A') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', 'G', 'R',  0 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('A', 'B', 'G', 'R') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG( 0 , 'B', 'G', 'R') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('A', 'R', 'G', 'B') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG( 0 , 'R', 'G', 'B') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', 'G', 'B', 24 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', 'G', 'R', 24 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('4', '1', '1', 'P') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('4', '2', '2', 'P') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('4', '2', '2', 'P') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('4', '4', '0', 'P') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('4', '4', '0', 'P') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('4', '4', '4', 'P') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('4', '4', '4', 'P') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', '1', 'W', '0') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', '0', 'W', '1') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', 'G', 'R',  8 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', 'G', 'B',  8 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', 'G', 'R',  4 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', 'G', 'B',  4 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', '4', 'B', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', '4', 'B', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', 'G', 'R', 48 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', 'G', 'B', 48 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(48 , 'B', 'G', 'R') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(48 , 'R', 'G', 'B') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', 'R', 'A', 64 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', 'B', 'A', 64 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(64 , 'B', 'R', 'A') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(64 , 'R', 'B', 'A') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '3', 11 , 10 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(10 , 11 , '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '3', 10 , 10 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(10 , 10 , '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '3',  0 , 10 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(10 ,  0 , '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '3', 11 , 12 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(12 , 11 , '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '3', 10 , 12 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(12 , 10 , '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '3',  0 , 12 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(12 ,  0 , '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '3', 11 , 14 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(14 , 11 , '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '3', 10 , 14 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(14 , 10 , '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '3',  0 , 14 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(14 ,  0 , '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '1',  0 , 16 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16 ,  0 , '1', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '3', 11 , 16 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16 , 11 , '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '3', 10 , 16 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16 , 10 , '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '3',  0 , 16 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16 ,  0 , '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4', 11 ,  8 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4', 10 ,  8 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',  0 ,  8 ) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '2',  0 ,  8 ) },
 
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1',  0 ,  9 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG( 9 ,  0 , '1', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11 ,  9 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG( 9 , 11 , '4', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10 ,  9 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG( 9 , 10 , '4', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4',  0 ,  9 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG( 9 ,  0 , '4', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '1',   0,   9) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(9,     0, '1', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',  11,   9) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(9,    11, '4', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',  10,   9) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(9,    10, '4', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',   0,   9) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(9,     0, '4', 'Y') },
 
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1',  0 , 10 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(10 ,  0 , '1', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11 , 10 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 11 , '4', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10 , 10 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 10 , '4', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4',  0 , 10 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(10 ,  0 , '4', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '1',   0,  10) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(10,    0, '1', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',  11,  10) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(10,   11, '4', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',  10,  10) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(10,   10, '4', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',   0,  10) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(10,    0, '4', 'Y') },
 
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1',  0 , 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 ,  0 , '1', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11 , 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 11 , '4', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10 , 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 10 , '4', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4',  0 , 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 ,  0 , '4', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '1',   0,  16) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16,    0, '1', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',  11,  16) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16,   11, '4', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',  10,  16) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16,   10, '4', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',   0,  16) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16,    0, '4', 'Y') },
 
-    { AV_CODEC_ID_NONE    , 0                         }
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('G', '3',   0,   8) },
+
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('G', '3',   0,   9) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG( 9,    0, '3', 'G') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('G', '3',   0,  10) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(10,    0, '3', 'G') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('G', '3',   0,  12) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(12,    0, '3', 'G') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('G', '3',   0,  14) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(14,    0, '3', 'G') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('G', '3',   0,  16) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16,    0, '3', 'G') },
+
+    { AV_CODEC_ID_NONE,             0 }
 };
 
 static const AVCodecTag nut_audio_extra_tags[] = {
@@ -186,42 +199,46 @@
     ff_codec_bmp_tags, ff_codec_wav_tags, nut_audio_extra_tags, ff_nut_data_tags, 0
 };
 
-void ff_nut_reset_ts(NUTContext *nut, AVRational time_base, int64_t val){
+void ff_nut_reset_ts(NUTContext *nut, AVRational time_base, int64_t val)
+{
     int i;
-    for(i=0; i<nut->avf->nb_streams; i++){
-        nut->stream[i].last_pts= av_rescale_rnd(
-            val,
-            time_base.num * (int64_t)nut->stream[i].time_base->den,
-            time_base.den * (int64_t)nut->stream[i].time_base->num,
-            AV_ROUND_DOWN);
-    }
+    for (i = 0; i < nut->avf->nb_streams; i++)
+        nut->stream[i].last_pts =
+            av_rescale_rnd(val,
+                           time_base.num * (int64_t)nut->stream[i].time_base->den,
+                           time_base.den * (int64_t)nut->stream[i].time_base->num,
+                           AV_ROUND_DOWN);
 }
 
-int64_t ff_lsb2full(StreamContext *stream, int64_t lsb){
-    int64_t mask = (1ULL<<stream->msb_pts_shift)-1;
-    int64_t delta= stream->last_pts - mask/2;
-    return  ((lsb - delta)&mask) + delta;
+int64_t ff_lsb2full(StreamContext *stream, int64_t lsb)
+{
+    int64_t mask  = (1ULL << stream->msb_pts_shift) - 1;
+    int64_t delta = stream->last_pts - mask / 2;
+    return ((lsb - delta) & mask) + delta;
 }
 
-int ff_nut_sp_pos_cmp(const Syncpoint *a, const Syncpoint *b){
+int ff_nut_sp_pos_cmp(const Syncpoint *a, const Syncpoint *b)
+{
     return ((a->pos - b->pos) >> 32) - ((b->pos - a->pos) >> 32);
 }
 
-int ff_nut_sp_pts_cmp(const Syncpoint *a, const Syncpoint *b){
+int ff_nut_sp_pts_cmp(const Syncpoint *a, const Syncpoint *b)
+{
     return ((a->ts - b->ts) >> 32) - ((b->ts - a->ts) >> 32);
 }
 
-void ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts){
-    Syncpoint *sp= av_mallocz(sizeof(Syncpoint));
+void ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts)
+{
+    Syncpoint *sp           = av_mallocz(sizeof(Syncpoint));
     struct AVTreeNode *node = av_tree_node_alloc();
 
     nut->sp_count++;
 
-    sp->pos= pos;
-    sp->back_ptr= back_ptr;
-    sp->ts= ts;
+    sp->pos      = pos;
+    sp->back_ptr = back_ptr;
+    sp->ts       = ts;
     av_tree_insert(&nut->syncpoints, sp, (void *) ff_nut_sp_pos_cmp, &node);
-    if(node){
+    if (node) {
         av_free(sp);
         av_free(node);
     }
@@ -240,13 +257,13 @@
 }
 
 const Dispositions ff_nut_dispositions[] = {
-    {"default"     , AV_DISPOSITION_DEFAULT},
-    {"dub"         , AV_DISPOSITION_DUB},
-    {"original"    , AV_DISPOSITION_ORIGINAL},
-    {"comment"     , AV_DISPOSITION_COMMENT},
-    {"lyrics"      , AV_DISPOSITION_LYRICS},
-    {"karaoke"     , AV_DISPOSITION_KARAOKE},
-    {""            , 0}
+    { "default",        AV_DISPOSITION_DEFAULT  },
+    { "dub",            AV_DISPOSITION_DUB      },
+    { "original",       AV_DISPOSITION_ORIGINAL },
+    { "comment",        AV_DISPOSITION_COMMENT  },
+    { "lyrics",         AV_DISPOSITION_LYRICS   },
+    { "karaoke",        AV_DISPOSITION_KARAOKE  },
+    { "",               0                       }
 };
 
 const AVMetadataConv ff_nut_metadata_conv[] = {
diff --git a/libavformat/nut.h b/libavformat/nut.h
index ab31c27..dc5af15 100644
--- a/libavformat/nut.h
+++ b/libavformat/nut.h
@@ -22,9 +22,6 @@
 #ifndef AVFORMAT_NUT_H
 #define AVFORMAT_NUT_H
 
-//#include <limits.h>
-//#include "libavutil/adler32.h"
-//#include "libavcodec/mpegaudio.h"
 #include "avformat.h"
 #include "internal.h"
 #include "metadata.h"
@@ -39,6 +36,8 @@
 
 #define MAX_DISTANCE (1024*32-1)
 
+#define NUT_VERSION 3
+
 typedef enum{
     FLAG_KEY        =   1, ///<if set, frame is keyframe
     FLAG_EOR        =   2, ///<if set, stream has no relevance on presentation. (EOR)
diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c
index 8896518..13048fb 100644
--- a/libavformat/nutdec.c
+++ b/libavformat/nutdec.c
@@ -196,7 +196,7 @@
         tmp = ffio_read_varlen(bc);                                           \
         if (!(check)) {                                                       \
             av_log(s, AV_LOG_ERROR, "Error " #dst " is (%"PRId64")\n", tmp);  \
-            return -1;                                                        \
+            return AVERROR_INVALIDDATA;                                       \
         }                                                                     \
         dst = tmp;                                                            \
     } while (0)
@@ -206,7 +206,7 @@
     pos -= avio_tell(bc);
     if (pos < 0) {
         avio_seek(bc, pos, SEEK_CUR);
-        return -1;
+        return AVERROR_INVALIDDATA;
     } else {
         while (pos--)
             avio_r8(bc);
@@ -226,7 +226,13 @@
     end  = get_packetheader(nut, bc, 1, MAIN_STARTCODE);
     end += avio_tell(bc);
 
-    GET_V(tmp, tmp >= 2 && tmp <= 3);
+    tmp = ffio_read_varlen(bc);
+    if (tmp < 2 && tmp > NUT_VERSION) {
+        av_log(s, AV_LOG_ERROR, "Version %"PRId64" not supported.\n",
+               tmp);
+        return AVERROR(ENOSYS);
+    }
+
     GET_V(stream_count, tmp > 0 && tmp <= NUT_MAX_STREAMS);
 
     nut->max_distance = ffio_read_varlen(bc);
@@ -389,7 +395,7 @@
         break;
     default:
         av_log(s, AV_LOG_ERROR, "unknown stream class (%d)\n", class);
-        return -1;
+        return AVERROR(ENOSYS);
     }
     if (class < 3 && st->codec->codec_id == AV_CODEC_ID_NONE)
         av_log(s, AV_LOG_ERROR,
@@ -418,7 +424,7 @@
         if ((!st->sample_aspect_ratio.num) != (!st->sample_aspect_ratio.den)) {
             av_log(s, AV_LOG_ERROR, "invalid aspect ratio %d/%d\n",
                    st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         ffio_read_varlen(bc); /* csp type */
     } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
@@ -429,7 +435,7 @@
     if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
         av_log(s, AV_LOG_ERROR,
                "stream header %d checksum mismatch\n", stream_id);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     stc->time_base = &nut->time_base[stc->time_base_id];
     avpriv_set_pts_info(s->streams[stream_id], 63, stc->time_base->num,
@@ -537,7 +543,7 @@
 
     if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
         av_log(s, AV_LOG_ERROR, "info header checksum mismatch\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     return 0;
 }
@@ -580,14 +586,8 @@
     AVFormatContext *s = nut->avf;
     int64_t duration = 0;
 
-    int64_t pos = FFMAX(0, filesize - 2*nut->max_distance);
-    for(;;){
-        int64_t ts = nut_read_timestamp(s, -1, &pos, INT64_MAX);
-        if(ts < 0)
-            break;
-        duration = FFMAX(duration, ts);
-        pos++;
-    }
+    ff_find_last_ts(s, -1, &duration, NULL, nut_read_timestamp);
+
     if(duration > 0)
         s->duration_estimation_method = AVFMT_DURATION_FROM_PTS;
     return duration;
@@ -601,8 +601,9 @@
     int i, j, syncpoint_count;
     int64_t filesize = avio_size(bc);
     int64_t *syncpoints;
+    uint64_t max_pts;
     int8_t *has_keyframe;
-    int ret = -1;
+    int ret = AVERROR_INVALIDDATA;
 
     if(filesize <= 0)
         return -1;
@@ -614,13 +615,18 @@
 
         if(s->duration<=0)
             s->duration = find_duration(nut, filesize);
-        return -1;
+        return ret;
     }
 
     end  = get_packetheader(nut, bc, 1, INDEX_STARTCODE);
     end += avio_tell(bc);
 
-    ffio_read_varlen(bc); // max_pts
+    max_pts = ffio_read_varlen(bc);
+    s->duration = av_rescale_q(max_pts / nut->time_base_count,
+                               nut->time_base[max_pts % nut->time_base_count],
+                               AV_TIME_BASE_Q);
+    s->duration_estimation_method = AVFMT_DURATION_FROM_PTS;
+
     GET_V(syncpoint_count, tmp < INT_MAX / 8 && tmp > 0);
     syncpoints   = av_malloc(sizeof(int64_t) *  syncpoint_count);
     has_keyframe = av_malloc(sizeof(int8_t)  * (syncpoint_count + 1));
@@ -891,7 +897,7 @@
         } else {
             frame_code = avio_r8(bc);
             if (url_feof(bc))
-                return -1;
+                return AVERROR_EOF;
             if (frame_code == 'N') {
                 tmp = frame_code;
                 for (i = 1; i < 8; i++)
diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c
index 2d8d265..9b7f41a 100644
--- a/libavformat/nutenc.c
+++ b/libavformat/nutenc.c
@@ -91,7 +91,7 @@
         header |= (bitrate_index & 1) << 9;
 
         return 2; //FIXME actually put the needed ones in build_elision_headers()
-        return 3; //we guess that the private bit is not set
+        //return 3; //we guess that the private bit is not set
 //FIXME the above assumptions should be checked, if these turn out false too often something should be done
     }
     return 0;
@@ -335,7 +335,7 @@
         tmp_head_idx;
     int64_t tmp_match;
 
-    ff_put_v(bc, 3); /* version */
+    ff_put_v(bc, NUT_VERSION);
     ff_put_v(bc, nut->avf->nb_streams);
     ff_put_v(bc, nut->max_distance);
     ff_put_v(bc, nut->time_base_count);
diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index fd954b8..03a2618 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -671,7 +671,12 @@
             av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
             ogg->streams[i].codec = NULL;
         } else if (os->codec && os->nb_header < os->codec->nb_header) {
-            av_log(s, AV_LOG_WARNING, "Number of headers (%d) mismatch for stream %d\n", os->nb_header, i);
+            av_log(s, AV_LOG_WARNING,
+                   "Headers mismatch for stream %d: "
+                   "expected %d received %d.\n",
+                   i, os->codec->nb_header, os->nb_header);
+            if (s->error_recognition & AV_EF_EXPLODE)
+                return AVERROR_INVALIDDATA;
         }
         if (os->start_granule != OGG_NOGRANULE_VALUE)
             os->lastpts = s->streams[i]->start_time =
@@ -854,5 +859,5 @@
     .read_seek      = ogg_read_seek,
     .read_timestamp = ogg_read_timestamp,
     .extensions     = "ogg",
-    .flags          = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT,
+    .flags          = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT | AVFMT_NOBINSEARCH,
 };
diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c
index 9a815d1..3135de6 100644
--- a/libavformat/oggenc.c
+++ b/libavformat/oggenc.c
@@ -447,11 +447,13 @@
             } while (j < i);
         oggstream->serial_num = serial_num;
 
+        av_dict_copy(&st->metadata, s->metadata, AV_DICT_DONT_OVERWRITE);
+
         st->priv_data = oggstream;
         if (st->codec->codec_id == AV_CODEC_ID_FLAC) {
             int err = ogg_build_flac_headers(st->codec, oggstream,
                                              st->codec->flags & CODEC_FLAG_BITEXACT,
-                                             &s->metadata);
+                                             &st->metadata);
             if (err) {
                 av_log(s, AV_LOG_ERROR, "Error writing FLAC headers\n");
                 av_freep(&st->priv_data);
@@ -460,7 +462,7 @@
         } else if (st->codec->codec_id == AV_CODEC_ID_SPEEX) {
             int err = ogg_build_speex_headers(st->codec, oggstream,
                                               st->codec->flags & CODEC_FLAG_BITEXACT,
-                                              &s->metadata);
+                                              &st->metadata);
             if (err) {
                 av_log(s, AV_LOG_ERROR, "Error writing Speex headers\n");
                 av_freep(&st->priv_data);
@@ -469,7 +471,7 @@
         } else if (st->codec->codec_id == AV_CODEC_ID_OPUS) {
             int err = ogg_build_opus_headers(st->codec, oggstream,
                                              st->codec->flags & CODEC_FLAG_BITEXACT,
-                                             &s->metadata);
+                                             &st->metadata);
             if (err) {
                 av_log(s, AV_LOG_ERROR, "Error writing Opus headers\n");
                 av_freep(&st->priv_data);
@@ -490,7 +492,7 @@
             }
 
             p = ogg_write_vorbiscomment(7, st->codec->flags & CODEC_FLAG_BITEXACT,
-                                        &oggstream->header_len[1], &s->metadata,
+                                        &oggstream->header_len[1], &st->metadata,
                                         framing_bit);
             oggstream->header[1] = p;
             if (!p)
@@ -632,5 +634,6 @@
     .write_header      = ogg_write_header,
     .write_packet      = ogg_write_packet,
     .write_trailer     = ogg_write_trailer,
+    .flags             = AVFMT_TS_NEGATIVE,
     .priv_class        = &ogg_muxer_class,
 };
diff --git a/libavformat/oggparseskeleton.c b/libavformat/oggparseskeleton.c
index 307387d..d94b0c2 100644
--- a/libavformat/oggparseskeleton.c
+++ b/libavformat/oggparseskeleton.c
@@ -37,6 +37,9 @@
     strcpy(st->codec->codec_name, "skeleton");
     st->codec->codec_type = AVMEDIA_TYPE_DATA;
 
+    if ((os->flags & OGG_FLAG_EOS) && os->psize == 0)
+        return 1;
+
     if (os->psize < 8)
         return -1;
 
@@ -74,12 +77,16 @@
 
         target_idx = ogg_find_stream(ogg, AV_RL32(buf+12));
         start_granule = AV_RL64(buf+36);
-        if (os->start_granule != OGG_NOGRANULE_VALUE) {
-            avpriv_report_missing_feature(s,
-                                          "Multiple fisbone for the same stream");
+        if (target_idx < 0) {
+            av_log(s, AV_LOG_WARNING, "Serial number in fisbone doesn't match any stream\n");
             return 1;
         }
-        if (target_idx >= 0 && start_granule != OGG_NOGRANULE_VALUE) {
+        os = ogg->streams + target_idx;
+        if (os->start_granule != OGG_NOGRANULE_VALUE) {
+            av_log(s, AV_LOG_WARNING, "Multiple fisbone for the same stream\n");
+            return 1;
+        }
+        if (start_granule != OGG_NOGRANULE_VALUE) {
             os->start_granule = start_granule;
         }
     }
diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c
index da029a4..7d525f4 100644
--- a/libavformat/oggparsevorbis.c
+++ b/libavformat/oggparsevorbis.c
@@ -24,12 +24,14 @@
 
 #include <stdlib.h>
 #include "libavutil/avstring.h"
+#include "libavutil/base64.h"
 #include "libavutil/bswap.h"
 #include "libavutil/dict.h"
 #include "libavcodec/get_bits.h"
 #include "libavcodec/bytestream.h"
 #include "libavcodec/vorbis_parser.h"
 #include "avformat.h"
+#include "flacdec.h"
 #include "internal.h"
 #include "oggdec.h"
 #include "vorbiscomment.h"
@@ -39,10 +41,10 @@
     int i, cnum, h, m, s, ms, keylen = strlen(key);
     AVChapter *chapter = NULL;
 
-    if (keylen < 9 || sscanf(key, "CHAPTER%02d", &cnum) != 1)
+    if (keylen < 9 || sscanf(key, "CHAPTER%03d", &cnum) != 1)
         return 0;
 
-    if (keylen == 9) {
+    if (keylen <= 10) {
         if (sscanf(val, "%02d:%02d:%02d.%03d", &h, &m, &s, &ms) < 4)
             return 0;
 
@@ -50,7 +52,7 @@
                        ms + 1000*(s + 60*(m + 60*h)),
                        AV_NOPTS_VALUE, NULL);
         av_free(val);
-    } else if (!strcmp(key+9, "NAME")) {
+    } else if (!strcmp(key+(keylen-4), "NAME")) {
         for(i = 0; i < as->nb_chapters; i++)
             if (as->chapters[i]->id == cnum) {
                 chapter = as->chapters[i];
@@ -128,7 +130,26 @@
             memcpy(ct, v, vl);
             ct[vl] = 0;
 
-            if (!ogm_chapter(as, tt, ct))
+            if (!strcmp(tt, "METADATA_BLOCK_PICTURE")) {
+                int ret;
+                char *pict = av_malloc(vl);
+
+                if (!pict) {
+                    av_log(as, AV_LOG_WARNING, "out-of-memory error. Skipping cover art block.\n");
+                    av_freep(&tt);
+                    av_freep(&ct);
+                    continue;
+                }
+                if ((ret = av_base64_decode(pict, ct, vl)) > 0)
+                    ret = ff_flac_parse_picture(as, pict, ret);
+                av_freep(&pict);
+                av_freep(&tt);
+                av_freep(&ct);
+                if (ret < 0) {
+                    av_log(as, AV_LOG_WARNING, "Failed to parse cover art block.\n");
+                    continue;
+                }
+            } else if (!ogm_chapter(as, tt, ct))
                 av_dict_set(m, tt, ct,
                                    AV_DICT_DONT_STRDUP_KEY |
                                    AV_DICT_DONT_STRDUP_VAL);
@@ -216,15 +237,15 @@
     struct oggvorbis_private *priv;
     int pkt_type = os->buf[os->pstart];
 
-    if (!(pkt_type & 1))
-        return os->private ? 0 : -1;
-
     if (!os->private) {
         os->private = av_mallocz(sizeof(struct oggvorbis_private));
         if (!os->private)
             return -1;
     }
 
+    if (!(pkt_type & 1))
+        return 0;
+
     if (os->psize < 1 || pkt_type > 5)
         return -1;
 
diff --git a/libavformat/omadec.c b/libavformat/omadec.c
index ae35907..d057954 100644
--- a/libavformat/omadec.c
+++ b/libavformat/omadec.c
@@ -73,18 +73,20 @@
     struct AVDES av_des;
 } OMAContext;
 
-static void hex_log(AVFormatContext *s, int level, const char *name, const uint8_t *value, int len)
+static void hex_log(AVFormatContext *s, int level,
+                    const char *name, const uint8_t *value, int len)
 {
     char buf[33];
     len = FFMIN(len, 16);
     if (av_log_get_level() < level)
         return;
     ff_data_to_hex(buf, value, len, 1);
-    buf[len<<1] = '\0';
+    buf[len << 1] = '\0';
     av_log(s, level, "%s: %s\n", name, buf);
 }
 
-static int kset(AVFormatContext *s, const uint8_t *r_val, const uint8_t *n_val, int len)
+static int kset(AVFormatContext *s, const uint8_t *r_val, const uint8_t *n_val,
+                int len)
 {
     OMAContext *oc = s->priv_data;
 
@@ -112,13 +114,18 @@
     return 0;
 }
 
-static int rprobe(AVFormatContext *s, uint8_t *enc_header, const uint8_t *r_val)
+#define OMA_RPROBE_M_VAL 48 + 1
+
+static int rprobe(AVFormatContext *s, uint8_t *enc_header, unsigned size,
+                  const uint8_t *r_val)
 {
     OMAContext *oc = s->priv_data;
     unsigned int pos;
     struct AVDES av_des;
 
-    if (!enc_header || !r_val)
+    if (!enc_header || !r_val ||
+        size < OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size ||
+        size < OMA_RPROBE_M_VAL)
         return -1;
 
     /* m_val */
@@ -139,35 +146,41 @@
     return memcmp(&enc_header[pos], oc->sm_val, 8) ? -1 : 0;
 }
 
-static int nprobe(AVFormatContext *s, uint8_t *enc_header, int size, const uint8_t *n_val)
+static int nprobe(AVFormatContext *s, uint8_t *enc_header, unsigned size,
+                  const uint8_t *n_val)
 {
     OMAContext *oc = s->priv_data;
-    uint32_t pos, taglen, datalen;
+    uint64_t pos;
+    uint32_t taglen, datalen;
     struct AVDES av_des;
 
-    if (!enc_header || !n_val)
+    if (!enc_header || !n_val ||
+        size < OMA_ENC_HEADER_SIZE + oc->k_size + 4)
         return -1;
 
     pos = OMA_ENC_HEADER_SIZE + oc->k_size;
     if (!memcmp(&enc_header[pos], "EKB ", 4))
         pos += 32;
 
+    if (size < pos + 44)
+        return -1;
+
     if (AV_RB32(&enc_header[pos]) != oc->rid)
         av_log(s, AV_LOG_DEBUG, "Mismatching RID\n");
 
-    taglen = AV_RB32(&enc_header[pos+32]);
-    datalen = AV_RB32(&enc_header[pos+36]) >> 4;
-
-    if(pos + (uint64_t)taglen + (((uint64_t)datalen)<<4) + 44 > size)
-        return -1;
+    taglen  = AV_RB32(&enc_header[pos + 32]);
+    datalen = AV_RB32(&enc_header[pos + 36]) >> 4;
 
     pos += 44 + taglen;
 
+    if (pos + (((uint64_t)datalen) << 4) > size)
+        return -1;
+
     av_des_init(&av_des, n_val, 192, 1);
     while (datalen-- > 0) {
         av_des_crypt(&av_des, oc->r_val, &enc_header[pos], 2, NULL, 1);
         kset(s, oc->r_val, NULL, 16);
-        if (!rprobe(s, enc_header, oc->r_val))
+        if (!rprobe(s, enc_header, size, oc->r_val))
             return 0;
         pos += 16;
     }
@@ -196,12 +209,13 @@
     }
     if (!em) {
         av_log(s, AV_LOG_ERROR, "No encryption header found\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (geob->datasize < 64) {
-        av_log(s, AV_LOG_ERROR, "Invalid GEOB data size: %u\n", geob->datasize);
-        return -1;
+        av_log(s, AV_LOG_ERROR,
+               "Invalid GEOB data size: %u\n", geob->datasize);
+        return AVERROR_INVALIDDATA;
     }
 
     gdata = geob->data;
@@ -216,7 +230,7 @@
 
     if (memcmp(&gdata[OMA_ENC_HEADER_SIZE], "KEYRING     ", 12)) {
         av_log(s, AV_LOG_ERROR, "Invalid encryption header\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (   OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size + 8 > geob->datasize
         || OMA_ENC_HEADER_SIZE + 48 > geob->datasize
@@ -230,32 +244,36 @@
     memcpy(oc->iv, &header[0x58], 8);
     hex_log(s, AV_LOG_DEBUG, "IV", oc->iv, 8);
 
-    hex_log(s, AV_LOG_DEBUG, "CBC-MAC", &gdata[OMA_ENC_HEADER_SIZE+oc->k_size+oc->e_size+oc->i_size], 8);
+    hex_log(s, AV_LOG_DEBUG, "CBC-MAC",
+            &gdata[OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size],
+            8);
 
     if (s->keylen > 0) {
         kset(s, s->key, s->key, s->keylen);
     }
     if (!memcmp(oc->r_val, (const uint8_t[8]){0}, 8) ||
-        rprobe(s, gdata, oc->r_val) < 0 &&
+        rprobe(s, gdata, geob->datasize, oc->r_val) < 0 &&
         nprobe(s, gdata, geob->datasize, oc->n_val) < 0) {
         int i;
         for (i = 0; i < FF_ARRAY_ELEMS(leaf_table); i += 2) {
             uint8_t buf[16];
-            AV_WL64(buf, leaf_table[i]);
-            AV_WL64(&buf[8], leaf_table[i+1]);
+            AV_WL64(buf,     leaf_table[i]);
+            AV_WL64(&buf[8], leaf_table[i + 1]);
             kset(s, buf, buf, 16);
-            if (!rprobe(s, gdata, oc->r_val) || !nprobe(s, gdata, geob->datasize, oc->n_val))
+            if (!rprobe(s, gdata, geob->datasize, oc->r_val) ||
+                !nprobe(s, gdata, geob->datasize, oc->n_val))
                 break;
         }
         if (i >= FF_ARRAY_ELEMS(leaf_table)) {
             av_log(s, AV_LOG_ERROR, "Invalid key\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
 
     /* e_val */
     av_des_init(&oc->av_des, oc->m_val, 64, 0);
-    av_des_crypt(&oc->av_des, oc->e_val, &gdata[OMA_ENC_HEADER_SIZE + 40], 1, NULL, 0);
+    av_des_crypt(&oc->av_des, oc->e_val,
+                 &gdata[OMA_ENC_HEADER_SIZE + 40], 1, NULL, 0);
     hex_log(s, AV_LOG_DEBUG, "EK", oc->e_val, 8);
 
     /* init e_val */
@@ -280,9 +298,10 @@
     if (ret < EA3_HEADER_SIZE)
         return -1;
 
-    if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}),3) || buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) {
+    if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}), 3) ||
+        buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) {
         av_log(s, AV_LOG_ERROR, "Couldn't find the EA3 header !\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     oc->content_start = avio_tell(s->pb);
@@ -303,74 +322,80 @@
         return AVERROR(ENOMEM);
 
     st->start_time = 0;
-    st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
-    st->codec->codec_tag   = buf[32];
-    st->codec->codec_id    = ff_codec_get_id(ff_oma_codec_tags, st->codec->codec_tag);
+    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_tag  = buf[32];
+    st->codec->codec_id   = ff_codec_get_id(ff_oma_codec_tags,
+                                            st->codec->codec_tag);
 
     switch (buf[32]) {
-        case OMA_CODECID_ATRAC3:
-            samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
-            if (!samplerate) {
-                av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
-                return AVERROR_INVALIDDATA;
-            }
-            if (samplerate != 44100)
-                avpriv_request_sample(s, "Sample rate %d", samplerate);
+    case OMA_CODECID_ATRAC3:
+        samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
+        if (!samplerate) {
+            av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
+            return AVERROR_INVALIDDATA;
+        }
+        if (samplerate != 44100)
+            avpriv_request_sample(s, "Sample rate %d", samplerate);
 
-            framesize = (codec_params & 0x3FF) * 8;
-            jsflag = (codec_params >> 17) & 1; /* get stereo coding mode, 1 for joint-stereo */
-            st->codec->channels    = 2;
-            st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
-            st->codec->sample_rate = samplerate;
-            st->codec->bit_rate    = st->codec->sample_rate * framesize * 8 / 1024;
+        framesize = (codec_params & 0x3FF) * 8;
 
-            /* fake the atrac3 extradata (wav format, makes stream copy to wav work) */
-            st->codec->extradata_size = 14;
-            edata = av_mallocz(14 + FF_INPUT_BUFFER_PADDING_SIZE);
-            if (!edata)
-                return AVERROR(ENOMEM);
+        /* get stereo coding mode, 1 for joint-stereo */
+        jsflag = (codec_params >> 17) & 1;
 
-            st->codec->extradata = edata;
-            AV_WL16(&edata[0],  1);             // always 1
-            AV_WL32(&edata[2],  samplerate);    // samples rate
-            AV_WL16(&edata[6],  jsflag);        // coding mode
-            AV_WL16(&edata[8],  jsflag);        // coding mode
-            AV_WL16(&edata[10], 1);             // always 1
-            // AV_WL16(&edata[12], 0);          // always 0
+        st->codec->channels    = 2;
+        st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
+        st->codec->sample_rate = samplerate;
+        st->codec->bit_rate    = st->codec->sample_rate * framesize * 8 / 1024;
 
-            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
-            break;
-        case OMA_CODECID_ATRAC3P:
-            st->codec->channels = (codec_params >> 10) & 7;
-            framesize = ((codec_params & 0x3FF) * 8) + 8;
-            samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
-            if (!samplerate) {
-                av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
-                return AVERROR_INVALIDDATA;
-            }
-            st->codec->sample_rate = samplerate;
-            st->codec->bit_rate    = samplerate * framesize * 8 / 1024;
-            avpriv_set_pts_info(st, 64, 1, samplerate);
-            av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n");
-            break;
-        case OMA_CODECID_MP3:
-            st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
-            framesize = 1024;
-            break;
-        case OMA_CODECID_LPCM:
-            /* PCM 44.1 kHz 16 bit stereo big-endian */
-            st->codec->channels = 2;
-            st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
-            st->codec->sample_rate = 44100;
-            framesize = 1024;
-            /* bit rate = sample rate x PCM block align (= 4) x 8 */
-            st->codec->bit_rate = st->codec->sample_rate * 32;
-            st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id);
-            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
-            break;
-        default:
-            av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n",buf[32]);
-            return -1;
+        /* fake the atrac3 extradata
+         * (wav format, makes stream copy to wav work) */
+        st->codec->extradata_size = 14;
+        edata = av_mallocz(14 + FF_INPUT_BUFFER_PADDING_SIZE);
+        if (!edata)
+            return AVERROR(ENOMEM);
+
+        st->codec->extradata = edata;
+        AV_WL16(&edata[0],  1);             // always 1
+        AV_WL32(&edata[2],  samplerate);    // samples rate
+        AV_WL16(&edata[6],  jsflag);        // coding mode
+        AV_WL16(&edata[8],  jsflag);        // coding mode
+        AV_WL16(&edata[10], 1);             // always 1
+        // AV_WL16(&edata[12], 0);          // always 0
+
+        avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+        break;
+    case OMA_CODECID_ATRAC3P:
+        st->codec->channels = (codec_params >> 10) & 7;
+        framesize = ((codec_params & 0x3FF) * 8) + 8;
+        samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
+        if (!samplerate) {
+            av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
+            return AVERROR_INVALIDDATA;
+        }
+        st->codec->sample_rate = samplerate;
+        st->codec->bit_rate    = samplerate * framesize * 8 / 1024;
+        avpriv_set_pts_info(st, 64, 1, samplerate);
+        av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n");
+        break;
+    case OMA_CODECID_MP3:
+        st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+        framesize = 1024;
+        break;
+    case OMA_CODECID_LPCM:
+        /* PCM 44.1 kHz 16 bit stereo big-endian */
+        st->codec->channels = 2;
+        st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
+        st->codec->sample_rate = 44100;
+        framesize = 1024;
+        /* bit rate = sample rate x PCM block align (= 4) x 8 */
+        st->codec->bit_rate = st->codec->sample_rate * 32;
+        st->codec->bits_per_coded_sample =
+            av_get_bits_per_sample(st->codec->codec_id);
+        avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+        break;
+    default:
+        av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n", buf[32]);
+        return AVERROR(ENOSYS);
     }
 
     st->codec->block_align = framesize;
@@ -385,14 +410,24 @@
     int packet_size = s->streams[0]->codec->block_align;
     int ret = av_get_packet(s->pb, pkt, packet_size);
 
-    if (ret <= 0)
-        return AVERROR(EIO);
+    if (ret < packet_size)
+        pkt->flags |= AV_PKT_FLAG_CORRUPT;
+
+    if (ret < 0)
+        return ret;
+    if (!ret)
+        return AVERROR_EOF;
 
     pkt->stream_index = 0;
 
     if (oc->encrypted) {
-        /* previous unencrypted block saved in IV for the next packet (CBC mode) */
-        av_des_crypt(&oc->av_des, pkt->data, pkt->data, (ret >> 3), oc->iv, 1);
+        /* previous unencrypted block saved in IV for
+         * the next packet (CBC mode) */
+        if (ret == packet_size)
+            av_des_crypt(&oc->av_des, pkt->data, pkt->data,
+                         (packet_size >> 3), oc->iv, 1);
+        else
+            memset(oc->iv, 0, 8);
     }
 
     return ret;
@@ -416,7 +451,7 @@
     /* This check cannot overflow as tag_len has at most 28 bits */
     if (p->buf_size < tag_len + 5)
         /* EA3 header comes late, might be outside of the probe buffer */
-        return AVPROBE_SCORE_MAX / 2;
+        return AVPROBE_SCORE_EXTENSION;
 
     buf += tag_len;
 
@@ -426,26 +461,30 @@
         return 0;
 }
 
-static int oma_read_seek(struct AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
+static int oma_read_seek(struct AVFormatContext *s,
+                         int stream_index, int64_t timestamp, int flags)
 {
     OMAContext *oc = s->priv_data;
+    int err = ff_pcm_read_seek(s, stream_index, timestamp, flags);
 
-    ff_pcm_read_seek(s, stream_index, timestamp, flags);
+    if (!oc->encrypted)
+        return err;
 
-    if (oc->encrypted) {
-        /* readjust IV for CBC */
-        int64_t pos = avio_tell(s->pb);
-        if (pos < oc->content_start)
-            memset(oc->iv, 0, 8);
-        else {
-            if (avio_seek(s->pb, -8, SEEK_CUR) < 0 || avio_read(s->pb, oc->iv, 8) < 8) {
-                memset(oc->iv, 0, 8);
-                return -1;
-            }
-        }
+    /* readjust IV for CBC */
+    if (err || avio_tell(s->pb) < oc->content_start)
+        goto wipe;
+    if ((err = avio_seek(s->pb, -8, SEEK_CUR)) < 0)
+        goto wipe;
+    if ((err = avio_read(s->pb, oc->iv, 8)) < 8) {
+        if (err >= 0)
+            err = AVERROR_EOF;
+        goto wipe;
     }
 
     return 0;
+wipe:
+    memset(oc->iv, 0, 8);
+    return err;
 }
 
 AVInputFormat ff_oma_demuxer = {
diff --git a/libavformat/options.c b/libavformat/options.c
index 42307d1..5218e5b 100644
--- a/libavformat/options.c
+++ b/libavformat/options.c
@@ -86,7 +86,7 @@
 static const AVClass av_format_context_class = {
     .class_name     = "AVFormatContext",
     .item_name      = format_to_name,
-    .option         = options,
+    .option         = avformat_options,
     .version        = LIBAVUTIL_VERSION_INT,
     .child_next     = format_child_next,
     .child_class_next = format_child_class_next,
diff --git a/libavformat/options_table.h b/libavformat/options_table.h
index 9f86137..a87868e 100644
--- a/libavformat/options_table.h
+++ b/libavformat/options_table.h
@@ -32,7 +32,7 @@
 #define E AV_OPT_FLAG_ENCODING_PARAM
 #define D AV_OPT_FLAG_DECODING_PARAM
 
-static const AVOption options[]={
+static const AVOption avformat_options[] = {
 {"avioflags", NULL, OFFSET(avio_flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, INT_MIN, INT_MAX, D|E, "avioflags"},
 {"direct", "reduce buffering", 0, AV_OPT_TYPE_CONST, {.i64 = AVIO_FLAG_DIRECT }, INT_MIN, INT_MAX, D|E, "avioflags"},
 {"probesize", "set probing size", OFFSET(probesize), AV_OPT_TYPE_INT, {.i64 = 5000000 }, 32, INT_MAX, D},
@@ -45,7 +45,7 @@
 {"igndts", "ignore dts", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_IGNDTS }, INT_MIN, INT_MAX, D, "fflags"},
 {"discardcorrupt", "discard corrupted frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_DISCARD_CORRUPT }, INT_MIN, INT_MAX, D, "fflags"},
 {"sortdts", "try to interleave outputted packets by dts", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_SORT_DTS }, INT_MIN, INT_MAX, D, "fflags"},
-{"keepside", "dont merge side data", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_KEEP_SIDE_DATA }, INT_MIN, INT_MAX, D, "fflags"},
+{"keepside", "don't merge side data", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_KEEP_SIDE_DATA }, INT_MIN, INT_MAX, D, "fflags"},
 {"latm", "enable RTP MP4A-LATM payload", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_MP4A_LATM }, INT_MIN, INT_MAX, E, "fflags"},
 {"nobuffer", "reduce the latency introduced by optional buffering", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_NOBUFFER }, 0, INT_MAX, D, "fflags"},
 {"seek2any", "forces seeking to enable seek to any mode", OFFSET(seek2any), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, D},
@@ -70,9 +70,9 @@
 {"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_EXPLODE }, INT_MIN, INT_MAX, D, "err_detect"},
 {"careful",    "consider things that violate the spec and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CAREFUL }, INT_MIN, INT_MAX, D, "err_detect"},
 {"compliant",  "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_COMPLIANT }, INT_MIN, INT_MAX, D, "err_detect"},
-{"aggressive", "consider things that a sane encoder shouldnt do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE }, INT_MIN, INT_MAX, D, "err_detect"},
+{"aggressive", "consider things that a sane encoder shouldn't do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE }, INT_MIN, INT_MAX, D, "err_detect"},
 {"use_wallclock_as_timestamps", "use wallclock as timestamps", OFFSET(use_wallclock_as_timestamps), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX-1, D},
-{"avoid_negative_ts", "shift timestamps to make them positive. 1 enables, 0 disables, default of -1 enables when required by target format.", OFFSET(avoid_negative_ts), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, E},
+{"avoid_negative_ts", "shift timestamps to make them non-negative. 1 enables, 0 disables, default of -1 enables when required by target format.", OFFSET(avoid_negative_ts), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, E},
 {"skip_initial_bytes", "skip initial bytes", OFFSET(skip_initial_bytes), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX-1, D},
 {"correct_ts_overflow", "correct single timestamp overflows", OFFSET(correct_ts_overflow), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, D},
 {"flush_packets", "enable flushing of the I/O context after each packet", OFFSET(flush_packets), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E},
diff --git a/libavformat/os_support.c b/libavformat/os_support.c
index dc88834..3218956 100644
--- a/libavformat/os_support.c
+++ b/libavformat/os_support.c
@@ -27,46 +27,6 @@
 #include "avformat.h"
 #include "os_support.h"
 
-#if defined(_WIN32) && !defined(__MINGW32CE__)
-#undef open
-#undef lseek
-#undef stat
-#undef fstat
-#include <fcntl.h>
-#include <io.h>
-#include <windows.h>
-#include <share.h>
-#include <errno.h>
-
-int ff_win32_open(const char *filename_utf8, int oflag, int pmode)
-{
-    int fd;
-    int num_chars;
-    wchar_t *filename_w;
-
-    /* convert UTF-8 to wide chars */
-    num_chars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filename_utf8, -1, NULL, 0);
-    if (num_chars <= 0)
-        goto fallback;
-    filename_w = av_mallocz(sizeof(wchar_t) * num_chars);
-    if (!filename_w) {
-        errno = ENOMEM;
-        return -1;
-    }
-    MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, filename_w, num_chars);
-
-    fd = _wsopen(filename_w, oflag, SH_DENYNO, pmode);
-    av_freep(&filename_w);
-
-    if (fd != -1 || (oflag & O_CREAT))
-        return fd;
-
-fallback:
-    /* filename may be be in CP_ACP */
-    return _sopen(filename_utf8, oflag, SH_DENYNO, pmode);
-}
-#endif
-
 #if CONFIG_NETWORK
 #include <fcntl.h>
 #if !HAVE_POLL_H
diff --git a/libavformat/os_support.h b/libavformat/os_support.h
index e5f31e0..b0f02c1 100644
--- a/libavformat/os_support.h
+++ b/libavformat/os_support.h
@@ -86,11 +86,6 @@
 #endif
 #endif
 
-#if defined(_WIN32) && !defined(__MINGW32CE__)
-int ff_win32_open(const char *filename, int oflag, int pmode);
-#define open ff_win32_open
-#endif
-
 #if CONFIG_NETWORK
 #if !HAVE_SOCKLEN_T
 typedef int socklen_t;
diff --git a/libavformat/paf.c b/libavformat/paf.c
index 09786eb..09aefe6 100644
--- a/libavformat/paf.c
+++ b/libavformat/paf.c
@@ -233,10 +233,11 @@
         p->current_frame_block++;
     }
 
-    size = p->video_size - p->frames_offset_table[p->current_frame];
-    if (size < 1)
+    if (p->frames_offset_table[p->current_frame] >= p->video_size)
         return AVERROR_INVALIDDATA;
 
+    size = p->video_size - p->frames_offset_table[p->current_frame];
+
     if (av_new_packet(pkt, size) < 0)
         return AVERROR(ENOMEM);
 
diff --git a/libavformat/pmpdec.c b/libavformat/pmpdec.c
index 2fe6c46..71f450e 100644
--- a/libavformat/pmpdec.c
+++ b/libavformat/pmpdec.c
@@ -174,7 +174,7 @@
 {
     PMPContext *pmp = s->priv_data;
     pmp->cur_stream = 0;
-    // fallback to default seek now
+    // fall back on default seek now
     return -1;
 }
 
diff --git a/libavformat/psxstr.c b/libavformat/psxstr.c
index 90c933e..3409d6a 100644
--- a/libavformat/psxstr.c
+++ b/libavformat/psxstr.c
@@ -30,6 +30,7 @@
  */
 
 #include "libavutil/channel_layout.h"
+#include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "avformat.h"
 #include "internal.h"
@@ -126,7 +127,7 @@
     }
     /* MPEG files (like those ripped from VCDs) can also look like this;
      * only return half certainty */
-    if(vid+aud > 3)  return 50;
+    if(vid+aud > 3)  return AVPROBE_SCORE_EXTENSION;
     else if(vid+aud) return 1;
     else             return 0;
 }
@@ -237,7 +238,9 @@
                     pkt->size= -1;
                     pkt->buf = NULL;
 #if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
                     pkt->destruct = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
                     return 0;
                 }
diff --git a/libavformat/pva.c b/libavformat/pva.c
index ae42c83..9b7a40a 100644
--- a/libavformat/pva.c
+++ b/libavformat/pva.c
@@ -49,7 +49,7 @@
 
     if (pd->buf_size >= len + 8 &&
         pva_check(buf + len) >= 0)
-        return AVPROBE_SCORE_MAX / 2;
+        return AVPROBE_SCORE_EXTENSION;
 
     return AVPROBE_SCORE_MAX / 4;
 }
diff --git a/libavformat/r3d.c b/libavformat/r3d.c
index 3b3ecce..8459cdd 100644
--- a/libavformat/r3d.c
+++ b/libavformat/r3d.c
@@ -19,8 +19,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-//#define DEBUG
-
 #include "libavutil/intreadwrite.h"
 #include "libavutil/dict.h"
 #include "libavutil/mathematics.h"
diff --git a/libavformat/rawdec.c b/libavformat/rawdec.c
index 153cc7b..a9ff22a 100644
--- a/libavformat/rawdec.c
+++ b/libavformat/rawdec.c
@@ -90,6 +90,17 @@
     return ret;
 }
 
+static int ff_raw_data_read_header(AVFormatContext *s)
+{
+    AVStream *st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+    st->codec->codec_type = AVMEDIA_TYPE_DATA;
+    st->codec->codec_id = s->iformat->raw_codec_id;
+    st->start_time = 0;
+    return 0;
+}
+
 /* Note: Do not forget to add new entries to the Makefile as well. */
 
 #define OFFSET(x) offsetof(FFRawVideoDemuxerContext, x)
@@ -99,6 +110,16 @@
     { NULL },
 };
 
+#if CONFIG_DATA_DEMUXER
+AVInputFormat ff_data_demuxer = {
+    .name           = "data",
+    .long_name      = NULL_IF_CONFIG_SMALL("raw data"),
+    .read_header    = ff_raw_data_read_header,
+    .read_packet    = ff_raw_read_partial_packet,
+    .raw_codec_id   = AV_CODEC_ID_NONE,
+};
+#endif
+
 #if CONFIG_LATM_DEMUXER
 AVInputFormat ff_latm_demuxer = {
     .name           = "latm",
diff --git a/libavformat/rawenc.c b/libavformat/rawenc.c
index 7894c8e..7a1fa93 100644
--- a/libavformat/rawenc.c
+++ b/libavformat/rawenc.c
@@ -68,6 +68,15 @@
 };
 #endif
 
+#if CONFIG_DATA_MUXER
+AVOutputFormat ff_data_muxer = {
+    .name              = "data",
+    .long_name         = NULL_IF_CONFIG_SMALL("raw data"),
+    .write_packet      = ff_raw_write_packet,
+    .flags             = AVFMT_NOTIMESTAMPS,
+};
+#endif
+
 #if CONFIG_DIRAC_MUXER
 AVOutputFormat ff_dirac_muxer = {
     .name              = "dirac",
diff --git a/libavformat/rdt.c b/libavformat/rdt.c
index 695323a..54111a5 100644
--- a/libavformat/rdt.c
+++ b/libavformat/rdt.c
@@ -98,7 +98,7 @@
     unsigned char zres[16],
         buf[64] = { 0xa1, 0xe9, 0x14, 0x9d, 0x0e, 0x6b, 0x3b, 0x59 };
 #define XOR_TABLE_SIZE 37
-    const unsigned char xor_table[XOR_TABLE_SIZE] = {
+    static const unsigned char xor_table[XOR_TABLE_SIZE] = {
         0x05, 0x18, 0x74, 0xd0, 0x0d, 0x09, 0x02, 0x53,
         0xc0, 0x01, 0x05, 0x05, 0x67, 0x03, 0x19, 0x70,
         0x08, 0x27, 0x66, 0x10, 0x10, 0x72, 0x08, 0x09,
@@ -548,7 +548,7 @@
 }
 
 #define RDT_HANDLER(n, s, t) \
-static RTPDynamicProtocolHandler ff_rdt_ ## n ## _handler = { \
+static RTPDynamicProtocolHandler rdt_ ## n ## _handler = { \
     .enc_name         = s, \
     .codec_type       = t, \
     .codec_id         = AV_CODEC_ID_NONE, \
@@ -565,8 +565,8 @@
 
 void av_register_rdt_dynamic_payload_handlers(void)
 {
-    ff_register_dynamic_payload_handler(&ff_rdt_video_handler);
-    ff_register_dynamic_payload_handler(&ff_rdt_audio_handler);
-    ff_register_dynamic_payload_handler(&ff_rdt_live_video_handler);
-    ff_register_dynamic_payload_handler(&ff_rdt_live_audio_handler);
+    ff_register_dynamic_payload_handler(&rdt_video_handler);
+    ff_register_dynamic_payload_handler(&rdt_audio_handler);
+    ff_register_dynamic_payload_handler(&rdt_live_video_handler);
+    ff_register_dynamic_payload_handler(&rdt_live_audio_handler);
 }
diff --git a/libavformat/realtextdec.c b/libavformat/realtextdec.c
index 67bc339..5e4981a 100644
--- a/libavformat/realtextdec.c
+++ b/libavformat/realtextdec.c
@@ -41,7 +41,7 @@
 
     if (AV_RB24(ptr) == 0xEFBBBF)
         ptr += 3;  /* skip UTF-8 BOM */
-    return !av_strncasecmp(ptr, "<window", 7) ? AVPROBE_SCORE_MAX/2 : 0;
+    return !av_strncasecmp(ptr, "<window", 7) ? AVPROBE_SCORE_EXTENSION : 0;
 }
 
 static int read_ts(const char *s)
diff --git a/libavformat/redspark.c b/libavformat/redspark.c
new file mode 100644
index 0000000..44d5da7
--- /dev/null
+++ b/libavformat/redspark.c
@@ -0,0 +1,167 @@
+/*
+ * RedSpark demuxer
+ * Copyright (c) 2013 James Almer
+ *
+ * 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
+ */
+
+#include "libavcodec/bytestream.h"
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+#include "avio.h"
+#include "internal.h"
+
+#define HEADER_SIZE 4096
+
+typedef struct RedSparkContext {
+    int         samples_count;
+} RedSparkContext;
+
+static int redspark_probe(AVProbeData *p)
+{
+    uint32_t key, data;
+    uint8_t header[8];
+
+    /* Decrypt first 8 bytes of the header */
+    data = AV_RB32(p->buf);
+    data = data ^ (key = data ^ 0x52656453);
+    AV_WB32(header, data);
+    key = (key << 11) | (key >> 21);
+
+    data = AV_RB32(p->buf + 4) ^ (((key << 3) | (key >> 29)) + key);
+    AV_WB32(header + 4, data);
+
+    if (AV_RB64(header) == AV_RB64("RedSpark"))
+        return AVPROBE_SCORE_MAX;
+
+    return 0;
+}
+
+static int redspark_read_header(AVFormatContext *s)
+{
+    AVIOContext *pb = s->pb;
+    RedSparkContext *redspark = s->priv_data;
+    AVCodecContext *codec;
+    GetByteContext gbc;
+    int i, coef_off, ret = 0;
+    uint32_t key, data;
+    uint8_t *header, *pbc;
+    AVStream *st;
+
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+    codec = st->codec;
+
+    header = av_malloc(HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!header)
+        return AVERROR(ENOMEM);
+    pbc = header;
+
+    /* Decrypt header */
+    data = avio_rb32(pb);
+    data = data ^ (key = data ^ 0x52656453);
+    bytestream_put_be32(&pbc, data);
+    key = (key << 11) | (key >> 21);
+
+    for (i = 4; i < HEADER_SIZE; i += 4) {
+        data = avio_rb32(pb) ^ (key = ((key << 3) | (key >> 29)) + key);
+        bytestream_put_be32(&pbc, data);
+    }
+
+    codec->codec_id    = AV_CODEC_ID_ADPCM_THP;
+    codec->codec_type  = AVMEDIA_TYPE_AUDIO;
+
+    bytestream2_init(&gbc, header, HEADER_SIZE);
+    bytestream2_seek(&gbc, 0x3c, SEEK_SET);
+    codec->sample_rate = bytestream2_get_be32u(&gbc);
+    if (codec->sample_rate <= 0 || codec->sample_rate > 96000) {
+        av_log(s, AV_LOG_ERROR, "Invalid sample rate: %d\n", codec->sample_rate);
+        ret = AVERROR_INVALIDDATA;
+        goto fail;
+    }
+
+    st->duration = bytestream2_get_be32u(&gbc) * 14;
+    redspark->samples_count = 0;
+    bytestream2_skipu(&gbc, 10);
+    codec->channels = bytestream2_get_byteu(&gbc);
+    if (!codec->channels) {
+        ret = AVERROR_INVALIDDATA;
+        goto fail;
+    }
+
+    coef_off = 0x54 + codec->channels * 8;
+    if (bytestream2_get_byteu(&gbc)) // Loop flag
+        coef_off += 16;
+
+    codec->extradata_size = 32 * codec->channels;
+    codec->extradata = av_malloc(codec->extradata_size);
+    if (!codec->extradata) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    /* Get the ADPCM table */
+    bytestream2_seek(&gbc, coef_off, SEEK_SET);
+    for (i = 0; i < codec->channels; i++) {
+        if (bytestream2_get_bufferu(&gbc, codec->extradata + i * 32, 32) != 32) {
+            ret = AVERROR_INVALIDDATA;
+            goto fail;
+        }
+        bytestream2_skipu(&gbc, 14);
+    }
+
+    avpriv_set_pts_info(st, 64, 1, codec->sample_rate);
+
+fail:
+    av_free(header);
+
+    return ret;
+}
+
+static int redspark_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    AVCodecContext *codec = s->streams[0]->codec;
+    RedSparkContext *redspark = s->priv_data;
+    uint32_t size = 8 * codec->channels;
+    int ret;
+
+    if (url_feof(s->pb) || redspark->samples_count == s->streams[0]->duration)
+        return AVERROR_EOF;
+
+    ret = av_get_packet(s->pb, pkt, size);
+    if (ret != size) {
+        av_free_packet(pkt);
+        return AVERROR(EIO);
+    }
+
+    pkt->duration = 14;
+    redspark->samples_count += pkt->duration;
+    pkt->stream_index = 0;
+
+    return ret;
+}
+
+AVInputFormat ff_redspark_demuxer = {
+    .name           =   "redspark",
+    .long_name      =   NULL_IF_CONFIG_SMALL("RedSpark"),
+    .priv_data_size =   sizeof(RedSparkContext),
+    .read_probe     =   redspark_probe,
+    .read_header    =   redspark_read_header,
+    .read_packet    =   redspark_read_packet,
+    .extensions     =   "rsd",
+};
diff --git a/libavformat/riff.c b/libavformat/riff.c
index 7ad96a8..38d12fd 100644
--- a/libavformat/riff.c
+++ b/libavformat/riff.c
@@ -19,13 +19,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/mathematics.h"
+#include "libavutil/error.h"
 #include "libavcodec/avcodec.h"
 #include "avformat.h"
-#include "avio_internal.h"
 #include "riff.h"
-#include "libavcodec/bytestream.h"
-#include "libavutil/avassert.h"
 
 /* Note: When encoding, the first matching tag is used, so order is
  * important if multiple tags are possible for a given codec.
@@ -87,6 +84,7 @@
     { AV_CODEC_ID_MPEG4,        MKTAG('G', 'E', 'O', 'X') },
     /* flipped video */
     { AV_CODEC_ID_MPEG4,        MKTAG('H', 'D', 'X', '4') },
+    { AV_CODEC_ID_MPEG4,        MKTAG('D', 'M', '4', 'V') },
     { AV_CODEC_ID_MPEG4,        MKTAG('D', 'M', 'K', '2') },
     { AV_CODEC_ID_MPEG4,        MKTAG('D', 'I', 'G', 'I') },
     { AV_CODEC_ID_MPEG4,        MKTAG('I', 'N', 'M', 'C') },
@@ -325,21 +323,20 @@
     { AV_CODEC_ID_DPX,          MKTAG('d', 'p', 'x', ' ') },
     { AV_CODEC_ID_KGV1,         MKTAG('K', 'G', 'V', '1') },
     { AV_CODEC_ID_LAGARITH,     MKTAG('L', 'A', 'G', 'S') },
-    { AV_CODEC_ID_G2M,          MKTAG('G', '2', 'M', '2') },
-    { AV_CODEC_ID_G2M,          MKTAG('G', '2', 'M', '3') },
-    { AV_CODEC_ID_G2M,          MKTAG('G', '2', 'M', '4') },
     { AV_CODEC_ID_AMV,          MKTAG('A', 'M', 'V', 'F') },
     { AV_CODEC_ID_UTVIDEO,      MKTAG('U', 'L', 'R', 'A') },
     { AV_CODEC_ID_UTVIDEO,      MKTAG('U', 'L', 'R', 'G') },
     { AV_CODEC_ID_UTVIDEO,      MKTAG('U', 'L', 'Y', '0') },
     { AV_CODEC_ID_UTVIDEO,      MKTAG('U', 'L', 'Y', '2') },
+    /* Ut Video version 13.0.1 BT.709 codecs */
+    { AV_CODEC_ID_UTVIDEO,      MKTAG('U', 'L', 'H', '0') },
+    { AV_CODEC_ID_UTVIDEO,      MKTAG('U', 'L', 'H', '2') },
     { AV_CODEC_ID_VBLE,         MKTAG('V', 'B', 'L', 'E') },
     { AV_CODEC_ID_ESCAPE130,    MKTAG('E', '1', '3', '0') },
     { AV_CODEC_ID_DXTORY,       MKTAG('x', 't', 'o', 'r') },
     { AV_CODEC_ID_ZEROCODEC,    MKTAG('Z', 'E', 'C', 'O') },
     { AV_CODEC_ID_Y41P,         MKTAG('Y', '4', '1', 'P') },
     { AV_CODEC_ID_FLIC,         MKTAG('A', 'F', 'L', 'C') },
-    { AV_CODEC_ID_EXR,          MKTAG('e', 'x', 'r', ' ') },
     { AV_CODEC_ID_MSS1,         MKTAG('M', 'S', 'S', '1') },
     { AV_CODEC_ID_MSA1,         MKTAG('M', 'S', 'A', '1') },
     { AV_CODEC_ID_TSCC2,        MKTAG('T', 'S', 'C', '2') },
@@ -349,6 +346,9 @@
     { AV_CODEC_ID_SVQ3,         MKTAG('S', 'V', 'Q', '3') },
     { AV_CODEC_ID_012V,         MKTAG('0', '1', '2', 'v') },
     { AV_CODEC_ID_012V,         MKTAG('a', '1', '2', 'v') },
+    { AV_CODEC_ID_G2M,          MKTAG('G', '2', 'M', '2') },
+    { AV_CODEC_ID_G2M,          MKTAG('G', '2', 'M', '3') },
+    { AV_CODEC_ID_G2M,          MKTAG('G', '2', 'M', '4') },
     { AV_CODEC_ID_NONE,         0 }
 };
 
@@ -373,6 +373,7 @@
     { AV_CODEC_ID_ADPCM_YAMAHA,    0x0020 },
     { AV_CODEC_ID_TRUESPEECH,      0x0022 },
     { AV_CODEC_ID_GSM_MS,          0x0031 },
+    { AV_CODEC_ID_GSM_MS,          0x0032 },  /* msn audio */
     { AV_CODEC_ID_AMR_NB,          0x0038 },  /* rogue format number */
     { AV_CODEC_ID_G723_1,          0x0042 },
     { AV_CODEC_ID_ADPCM_G726,      0x0045 },
@@ -385,7 +386,7 @@
     /* rogue format number */
     { AV_CODEC_ID_ADPCM_IMA_DK3,   0x0062 },
     { AV_CODEC_ID_ADPCM_IMA_WAV,   0x0069 },
-    { AV_CODEC_ID_VOXWARE,         0x0075 },
+    { AV_CODEC_ID_METASOUND,       0x0075 },
     { AV_CODEC_ID_AAC,             0x00ff },
     { AV_CODEC_ID_SIPR,            0x0130 },
     { AV_CODEC_ID_WMAV1,           0x0160 },
@@ -419,14 +420,6 @@
     { AV_CODEC_ID_NONE,      0 },
 };
 
-const AVCodecGuid ff_codec_wav_guids[] = {
-    { AV_CODEC_ID_AC3,      { 0x2C, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11, 0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA } },
-    { AV_CODEC_ID_ATRAC3P,  { 0xBF, 0xAA, 0x23, 0xE9, 0x58, 0xCB, 0x71, 0x44, 0xA1, 0x19, 0xFF, 0xFA, 0x01, 0xE4, 0xCE, 0x62 } },
-    { AV_CODEC_ID_EAC3,     { 0xAF, 0x87, 0xFB, 0xA7, 0x02, 0x2D, 0xFB, 0x42, 0xA4, 0xD4, 0x05, 0xCD, 0x93, 0x84, 0x3B, 0xDD } },
-    { AV_CODEC_ID_MP2,      { 0x2B, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11, 0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA } },
-    { AV_CODEC_ID_NONE }
-};
-
 const AVMetadataConv ff_riff_info_conv[] = {
     { "IART", "artist"     },
     { "ICMT", "comment"    },
@@ -437,504 +430,19 @@
     { "INAM", "title"      },
     { "IPRD", "album"      },
     { "IPRT", "track"      },
+    { "ITRK", "track"      },
     { "ISFT", "encoder"    },
     { "ISMP", "timecode"   },
     { "ITCH", "encoded_by" },
     { 0 },
 };
 
-void ff_get_guid(AVIOContext *s, ff_asf_guid *g)
+const struct AVCodecTag *avformat_get_riff_video_tags(void)
 {
-    av_assert0(sizeof(*g) == 16); //compiler will optimize this out
-    if (avio_read(s, *g, sizeof(*g)) < (int)sizeof(*g))
-        memset(*g, 0, sizeof(*g));
+    return ff_codec_bmp_tags;
 }
 
-enum AVCodecID ff_codec_guid_get_id(const AVCodecGuid *guids, ff_asf_guid guid)
+const struct AVCodecTag *avformat_get_riff_audio_tags(void)
 {
-    int i;
-    for (i = 0; guids[i].id != AV_CODEC_ID_NONE; i++)
-        if (!ff_guidcmp(guids[i].guid, guid))
-            return guids[i].id;
-    return AV_CODEC_ID_NONE;
+    return ff_codec_wav_tags;
 }
-
-#if CONFIG_MUXERS
-int64_t ff_start_tag(AVIOContext *pb, const char *tag)
-{
-    ffio_wfourcc(pb, tag);
-    avio_wl32(pb, 0);
-    return avio_tell(pb);
-}
-
-void ff_end_tag(AVIOContext *pb, int64_t start)
-{
-    int64_t pos;
-
-    av_assert0((start&1) == 0);
-
-    pos = avio_tell(pb);
-    if (pos & 1)
-        avio_w8(pb, 0);
-    avio_seek(pb, start - 4, SEEK_SET);
-    avio_wl32(pb, (uint32_t)(pos - start));
-    avio_seek(pb, FFALIGN(pos, 2), SEEK_SET);
-}
-
-/* WAVEFORMATEX header */
-/* returns the size or -1 on error */
-int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc)
-{
-    int bps, blkalign, bytespersec, frame_size;
-    int hdrsize = 18;
-    int waveformatextensible;
-    uint8_t temp[256];
-    uint8_t *riff_extradata       = temp;
-    uint8_t *riff_extradata_start = temp;
-
-    if (!enc->codec_tag || enc->codec_tag > 0xffff)
-        return -1;
-
-    /* We use the known constant frame size for the codec if known, otherwise
-     * fall back on using AVCodecContext.frame_size, which is not as reliable
-     * for indicating packet duration. */
-    frame_size = av_get_audio_frame_duration(enc, 0);
-    if (!frame_size)
-        frame_size = enc->frame_size;
-
-    waveformatextensible = (enc->channels > 2 && enc->channel_layout) ||
-                           enc->sample_rate > 48000 ||
-                           av_get_bits_per_sample(enc->codec_id) > 16;
-
-    if (waveformatextensible)
-        avio_wl16(pb, 0xfffe);
-    else
-        avio_wl16(pb, enc->codec_tag);
-
-    avio_wl16(pb, enc->channels);
-    avio_wl32(pb, enc->sample_rate);
-    if (enc->codec_id == AV_CODEC_ID_ATRAC3 ||
-        enc->codec_id == AV_CODEC_ID_G723_1 ||
-        enc->codec_id == AV_CODEC_ID_MP2    ||
-        enc->codec_id == AV_CODEC_ID_MP3    ||
-        enc->codec_id == AV_CODEC_ID_GSM_MS) {
-        bps = 0;
-    } else {
-        if (!(bps = av_get_bits_per_sample(enc->codec_id))) {
-            if (enc->bits_per_coded_sample)
-                bps = enc->bits_per_coded_sample;
-            else
-                bps = 16;  // default to 16
-        }
-    }
-    if (bps != enc->bits_per_coded_sample && enc->bits_per_coded_sample) {
-        av_log(enc, AV_LOG_WARNING,
-               "requested bits_per_coded_sample (%d) "
-               "and actually stored (%d) differ\n",
-               enc->bits_per_coded_sample, bps);
-    }
-
-    if (enc->codec_id == AV_CODEC_ID_MP2 ||
-        enc->codec_id == AV_CODEC_ID_MP3) {
-        /* This is wrong, but it seems many demuxers do not work if this
-         * is set correctly. */
-        blkalign = frame_size;
-        // blkalign = 144 * enc->bit_rate/enc->sample_rate;
-    } else if (enc->codec_id == AV_CODEC_ID_AC3) {
-        blkalign = 3840;                /* maximum bytes per frame */
-    } else if (enc->codec_id == AV_CODEC_ID_AAC) {
-        blkalign = 768 * enc->channels; /* maximum bytes per frame */
-    } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
-        blkalign = 24;
-    } else if (enc->block_align != 0) { /* specified by the codec */
-        blkalign = enc->block_align;
-    } else
-        blkalign = bps * enc->channels / av_gcd(8, bps);
-    if (enc->codec_id == AV_CODEC_ID_PCM_U8 ||
-        enc->codec_id == AV_CODEC_ID_PCM_S24LE ||
-        enc->codec_id == AV_CODEC_ID_PCM_S32LE ||
-        enc->codec_id == AV_CODEC_ID_PCM_F32LE ||
-        enc->codec_id == AV_CODEC_ID_PCM_F64LE ||
-        enc->codec_id == AV_CODEC_ID_PCM_S16LE) {
-        bytespersec = enc->sample_rate * blkalign;
-    } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
-        bytespersec = 800;
-    } else {
-        bytespersec = enc->bit_rate / 8;
-    }
-    avio_wl32(pb, bytespersec); /* bytes per second */
-    avio_wl16(pb, blkalign);    /* block align */
-    avio_wl16(pb, bps);         /* bits per sample */
-    if (enc->codec_id == AV_CODEC_ID_MP3) {
-        hdrsize += 12;
-        bytestream_put_le16(&riff_extradata, 1);    /* wID */
-        bytestream_put_le32(&riff_extradata, 2);    /* fdwFlags */
-        bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */
-        bytestream_put_le16(&riff_extradata, 1);    /* nFramesPerBlock */
-        bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */
-    } else if (enc->codec_id == AV_CODEC_ID_MP2) {
-        hdrsize += 22;
-        /* fwHeadLayer */
-        bytestream_put_le16(&riff_extradata, 2);
-        /* dwHeadBitrate */
-        bytestream_put_le32(&riff_extradata, enc->bit_rate);
-        /* fwHeadMode */
-        bytestream_put_le16(&riff_extradata, enc->channels == 2 ? 1 : 8);
-        /* fwHeadModeExt */
-        bytestream_put_le16(&riff_extradata, 0);
-        /* wHeadEmphasis */
-        bytestream_put_le16(&riff_extradata, 1);
-        /* fwHeadFlags */
-        bytestream_put_le16(&riff_extradata, 16);
-        /* dwPTSLow */
-        bytestream_put_le32(&riff_extradata, 0);
-        /* dwPTSHigh */
-        bytestream_put_le32(&riff_extradata, 0);
-    } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
-        hdrsize += 20;
-        bytestream_put_le32(&riff_extradata, 0x9ace0002); /* extradata needed for msacm g723.1 codec */
-        bytestream_put_le32(&riff_extradata, 0xaea2f732);
-        bytestream_put_le16(&riff_extradata, 0xacde);
-    } else if (enc->codec_id == AV_CODEC_ID_GSM_MS ||
-               enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
-        hdrsize += 2;
-        /* wSamplesPerBlock */
-        bytestream_put_le16(&riff_extradata, frame_size);
-    } else if (enc->extradata_size) {
-        riff_extradata_start = enc->extradata;
-        riff_extradata       = enc->extradata + enc->extradata_size;
-        hdrsize             += enc->extradata_size;
-    }
-    /* write WAVEFORMATEXTENSIBLE extensions */
-    if (waveformatextensible) {
-        hdrsize += 22;
-        /* 22 is WAVEFORMATEXTENSIBLE size */
-        avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
-        /* ValidBitsPerSample || SamplesPerBlock || Reserved */
-        avio_wl16(pb, bps);
-        /* dwChannelMask */
-        avio_wl32(pb, enc->channel_layout);
-        /* GUID + next 3 */
-        avio_wl32(pb, enc->codec_tag);
-        avio_wl32(pb, 0x00100000);
-        avio_wl32(pb, 0xAA000080);
-        avio_wl32(pb, 0x719B3800);
-    } else {
-        avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
-    }
-    avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
-    if (hdrsize & 1) {
-        hdrsize++;
-        avio_w8(pb, 0);
-    }
-
-    return hdrsize;
-}
-
-/* BITMAPINFOHEADER header */
-void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc,
-                       const AVCodecTag *tags, int for_asf)
-{
-    /* size */
-    avio_wl32(pb, 40 + enc->extradata_size);
-    avio_wl32(pb, enc->width);
-    //We always store RGB TopDown
-    avio_wl32(pb, enc->codec_tag ? enc->height : -enc->height);
-    /* planes */
-    avio_wl16(pb, 1);
-    /* depth */
-    avio_wl16(pb, enc->bits_per_coded_sample ? enc->bits_per_coded_sample : 24);
-    /* compression type */
-    avio_wl32(pb, enc->codec_tag);
-    avio_wl32(pb, (enc->width * enc->height * (enc->bits_per_coded_sample ? enc->bits_per_coded_sample : 24)+7) / 8);
-    avio_wl32(pb, 0);
-    avio_wl32(pb, 0);
-    avio_wl32(pb, 0);
-    avio_wl32(pb, 0);
-
-    avio_write(pb, enc->extradata, enc->extradata_size);
-
-    if (!for_asf && enc->extradata_size & 1)
-        avio_w8(pb, 0);
-}
-
-void ff_parse_specific_params(AVCodecContext *stream, int *au_rate,
-                              int *au_ssize, int *au_scale)
-{
-    int gcd;
-    int audio_frame_size;
-
-    /* We use the known constant frame size for the codec if known, otherwise
-     * fall back on using AVCodecContext.frame_size, which is not as reliable
-     * for indicating packet duration. */
-    audio_frame_size = av_get_audio_frame_duration(stream, 0);
-    if (!audio_frame_size)
-        audio_frame_size = stream->frame_size;
-
-    *au_ssize = stream->block_align;
-    if (audio_frame_size && stream->sample_rate) {
-        *au_scale = audio_frame_size;
-        *au_rate  = stream->sample_rate;
-    } else if (stream->codec_type == AVMEDIA_TYPE_VIDEO ||
-               stream->codec_type == AVMEDIA_TYPE_DATA ||
-               stream->codec_type == AVMEDIA_TYPE_SUBTITLE) {
-        *au_scale = stream->time_base.num;
-        *au_rate  = stream->time_base.den;
-    } else {
-        *au_scale = stream->block_align ? stream->block_align * 8 : 8;
-        *au_rate  = stream->bit_rate ? stream->bit_rate :
-                    8 * stream->sample_rate;
-    }
-    gcd        = av_gcd(*au_scale, *au_rate);
-    *au_scale /= gcd;
-    *au_rate  /= gcd;
-}
-
-void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
-{
-    int len = strlen(str);
-    if (len > 0) {
-        len++;
-        ffio_wfourcc(pb, tag);
-        avio_wl32(pb, len);
-        avio_put_str(pb, str);
-        if (len & 1)
-            avio_w8(pb, 0);
-    }
-}
-
-static const char riff_tags[][5] = {
-    "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
-    "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
-    "IPRT", "ISBJ", "ISFT", "ISHP", "ISMP", "ISRC", "ISRF", "ITCH",
-    { 0 }
-};
-
-static int riff_has_valid_tags(AVFormatContext *s)
-{
-    int i;
-
-    for (i = 0; *riff_tags[i]; i++)
-        if (av_dict_get(s->metadata, riff_tags[i], NULL, AV_DICT_MATCH_CASE))
-            return 1;
-
-    return 0;
-}
-
-void ff_riff_write_info(AVFormatContext *s)
-{
-    AVIOContext *pb = s->pb;
-    int i;
-    int64_t list_pos;
-    AVDictionaryEntry *t = NULL;
-
-    ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL);
-
-    /* writing empty LIST is not nice and may cause problems */
-    if (!riff_has_valid_tags(s))
-        return;
-
-    list_pos = ff_start_tag(pb, "LIST");
-    ffio_wfourcc(pb, "INFO");
-    for (i = 0; *riff_tags[i]; i++)
-        if ((t = av_dict_get(s->metadata, riff_tags[i],
-                             NULL, AV_DICT_MATCH_CASE)))
-            ff_riff_write_info_tag(s->pb, t->key, t->value);
-    ff_end_tag(pb, list_pos);
-}
-#endif /* CONFIG_MUXERS */
-
-#if CONFIG_DEMUXERS
-/* We could be given one of the three possible structures here:
- * WAVEFORMAT, PCMWAVEFORMAT or WAVEFORMATEX. Each structure
- * is an expansion of the previous one with the fields added
- * at the bottom. PCMWAVEFORMAT adds 'WORD wBitsPerSample' and
- * WAVEFORMATEX adds 'WORD  cbSize' and basically makes itself
- * an openended structure.
- */
-
-static void parse_waveformatex(AVIOContext *pb, AVCodecContext *c)
-{
-    ff_asf_guid subformat;
-    int bps = avio_rl16(pb);
-    if (bps)
-        c->bits_per_coded_sample = bps;
-
-    c->channel_layout        = avio_rl32(pb); /* dwChannelMask */
-
-    ff_get_guid(pb, &subformat);
-    if (!memcmp(subformat + 4,
-                (const uint8_t[]){ FF_MEDIASUBTYPE_BASE_GUID }, 12)) {
-        c->codec_tag = AV_RL32(subformat);
-        c->codec_id  = ff_wav_codec_get_id(c->codec_tag,
-                                           c->bits_per_coded_sample);
-    } else {
-        c->codec_id = ff_codec_guid_get_id(ff_codec_wav_guids, subformat);
-        if (!c->codec_id)
-            av_log(c, AV_LOG_WARNING,
-                   "unknown subformat:"FF_PRI_GUID"\n",
-                   FF_ARG_GUID(subformat));
-    }
-}
-
-int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size)
-{
-    int id;
-
-    id                 = avio_rl16(pb);
-    codec->codec_type  = AVMEDIA_TYPE_AUDIO;
-    codec->channels    = avio_rl16(pb);
-    codec->sample_rate = avio_rl32(pb);
-    codec->bit_rate    = avio_rl32(pb) * 8;
-    codec->block_align = avio_rl16(pb);
-    if (size == 14) {  /* We're dealing with plain vanilla WAVEFORMAT */
-        codec->bits_per_coded_sample = 8;
-    } else
-        codec->bits_per_coded_sample = avio_rl16(pb);
-    if (id == 0xFFFE) {
-        codec->codec_tag = 0;
-    } else {
-        codec->codec_tag = id;
-        codec->codec_id  = ff_wav_codec_get_id(id,
-                                               codec->bits_per_coded_sample);
-    }
-    if (size >= 18) {  /* We're obviously dealing with WAVEFORMATEX */
-        int cbSize = avio_rl16(pb); /* cbSize */
-        size  -= 18;
-        cbSize = FFMIN(size, cbSize);
-        if (cbSize >= 22 && id == 0xfffe) { /* WAVEFORMATEXTENSIBLE */
-            parse_waveformatex(pb, codec);
-            cbSize -= 22;
-            size   -= 22;
-        }
-        codec->extradata_size = cbSize;
-        if (cbSize > 0) {
-            av_free(codec->extradata);
-            codec->extradata = av_mallocz(codec->extradata_size +
-                                          FF_INPUT_BUFFER_PADDING_SIZE);
-            if (!codec->extradata)
-                return AVERROR(ENOMEM);
-            avio_read(pb, codec->extradata, codec->extradata_size);
-            size -= cbSize;
-        }
-
-        /* It is possible for the chunk to contain garbage at the end */
-        if (size > 0)
-            avio_skip(pb, size);
-    }
-    if (codec->codec_id == AV_CODEC_ID_AAC_LATM) {
-        /* Channels and sample_rate values are those prior to applying SBR
-         * and/or PS. */
-        codec->channels    = 0;
-        codec->sample_rate = 0;
-    }
-    /* override bits_per_coded_sample for G.726 */
-    if (codec->codec_id == AV_CODEC_ID_ADPCM_G726 && codec->sample_rate)
-        codec->bits_per_coded_sample = codec->bit_rate / codec->sample_rate;
-
-    return 0;
-}
-
-enum AVCodecID ff_wav_codec_get_id(unsigned int tag, int bps)
-{
-    enum AVCodecID id;
-    id = ff_codec_get_id(ff_codec_wav_tags, tag);
-    if (id <= 0)
-        return id;
-
-    if (id == AV_CODEC_ID_PCM_S16LE)
-        id = ff_get_pcm_codec_id(bps, 0, 0, ~1);
-    else if (id == AV_CODEC_ID_PCM_F32LE)
-        id = ff_get_pcm_codec_id(bps, 1, 0,  0);
-
-    if (id == AV_CODEC_ID_ADPCM_IMA_WAV && bps == 8)
-        id = AV_CODEC_ID_PCM_ZORK;
-    return id;
-}
-
-int ff_get_bmp_header(AVIOContext *pb, AVStream *st, unsigned *esize)
-{
-    int tag1;
-    if(esize) *esize  = avio_rl32(pb);
-    else                avio_rl32(pb);
-    st->codec->width  = avio_rl32(pb);
-    st->codec->height = (int32_t)avio_rl32(pb);
-    avio_rl16(pb); /* planes */
-    st->codec->bits_per_coded_sample = avio_rl16(pb); /* depth */
-    tag1                             = avio_rl32(pb);
-    avio_rl32(pb); /* ImageSize */
-    avio_rl32(pb); /* XPelsPerMeter */
-    avio_rl32(pb); /* YPelsPerMeter */
-    avio_rl32(pb); /* ClrUsed */
-    avio_rl32(pb); /* ClrImportant */
-    return tag1;
-}
-
-int ff_read_riff_info(AVFormatContext *s, int64_t size)
-{
-    int64_t start, end, cur;
-    AVIOContext *pb = s->pb;
-
-    start = avio_tell(pb);
-    end   = start + size;
-
-    while ((cur = avio_tell(pb)) >= 0 &&
-           cur <= end - 8 /* = tag + size */) {
-        uint32_t chunk_code;
-        int64_t chunk_size;
-        char key[5] = { 0 };
-        char *value;
-
-        chunk_code = avio_rl32(pb);
-        chunk_size = avio_rl32(pb);
-        if (url_feof(pb)) {
-            if (chunk_code || chunk_size) {
-                av_log(s, AV_LOG_WARNING, "INFO subchunk truncated\n");
-                return AVERROR_INVALIDDATA;
-            }
-            return AVERROR_EOF;
-        }
-        if (chunk_size > end ||
-            end - chunk_size < cur ||
-            chunk_size == UINT_MAX) {
-            avio_seek(pb, -9, SEEK_CUR);
-            chunk_code = avio_rl32(pb);
-            chunk_size = avio_rl32(pb);
-            if (chunk_size > end || end - chunk_size < cur || chunk_size == UINT_MAX) {
-                av_log(s, AV_LOG_WARNING, "too big INFO subchunk\n");
-                return AVERROR_INVALIDDATA;
-            }
-        }
-
-        chunk_size += (chunk_size & 1);
-
-        if (!chunk_code) {
-            if (chunk_size)
-                avio_skip(pb, chunk_size);
-            else if (pb->eof_reached) {
-                av_log(s, AV_LOG_WARNING, "truncated file\n");
-                return AVERROR_EOF;
-            }
-            continue;
-        }
-
-        value = av_mallocz(chunk_size + 1);
-        if (!value) {
-            av_log(s, AV_LOG_ERROR,
-                   "out of memory, unable to read INFO tag\n");
-            return AVERROR(ENOMEM);
-        }
-
-        AV_WL32(key, chunk_code);
-
-        if (avio_read(pb, value, chunk_size) != chunk_size) {
-            av_log(s, AV_LOG_WARNING,
-                   "premature end of file while reading INFO tag\n");
-        }
-
-        av_dict_set(&s->metadata, key, value, AV_DICT_DONT_STRDUP_VAL);
-    }
-
-    return 0;
-}
-#endif /* CONFIG_DEMUXERS */
diff --git a/libavformat/riff.h b/libavformat/riff.h
index cb83789..1bf437e 100644
--- a/libavformat/riff.h
+++ b/libavformat/riff.h
@@ -34,7 +34,6 @@
 #include "metadata.h"
 
 extern const AVMetadataConv ff_riff_info_conv[];
-extern const char ff_riff_tags[][5];
 
 int64_t ff_start_tag(AVIOContext *pb, const char *tag);
 void ff_end_tag(AVIOContext *pb, int64_t start);
diff --git a/libavformat/riffdec.c b/libavformat/riffdec.c
new file mode 100644
index 0000000..973f3fa
--- /dev/null
+++ b/libavformat/riffdec.c
@@ -0,0 +1,247 @@
+/*
+ * RIFF demuxing functions and data
+ * Copyright (c) 2000 Fabrice Bellard
+ *
+ * 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
+ */
+
+#include "libavutil/dict.h"
+#include "libavutil/error.h"
+#include "libavutil/log.h"
+#include "libavutil/mathematics.h"
+#include "libavcodec/avcodec.h"
+#include "libavcodec/bytestream.h"
+#include "avformat.h"
+#include "avio_internal.h"
+#include "riff.h"
+
+const AVCodecGuid ff_codec_wav_guids[] = {
+    { AV_CODEC_ID_AC3,      { 0x2C, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11, 0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA } },
+    { AV_CODEC_ID_ATRAC3P,  { 0xBF, 0xAA, 0x23, 0xE9, 0x58, 0xCB, 0x71, 0x44, 0xA1, 0x19, 0xFF, 0xFA, 0x01, 0xE4, 0xCE, 0x62 } },
+    { AV_CODEC_ID_EAC3,     { 0xAF, 0x87, 0xFB, 0xA7, 0x02, 0x2D, 0xFB, 0x42, 0xA4, 0xD4, 0x05, 0xCD, 0x93, 0x84, 0x3B, 0xDD } },
+    { AV_CODEC_ID_MP2,      { 0x2B, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11, 0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA } },
+    { AV_CODEC_ID_NONE }
+};
+
+void ff_get_guid(AVIOContext *s, ff_asf_guid *g)
+{
+    av_assert0(sizeof(*g) == 16); //compiler will optimize this out
+    if (avio_read(s, *g, sizeof(*g)) < (int)sizeof(*g))
+        memset(*g, 0, sizeof(*g));
+}
+
+enum AVCodecID ff_codec_guid_get_id(const AVCodecGuid *guids, ff_asf_guid guid)
+{
+    int i;
+    for (i = 0; guids[i].id != AV_CODEC_ID_NONE; i++)
+        if (!ff_guidcmp(guids[i].guid, guid))
+            return guids[i].id;
+    return AV_CODEC_ID_NONE;
+}
+
+/* We could be given one of the three possible structures here:
+ * WAVEFORMAT, PCMWAVEFORMAT or WAVEFORMATEX. Each structure
+ * is an expansion of the previous one with the fields added
+ * at the bottom. PCMWAVEFORMAT adds 'WORD wBitsPerSample' and
+ * WAVEFORMATEX adds 'WORD  cbSize' and basically makes itself
+ * an openended structure.
+ */
+
+static void parse_waveformatex(AVIOContext *pb, AVCodecContext *c)
+{
+    ff_asf_guid subformat;
+    int bps = avio_rl16(pb);
+    if (bps)
+        c->bits_per_coded_sample = bps;
+
+    c->channel_layout        = avio_rl32(pb); /* dwChannelMask */
+
+    ff_get_guid(pb, &subformat);
+    if (!memcmp(subformat + 4,
+                (const uint8_t[]){ FF_MEDIASUBTYPE_BASE_GUID }, 12)) {
+        c->codec_tag = AV_RL32(subformat);
+        c->codec_id  = ff_wav_codec_get_id(c->codec_tag,
+                                           c->bits_per_coded_sample);
+    } else {
+        c->codec_id = ff_codec_guid_get_id(ff_codec_wav_guids, subformat);
+        if (!c->codec_id)
+            av_log(c, AV_LOG_WARNING,
+                   "unknown subformat:"FF_PRI_GUID"\n",
+                   FF_ARG_GUID(subformat));
+    }
+}
+
+int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size)
+{
+    int id;
+
+    id                 = avio_rl16(pb);
+    codec->codec_type  = AVMEDIA_TYPE_AUDIO;
+    codec->channels    = avio_rl16(pb);
+    codec->sample_rate = avio_rl32(pb);
+    codec->bit_rate    = avio_rl32(pb) * 8;
+    codec->block_align = avio_rl16(pb);
+    if (size == 14) {  /* We're dealing with plain vanilla WAVEFORMAT */
+        codec->bits_per_coded_sample = 8;
+    } else
+        codec->bits_per_coded_sample = avio_rl16(pb);
+    if (id == 0xFFFE) {
+        codec->codec_tag = 0;
+    } else {
+        codec->codec_tag = id;
+        codec->codec_id  = ff_wav_codec_get_id(id,
+                                               codec->bits_per_coded_sample);
+    }
+    if (size >= 18) {  /* We're obviously dealing with WAVEFORMATEX */
+        int cbSize = avio_rl16(pb); /* cbSize */
+        size  -= 18;
+        cbSize = FFMIN(size, cbSize);
+        if (cbSize >= 22 && id == 0xfffe) { /* WAVEFORMATEXTENSIBLE */
+            parse_waveformatex(pb, codec);
+            cbSize -= 22;
+            size   -= 22;
+        }
+        codec->extradata_size = cbSize;
+        if (cbSize > 0) {
+            av_free(codec->extradata);
+            codec->extradata = av_mallocz(codec->extradata_size +
+                                          FF_INPUT_BUFFER_PADDING_SIZE);
+            if (!codec->extradata)
+                return AVERROR(ENOMEM);
+            avio_read(pb, codec->extradata, codec->extradata_size);
+            size -= cbSize;
+        }
+
+        /* It is possible for the chunk to contain garbage at the end */
+        if (size > 0)
+            avio_skip(pb, size);
+    }
+    if (codec->codec_id == AV_CODEC_ID_AAC_LATM) {
+        /* Channels and sample_rate values are those prior to applying SBR
+         * and/or PS. */
+        codec->channels    = 0;
+        codec->sample_rate = 0;
+    }
+    /* override bits_per_coded_sample for G.726 */
+    if (codec->codec_id == AV_CODEC_ID_ADPCM_G726 && codec->sample_rate)
+        codec->bits_per_coded_sample = codec->bit_rate / codec->sample_rate;
+
+    return 0;
+}
+
+enum AVCodecID ff_wav_codec_get_id(unsigned int tag, int bps)
+{
+    enum AVCodecID id;
+    id = ff_codec_get_id(ff_codec_wav_tags, tag);
+    if (id <= 0)
+        return id;
+
+    if (id == AV_CODEC_ID_PCM_S16LE)
+        id = ff_get_pcm_codec_id(bps, 0, 0, ~1);
+    else if (id == AV_CODEC_ID_PCM_F32LE)
+        id = ff_get_pcm_codec_id(bps, 1, 0,  0);
+
+    if (id == AV_CODEC_ID_ADPCM_IMA_WAV && bps == 8)
+        id = AV_CODEC_ID_PCM_ZORK;
+    return id;
+}
+
+int ff_get_bmp_header(AVIOContext *pb, AVStream *st, unsigned *esize)
+{
+    int tag1;
+    if(esize) *esize  = avio_rl32(pb);
+    else                avio_rl32(pb);
+    st->codec->width  = avio_rl32(pb);
+    st->codec->height = (int32_t)avio_rl32(pb);
+    avio_rl16(pb); /* planes */
+    st->codec->bits_per_coded_sample = avio_rl16(pb); /* depth */
+    tag1                             = avio_rl32(pb);
+    avio_rl32(pb); /* ImageSize */
+    avio_rl32(pb); /* XPelsPerMeter */
+    avio_rl32(pb); /* YPelsPerMeter */
+    avio_rl32(pb); /* ClrUsed */
+    avio_rl32(pb); /* ClrImportant */
+    return tag1;
+}
+
+int ff_read_riff_info(AVFormatContext *s, int64_t size)
+{
+    int64_t start, end, cur;
+    AVIOContext *pb = s->pb;
+
+    start = avio_tell(pb);
+    end   = start + size;
+
+    while ((cur = avio_tell(pb)) >= 0 &&
+           cur <= end - 8 /* = tag + size */) {
+        uint32_t chunk_code;
+        int64_t chunk_size;
+        char key[5] = { 0 };
+        char *value;
+
+        chunk_code = avio_rl32(pb);
+        chunk_size = avio_rl32(pb);
+        if (url_feof(pb)) {
+            if (chunk_code || chunk_size) {
+                av_log(s, AV_LOG_WARNING, "INFO subchunk truncated\n");
+                return AVERROR_INVALIDDATA;
+            }
+            return AVERROR_EOF;
+        }
+        if (chunk_size > end ||
+            end - chunk_size < cur ||
+            chunk_size == UINT_MAX) {
+            avio_seek(pb, -9, SEEK_CUR);
+            chunk_code = avio_rl32(pb);
+            chunk_size = avio_rl32(pb);
+            if (chunk_size > end || end - chunk_size < cur || chunk_size == UINT_MAX) {
+                av_log(s, AV_LOG_WARNING, "too big INFO subchunk\n");
+                return AVERROR_INVALIDDATA;
+            }
+        }
+
+        chunk_size += (chunk_size & 1);
+
+        if (!chunk_code) {
+            if (chunk_size)
+                avio_skip(pb, chunk_size);
+            else if (pb->eof_reached) {
+                av_log(s, AV_LOG_WARNING, "truncated file\n");
+                return AVERROR_EOF;
+            }
+            continue;
+        }
+
+        value = av_mallocz(chunk_size + 1);
+        if (!value) {
+            av_log(s, AV_LOG_ERROR,
+                   "out of memory, unable to read INFO tag\n");
+            return AVERROR(ENOMEM);
+        }
+
+        AV_WL32(key, chunk_code);
+
+        if (avio_read(pb, value, chunk_size) != chunk_size) {
+            av_log(s, AV_LOG_WARNING,
+                   "premature end of file while reading INFO tag\n");
+        }
+
+        av_dict_set(&s->metadata, key, value, AV_DICT_DONT_STRDUP_VAL);
+    }
+
+    return 0;
+}
diff --git a/libavformat/riffenc.c b/libavformat/riffenc.c
new file mode 100644
index 0000000..bcfe018
--- /dev/null
+++ b/libavformat/riffenc.c
@@ -0,0 +1,312 @@
+/*
+ * RIFF muxing functions
+ * Copyright (c) 2000 Fabrice Bellard
+ *
+ * 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
+ */
+
+#include "libavutil/dict.h"
+#include "libavutil/log.h"
+#include "libavutil/mathematics.h"
+#include "libavcodec/avcodec.h"
+#include "libavcodec/bytestream.h"
+#include "avformat.h"
+#include "avio_internal.h"
+#include "riff.h"
+
+int64_t ff_start_tag(AVIOContext *pb, const char *tag)
+{
+    ffio_wfourcc(pb, tag);
+    avio_wl32(pb, 0);
+    return avio_tell(pb);
+}
+
+void ff_end_tag(AVIOContext *pb, int64_t start)
+{
+    int64_t pos;
+
+    av_assert0((start&1) == 0);
+
+    pos = avio_tell(pb);
+    if (pos & 1)
+        avio_w8(pb, 0);
+    avio_seek(pb, start - 4, SEEK_SET);
+    avio_wl32(pb, (uint32_t)(pos - start));
+    avio_seek(pb, FFALIGN(pos, 2), SEEK_SET);
+}
+
+/* WAVEFORMATEX header */
+/* returns the size or -1 on error */
+int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc)
+{
+    int bps, blkalign, bytespersec, frame_size;
+    int hdrsize = 18;
+    int waveformatextensible;
+    uint8_t temp[256];
+    uint8_t *riff_extradata       = temp;
+    uint8_t *riff_extradata_start = temp;
+
+    if (!enc->codec_tag || enc->codec_tag > 0xffff)
+        return -1;
+
+    /* We use the known constant frame size for the codec if known, otherwise
+     * fall back on using AVCodecContext.frame_size, which is not as reliable
+     * for indicating packet duration. */
+    frame_size = av_get_audio_frame_duration(enc, 0);
+    if (!frame_size)
+        frame_size = enc->frame_size;
+
+    waveformatextensible = (enc->channels > 2 && enc->channel_layout) ||
+                           enc->sample_rate > 48000 ||
+                           av_get_bits_per_sample(enc->codec_id) > 16;
+
+    if (waveformatextensible)
+        avio_wl16(pb, 0xfffe);
+    else
+        avio_wl16(pb, enc->codec_tag);
+
+    avio_wl16(pb, enc->channels);
+    avio_wl32(pb, enc->sample_rate);
+    if (enc->codec_id == AV_CODEC_ID_ATRAC3 ||
+        enc->codec_id == AV_CODEC_ID_G723_1 ||
+        enc->codec_id == AV_CODEC_ID_MP2    ||
+        enc->codec_id == AV_CODEC_ID_MP3    ||
+        enc->codec_id == AV_CODEC_ID_GSM_MS) {
+        bps = 0;
+    } else {
+        if (!(bps = av_get_bits_per_sample(enc->codec_id))) {
+            if (enc->bits_per_coded_sample)
+                bps = enc->bits_per_coded_sample;
+            else
+                bps = 16;  // default to 16
+        }
+    }
+    if (bps != enc->bits_per_coded_sample && enc->bits_per_coded_sample) {
+        av_log(enc, AV_LOG_WARNING,
+               "requested bits_per_coded_sample (%d) "
+               "and actually stored (%d) differ\n",
+               enc->bits_per_coded_sample, bps);
+    }
+
+    if (enc->codec_id == AV_CODEC_ID_MP2 ||
+        enc->codec_id == AV_CODEC_ID_MP3) {
+        /* This is wrong, but it seems many demuxers do not work if this
+         * is set correctly. */
+        blkalign = frame_size;
+        // blkalign = 144 * enc->bit_rate/enc->sample_rate;
+    } else if (enc->codec_id == AV_CODEC_ID_AC3) {
+        blkalign = 3840;                /* maximum bytes per frame */
+    } else if (enc->codec_id == AV_CODEC_ID_AAC) {
+        blkalign = 768 * enc->channels; /* maximum bytes per frame */
+    } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
+        blkalign = 24;
+    } else if (enc->block_align != 0) { /* specified by the codec */
+        blkalign = enc->block_align;
+    } else
+        blkalign = bps * enc->channels / av_gcd(8, bps);
+    if (enc->codec_id == AV_CODEC_ID_PCM_U8 ||
+        enc->codec_id == AV_CODEC_ID_PCM_S24LE ||
+        enc->codec_id == AV_CODEC_ID_PCM_S32LE ||
+        enc->codec_id == AV_CODEC_ID_PCM_F32LE ||
+        enc->codec_id == AV_CODEC_ID_PCM_F64LE ||
+        enc->codec_id == AV_CODEC_ID_PCM_S16LE) {
+        bytespersec = enc->sample_rate * blkalign;
+    } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
+        bytespersec = 800;
+    } else {
+        bytespersec = enc->bit_rate / 8;
+    }
+    avio_wl32(pb, bytespersec); /* bytes per second */
+    avio_wl16(pb, blkalign);    /* block align */
+    avio_wl16(pb, bps);         /* bits per sample */
+    if (enc->codec_id == AV_CODEC_ID_MP3) {
+        hdrsize += 12;
+        bytestream_put_le16(&riff_extradata, 1);    /* wID */
+        bytestream_put_le32(&riff_extradata, 2);    /* fdwFlags */
+        bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */
+        bytestream_put_le16(&riff_extradata, 1);    /* nFramesPerBlock */
+        bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */
+    } else if (enc->codec_id == AV_CODEC_ID_MP2) {
+        hdrsize += 22;
+        /* fwHeadLayer */
+        bytestream_put_le16(&riff_extradata, 2);
+        /* dwHeadBitrate */
+        bytestream_put_le32(&riff_extradata, enc->bit_rate);
+        /* fwHeadMode */
+        bytestream_put_le16(&riff_extradata, enc->channels == 2 ? 1 : 8);
+        /* fwHeadModeExt */
+        bytestream_put_le16(&riff_extradata, 0);
+        /* wHeadEmphasis */
+        bytestream_put_le16(&riff_extradata, 1);
+        /* fwHeadFlags */
+        bytestream_put_le16(&riff_extradata, 16);
+        /* dwPTSLow */
+        bytestream_put_le32(&riff_extradata, 0);
+        /* dwPTSHigh */
+        bytestream_put_le32(&riff_extradata, 0);
+    } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
+        hdrsize += 20;
+        bytestream_put_le32(&riff_extradata, 0x9ace0002); /* extradata needed for msacm g723.1 codec */
+        bytestream_put_le32(&riff_extradata, 0xaea2f732);
+        bytestream_put_le16(&riff_extradata, 0xacde);
+    } else if (enc->codec_id == AV_CODEC_ID_GSM_MS ||
+               enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
+        hdrsize += 2;
+        /* wSamplesPerBlock */
+        bytestream_put_le16(&riff_extradata, frame_size);
+    } else if (enc->extradata_size) {
+        riff_extradata_start = enc->extradata;
+        riff_extradata       = enc->extradata + enc->extradata_size;
+        hdrsize             += enc->extradata_size;
+    }
+    /* write WAVEFORMATEXTENSIBLE extensions */
+    if (waveformatextensible) {
+        hdrsize += 22;
+        /* 22 is WAVEFORMATEXTENSIBLE size */
+        avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
+        /* ValidBitsPerSample || SamplesPerBlock || Reserved */
+        avio_wl16(pb, bps);
+        /* dwChannelMask */
+        avio_wl32(pb, enc->channel_layout);
+        /* GUID + next 3 */
+        avio_wl32(pb, enc->codec_tag);
+        avio_wl32(pb, 0x00100000);
+        avio_wl32(pb, 0xAA000080);
+        avio_wl32(pb, 0x719B3800);
+    } else {
+        avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
+    }
+    avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
+    if (hdrsize & 1) {
+        hdrsize++;
+        avio_w8(pb, 0);
+    }
+
+    return hdrsize;
+}
+
+/* BITMAPINFOHEADER header */
+void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc,
+                       const AVCodecTag *tags, int for_asf)
+{
+    /* size */
+    avio_wl32(pb, 40 + enc->extradata_size);
+    avio_wl32(pb, enc->width);
+    //We always store RGB TopDown
+    avio_wl32(pb, enc->codec_tag ? enc->height : -enc->height);
+    /* planes */
+    avio_wl16(pb, 1);
+    /* depth */
+    avio_wl16(pb, enc->bits_per_coded_sample ? enc->bits_per_coded_sample : 24);
+    /* compression type */
+    avio_wl32(pb, enc->codec_tag);
+    avio_wl32(pb, (enc->width * enc->height * (enc->bits_per_coded_sample ? enc->bits_per_coded_sample : 24)+7) / 8);
+    avio_wl32(pb, 0);
+    avio_wl32(pb, 0);
+    avio_wl32(pb, 0);
+    avio_wl32(pb, 0);
+
+    avio_write(pb, enc->extradata, enc->extradata_size);
+
+    if (!for_asf && enc->extradata_size & 1)
+        avio_w8(pb, 0);
+}
+
+void ff_parse_specific_params(AVCodecContext *stream, int *au_rate,
+                              int *au_ssize, int *au_scale)
+{
+    int gcd;
+    int audio_frame_size;
+
+    /* We use the known constant frame size for the codec if known, otherwise
+     * fall back on using AVCodecContext.frame_size, which is not as reliable
+     * for indicating packet duration. */
+    audio_frame_size = av_get_audio_frame_duration(stream, 0);
+    if (!audio_frame_size)
+        audio_frame_size = stream->frame_size;
+
+    *au_ssize = stream->block_align;
+    if (audio_frame_size && stream->sample_rate) {
+        *au_scale = audio_frame_size;
+        *au_rate  = stream->sample_rate;
+    } else if (stream->codec_type == AVMEDIA_TYPE_VIDEO ||
+               stream->codec_type == AVMEDIA_TYPE_DATA ||
+               stream->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+        *au_scale = stream->time_base.num;
+        *au_rate  = stream->time_base.den;
+    } else {
+        *au_scale = stream->block_align ? stream->block_align * 8 : 8;
+        *au_rate  = stream->bit_rate ? stream->bit_rate :
+                    8 * stream->sample_rate;
+    }
+    gcd        = av_gcd(*au_scale, *au_rate);
+    *au_scale /= gcd;
+    *au_rate  /= gcd;
+}
+
+void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
+{
+    int len = strlen(str);
+    if (len > 0) {
+        len++;
+        ffio_wfourcc(pb, tag);
+        avio_wl32(pb, len);
+        avio_put_str(pb, str);
+        if (len & 1)
+            avio_w8(pb, 0);
+    }
+}
+
+static const char riff_tags[][5] = {
+    "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
+    "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
+    "IPRT", "ITRK", "ISBJ", "ISFT", "ISHP", "ISMP", "ISRC", "ISRF", "ITCH",
+    { 0 }
+};
+
+static int riff_has_valid_tags(AVFormatContext *s)
+{
+    int i;
+
+    for (i = 0; *riff_tags[i]; i++)
+        if (av_dict_get(s->metadata, riff_tags[i], NULL, AV_DICT_MATCH_CASE))
+            return 1;
+
+    return 0;
+}
+
+void ff_riff_write_info(AVFormatContext *s)
+{
+    AVIOContext *pb = s->pb;
+    int i;
+    int64_t list_pos;
+    AVDictionaryEntry *t = NULL;
+
+    ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL);
+
+    /* writing empty LIST is not nice and may cause problems */
+    if (!riff_has_valid_tags(s))
+        return;
+
+    list_pos = ff_start_tag(pb, "LIST");
+    ffio_wfourcc(pb, "INFO");
+    for (i = 0; *riff_tags[i]; i++)
+        if ((t = av_dict_get(s->metadata, riff_tags[i],
+                             NULL, AV_DICT_MATCH_CASE)))
+            ff_riff_write_info_tag(s->pb, t->key, t->value);
+    ff_end_tag(pb, list_pos);
+}
diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c
index 13d1d25..38bddc3 100644
--- a/libavformat/rmdec.c
+++ b/libavformat/rmdec.c
@@ -22,6 +22,7 @@
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
+#include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/dict.h"
 #include "avformat.h"
@@ -95,13 +96,14 @@
     return 0;
 }
 
-static void rm_read_metadata(AVFormatContext *s, int wide)
+static void rm_read_metadata(AVFormatContext *s, AVIOContext *pb, int wide)
 {
     char buf[1024];
     int i;
+
     for (i=0; i<FF_ARRAY_ELEMS(ff_rm_metadata); i++) {
-        int len = wide ? avio_rb16(s->pb) : avio_r8(s->pb);
-        get_strl(s->pb, buf, sizeof(buf), len);
+        int len = wide ? avio_rb16(pb) : avio_r8(pb);
+        get_strl(pb, buf, sizeof(buf), len);
         av_dict_set(&s->metadata, ff_rm_metadata[i], buf, 0);
     }
 }
@@ -134,7 +136,7 @@
         avio_skip(pb, 8);
         bytes_per_minute = avio_rb16(pb);
         avio_skip(pb, 4);
-        rm_read_metadata(s, 0);
+        rm_read_metadata(s, pb, 0);
         if ((startpos + header_size) >= avio_tell(pb) + 2) {
             // fourcc (should always be "lpcJ")
             avio_r8(pb);
@@ -293,7 +295,7 @@
             avio_r8(pb);
             avio_r8(pb);
             avio_r8(pb);
-            rm_read_metadata(s, 0);
+            rm_read_metadata(s, pb, 0);
         }
     }
     return 0;
@@ -516,7 +518,7 @@
             flags = avio_rb16(pb); /* flags */
             break;
         case MKTAG('C', 'O', 'N', 'T'):
-            rm_read_metadata(s, 1);
+            rm_read_metadata(s, pb, 1);
             break;
         case MKTAG('M', 'D', 'P', 'R'):
             st = avformat_new_stream(s, NULL);
@@ -721,6 +723,8 @@
 
     if(++vst->cur_slice > vst->slices)
         return 1;
+    if(!vst->pkt.data)
+        return AVERROR(ENOMEM);
     AV_WL32(vst->pkt.data - 7 + 8*vst->cur_slice, 1);
     AV_WL32(vst->pkt.data - 3 + 8*vst->cur_slice, vst->videobufpos - 8*vst->slices - 1);
     if(vst->videobufpos + len > vst->videobufsize)
@@ -737,7 +741,9 @@
         vst->pkt.size= 0;
         vst->pkt.buf = NULL;
 #if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
         vst->pkt.destruct = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
         if(vst->slices != vst->cur_slice) //FIXME find out how to set slices correct from the begin
             memmove(pkt->data + 1 + 8*vst->cur_slice, pkt->data + 1 + 8*vst->slices,
@@ -773,11 +779,13 @@
                     int *seq, int flags, int64_t timestamp)
 {
     RMDemuxContext *rm = s->priv_data;
+    int ret;
 
     if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
         rm->current_stream= st->id;
-        if(rm_assemble_video_frame(s, pb, rm, ast, pkt, len, seq, &timestamp))
-            return -1; //got partial frame
+        ret = rm_assemble_video_frame(s, pb, rm, ast, pkt, len, seq, &timestamp);
+        if(ret)
+            return ret; //got partial frame or error
     } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
         if ((ast->deint_id == DEINT_ID_GENR) ||
             (ast->deint_id == DEINT_ID_INT4) ||
@@ -924,6 +932,8 @@
 
             res = ff_rm_parse_packet (s, s->pb, st, st->priv_data, len, pkt,
                                       &seq, flags, timestamp);
+            if (res < -1)
+                return res;
             if((flags&2) && (seq&0x7F) == 1)
                 av_add_index_entry(st, pos, timestamp, 0, 0, AVINDEX_KEYFRAME);
             if (res)
diff --git a/libavformat/rsd.c b/libavformat/rsd.c
new file mode 100644
index 0000000..5b53cef
--- /dev/null
+++ b/libavformat/rsd.c
@@ -0,0 +1,170 @@
+/*
+ * RSD demuxer
+ * Copyright (c) 2013 James Almer
+ *
+ * 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
+ */
+
+#include "libavcodec/bytestream.h"
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+#include "avio.h"
+#include "internal.h"
+
+static const AVCodecTag rsd_tags[] = {
+    { AV_CODEC_ID_ADPCM_THP,       MKTAG('G','A','D','P') },
+    { AV_CODEC_ID_ADPCM_IMA_RAD,   MKTAG('R','A','D','P') },
+    { AV_CODEC_ID_PCM_S16BE,       MKTAG('P','C','M','B') },
+    { AV_CODEC_ID_PCM_S16LE,       MKTAG('P','C','M',' ') },
+    { AV_CODEC_ID_NONE, 0 },
+};
+
+static const uint32_t rsd_unsupported_tags[] = {
+    MKTAG('O','G','G',' '),
+    MKTAG('V','A','G',' '),
+    MKTAG('W','A','D','P'),
+    MKTAG('X','A','D','P'),
+    MKTAG('X','M','A',' '),
+};
+
+static int rsd_probe(AVProbeData *p)
+{
+    if (!memcmp(p->buf, "RSD", 3) &&
+        p->buf[3] - '0' >= 2 && p->buf[3] - '0' <= 6)
+        return AVPROBE_SCORE_EXTENSION;
+    return 0;
+}
+
+static int rsd_read_header(AVFormatContext *s)
+{
+    AVIOContext *pb = s->pb;
+    int i, version, start = 0x800;
+    AVCodecContext *codec;
+    AVStream *st = avformat_new_stream(s, NULL);
+
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    avio_skip(pb, 3); // "RSD"
+    version = avio_r8(pb) - '0';
+
+    codec = st->codec;
+    codec->codec_type = AVMEDIA_TYPE_AUDIO;
+    codec->codec_tag  = avio_rl32(pb);
+    codec->codec_id   = ff_codec_get_id(rsd_tags, codec->codec_tag);
+    if (!codec->codec_id) {
+        char tag_buf[5];
+
+        av_get_codec_tag_string(tag_buf, sizeof(tag_buf), codec->codec_tag);
+        for (i=0; i < FF_ARRAY_ELEMS(rsd_unsupported_tags); i++) {
+            if (codec->codec_tag == rsd_unsupported_tags[i]) {
+                avpriv_request_sample(s, "Codec tag: %s", tag_buf);
+                return AVERROR_PATCHWELCOME;
+            }
+        }
+        av_log(s, AV_LOG_ERROR, "Unknown codec tag: %s\n", tag_buf);
+        return AVERROR_INVALIDDATA;
+    }
+
+    codec->channels = avio_rl32(pb);
+    if (!codec->channels)
+        return AVERROR_INVALIDDATA;
+
+    avio_skip(pb, 4); // Bit depth
+    codec->sample_rate = avio_rl32(pb);
+    if (!codec->sample_rate)
+        return AVERROR_INVALIDDATA;
+
+    avio_skip(pb, 4); // Unknown
+
+    switch (codec->codec_id) {
+    case AV_CODEC_ID_ADPCM_IMA_RAD:
+        codec->block_align = 20 * codec->channels;
+        if (pb->seekable)
+            st->duration = av_get_audio_frame_duration(codec, avio_size(pb) - start);
+        break;
+    case AV_CODEC_ID_ADPCM_THP:
+        /* RSD3GADP is mono, so only alloc enough memory
+           to store the coeff table for a single channel. */
+
+        codec->extradata_size = 32;
+        codec->extradata = av_malloc(codec->extradata_size);
+        if (!codec->extradata)
+            return AVERROR(ENOMEM);
+
+        start = avio_rl32(pb);
+
+        if (avio_read(s->pb, codec->extradata, 32) != 32)
+            return AVERROR_INVALIDDATA;
+
+        for (i = 0; i < 16; i++)
+            AV_WB16(codec->extradata + i * 2, AV_RL16(codec->extradata + i * 2));
+
+        if (pb->seekable)
+            st->duration = (avio_size(pb) - start) / 8 * 14;
+        break;
+    case AV_CODEC_ID_PCM_S16LE:
+    case AV_CODEC_ID_PCM_S16BE:
+        if (version != 4)
+            start = avio_rl32(pb);
+
+        if (pb->seekable)
+            st->duration = (avio_size(pb) - start) / 2 / codec->channels;
+        break;
+    }
+
+    avio_skip(pb, start - avio_tell(pb));
+
+    avpriv_set_pts_info(st, 64, 1, codec->sample_rate);
+
+    return 0;
+}
+
+static int rsd_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    AVCodecContext *codec = s->streams[0]->codec;
+    int ret, size = 1024;
+
+    if (url_feof(s->pb))
+        return AVERROR_EOF;
+
+    if (codec->codec_id == AV_CODEC_ID_ADPCM_IMA_RAD)
+        ret = av_get_packet(s->pb, pkt, codec->block_align);
+    else
+        ret = av_get_packet(s->pb, pkt, size);
+
+    if (ret != size) {
+        if (ret < 0) {
+            av_free_packet(pkt);
+            return ret;
+        }
+        av_shrink_packet(pkt, ret);
+    }
+    pkt->stream_index = 0;
+
+    return ret;
+}
+
+AVInputFormat ff_rsd_demuxer = {
+    .name           =   "rsd",
+    .long_name      =   NULL_IF_CONFIG_SMALL("GameCube RSD"),
+    .read_probe     =   rsd_probe,
+    .read_header    =   rsd_read_header,
+    .read_packet    =   rsd_read_packet,
+    .extensions     =   "rsd",
+    .codec_tag      =   (const AVCodecTag* const []){rsd_tags, 0},
+};
diff --git a/libavformat/rtmp.h b/libavformat/rtmp.h
index 7c9bb6d..8fc8040 100644
--- a/libavformat/rtmp.h
+++ b/libavformat/rtmp.h
@@ -1,6 +1,6 @@
 /*
  * RTMP definitions
- * Copyright (c) 2009 Kostya Shishkov
+ * Copyright (c) 2009 Konstantin Shishkov
  *
  * This file is part of FFmpeg.
  *
diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c
index 3bd28eb..0982775 100644
--- a/libavformat/rtmppkt.c
+++ b/libavformat/rtmppkt.c
@@ -1,6 +1,6 @@
 /*
  * RTMP input format
- * Copyright (c) 2009 Kostya Shishkov
+ * Copyright (c) 2009 Konstantin Shishkov
  *
  * This file is part of FFmpeg.
  *
@@ -145,25 +145,25 @@
 {
 
     uint8_t t, buf[16];
-    int channel_id, timestamp, data_size, offset = 0;
+    int channel_id, timestamp, size, offset = 0;
     uint32_t extra = 0;
     enum RTMPPacketType type;
-    int size = 0;
+    int written = 0;
     int ret;
 
-    size++;
+    written++;
     channel_id = hdr & 0x3F;
 
     if (channel_id < 2) { //special case for channel number >= 64
         buf[1] = 0;
         if (ffurl_read_complete(h, buf, channel_id + 1) != channel_id + 1)
             return AVERROR(EIO);
-        size += channel_id + 1;
+        written += channel_id + 1;
         channel_id = AV_RL16(buf) + 64;
     }
-    data_size = prev_pkt[channel_id].data_size;
-    type      = prev_pkt[channel_id].type;
-    extra     = prev_pkt[channel_id].extra;
+    size  = prev_pkt[channel_id].size;
+    type  = prev_pkt[channel_id].type;
+    extra = prev_pkt[channel_id].extra;
 
     hdr >>= 6;
     if (hdr == RTMP_PS_ONEBYTE) {
@@ -171,21 +171,21 @@
     } else {
         if (ffurl_read_complete(h, buf, 3) != 3)
             return AVERROR(EIO);
-        size += 3;
+        written += 3;
         timestamp = AV_RB24(buf);
         if (hdr != RTMP_PS_FOURBYTES) {
             if (ffurl_read_complete(h, buf, 3) != 3)
                 return AVERROR(EIO);
-            size += 3;
-            data_size = AV_RB24(buf);
+            written += 3;
+            size = AV_RB24(buf);
             if (ffurl_read_complete(h, buf, 1) != 1)
                 return AVERROR(EIO);
-            size++;
+            written++;
             type = buf[0];
             if (hdr == RTMP_PS_TWELVEBYTES) {
                 if (ffurl_read_complete(h, buf, 4) != 4)
                     return AVERROR(EIO);
-                size += 4;
+                written += 4;
                 extra = AV_RL32(buf);
             }
         }
@@ -199,36 +199,36 @@
         timestamp += prev_pkt[channel_id].timestamp;
 
     if ((ret = ff_rtmp_packet_create(p, channel_id, type, timestamp,
-                                     data_size)) < 0)
+                                     size)) < 0)
         return ret;
     p->extra = extra;
     // save history
     prev_pkt[channel_id].channel_id = channel_id;
     prev_pkt[channel_id].type       = type;
-    prev_pkt[channel_id].data_size  = data_size;
+    prev_pkt[channel_id].size       = size;
     prev_pkt[channel_id].ts_delta   = timestamp - prev_pkt[channel_id].timestamp;
     prev_pkt[channel_id].timestamp  = timestamp;
     prev_pkt[channel_id].extra      = extra;
-    while (data_size > 0) {
-        int toread = FFMIN(data_size, chunk_size);
+    while (size > 0) {
+        int toread = FFMIN(size, chunk_size);
         if (ffurl_read_complete(h, p->data + offset, toread) != toread) {
             ff_rtmp_packet_destroy(p);
             return AVERROR(EIO);
         }
-        data_size -= chunk_size;
-        offset    += chunk_size;
-        size      += chunk_size;
-        if (data_size > 0) {
+        size    -= chunk_size;
+        offset  += chunk_size;
+        written += chunk_size;
+        if (size > 0) {
             if ((ret = ffurl_read_complete(h, &t, 1)) < 0) { // marker
                 ff_rtmp_packet_destroy(p);
                 return ret;
             }
-            size++;
+            written++;
             if (t != (0xC0 + channel_id))
                 return -1;
         }
     }
-    return size;
+    return written;
 }
 
 int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
@@ -237,7 +237,7 @@
     uint8_t pkt_hdr[16], *p = pkt_hdr;
     int mode = RTMP_PS_TWELVEBYTES;
     int off = 0;
-    int size = 0;
+    int written = 0;
     int ret;
 
     pkt->ts_delta = pkt->timestamp - prev_pkt[pkt->channel_id].timestamp;
@@ -246,7 +246,7 @@
     if (prev_pkt[pkt->channel_id].channel_id &&
         pkt->extra == prev_pkt[pkt->channel_id].extra) {
         if (pkt->type == prev_pkt[pkt->channel_id].type &&
-            pkt->data_size == prev_pkt[pkt->channel_id].data_size) {
+            pkt->size == prev_pkt[pkt->channel_id].size) {
             mode = RTMP_PS_FOURBYTES;
             if (pkt->ts_delta == prev_pkt[pkt->channel_id].ts_delta)
                 mode = RTMP_PS_ONEBYTE;
@@ -270,7 +270,7 @@
             timestamp = pkt->ts_delta;
         bytestream_put_be24(&p, timestamp >= 0xFFFFFF ? 0xFFFFFF : timestamp);
         if (mode != RTMP_PS_FOURBYTES) {
-            bytestream_put_be24(&p, pkt->data_size);
+            bytestream_put_be24(&p, pkt->size);
             bytestream_put_byte(&p, pkt->type);
             if (mode == RTMP_PS_TWELVEBYTES)
                 bytestream_put_le32(&p, pkt->extra);
@@ -281,7 +281,7 @@
     // save history
     prev_pkt[pkt->channel_id].channel_id = pkt->channel_id;
     prev_pkt[pkt->channel_id].type       = pkt->type;
-    prev_pkt[pkt->channel_id].data_size  = pkt->data_size;
+    prev_pkt[pkt->channel_id].size       = pkt->size;
     prev_pkt[pkt->channel_id].timestamp  = pkt->timestamp;
     if (mode != RTMP_PS_TWELVEBYTES) {
         prev_pkt[pkt->channel_id].ts_delta   = pkt->ts_delta;
@@ -292,20 +292,20 @@
 
     if ((ret = ffurl_write(h, pkt_hdr, p - pkt_hdr)) < 0)
         return ret;
-    size = p - pkt_hdr + pkt->data_size;
-    while (off < pkt->data_size) {
-        int towrite = FFMIN(chunk_size, pkt->data_size - off);
+    written = p - pkt_hdr + pkt->size;
+    while (off < pkt->size) {
+        int towrite = FFMIN(chunk_size, pkt->size - off);
         if ((ret = ffurl_write(h, pkt->data + off, towrite)) < 0)
             return ret;
         off += towrite;
-        if (off < pkt->data_size) {
+        if (off < pkt->size) {
             uint8_t marker = 0xC0 | pkt->channel_id;
             if ((ret = ffurl_write(h, &marker, 1)) < 0)
                 return ret;
-            size++;
+            written++;
         }
     }
-    return size;
+    return written;
 }
 
 int ff_rtmp_packet_create(RTMPPacket *pkt, int channel_id, RTMPPacketType type,
@@ -316,7 +316,7 @@
         if (!pkt->data)
             return AVERROR(ENOMEM);
     }
-    pkt->data_size  = size;
+    pkt->size       = size;
     pkt->channel_id = channel_id;
     pkt->type       = type;
     pkt->timestamp  = timestamp;
@@ -331,7 +331,7 @@
     if (!pkt)
         return;
     av_freep(&pkt->data);
-    pkt->data_size = 0;
+    pkt->size = 0;
 }
 
 int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end)
@@ -438,7 +438,8 @@
     }
 }
 
-static void ff_amf_tag_contents(void *ctx, const uint8_t *data, const uint8_t *data_end)
+static void amf_tag_contents(void *ctx, const uint8_t *data,
+                             const uint8_t *data_end)
 {
     unsigned int size;
     char buf[1024];
@@ -484,7 +485,7 @@
                 return;
             data += size;
             av_log(ctx, AV_LOG_DEBUG, "  %s: ", buf);
-            ff_amf_tag_contents(ctx, data, data_end);
+            amf_tag_contents(ctx, data, data_end);
             t = ff_amf_tag_size(data, data_end);
             if (t < 0 || t >= data_end - data)
                 return;
@@ -502,12 +503,12 @@
 void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p)
 {
     av_log(ctx, AV_LOG_DEBUG, "RTMP packet type '%s'(%d) for channel %d, timestamp %d, extra field %d size %d\n",
-           rtmp_packet_type(p->type), p->type, p->channel_id, p->timestamp, p->extra, p->data_size);
+           rtmp_packet_type(p->type), p->type, p->channel_id, p->timestamp, p->extra, p->size);
     if (p->type == RTMP_PT_INVOKE || p->type == RTMP_PT_NOTIFY) {
-        uint8_t *src = p->data, *src_end = p->data + p->data_size;
+        uint8_t *src = p->data, *src_end = p->data + p->size;
         while (src < src_end) {
             int sz;
-            ff_amf_tag_contents(ctx, src, src_end);
+            amf_tag_contents(ctx, src, src_end);
             sz = ff_amf_tag_size(src, src_end);
             if (sz < 0)
                 break;
@@ -519,8 +520,41 @@
         av_log(ctx, AV_LOG_DEBUG, "Client BW = %d\n", AV_RB32(p->data));
     } else if (p->type != RTMP_PT_AUDIO && p->type != RTMP_PT_VIDEO && p->type != RTMP_PT_METADATA) {
         int i;
-        for (i = 0; i < p->data_size; i++)
+        for (i = 0; i < p->size; i++)
             av_log(ctx, AV_LOG_DEBUG, " %02X", p->data[i]);
         av_log(ctx, AV_LOG_DEBUG, "\n");
     }
 }
+
+int ff_amf_match_string(const uint8_t *data, int size, const char *str)
+{
+    int len = strlen(str);
+    int amf_len, type;
+
+    if (size < 1)
+        return 0;
+
+    type = *data++;
+
+    if (type != AMF_DATA_TYPE_LONG_STRING &&
+        type != AMF_DATA_TYPE_STRING)
+        return 0;
+
+    if (type == AMF_DATA_TYPE_LONG_STRING) {
+        if ((size -= 4 + 1) < 0)
+            return 0;
+        amf_len = bytestream_get_be32(&data);
+    } else {
+        if ((size -= 2 + 1) < 0)
+            return 0;
+        amf_len = bytestream_get_be16(&data);
+    }
+
+    if (amf_len > size)
+        return 0;
+
+    if (amf_len != len)
+        return 0;
+
+    return !memcmp(data, str, len);
+}
diff --git a/libavformat/rtmppkt.h b/libavformat/rtmppkt.h
index a942295..9ca6382 100644
--- a/libavformat/rtmppkt.h
+++ b/libavformat/rtmppkt.h
@@ -1,6 +1,6 @@
 /*
  * RTMP packet utilities
- * Copyright (c) 2009 Kostya Shishkov
+ * Copyright (c) 2009 Konstantin Shishkov
  *
  * This file is part of FFmpeg.
  *
@@ -81,7 +81,7 @@
     uint32_t       ts_delta;   ///< timestamp increment to the previous one in milliseconds (latter only for media packets)
     uint32_t       extra;      ///< probably an additional channel ID used during streaming data
     uint8_t        *data;      ///< packet payload
-    int            data_size;  ///< packet payload size
+    int            size;       ///< packet payload size
 } RTMPPacket;
 
 /**
@@ -282,6 +282,13 @@
 */
 int ff_amf_read_null(GetByteContext *gbc);
 
+/**
+ * Match AMF string with a NULL-terminated string.
+ *
+ * @return 0 if the strings do not match.
+ */
+
+int ff_amf_match_string(const uint8_t *data, int size, const char *str);
 
 /** @} */ // AMF funcs
 
diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
index d73e015..f230f9e 100644
--- a/libavformat/rtmpproto.c
+++ b/libavformat/rtmpproto.c
@@ -1,6 +1,6 @@
 /*
  * RTMP network protocol
- * Copyright (c) 2009 Kostya Shishkov
+ * Copyright (c) 2009 Konstantin Shishkov
  *
  * This file is part of FFmpeg.
  *
@@ -48,8 +48,6 @@
 #include <zlib.h>
 #endif
 
-//#define DEBUG
-
 #define APP_MAX_LENGTH 1024
 #define PLAYPATH_MAX_LENGTH 256
 #define TCURL_MAX_LENGTH 512
@@ -62,6 +60,7 @@
     STATE_HANDSHAKED, ///< client has performed handshake
     STATE_FCPUBLISH,  ///< client FCPublishing stream (for output)
     STATE_PLAYING,    ///< client has started receiving multimedia data from server
+    STATE_SEEKING,    ///< client has started the seek operation. Back on STATE_PLAYING when the time comes
     STATE_PUBLISHING, ///< client has started sending multimedia data to server (for output)
     STATE_RECEIVING,  ///< received a publish command (for input)
     STATE_STOPPED,    ///< the broadcast has been stopped
@@ -186,7 +185,7 @@
     int ret;
     int i;
 
-    bytestream2_init(&gbc, pkt->data + offset, pkt->data_size - offset);
+    bytestream2_init(&gbc, pkt->data + offset, pkt->size - offset);
     if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
         return ret;
 
@@ -224,7 +223,7 @@
         double pkt_id;
         int len;
 
-        bytestream2_init(&gbc, pkt->data, pkt->data_size);
+        bytestream2_init(&gbc, pkt->data, pkt->size);
         if ((ret = ff_amf_read_string(&gbc, name, sizeof(name), &len)) < 0)
             goto fail;
 
@@ -385,7 +384,7 @@
         }
     }
 
-    pkt.data_size = p - pkt.data;
+    pkt.size = p - pkt.data;
 
     return rtmp_send_packet(rt, &pkt, 1);
 }
@@ -406,7 +405,7 @@
                                    rt->prev_pkt[1])) < 0)
         return ret;
     cp = pkt.data;
-    bytestream2_init(&gbc, cp, pkt.data_size);
+    bytestream2_init(&gbc, cp, pkt.size);
     if (ff_amf_read_string(&gbc, command, sizeof(command), &stringlen)) {
         av_log(s, AV_LOG_ERROR, "Unable to read command string\n");
         ff_rtmp_packet_destroy(&pkt);
@@ -437,7 +436,7 @@
         return ret;
     p = pkt.data;
     bytestream_put_be32(&p, rt->server_bw);
-    pkt.data_size = p - pkt.data;
+    pkt.size = p - pkt.data;
     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
                                rt->prev_pkt[1]);
     ff_rtmp_packet_destroy(&pkt);
@@ -450,7 +449,7 @@
     p = pkt.data;
     bytestream_put_be32(&p, rt->server_bw);
     bytestream_put_byte(&p, 2); // dynamic
-    pkt.data_size = p - pkt.data;
+    pkt.size = p - pkt.data;
     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
                                rt->prev_pkt[1]);
     ff_rtmp_packet_destroy(&pkt);
@@ -512,7 +511,7 @@
     ff_amf_write_number(&p, 0);
     ff_amf_write_object_end(&p);
 
-    pkt.data_size = p - pkt.data;
+    pkt.size = p - pkt.data;
     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
                                rt->prev_pkt[1]);
     ff_rtmp_packet_destroy(&pkt);
@@ -527,7 +526,7 @@
     ff_amf_write_number(&p, 0);
     ff_amf_write_null(&p);
     ff_amf_write_number(&p, 8192);
-    pkt.data_size = p - pkt.data;
+    pkt.size = p - pkt.data;
     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
                                rt->prev_pkt[1]);
     ff_rtmp_packet_destroy(&pkt);
@@ -706,6 +705,29 @@
     return rtmp_send_packet(rt, &pkt, 1);
 }
 
+static int gen_seek(URLContext *s, RTMPContext *rt, int64_t timestamp)
+{
+    RTMPPacket pkt;
+    uint8_t *p;
+    int ret;
+
+    av_log(s, AV_LOG_DEBUG, "Sending seek command for timestamp %"PRId64"\n",
+           timestamp);
+
+    if ((ret = ff_rtmp_packet_create(&pkt, 3, RTMP_PT_INVOKE, 0, 26)) < 0)
+        return ret;
+
+    pkt.extra = rt->main_channel_id;
+
+    p = pkt.data;
+    ff_amf_write_string(&p, "seek");
+    ff_amf_write_number(&p, 0); //no tracking back responses
+    ff_amf_write_null(&p); //as usual, the first null param
+    ff_amf_write_number(&p, timestamp); //where we want to jump
+
+    return rtmp_send_packet(rt, &pkt, 1);
+}
+
 /**
  * Generate 'publish' call and send it to the server.
  */
@@ -742,9 +764,9 @@
     uint8_t *p;
     int ret;
 
-    if (ppkt->data_size < 6) {
+    if (ppkt->size < 6) {
         av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
-               ppkt->data_size);
+               ppkt->size);
         return AVERROR_INVALIDDATA;
     }
 
@@ -1418,10 +1440,10 @@
     RTMPContext *rt = s->priv_data;
     int ret;
 
-    if (pkt->data_size < 4) {
+    if (pkt->size < 4) {
         av_log(s, AV_LOG_ERROR,
                "Too short chunk size change packet (%d)\n",
-               pkt->data_size);
+               pkt->size);
         return AVERROR_INVALIDDATA;
     }
 
@@ -1451,9 +1473,9 @@
     RTMPContext *rt = s->priv_data;
     int t, ret;
 
-    if (pkt->data_size < 2) {
+    if (pkt->size < 2) {
         av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
-               pkt->data_size);
+               pkt->size);
         return AVERROR_INVALIDDATA;
     }
 
@@ -1477,10 +1499,10 @@
 {
     RTMPContext *rt = s->priv_data;
 
-    if (pkt->data_size < 4) {
+    if (pkt->size < 4) {
         av_log(s, AV_LOG_ERROR,
                "Client bandwidth report packet is less than 4 bytes long (%d)\n",
-               pkt->data_size);
+               pkt->size);
         return AVERROR_INVALIDDATA;
     }
 
@@ -1501,10 +1523,10 @@
 {
     RTMPContext *rt = s->priv_data;
 
-    if (pkt->data_size < 4) {
+    if (pkt->size < 4) {
         av_log(s, AV_LOG_ERROR,
                "Too short server bandwidth report packet (%d)\n",
-               pkt->data_size);
+               pkt->size);
         return AVERROR_INVALIDDATA;
     }
 
@@ -1704,7 +1726,7 @@
 static int handle_invoke_error(URLContext *s, RTMPPacket *pkt)
 {
     RTMPContext *rt = s->priv_data;
-    const uint8_t *data_end = pkt->data + pkt->data_size;
+    const uint8_t *data_end = pkt->data + pkt->size;
     char *tracked_method = NULL;
     int level = AV_LOG_ERROR;
     uint8_t tmpstr[256];
@@ -1752,7 +1774,7 @@
     GetByteContext gbc;
     int ret;
 
-    bytestream2_init(&gbc, p, pkt->data_size);
+    bytestream2_init(&gbc, p, pkt->size);
     if (ff_amf_read_string(&gbc, command, sizeof(command),
                            &stringlen)) {
         av_log(s, AV_LOG_ERROR, "Error in PT_INVOKE\n");
@@ -1804,7 +1826,7 @@
             return ret;
         }
         pp = spkt.data;
-        bytestream2_init_writer(&pbc, pp, spkt.data_size);
+        bytestream2_init_writer(&pbc, pp, spkt.size);
         bytestream2_put_be16(&pbc, 0);          // 0 -> Stream Begin
         bytestream2_put_be32(&pbc, rt->nb_streamid);
         ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
@@ -1863,7 +1885,7 @@
              * if a client creates more than 2^32 - 2 streams. */
         }
     }
-    spkt.data_size = pp - spkt.data;
+    spkt.size = pp - spkt.data;
     ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
                                rt->prev_pkt[1]);
     ff_rtmp_packet_destroy(&spkt);
@@ -1884,7 +1906,7 @@
         return ret;
     }
 
-    if (!memcmp(tracked_method, "connect", 7)) {
+    if (!strcmp(tracked_method, "connect")) {
         if (!rt->is_input) {
             if ((ret = gen_release_stream(s, rt)) < 0)
                 goto fail;
@@ -1910,7 +1932,7 @@
                     goto fail;
             }
         }
-    } else if (!memcmp(tracked_method, "createStream", 12)) {
+    } else if (!strcmp(tracked_method, "createStream")) {
         //extract a number from the result
         if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) {
             av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n");
@@ -1937,7 +1959,7 @@
 static int handle_invoke_status(URLContext *s, RTMPPacket *pkt)
 {
     RTMPContext *rt = s->priv_data;
-    const uint8_t *data_end = pkt->data + pkt->data_size;
+    const uint8_t *data_end = pkt->data + pkt->size;
     const uint8_t *ptr = pkt->data + 11;
     uint8_t tmpstr[256];
     int i, t;
@@ -1962,6 +1984,7 @@
     if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
     if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
     if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
+    if (!t && !strcmp(tmpstr, "NetStream.Seek.Notify")) rt->state = STATE_PLAYING;
 
     return 0;
 }
@@ -1972,23 +1995,23 @@
     int ret = 0;
 
     //TODO: check for the messages sent for wrong state?
-    if (!memcmp(pkt->data, "\002\000\006_error", 9)) {
+    if (ff_amf_match_string(pkt->data, pkt->size, "_error")) {
         if ((ret = handle_invoke_error(s, pkt)) < 0)
             return ret;
-    } else if (!memcmp(pkt->data, "\002\000\007_result", 10)) {
+    } else if (ff_amf_match_string(pkt->data, pkt->size, "_result")) {
         if ((ret = handle_invoke_result(s, pkt)) < 0)
             return ret;
-    } else if (!memcmp(pkt->data, "\002\000\010onStatus", 11)) {
+    } else if (ff_amf_match_string(pkt->data, pkt->size, "onStatus")) {
         if ((ret = handle_invoke_status(s, pkt)) < 0)
             return ret;
-    } else if (!memcmp(pkt->data, "\002\000\010onBWDone", 11)) {
+    } else if (ff_amf_match_string(pkt->data, pkt->size, "onBWDone")) {
         if ((ret = gen_check_bw(s, rt)) < 0)
             return ret;
-    } else if (!memcmp(pkt->data, "\002\000\015releaseStream", 16) ||
-               !memcmp(pkt->data, "\002\000\011FCPublish", 12)     ||
-               !memcmp(pkt->data, "\002\000\007publish", 10)       ||
-               !memcmp(pkt->data, "\002\000\010_checkbw", 11)      ||
-               !memcmp(pkt->data, "\002\000\014createStream", 15)) {
+    } else if (ff_amf_match_string(pkt->data, pkt->size, "releaseStream") ||
+               ff_amf_match_string(pkt->data, pkt->size, "FCPublish")     ||
+               ff_amf_match_string(pkt->data, pkt->size, "publish")       ||
+               ff_amf_match_string(pkt->data, pkt->size, "_checkbw")      ||
+               ff_amf_match_string(pkt->data, pkt->size, "createStream")) {
         if ((ret = send_invoke_response(s, pkt)) < 0)
             return ret;
     }
@@ -2011,7 +2034,7 @@
     unsigned datatowritelength;
 
     p = pkt->data;
-    bytestream2_init(&gbc, p, pkt->data_size);
+    bytestream2_init(&gbc, p, pkt->size);
     if (ff_amf_read_string(&gbc, commandbuffer, sizeof(commandbuffer),
                            &stringlen))
         return AVERROR_INVALIDDATA;
@@ -2125,7 +2148,7 @@
     int ret;
     uint8_t *p;
     const uint8_t *next;
-    uint32_t data_size;
+    uint32_t size;
     uint32_t ts, cts, pts=0;
 
     if (rt->state == STATE_STOPPED)
@@ -2150,6 +2173,17 @@
         }
 
         ret = rtmp_parse_result(s, rt, &rpkt);
+
+        // At this point we must check if we are in the seek state and continue
+        // with the next packet. handle_invoke will get us out of this state
+        // when the right message is encountered
+        if (rt->state == STATE_SEEKING) {
+            ff_rtmp_packet_destroy(&rpkt);
+            // We continue, let the natural flow of things happen:
+            // AVERROR(EAGAIN) or handle_invoke gets us out of here
+            continue;
+        }
+
         if (ret < 0) {//serious error in current packet
             ff_rtmp_packet_destroy(&rpkt);
             return ret;
@@ -2168,24 +2202,25 @@
             ff_rtmp_packet_destroy(&rpkt);
             return 0;
         }
-        if (!rpkt.data_size || !rt->is_input) {
+        if (!rpkt.size || !rt->is_input) {
             ff_rtmp_packet_destroy(&rpkt);
             continue;
         }
         if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO ||
-           (rpkt.type == RTMP_PT_NOTIFY && !memcmp("\002\000\012onMetaData", rpkt.data, 13))) {
+           (rpkt.type == RTMP_PT_NOTIFY &&
+            ff_amf_match_string(rpkt.data, rpkt.size, "onMetaData"))) {
             ts = rpkt.timestamp;
 
             // generate packet header and put data into buffer for FLV demuxer
             rt->flv_off  = 0;
-            rt->flv_size = rpkt.data_size + 15;
+            rt->flv_size = rpkt.size + 15;
             rt->flv_data = p = av_realloc(rt->flv_data, rt->flv_size);
             bytestream_put_byte(&p, rpkt.type);
-            bytestream_put_be24(&p, rpkt.data_size);
+            bytestream_put_be24(&p, rpkt.size);
             bytestream_put_be24(&p, ts);
             bytestream_put_byte(&p, ts >> 24);
             bytestream_put_be24(&p, 0);
-            bytestream_put_buffer(&p, rpkt.data, rpkt.data_size);
+            bytestream_put_buffer(&p, rpkt.data, rpkt.size);
             bytestream_put_be32(&p, 0);
             ff_rtmp_packet_destroy(&rpkt);
             return 0;
@@ -2200,14 +2235,14 @@
         } else if (rpkt.type == RTMP_PT_METADATA) {
             // we got raw FLV data, make it available for FLV demuxer
             rt->flv_off  = 0;
-            rt->flv_size = rpkt.data_size;
+            rt->flv_size = rpkt.size;
             rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
             /* rewrite timestamps */
             next = rpkt.data;
             ts = rpkt.timestamp;
-            while (next - rpkt.data < rpkt.data_size - 11) {
+            while (next - rpkt.data < rpkt.size - 11) {
                 next++;
-                data_size = bytestream_get_be24(&next);
+                size = bytestream_get_be24(&next);
                 p=next;
                 cts = bytestream_get_be24(&next);
                 cts |= bytestream_get_byte(&next) << 24;
@@ -2217,9 +2252,9 @@
                 pts = cts;
                 bytestream_put_be24(&p, ts);
                 bytestream_put_byte(&p, ts >> 24);
-                next += data_size + 3 + 4;
+                next += size + 3 + 4;
             }
-            memcpy(rt->flv_data, rpkt.data, rpkt.data_size);
+            memcpy(rt->flv_data, rpkt.data, rpkt.size);
             ff_rtmp_packet_destroy(&rpkt);
             return 0;
         }
@@ -2234,7 +2269,7 @@
 
     if (!rt->is_input) {
         rt->flv_data = NULL;
-        if (rt->out_pkt.data_size)
+        if (rt->out_pkt.size)
             ff_rtmp_packet_destroy(&rt->out_pkt);
         if (rt->state > STATE_FCPUBLISH)
             ret = gen_fcunpublish_stream(h, rt);
@@ -2276,6 +2311,13 @@
                  hostname, sizeof(hostname), &port,
                  path, sizeof(path), s->filename);
 
+    if (strchr(path, ' ')) {
+        av_log(s, AV_LOG_WARNING,
+               "Detected librtmp style URL parameters, these aren't supported "
+               "by the libavformat internal RTMP handler currently enabled. "
+               "See the documentation for the correct way to pass parameters.\n");
+    }
+
     if (auth[0]) {
         char *ptr = strchr(auth, ':');
         if (ptr) {
@@ -2514,6 +2556,26 @@
     return orig_size;
 }
 
+static int64_t rtmp_seek(URLContext *s, int stream_index, int64_t timestamp,
+                         int flags)
+{
+    RTMPContext *rt = s->priv_data;
+    int ret;
+    av_log(s, AV_LOG_DEBUG,
+           "Seek on stream index %d at timestamp %"PRId64" with flags %08x\n",
+           stream_index, timestamp, flags);
+    if ((ret = gen_seek(s, rt, timestamp)) < 0) {
+        av_log(s, AV_LOG_ERROR,
+               "Unable to send seek command on stream index %d at timestamp "
+               "%"PRId64" with flags %08x\n",
+               stream_index, timestamp, flags);
+        return ret;
+    }
+    rt->flv_off = rt->flv_size;
+    rt->state = STATE_SEEKING;
+    return timestamp;
+}
+
 static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
 {
     RTMPContext *rt = s->priv_data;
@@ -2665,6 +2727,7 @@
     .name           = #flavor,                   \
     .url_open       = rtmp_open,                 \
     .url_read       = rtmp_read,                 \
+    .url_read_seek  = rtmp_seek,                 \
     .url_write      = rtmp_write,                \
     .url_close      = rtmp_close,                \
     .priv_data_size = sizeof(RTMPContext),       \
diff --git a/libavformat/rtp.c b/libavformat/rtp.c
index c4dcf6a..4d41350 100644
--- a/libavformat/rtp.c
+++ b/libavformat/rtp.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/avstring.h"
 #include "libavutil/opt.h"
 #include "avformat.h"
 
@@ -144,7 +145,7 @@
     int i;
 
     for (i = 0; rtp_payload_types[i].pt >= 0; i++)
-        if (!strcmp(buf, rtp_payload_types[i].enc_name) && (codec_type == rtp_payload_types[i].codec_type))
+        if (!av_strcasecmp(buf, rtp_payload_types[i].enc_name) && (codec_type == rtp_payload_types[i].codec_type))
             return rtp_payload_types[i].codec_id;
 
     return AV_CODEC_ID_NONE;
diff --git a/libavformat/rtp.h b/libavformat/rtp.h
index 1732af8..66a4f3a 100644
--- a/libavformat/rtp.h
+++ b/libavformat/rtp.h
@@ -23,6 +23,7 @@
 
 #include "libavformat/avformat.h"
 #include "libavcodec/avcodec.h"
+#include "libavutil/mathematics.h"
 
 /**
  * Return the payload type for a given stream used in the given format context.
@@ -109,4 +110,6 @@
 #define RTP_PT_IS_RTCP(x) (((x) >= RTCP_FIR && (x) <= RTCP_IJ) || \
                            ((x) >= RTCP_SR  && (x) <= RTCP_TOKEN))
 
+#define NTP_TO_RTP_FORMAT(x) av_rescale((x), INT64_C(1) << 32, 1000000)
+
 #endif /* AVFORMAT_RTP_H */
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index b512b89..b2342f1 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -78,8 +78,8 @@
     ff_register_dynamic_payload_handler(&ff_mpeg_video_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_mpeg4_generic_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_mpegts_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfv_handler);
     ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfa_handler);
+    ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfv_handler);
     ff_register_dynamic_payload_handler(&ff_qcelp_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_qdm2_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_qt_rtp_aud_handler);
diff --git a/libavformat/rtpdec.h b/libavformat/rtpdec.h
index 623d911..2a191ec 100644
--- a/libavformat/rtpdec.h
+++ b/libavformat/rtpdec.h
@@ -51,10 +51,6 @@
 void ff_rtp_parse_close(RTPDemuxContext *s);
 int64_t ff_rtp_queued_packet_time(RTPDemuxContext *s);
 void ff_rtp_reset_packet_queue(RTPDemuxContext *s);
-int ff_rtp_get_local_rtp_port(URLContext *h);
-int ff_rtp_get_local_rtcp_port(URLContext *h);
-
-int ff_rtp_set_remote_url(URLContext *h, const char *uri);
 
 /**
  * Send a dummy packet on both port pairs to set up the connection
diff --git a/libavformat/rtpdec_g726.c b/libavformat/rtpdec_g726.c
index ec37f09..7e9ef56 100644
--- a/libavformat/rtpdec_g726.c
+++ b/libavformat/rtpdec_g726.c
@@ -18,11 +18,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "avformat.h"
 #include "rtpdec_formats.h"
 
 #define RTP_G726_HANDLER(bitrate) \
-static int g726_ ## bitrate ##_init(AVFormatContext *s, int st_index, PayloadContext *data) \
+static av_cold int g726_ ## bitrate ##_init(AVFormatContext *s, int st_index, \
+                                            PayloadContext *data) \
 { \
     AVStream *stream = s->streams[st_index]; \
     AVCodecContext *codec = stream->codec; \
diff --git a/libavformat/rtpdec_h263.c b/libavformat/rtpdec_h263.c
index dd7aa60..ae4cc27 100644
--- a/libavformat/rtpdec_h263.c
+++ b/libavformat/rtpdec_h263.c
@@ -21,9 +21,11 @@
 
 #include "avformat.h"
 #include "rtpdec_formats.h"
+#include "libavutil/attributes.h"
 #include "libavutil/intreadwrite.h"
 
-static int h263_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
+static av_cold int h263_init(AVFormatContext *ctx, int st_index,
+                             PayloadContext *data)
 {
     if (st_index < 0)
         return 0;
diff --git a/libavformat/rtpdec_h263_rfc2190.c b/libavformat/rtpdec_h263_rfc2190.c
index 4b6e996..116db75 100644
--- a/libavformat/rtpdec_h263_rfc2190.c
+++ b/libavformat/rtpdec_h263_rfc2190.c
@@ -27,6 +27,7 @@
 
 #include "avformat.h"
 #include "rtpdec_formats.h"
+#include "libavutil/attributes.h"
 #include "libavutil/intreadwrite.h"
 #include "libavcodec/get_bits.h"
 
@@ -55,7 +56,7 @@
     av_free(data);
 }
 
-static int h263_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
+static av_cold int h263_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
 {
     if (st_index < 0)
         return 0;
diff --git a/libavformat/rtpdec_h264.c b/libavformat/rtpdec_h264.c
index d1133b7..be657c0 100644
--- a/libavformat/rtpdec_h264.c
+++ b/libavformat/rtpdec_h264.c
@@ -33,6 +33,7 @@
  *                        FU-B packet types)
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/base64.h"
 #include "libavutil/avstring.h"
 #include "libavcodec/get_bits.h"
@@ -338,7 +339,8 @@
     av_free(data);
 }
 
-static int h264_init(AVFormatContext *s, int st_index, PayloadContext *data)
+static av_cold int h264_init(AVFormatContext *s, int st_index,
+                             PayloadContext *data)
 {
     if (st_index < 0)
         return 0;
diff --git a/libavformat/rtpdec_mpeg12.c b/libavformat/rtpdec_mpeg12.c
index 82e58a0..d73ff1e 100644
--- a/libavformat/rtpdec_mpeg12.c
+++ b/libavformat/rtpdec_mpeg12.c
@@ -19,10 +19,11 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "rtpdec_formats.h"
+#include "libavutil/attributes.h"
 #include "libavutil/intreadwrite.h"
+#include "rtpdec_formats.h"
 
-static int mpeg_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
+static av_cold int mpeg_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
 {
     if (st_index < 0)
         return 0;
diff --git a/libavformat/rtpdec_mpeg4.c b/libavformat/rtpdec_mpeg4.c
index 3f1f244..571b739 100644
--- a/libavformat/rtpdec_mpeg4.c
+++ b/libavformat/rtpdec_mpeg4.c
@@ -29,6 +29,7 @@
 
 #include "rtpdec_formats.h"
 #include "internal.h"
+#include "libavutil/attributes.h"
 #include "libavutil/avstring.h"
 #include "libavcodec/get_bits.h"
 
@@ -252,7 +253,8 @@
     return 0;
 }
 
-static int init_video(AVFormatContext *s, int st_index, PayloadContext *data)
+static av_cold int init_video(AVFormatContext *s, int st_index,
+                              PayloadContext *data)
 {
     if (st_index < 0)
         return 0;
diff --git a/libavformat/rtpdec_mpegts.c b/libavformat/rtpdec_mpegts.c
index cbb8eb4..5b851c4 100644
--- a/libavformat/rtpdec_mpegts.c
+++ b/libavformat/rtpdec_mpegts.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "mpegts.h"
 #include "rtpdec_formats.h"
 
@@ -43,7 +44,8 @@
     av_free(data);
 }
 
-static int mpegts_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
+static av_cold int mpegts_init(AVFormatContext *ctx, int st_index,
+                               PayloadContext *data)
 {
     data->ts = ff_mpegts_parse_open(ctx);
     if (!data->ts)
diff --git a/libavformat/rtpdec_xiph.c b/libavformat/rtpdec_xiph.c
index eddb781..52a94b3 100644
--- a/libavformat/rtpdec_xiph.c
+++ b/libavformat/rtpdec_xiph.c
@@ -27,6 +27,7 @@
  * @author Josh Allmann <joshua.allmann@gmail.com>
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/base64.h"
@@ -69,8 +70,8 @@
     av_free(data);
 }
 
-static int xiph_vorbis_init(AVFormatContext *ctx, int st_index,
-                            PayloadContext *data)
+static av_cold int xiph_vorbis_init(AVFormatContext *ctx, int st_index,
+                                    PayloadContext *data)
 {
     if (st_index < 0)
         return 0;
diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c
index 7adf687..9fd361d 100644
--- a/libavformat/rtpenc.c
+++ b/libavformat/rtpenc.c
@@ -28,8 +28,6 @@
 
 #include "rtpenc.h"
 
-//#define DEBUG
-
 static const AVOption options[] = {
     FF_RTP_FLAG_OPTS(RTPMuxContext, flags),
     { "payload_type", "Specify RTP payload type", offsetof(RTPMuxContext, payload_type), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 127, AV_OPT_FLAG_ENCODING_PARAM },
@@ -278,8 +276,7 @@
     avio_w8(s1->pb, RTCP_SR);
     avio_wb16(s1->pb, 6); /* length in words - 1 */
     avio_wb32(s1->pb, s->ssrc);
-    avio_wb32(s1->pb, ntp_time / 1000000);
-    avio_wb32(s1->pb, ((ntp_time % 1000000) << 32) / 1000000);
+    avio_wb64(s1->pb, NTP_TO_RTP_FORMAT(ntp_time));
     avio_wb32(s1->pb, rtp_ts);
     avio_wb32(s1->pb, s->packet_count);
     avio_wb32(s1->pb, s->octet_count);
diff --git a/libavformat/rtpenc.h b/libavformat/rtpenc.h
index 72a5fa4..b0c9630 100644
--- a/libavformat/rtpenc.h
+++ b/libavformat/rtpenc.h
@@ -38,11 +38,9 @@
     int max_payload_size;
     int num_frames;
 
-    /* rtcp sender statistics receive */
+    /* rtcp sender statistics */
     int64_t last_rtcp_ntp_time;
     int64_t first_rtcp_ntp_time;
-
-    /* rtcp sender statistics */
     unsigned int packet_count;
     unsigned int octet_count;
     unsigned int last_octet_count;
diff --git a/libavformat/rtpenc_chain.c b/libavformat/rtpenc_chain.c
index 70d68ce..9379d94 100644
--- a/libavformat/rtpenc_chain.c
+++ b/libavformat/rtpenc_chain.c
@@ -78,16 +78,19 @@
     avcodec_copy_context(rtpctx->streams[0]->codec, st->codec);
 
     if (handle) {
-        ffio_fdopen(&rtpctx->pb, handle);
+        ret = ffio_fdopen(&rtpctx->pb, handle);
+        if (ret < 0)
+            ffurl_close(handle);
     } else
-        ffio_open_dyn_packet_buf(&rtpctx->pb, packet_size);
-    ret = avformat_write_header(rtpctx, &opts);
+        ret = ffio_open_dyn_packet_buf(&rtpctx->pb, packet_size);
+    if (!ret)
+        ret = avformat_write_header(rtpctx, &opts);
     av_dict_free(&opts);
 
     if (ret) {
-        if (handle) {
+        if (handle && rtpctx->pb) {
             avio_close(rtpctx->pb);
-        } else {
+        } else if (rtpctx->pb) {
             uint8_t *ptr;
             avio_close_dyn_buf(rtpctx->pb, &ptr);
             av_free(ptr);
diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c
index 62ec4c9..bf9c60d 100644
--- a/libavformat/rtpproto.c
+++ b/libavformat/rtpproto.c
@@ -28,7 +28,8 @@
 #include "libavutil/avstring.h"
 #include "avformat.h"
 #include "avio_internal.h"
-#include "rtpdec.h"
+#include "rtp.h"
+#include "rtpproto.h"
 #include "url.h"
 
 #include <stdarg.h>
@@ -42,7 +43,11 @@
 
 typedef struct RTPContext {
     URLContext *rtp_hd, *rtcp_hd;
-    int rtp_fd, rtcp_fd;
+    int rtp_fd, rtcp_fd, nb_ssm_include_addrs, nb_ssm_exclude_addrs;
+    struct sockaddr_storage **ssm_include_addrs, **ssm_exclude_addrs;
+    int write_to_source;
+    struct sockaddr_storage last_rtp_source, last_rtcp_source;
+    socklen_t last_rtp_source_len, last_rtcp_source_len;
 } RTPContext;
 
 /**
@@ -59,22 +64,109 @@
 {
     RTPContext *s = h->priv_data;
     char hostname[256];
-    int port;
+    int port, rtcp_port;
+    const char *p;
 
     char buf[1024];
     char path[1024];
 
     av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port,
                  path, sizeof(path), uri);
+    rtcp_port = port + 1;
+
+    p = strchr(uri, '?');
+    if (p) {
+        if (av_find_info_tag(buf, sizeof(buf), "rtcpport", p)) {
+            rtcp_port = strtol(buf, NULL, 10);
+        }
+    }
 
     ff_url_join(buf, sizeof(buf), "udp", NULL, hostname, port, "%s", path);
     ff_udp_set_remote_url(s->rtp_hd, buf);
 
-    ff_url_join(buf, sizeof(buf), "udp", NULL, hostname, port + 1, "%s", path);
+    ff_url_join(buf, sizeof(buf), "udp", NULL, hostname, rtcp_port, "%s", path);
     ff_udp_set_remote_url(s->rtcp_hd, buf);
     return 0;
 }
 
+static struct addrinfo* rtp_resolve_host(const char *hostname, int port,
+                                         int type, int family, int flags)
+{
+    struct addrinfo hints = { 0 }, *res = 0;
+    int error;
+    char service[16];
+
+    snprintf(service, sizeof(service), "%d", port);
+    hints.ai_socktype = type;
+    hints.ai_family   = family;
+    hints.ai_flags    = flags;
+    if ((error = getaddrinfo(hostname, service, &hints, &res))) {
+        res = NULL;
+        av_log(NULL, AV_LOG_ERROR, "rtp_resolve_host: %s\n", gai_strerror(error));
+    }
+
+    return res;
+}
+
+static int compare_addr(const struct sockaddr_storage *a,
+                        const struct sockaddr_storage *b)
+{
+    if (a->ss_family != b->ss_family)
+        return 1;
+    if (a->ss_family == AF_INET) {
+        return (((const struct sockaddr_in *)a)->sin_addr.s_addr !=
+                ((const struct sockaddr_in *)b)->sin_addr.s_addr);
+    }
+
+#if HAVE_STRUCT_SOCKADDR_IN6
+    if (a->ss_family == AF_INET6) {
+        const uint8_t *s6_addr_a = ((const struct sockaddr_in6 *)a)->sin6_addr.s6_addr;
+        const uint8_t *s6_addr_b = ((const struct sockaddr_in6 *)b)->sin6_addr.s6_addr;
+        return memcmp(s6_addr_a, s6_addr_b, 16);
+    }
+#endif
+    return 1;
+}
+
+static int get_port(const struct sockaddr_storage *ss)
+{
+    if (ss->ss_family == AF_INET)
+        return ntohs(((const struct sockaddr_in *)ss)->sin_port);
+#if HAVE_STRUCT_SOCKADDR_IN6
+    if (ss->ss_family == AF_INET6)
+        return ntohs(((const struct sockaddr_in6 *)ss)->sin6_port);
+#endif
+    return 0;
+}
+
+static void set_port(struct sockaddr_storage *ss, int port)
+{
+    if (ss->ss_family == AF_INET)
+        ((struct sockaddr_in *)ss)->sin_port = htons(port);
+#if HAVE_STRUCT_SOCKADDR_IN6
+    else if (ss->ss_family == AF_INET6)
+        ((struct sockaddr_in6 *)ss)->sin6_port = htons(port);
+#endif
+}
+
+static int rtp_check_source_lists(RTPContext *s, struct sockaddr_storage *source_addr_ptr)
+{
+    int i;
+    if (s->nb_ssm_exclude_addrs) {
+        for (i = 0; i < s->nb_ssm_exclude_addrs; i++) {
+            if (!compare_addr(source_addr_ptr, s->ssm_exclude_addrs[i]))
+                return 1;
+        }
+    }
+    if (s->nb_ssm_include_addrs) {
+        for (i = 0; i < s->nb_ssm_include_addrs; i++) {
+            if (!compare_addr(source_addr_ptr, s->ssm_include_addrs[i]))
+                return 0;
+        }
+        return 1;
+    }
+    return 0;
+}
 
 /**
  * add option to url of the form:
@@ -99,7 +191,9 @@
 static void build_udp_url(char *buf, int buf_size,
                           const char *hostname, int port,
                           int local_port, int ttl,
-                          int max_packet_size, int connect)
+                          int max_packet_size, int connect,
+                          const char *include_sources,
+                          const char *exclude_sources)
 {
     ff_url_join(buf, buf_size, "udp", NULL, hostname, port, NULL);
     if (local_port >= 0)
@@ -111,6 +205,50 @@
     if (connect)
         url_add_option(buf, buf_size, "connect=1");
     url_add_option(buf, buf_size, "fifo_size=0");
+    if (include_sources && include_sources[0])
+        url_add_option(buf, buf_size, "sources=%s", include_sources);
+    if (exclude_sources && exclude_sources[0])
+        url_add_option(buf, buf_size, "block=%s", exclude_sources);
+}
+
+static void rtp_parse_addr_list(URLContext *h, char *buf,
+                                struct sockaddr_storage ***address_list_ptr,
+                                int *address_list_size_ptr)
+{
+    struct addrinfo *ai = NULL;
+    struct sockaddr_storage *source_addr;
+    char tmp = '\0', *p = buf, *next;
+
+    /* Resolve all of the IPs */
+
+    while (p && p[0]) {
+        next = strchr(p, ',');
+
+        if (next) {
+            tmp = *next;
+            *next = '\0';
+        }
+
+        ai = rtp_resolve_host(p, 0, SOCK_DGRAM, AF_UNSPEC, 0);
+        if (ai) {
+            source_addr = av_mallocz(sizeof(struct sockaddr_storage));
+            if (!source_addr)
+                break;
+
+            memcpy(source_addr, ai->ai_addr, ai->ai_addrlen);
+            freeaddrinfo(ai);
+            dynarray_add(address_list_ptr, address_list_size_ptr, source_addr);
+        } else {
+            av_log(h, AV_LOG_WARNING, "Unable to resolve %s\n", p);
+        }
+
+        if (next) {
+            *next = tmp;
+            p = next + 1;
+        } else {
+            p = NULL;
+        }
+    }
 }
 
 /**
@@ -121,6 +259,9 @@
  *         'localrtcpport=n'  : set the local rtcp port to n
  *         'pkt_size=n'       : set max packet size
  *         'connect=0/1'      : do a connect() on the UDP socket
+ *         'sources=ip[,ip]'  : list allowed source IP addresses
+ *         'block=ip[,ip]'    : list disallowed source IP addresses
+ *         'write_to_source=0/1' : send packets to the source address of the latest received packet
  * deprecated option:
  *         'localport=n'      : set the local port to n
  *
@@ -136,7 +277,7 @@
     int rtp_port, rtcp_port,
         ttl, connect,
         local_rtp_port, local_rtcp_port, max_packet_size;
-    char hostname[256];
+    char hostname[256], include_sources[1024] = "", exclude_sources[1024] = "";
     char buf[1024];
     char path[1024];
     const char *p;
@@ -174,11 +315,22 @@
         if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
             connect = strtol(buf, NULL, 10);
         }
+        if (av_find_info_tag(buf, sizeof(buf), "write_to_source", p)) {
+            s->write_to_source = strtol(buf, NULL, 10);
+        }
+        if (av_find_info_tag(buf, sizeof(buf), "sources", p)) {
+            av_strlcpy(include_sources, buf, sizeof(include_sources));
+            rtp_parse_addr_list(h, buf, &s->ssm_include_addrs, &s->nb_ssm_include_addrs);
+        }
+        if (av_find_info_tag(buf, sizeof(buf), "block", p)) {
+            av_strlcpy(exclude_sources, buf, sizeof(exclude_sources));
+            rtp_parse_addr_list(h, buf, &s->ssm_exclude_addrs, &s->nb_ssm_exclude_addrs);
+        }
     }
 
     build_udp_url(buf, sizeof(buf),
                   hostname, rtp_port, local_rtp_port, ttl, max_packet_size,
-                  connect);
+                  connect, include_sources, exclude_sources);
     if (ffurl_open(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
         goto fail;
     if (local_rtp_port>=0 && local_rtcp_port<0)
@@ -186,7 +338,7 @@
 
     build_udp_url(buf, sizeof(buf),
                   hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size,
-                  connect);
+                  connect, include_sources, exclude_sources);
     if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
         goto fail;
 
@@ -210,48 +362,41 @@
 static int rtp_read(URLContext *h, uint8_t *buf, int size)
 {
     RTPContext *s = h->priv_data;
-    struct sockaddr_storage from;
-    socklen_t from_len;
-    int len, n;
+    int len, n, i;
     struct pollfd p[2] = {{s->rtp_fd, POLLIN, 0}, {s->rtcp_fd, POLLIN, 0}};
+    int poll_delay = h->flags & AVIO_FLAG_NONBLOCK ? 0 : 100;
+    struct sockaddr_storage *addrs[2] = { &s->last_rtp_source, &s->last_rtcp_source };
+    socklen_t *addr_lens[2] = { &s->last_rtp_source_len, &s->last_rtcp_source_len };
 
     for(;;) {
         if (ff_check_interrupt(&h->interrupt_callback))
             return AVERROR_EXIT;
-        /* build fdset to listen to RTP and RTCP packets */
-        n = poll(p, 2, 100);
+        n = poll(p, 2, poll_delay);
         if (n > 0) {
-            /* first try RTCP */
-            if (p[1].revents & POLLIN) {
-                from_len = sizeof(from);
-                len = recvfrom (s->rtcp_fd, buf, size, 0,
-                                (struct sockaddr *)&from, &from_len);
+            /* first try RTCP, then RTP */
+            for (i = 1; i >= 0; i--) {
+                if (!(p[i].revents & POLLIN))
+                    continue;
+                *addr_lens[i] = sizeof(*addrs[i]);
+                len = recvfrom(p[i].fd, buf, size, 0,
+                                (struct sockaddr *)addrs[i], addr_lens[i]);
                 if (len < 0) {
                     if (ff_neterrno() == AVERROR(EAGAIN) ||
                         ff_neterrno() == AVERROR(EINTR))
                         continue;
                     return AVERROR(EIO);
                 }
-                break;
-            }
-            /* then RTP */
-            if (p[0].revents & POLLIN) {
-                from_len = sizeof(from);
-                len = recvfrom (s->rtp_fd, buf, size, 0,
-                                (struct sockaddr *)&from, &from_len);
-                if (len < 0) {
-                    if (ff_neterrno() == AVERROR(EAGAIN) ||
-                        ff_neterrno() == AVERROR(EINTR))
-                        continue;
-                    return AVERROR(EIO);
-                }
-                break;
+                if (rtp_check_source_lists(s, addrs[i]))
+                    continue;
+                return len;
             }
         } else if (n < 0) {
             if (ff_neterrno() == AVERROR(EINTR))
                 continue;
             return AVERROR(EIO);
         }
+        if (h->flags & AVIO_FLAG_NONBLOCK)
+            return AVERROR(EAGAIN);
     }
     return len;
 }
@@ -262,6 +407,60 @@
     int ret;
     URLContext *hd;
 
+    if (size < 2)
+        return AVERROR(EINVAL);
+
+    if (s->write_to_source) {
+        int fd;
+        struct sockaddr_storage *source, temp_source;
+        socklen_t *source_len, temp_len;
+        if (!s->last_rtp_source.ss_family && !s->last_rtcp_source.ss_family) {
+            av_log(h, AV_LOG_ERROR,
+                   "Unable to send packet to source, no packets received yet\n");
+            // Intentionally not returning an error here
+            return size;
+        }
+
+        if (RTP_PT_IS_RTCP(buf[1])) {
+            fd = s->rtcp_fd;
+            source     = &s->last_rtcp_source;
+            source_len = &s->last_rtcp_source_len;
+        } else {
+            fd = s->rtp_fd;
+            source     = &s->last_rtp_source;
+            source_len = &s->last_rtp_source_len;
+        }
+        if (!source->ss_family) {
+            source      = &temp_source;
+            source_len  = &temp_len;
+            if (RTP_PT_IS_RTCP(buf[1])) {
+                temp_source = s->last_rtp_source;
+                temp_len    = s->last_rtp_source_len;
+                set_port(source, get_port(source) + 1);
+                av_log(h, AV_LOG_INFO,
+                       "Not received any RTCP packets yet, inferring peer port "
+                       "from the RTP port\n");
+            } else {
+                temp_source = s->last_rtcp_source;
+                temp_len    = s->last_rtcp_source_len;
+                set_port(source, get_port(source) - 1);
+                av_log(h, AV_LOG_INFO,
+                       "Not received any RTP packets yet, inferring peer port "
+                       "from the RTCP port\n");
+            }
+        }
+
+        if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+            ret = ff_network_wait_fd(fd, 1);
+            if (ret < 0)
+                return ret;
+        }
+        ret = sendto(fd, buf, size, 0, (struct sockaddr *) source,
+                     *source_len);
+
+        return ret < 0 ? ff_neterrno() : ret;
+    }
+
     if (RTP_PT_IS_RTCP(buf[1])) {
         /* RTCP payload type */
         hd = s->rtcp_hd;
@@ -277,6 +476,14 @@
 static int rtp_close(URLContext *h)
 {
     RTPContext *s = h->priv_data;
+    int i;
+
+    for (i = 0; i < s->nb_ssm_include_addrs; i++)
+        av_free(s->ssm_include_addrs[i]);
+    av_freep(&s->ssm_include_addrs);
+    for (i = 0; i < s->nb_ssm_exclude_addrs; i++)
+        av_free(s->ssm_exclude_addrs[i]);
+    av_freep(&s->ssm_exclude_addrs);
 
     ffurl_close(s->rtp_hd);
     ffurl_close(s->rtcp_hd);
diff --git a/libavformat/rtpproto.h b/libavformat/rtpproto.h
new file mode 100644
index 0000000..5b243fb
--- /dev/null
+++ b/libavformat/rtpproto.h
@@ -0,0 +1,31 @@
+/*
+ * RTP network protocol
+ *
+ * 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
+ */
+
+#ifndef AVFORMAT_RTPPROTO_H
+#define AVFORMAT_RTPPROTO_H
+
+#include "url.h"
+
+int ff_rtp_set_remote_url(URLContext *h, const char *uri);
+
+int ff_rtp_get_local_rtp_port(URLContext *h);
+int ff_rtp_get_local_rtcp_port(URLContext *h);
+
+#endif /* AVFORMAT_RTPPROTO_H */
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index dc94f0f..2abb36b 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -42,6 +42,7 @@
 #include "rtsp.h"
 
 #include "rtpdec.h"
+#include "rtpproto.h"
 #include "rdt.h"
 #include "rtpdec_formats.h"
 #include "rtpenc_chain.h"
@@ -49,8 +50,6 @@
 #include "rtpenc.h"
 #include "mpegts.h"
 
-//#define DEBUG
-
 /* Timeout values for socket poll, in ms,
  * and read_packet(), in seconds  */
 #define POLL_TIMEOUT_MS 100
@@ -66,8 +65,7 @@
 
 #define RTSP_FLAG_OPTS(name, longname) \
     { name, longname, OFFSET(rtsp_flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtsp_flags" }, \
-    { "filter_src", "Only receive packets from the negotiated peer IP", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_FILTER_SRC}, 0, 0, DEC, "rtsp_flags" }, \
-    { "listen", "Wait for incoming connections", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_LISTEN}, 0, 0, DEC, "rtsp_flags" }
+    { "filter_src", "Only receive packets from the negotiated peer IP", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_FILTER_SRC}, 0, 0, DEC, "rtsp_flags" }
 
 #define RTSP_MEDIATYPE_OPTS(name, longname) \
     { name, longname, OFFSET(media_type_mask), AV_OPT_TYPE_FLAGS, { .i64 = (1 << (AVMEDIA_TYPE_DATA+1)) - 1 }, INT_MIN, INT_MAX, DEC, "allowed_media_types" }, \
@@ -87,18 +85,21 @@
     { "udp_multicast", "UDP multicast", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << RTSP_LOWER_TRANSPORT_UDP_MULTICAST}, 0, 0, DEC, "rtsp_transport" },
     { "http", "HTTP tunneling", 0, AV_OPT_TYPE_CONST, {.i64 = (1 << RTSP_LOWER_TRANSPORT_HTTP)}, 0, 0, DEC, "rtsp_transport" },
     RTSP_FLAG_OPTS("rtsp_flags", "RTSP flags"),
+    { "listen", "Wait for incoming connections", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_LISTEN}, 0, 0, DEC, "rtsp_flags" },
     RTSP_MEDIATYPE_OPTS("allowed_media_types", "Media types to accept from the server"),
     { "min_port", "Minimum local UDP port", OFFSET(rtp_port_min), AV_OPT_TYPE_INT, {.i64 = RTSP_RTP_PORT_MIN}, 0, 65535, DEC|ENC },
     { "max_port", "Maximum local UDP port", OFFSET(rtp_port_max), AV_OPT_TYPE_INT, {.i64 = RTSP_RTP_PORT_MAX}, 0, 65535, DEC|ENC },
     { "timeout", "Maximum timeout (in seconds) to wait for incoming connections. -1 is infinite. Implies flag listen", OFFSET(initial_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, DEC },
     { "stimeout", "timeout (in micro seconds) of socket i/o operations.", OFFSET(stimeout), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC },
     RTSP_REORDERING_OPTS(),
+    { "user-agent", "override User-Agent header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, DEC },
     { NULL },
 };
 
 static const AVOption sdp_options[] = {
     RTSP_FLAG_OPTS("sdp_flags", "SDP flags"),
     { "custom_io", "Use custom IO", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_CUSTOM_IO}, 0, 0, DEC, "rtsp_flags" },
+    { "rtcp_to_source", "Send RTCP packets to the source address of received packets", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_RTCP_TO_SOURCE}, 0, 0, DEC, "rtsp_flags" },
     RTSP_MEDIATYPE_OPTS("allowed_media_types", "Media types to accept from the server"),
     RTSP_REORDERING_OPTS(),
     { NULL },
@@ -290,8 +291,27 @@
     struct sockaddr_storage default_ip;
     int            default_ttl;
     int            skip_media;  ///< set if an unknown m= line occurs
+    int nb_default_include_source_addrs; /**< Number of source-specific multicast include source IP address (from SDP content) */
+    struct RTSPSource **default_include_source_addrs; /**< Source-specific multicast include source IP address (from SDP content) */
+    int nb_default_exclude_source_addrs; /**< Number of source-specific multicast exclude source IP address (from SDP content) */
+    struct RTSPSource **default_exclude_source_addrs; /**< Source-specific multicast exclude source IP address (from SDP content) */
 } SDPParseState;
 
+static void copy_default_source_addrs(struct RTSPSource **addrs, int count,
+                                      struct RTSPSource ***dest, int *dest_count)
+{
+    RTSPSource *rtsp_src, *rtsp_src2;
+    int i;
+    for (i = 0; i < count; i++) {
+        rtsp_src = addrs[i];
+        rtsp_src2 = av_malloc(sizeof(*rtsp_src2));
+        if (!rtsp_src2)
+            continue;
+        memcpy(rtsp_src2, rtsp_src, sizeof(*rtsp_src));
+        dynarray_add(dest, dest_count, rtsp_src2);
+    }
+}
+
 static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
                            int letter, const char *buf)
 {
@@ -302,6 +322,7 @@
     int payload_type, i;
     AVStream *st;
     RTSPStream *rtsp_st;
+    RTSPSource *rtsp_src;
     struct sockaddr_storage sdp_ip;
     int ttl;
 
@@ -370,6 +391,15 @@
         rtsp_st->sdp_ip = s1->default_ip;
         rtsp_st->sdp_ttl = s1->default_ttl;
 
+        copy_default_source_addrs(s1->default_include_source_addrs,
+                                  s1->nb_default_include_source_addrs,
+                                  &rtsp_st->include_source_addrs,
+                                  &rtsp_st->nb_include_source_addrs);
+        copy_default_source_addrs(s1->default_exclude_source_addrs,
+                                  s1->nb_default_exclude_source_addrs,
+                                  &rtsp_st->exclude_source_addrs,
+                                  &rtsp_st->nb_exclude_source_addrs);
+
         get_word(buf1, sizeof(buf1), &p); /* port */
         rtsp_st->sdp_port = atoi(buf1);
 
@@ -499,6 +529,43 @@
             p += strspn(p, SPACE_CHARS);
             if (av_strstart(p, "inline:", &p))
                 get_word(rtsp_st->crypto_params, sizeof(rtsp_st->crypto_params), &p);
+        } else if (av_strstart(p, "source-filter:", &p)) {
+            int exclude = 0;
+            get_word(buf1, sizeof(buf1), &p);
+            if (strcmp(buf1, "incl") && strcmp(buf1, "excl"))
+                return;
+            exclude = !strcmp(buf1, "excl");
+
+            get_word(buf1, sizeof(buf1), &p);
+            if (strcmp(buf1, "IN") != 0)
+                return;
+            get_word(buf1, sizeof(buf1), &p);
+            if (strcmp(buf1, "IP4") && strcmp(buf1, "IP6") && strcmp(buf1, "*"))
+                return;
+            // not checking that the destination address actually matches or is wildcard
+            get_word(buf1, sizeof(buf1), &p);
+
+            while (*p != '\0') {
+                rtsp_src = av_mallocz(sizeof(*rtsp_src));
+                if (!rtsp_src)
+                    return;
+                get_word(rtsp_src->addr, sizeof(rtsp_src->addr), &p);
+                if (exclude) {
+                    if (s->nb_streams == 0) {
+                        dynarray_add(&s1->default_exclude_source_addrs, &s1->nb_default_exclude_source_addrs, rtsp_src);
+                    } else {
+                        rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
+                        dynarray_add(&rtsp_st->exclude_source_addrs, &rtsp_st->nb_exclude_source_addrs, rtsp_src);
+                    }
+                } else {
+                    if (s->nb_streams == 0) {
+                        dynarray_add(&s1->default_include_source_addrs, &s1->nb_default_include_source_addrs, rtsp_src);
+                    } else {
+                        rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
+                        dynarray_add(&rtsp_st->include_source_addrs, &rtsp_st->nb_include_source_addrs, rtsp_src);
+                    }
+                }
+            }
         } else {
             if (rt->server_type == RTSP_SERVER_WMS)
                 ff_wms_parse_sdp_a_line(s, p);
@@ -523,7 +590,7 @@
 {
     RTSPState *rt = s->priv_data;
     const char *p;
-    int letter;
+    int letter, i;
     /* Some SDP lines, particularly for Realmedia or ASF RTSP streams,
      * contain long SDP lines containing complete ASF Headers (several
      * kB) or arrays of MDPR (RM stream descriptor) headers plus
@@ -560,6 +627,14 @@
         if (*p == '\n')
             p++;
     }
+
+    for (i = 0; i < s1->nb_default_include_source_addrs; i++)
+        av_free(s1->default_include_source_addrs[i]);
+    av_freep(&s1->default_include_source_addrs);
+    for (i = 0; i < s1->nb_default_exclude_source_addrs; i++)
+        av_free(s1->default_exclude_source_addrs[i]);
+    av_freep(&s1->default_exclude_source_addrs);
+
     rt->p = av_malloc(sizeof(struct pollfd)*2*(rt->nb_rtsp_streams+1));
     if (!rt->p) return AVERROR(ENOMEM);
     return 0;
@@ -603,7 +678,7 @@
 void ff_rtsp_close_streams(AVFormatContext *s)
 {
     RTSPState *rt = s->priv_data;
-    int i;
+    int i, j;
     RTSPStream *rtsp_st;
 
     ff_rtsp_undo_setup(s);
@@ -613,6 +688,13 @@
             if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context)
                 rtsp_st->dynamic_handler->free(
                     rtsp_st->dynamic_protocol_context);
+            for (j = 0; j < rtsp_st->nb_include_source_addrs; j++)
+                av_free(rtsp_st->include_source_addrs[j]);
+            av_freep(&rtsp_st->include_source_addrs);
+            for (j = 0; j < rtsp_st->nb_exclude_source_addrs; j++)
+                av_free(rtsp_st->exclude_source_addrs[j]);
+            av_freep(&rtsp_st->exclude_source_addrs);
+
             av_free(rtsp_st);
         }
     }
@@ -1120,11 +1202,11 @@
  *
  * @return zero if success, nonzero otherwise
  */
-static int ff_rtsp_send_cmd_with_content_async(AVFormatContext *s,
-                                               const char *method, const char *url,
-                                               const char *headers,
-                                               const unsigned char *send_content,
-                                               int send_content_length)
+static int rtsp_send_cmd_with_content_async(AVFormatContext *s,
+                                            const char *method, const char *url,
+                                            const char *headers,
+                                            const unsigned char *send_content,
+                                            int send_content_length)
 {
     RTSPState *rt = s->priv_data;
     char buf[4096], *out_buf;
@@ -1137,6 +1219,7 @@
     if (headers)
         av_strlcat(buf, headers, sizeof(buf));
     av_strlcatf(buf, sizeof(buf), "CSeq: %d\r\n", rt->seq);
+    av_strlcatf(buf, sizeof(buf), "User-Agent: %s\r\n",  rt->user_agent);
     if (rt->session_id[0] != '\0' && (!headers ||
         !strstr(headers, "\nIf-Match:"))) {
         av_strlcatf(buf, sizeof(buf), "Session: %s\r\n", rt->session_id);
@@ -1177,7 +1260,7 @@
 int ff_rtsp_send_cmd_async(AVFormatContext *s, const char *method,
                            const char *url, const char *headers)
 {
-    return ff_rtsp_send_cmd_with_content_async(s, method, url, headers, NULL, 0);
+    return rtsp_send_cmd_with_content_async(s, method, url, headers, NULL, 0);
 }
 
 int ff_rtsp_send_cmd(AVFormatContext *s, const char *method, const char *url,
@@ -1202,9 +1285,9 @@
 
 retry:
     cur_auth_type = rt->auth_state.auth_type;
-    if ((ret = ff_rtsp_send_cmd_with_content_async(s, method, url, header,
-                                                   send_content,
-                                                   send_content_length)))
+    if ((ret = rtsp_send_cmd_with_content_async(s, method, url, header,
+                                                send_content,
+                                                send_content_length)))
         return ret;
 
     if ((ret = ff_rtsp_read_reply(s, reply, content_ptr, 0, method) ) < 0)
@@ -1399,18 +1482,15 @@
 
         case RTSP_LOWER_TRANSPORT_UDP: {
             char url[1024], options[30] = "";
+            const char *peer = host;
 
             if (rt->rtsp_flags & RTSP_FLAG_FILTER_SRC)
                 av_strlcpy(options, "?connect=1", sizeof(options));
             /* Use source address if specified */
-            if (reply->transports[0].source[0]) {
-                ff_url_join(url, sizeof(url), "rtp", NULL,
-                            reply->transports[0].source,
-                            reply->transports[0].server_port_min, "%s", options);
-            } else {
-                ff_url_join(url, sizeof(url), "rtp", NULL, host,
-                            reply->transports[0].server_port_min, "%s", options);
-            }
+            if (reply->transports[0].source[0])
+                peer = reply->transports[0].source;
+            ff_url_join(url, sizeof(url), "rtp", NULL, peer,
+                        reply->transports[0].server_port_min, "%s", options);
             if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) &&
                 ff_rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
                 err = AVERROR_INVALIDDATA;
@@ -2030,7 +2110,7 @@
     while (p < p_end && *p != '\0') {
         if (p + sizeof("c=IN IP") - 1 < p_end &&
             av_strstart(p, "c=IN IP", NULL))
-            return AVPROBE_SCORE_MAX / 2;
+            return AVPROBE_SCORE_EXTENSION;
 
         while (p < p_end - 1 && *p != '\n') p++;
         if (++p >= p_end)
@@ -2041,6 +2121,17 @@
     return 0;
 }
 
+static void append_source_addrs(char *buf, int size, const char *name,
+                                int count, struct RTSPSource **addrs)
+{
+    int i;
+    if (!count)
+        return;
+    av_strlcatf(buf, size, "&%s=%s", name, addrs[0]->addr);
+    for (i = 1; i < count; i++)
+        av_strlcatf(buf, size, ",%s", addrs[i]->addr);
+}
+
 static int sdp_read_header(AVFormatContext *s)
 {
     RTSPState *rt = s->priv_data;
@@ -2081,9 +2172,17 @@
                         namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
             ff_url_join(url, sizeof(url), "rtp", NULL,
                         namebuf, rtsp_st->sdp_port,
-                        "?localport=%d&ttl=%d&connect=%d", rtsp_st->sdp_port,
-                        rtsp_st->sdp_ttl,
-                        rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0);
+                        "?localport=%d&ttl=%d&connect=%d&write_to_source=%d",
+                        rtsp_st->sdp_port, rtsp_st->sdp_ttl,
+                        rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0,
+                        rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0);
+
+            append_source_addrs(url, sizeof(url), "sources",
+                                rtsp_st->nb_include_source_addrs,
+                                rtsp_st->include_source_addrs);
+            append_source_addrs(url, sizeof(url), "block",
+                                rtsp_st->nb_exclude_source_addrs,
+                                rtsp_st->exclude_source_addrs);
             if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
                            &s->interrupt_callback, NULL) < 0) {
                 err = AVERROR_INVALIDDATA;
diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
index 4af3507..2dc4b6c 100644
--- a/libavformat/rtsp.h
+++ b/libavformat/rtsp.h
@@ -399,6 +399,11 @@
      * Size of RTP packet reordering queue.
      */
     int reordering_queue_size;
+
+    /**
+     * User-Agent string
+     */
+    char *user_agent;
 } RTSPState;
 
 #define RTSP_FLAG_FILTER_SRC  0x1    /**< Filter incoming UDP packets -
@@ -406,6 +411,12 @@
                                           source address and port. */
 #define RTSP_FLAG_LISTEN      0x2    /**< Wait for incoming connections. */
 #define RTSP_FLAG_CUSTOM_IO   0x4    /**< Do all IO via the AVIOContext. */
+#define RTSP_FLAG_RTCP_TO_SOURCE 0x8 /**< Send RTCP packets to the source
+                                          address of received packets. */
+
+typedef struct RTSPSource {
+    char addr[128]; /**< Source-specific multicast include source IP address (from SDP content) */
+} RTSPSource;
 
 /**
  * Describe a single stream, as identified by a single m= line block in the
@@ -430,6 +441,10 @@
     //@{
     int sdp_port;             /**< port (from SDP content) */
     struct sockaddr_storage sdp_ip; /**< IP address (from SDP content) */
+    int nb_include_source_addrs; /**< Number of source-specific multicast include source IP addresses (from SDP content) */
+    struct RTSPSource **include_source_addrs; /**< Source-specific multicast include source IP addresses (from SDP content) */
+    int nb_exclude_source_addrs; /**< Number of source-specific multicast exclude source IP addresses (from SDP content) */
+    struct RTSPSource **exclude_source_addrs; /**< Source-specific multicast exclude source IP addresses (from SDP content) */
     int sdp_ttl;              /**< IP Time-To-Live (from SDP content) */
     int sdp_payload_type;     /**< payload type */
     //@}
diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c
index da571a8..3615226 100644
--- a/libavformat/rtspdec.c
+++ b/libavformat/rtspdec.c
@@ -29,6 +29,7 @@
 #include "internal.h"
 #include "network.h"
 #include "os_support.h"
+#include "rtpproto.h"
 #include "rtsp.h"
 #include "rdt.h"
 #include "url.h"
diff --git a/libavformat/rtspenc.c b/libavformat/rtspenc.c
index bad6fbd..bea1831 100644
--- a/libavformat/rtspenc.c
+++ b/libavformat/rtspenc.c
@@ -145,6 +145,7 @@
     uint8_t *interleave_header, *interleaved_packet;
 
     size = avio_close_dyn_buf(rtpctx->pb, &buf);
+    rtpctx->pb = NULL;
     ptr = buf;
     while (size > 4) {
         uint32_t packet_len = AV_RB32(ptr);
@@ -171,8 +172,7 @@
         size -= packet_len;
     }
     av_free(buf);
-    ffio_open_dyn_packet_buf(&rtpctx->pb, RTSP_TCP_MAX_PACKET_SIZE);
-    return 0;
+    return ffio_open_dyn_packet_buf(&rtpctx->pb, RTSP_TCP_MAX_PACKET_SIZE);
 }
 
 static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt)
diff --git a/libavformat/sctp.c b/libavformat/sctp.c
index 2fd5400..e3585b4 100644
--- a/libavformat/sctp.c
+++ b/libavformat/sctp.c
@@ -56,10 +56,10 @@
 
 /*
  * The sctp_recvmsg and sctp_sendmsg functions are part of the user
- * library that offers support
- * for the SCTP kernel Implementation. The main purpose of this
- * code is to provide the SCTP Socket API mappings for user
- * application to interface with the SCTP in kernel.
+ * library that offers support for the SCTP kernel Implementation.
+ * To avoid build-time clashes the functions sport an ff_-prefix here.
+ * The main purpose of this code is to provide the SCTP Socket API
+ * mappings for user applications to interface with SCTP in the kernel.
  *
  * This implementation is based on the Socket API Extensions for SCTP
  * defined in <draft-ietf-tsvwg-sctpsocket-10.txt>
@@ -198,7 +198,7 @@
 
     cur_ai = ai;
 
-    fd = socket(cur_ai->ai_family, SOCK_STREAM, IPPROTO_SCTP);
+    fd = ff_socket(cur_ai->ai_family, SOCK_STREAM, IPPROTO_SCTP);
     if (fd < 0)
         goto fail;
 
diff --git a/libavformat/seek-test.c b/libavformat/seek-test.c
index 34ac4de..8b0611d 100644
--- a/libavformat/seek-test.c
+++ b/libavformat/seek-test.c
@@ -64,6 +64,7 @@
     int64_t seekfirst = AV_NOPTS_VALUE;
     int firstback=0;
     int frame_count = 1;
+    int duration = 4;
 
     for(i=2; i<argc; i+=2){
         if       (!strcmp(argv[i], "-seekforw")){
@@ -73,6 +74,8 @@
             firstback = 1;
         } else if(!strcmp(argv[i], "-frames")){
             frame_count = atoi(argv[i+1]);
+        } else if(!strcmp(argv[i], "-duration")){
+            duration = atoi(argv[i+1]);
         } else {
             argc = 1;
         }
@@ -133,7 +136,7 @@
         if(i>25) break;
 
         stream_id= (i>>1)%(ic->nb_streams+1) - 1;
-        timestamp= (i*19362894167LL) % (4*AV_TIME_BASE) - AV_TIME_BASE;
+        timestamp= (i*19362894167LL) % (duration*AV_TIME_BASE) - AV_TIME_BASE;
         if(stream_id>=0){
             st= ic->streams[stream_id];
             timestamp= av_rescale_q(timestamp, AV_TIME_BASE_Q, st->time_base);
diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c
index a33ad85..232a931 100644
--- a/libavformat/segafilm.c
+++ b/libavformat/segafilm.c
@@ -215,6 +215,8 @@
         film->sample_table[i].sample_offset =
             data_offset + AV_RB32(&scratch[0]);
         film->sample_table[i].sample_size = AV_RB32(&scratch[4]);
+        if (film->sample_table[i].sample_size > INT_MAX / 4)
+            return AVERROR_INVALIDDATA;
         if (AV_RB32(&scratch[8]) == 0xFFFFFFFF) {
             film->sample_table[i].stream = film->audio_stream_index;
             film->sample_table[i].pts = audio_frame_counter;
diff --git a/libavformat/segment.c b/libavformat/segment.c
index dbcfe89..95984bd 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -43,6 +43,7 @@
     int index;
     double start_time, end_time;
     int64_t start_pts;
+    int64_t offset_pts;
     char filename[1024];
     struct SegmentListEntry *next;
 } SegmentListEntry;
@@ -85,12 +86,12 @@
     int nb_frames;         ///< number of elments in the frames array
     int frame_count;
 
-    char *time_delta_str;  ///< approximation value duration used for the segment times
     int64_t time_delta;
     int  individual_header_trailer; /**< Set by a private option. */
     int  write_header_trailer; /**< Set by a private option. */
 
     int reset_timestamps;  ///< reset timestamps at the begin of each segment
+    int64_t initial_offset;    ///< initial timestamps offset, expressed in microseconds
     char *reference_stream_specifier; ///< reference stream specifier
     int   reference_stream_index;
 
@@ -554,15 +555,6 @@
         }
     }
 
-    if (seg->time_delta_str) {
-        if ((ret = av_parse_time(&seg->time_delta, seg->time_delta_str, 1)) < 0) {
-            av_log(s, AV_LOG_ERROR,
-                   "Invalid time duration specification '%s' for delta option\n",
-                   seg->time_delta_str);
-            return ret;
-        }
-    }
-
     if (seg->list) {
         if (seg->list_type == LIST_TYPE_UNDEFINED) {
             if      (av_match_ext(seg->list, "csv" )) seg->list_type = LIST_TYPE_CSV;
@@ -644,7 +636,7 @@
     SegmentContext *seg = s->priv_data;
     AVFormatContext *oc = seg->avf;
     AVStream *st = s->streams[pkt->stream_index];
-    int64_t end_pts = INT64_MAX;
+    int64_t end_pts = INT64_MAX, offset;
     int start_frame = INT_MAX;
     int ret;
 
@@ -694,23 +686,23 @@
         seg->is_first_pkt = 0;
     }
 
-    if (seg->reset_timestamps) {
-        av_log(s, AV_LOG_DEBUG, "stream:%d start_pts_time:%s pts:%s pts_time:%s dts:%s dts_time:%s",
-               pkt->stream_index,
-               av_ts2timestr(seg->cur_entry.start_pts, &AV_TIME_BASE_Q),
-               av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
-               av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
+    av_log(s, AV_LOG_DEBUG, "stream:%d start_pts_time:%s pts:%s pts_time:%s dts:%s dts_time:%s",
+           pkt->stream_index,
+           av_ts2timestr(seg->cur_entry.start_pts, &AV_TIME_BASE_Q),
+           av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
+           av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
 
-        /* compute new timestamps */
-        if (pkt->pts != AV_NOPTS_VALUE)
-            pkt->pts -= av_rescale_q(seg->cur_entry.start_pts, AV_TIME_BASE_Q, st->time_base);
-        if (pkt->dts != AV_NOPTS_VALUE)
-            pkt->dts -= av_rescale_q(seg->cur_entry.start_pts, AV_TIME_BASE_Q, st->time_base);
+    /* compute new timestamps */
+    offset = av_rescale_q(seg->initial_offset - (seg->reset_timestamps ? seg->cur_entry.start_pts : 0),
+                          AV_TIME_BASE_Q, st->time_base);
+    if (pkt->pts != AV_NOPTS_VALUE)
+        pkt->pts += offset;
+    if (pkt->dts != AV_NOPTS_VALUE)
+        pkt->dts += offset;
 
-        av_log(s, AV_LOG_DEBUG, " -> pts:%s pts_time:%s dts:%s dts_time:%s\n",
-               av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
-               av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
-    }
+    av_log(s, AV_LOG_DEBUG, " -> pts:%s pts_time:%s dts:%s dts_time:%s\n",
+           av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
+           av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
 
     ret = ff_write_chained(oc, pkt->stream_index, pkt, s);
 
@@ -784,7 +776,7 @@
     { "hls", "Apple HTTP Live Streaming compatible", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_M3U8 }, INT_MIN, INT_MAX, E, "list_type" },
 
     { "segment_time",      "set segment duration",                       OFFSET(time_str),AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       E },
-    { "segment_time_delta","set approximation value used for the segment times", OFFSET(time_delta_str), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, E },
+    { "segment_time_delta","set approximation value used for the segment times", OFFSET(time_delta), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, 0, E },
     { "segment_times",     "set segment split time points",              OFFSET(times_str),AV_OPT_TYPE_STRING,{.str = NULL},  0, 0,       E },
     { "segment_frames",    "set segment split frame numbers",            OFFSET(frames_str),AV_OPT_TYPE_STRING,{.str = NULL},  0, 0,       E },
     { "segment_wrap",      "set number after which the index wraps",     OFFSET(segment_idx_wrap), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
@@ -793,6 +785,7 @@
     { "individual_header_trailer", "write header/trailer to each segment", OFFSET(individual_header_trailer), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E },
     { "write_header_trailer", "write a header to the first segment and a trailer to the last one", OFFSET(write_header_trailer), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E },
     { "reset_timestamps", "reset timestamps at the begin of each segment", OFFSET(reset_timestamps), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, E },
+    { "initial_offset", "set initial timestamp offset", OFFSET(initial_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, -INT64_MAX, INT64_MAX, E },
     { NULL },
 };
 
diff --git a/libavformat/sierravmd.c b/libavformat/sierravmd.c
index b0b582d..b2d1e5d 100644
--- a/libavformat/sierravmd.c
+++ b/libavformat/sierravmd.c
@@ -64,8 +64,8 @@
 
 static int vmd_probe(AVProbeData *p)
 {
-    int w, h;
-    if (p->buf_size < 16)
+    int w, h, sample_rate;
+    if (p->buf_size < 806)
         return 0;
     /* check if the first 2 bytes of the file contain the appropriate size
      * of a VMD header chunk */
@@ -73,23 +73,25 @@
         return 0;
     w = AV_RL16(&p->buf[12]);
     h = AV_RL16(&p->buf[14]);
-    if (!w || w > 2048 || !h || h > 2048)
+    sample_rate = AV_RL16(&p->buf[804]);
+    if ((!w || w > 2048 || !h || h > 2048) &&
+        sample_rate != 22050)
         return 0;
 
     /* only return half certainty since this check is a bit sketchy */
-    return AVPROBE_SCORE_MAX / 2;
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 static int vmd_read_header(AVFormatContext *s)
 {
     VmdDemuxContext *vmd = s->priv_data;
     AVIOContext *pb = s->pb;
-    AVStream *st = NULL, *vst;
+    AVStream *st = NULL, *vst = NULL;
     unsigned int toc_offset;
     unsigned char *raw_frame_table;
     int raw_frame_table_size;
     int64_t current_offset;
-    int i, j;
+    int i, j, width, height;
     unsigned int total_frames;
     int64_t current_audio_pts = 0;
     unsigned char chunk[BYTES_PER_FRAME_RECORD];
@@ -101,28 +103,33 @@
     if (avio_read(pb, vmd->vmd_header, VMD_HEADER_SIZE) != VMD_HEADER_SIZE)
         return AVERROR(EIO);
 
-    if(vmd->vmd_header[24] == 'i' && vmd->vmd_header[25] == 'v' && vmd->vmd_header[26] == '3')
-        vmd->is_indeo3 = 1;
-    else
-        vmd->is_indeo3 = 0;
-    /* start up the decoders */
-    vst = avformat_new_stream(s, NULL);
-    if (!vst)
-        return AVERROR(ENOMEM);
-    avpriv_set_pts_info(vst, 33, 1, 10);
-    vmd->video_stream_index = vst->index;
-    vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
-    vst->codec->codec_id = vmd->is_indeo3 ? AV_CODEC_ID_INDEO3 : AV_CODEC_ID_VMDVIDEO;
-    vst->codec->codec_tag = 0;  /* no fourcc */
-    vst->codec->width = AV_RL16(&vmd->vmd_header[12]);
-    vst->codec->height = AV_RL16(&vmd->vmd_header[14]);
-    if(vmd->is_indeo3 && vst->codec->width > 320){
-        vst->codec->width >>= 1;
-        vst->codec->height >>= 1;
+    width = AV_RL16(&vmd->vmd_header[12]);
+    height = AV_RL16(&vmd->vmd_header[14]);
+    if (width && height) {
+        if(vmd->vmd_header[24] == 'i' && vmd->vmd_header[25] == 'v' && vmd->vmd_header[26] == '3') {
+            vmd->is_indeo3 = 1;
+        } else {
+            vmd->is_indeo3 = 0;
+        }
+        /* start up the decoders */
+        vst = avformat_new_stream(s, NULL);
+        if (!vst)
+            return AVERROR(ENOMEM);
+        avpriv_set_pts_info(vst, 33, 1, 10);
+        vmd->video_stream_index = vst->index;
+        vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+        vst->codec->codec_id = vmd->is_indeo3 ? AV_CODEC_ID_INDEO3 : AV_CODEC_ID_VMDVIDEO;
+        vst->codec->codec_tag = 0;  /* no fourcc */
+        vst->codec->width = width;
+        vst->codec->height = height;
+        if(vmd->is_indeo3 && vst->codec->width > 320){
+            vst->codec->width >>= 1;
+            vst->codec->height >>= 1;
+        }
+        vst->codec->extradata_size = VMD_HEADER_SIZE;
+        vst->codec->extradata = av_mallocz(VMD_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
+        memcpy(vst->codec->extradata, vmd->vmd_header, VMD_HEADER_SIZE);
     }
-    vst->codec->extradata_size = VMD_HEADER_SIZE;
-    vst->codec->extradata = av_mallocz(VMD_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
-    memcpy(vst->codec->extradata, vmd->vmd_header, VMD_HEADER_SIZE);
 
     /* if sample rate is 0, assume no audio */
     vmd->sample_rate = AV_RL16(&vmd->vmd_header[804]);
@@ -156,7 +163,8 @@
         num = st->codec->block_align;
         den = st->codec->sample_rate * st->codec->channels;
         av_reduce(&num, &den, num, den, (1UL<<31)-1);
-        avpriv_set_pts_info(vst, 33, num, den);
+        if (vst)
+            avpriv_set_pts_info(vst, 33, num, den);
         avpriv_set_pts_info(st, 33, num, den);
     }
 
diff --git a/libavformat/smacker.c b/libavformat/smacker.c
index 84481e2..b4c1bf4 100644
--- a/libavformat/smacker.c
+++ b/libavformat/smacker.c
@@ -210,7 +210,8 @@
 
 
     /* load trees to extradata, they will be unpacked by decoder */
-    st->codec->extradata = av_malloc(smk->treesize + 16 + FF_INPUT_BUFFER_PADDING_SIZE);
+    st->codec->extradata = av_mallocz(smk->treesize + 16 +
+                                      FF_INPUT_BUFFER_PADDING_SIZE);
     st->codec->extradata_size = smk->treesize + 16;
     if(!st->codec->extradata){
         av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16);
@@ -276,7 +277,7 @@
                 } else if(t & 0x40){ /* copy with offset */
                     off = avio_r8(s->pb);
                     j = (t & 0x3F) + 1;
-                    if (off + j - 1 > 0xff) {
+                    if (off + j > 0x100) {
                         av_log(s, AV_LOG_ERROR,
                                "Invalid palette update, offset=%d length=%d extends beyond palette size\n",
                                off, j);
@@ -305,12 +306,14 @@
         /* if audio chunks are present, put them to stack and retrieve later */
         for(i = 0; i < 7; i++) {
             if(flags & 1) {
-                unsigned int size;
+                uint32_t size;
                 uint8_t *tmpbuf;
 
                 size = avio_rl32(s->pb) - 4;
-                if(size + 4L > frame_size)
+                if (!size || size + 4L > frame_size) {
+                    av_log(s, AV_LOG_ERROR, "Invalid audio part size\n");
                     return AVERROR_INVALIDDATA;
+                }
                 frame_size -= size;
                 frame_size -= 4;
                 smk->curstream++;
@@ -338,6 +341,7 @@
         if(ret != frame_size)
             return AVERROR(EIO);
         pkt->stream_index = smk->videoindex;
+        pkt->pts          = smk->cur_frame;
         pkt->size = ret + 769;
         smk->cur_frame++;
         smk->nextpos = avio_tell(s->pb);
diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c
index 096bf79..7163c90 100644
--- a/libavformat/smoothstreamingenc.c
+++ b/libavformat/smoothstreamingenc.c
@@ -428,7 +428,7 @@
         if (len < 8 || len >= *moof_size)
             goto fail;
         if (tag == MKTAG('u','u','i','d')) {
-            const uint8_t tfxd[] = {
+            static const uint8_t tfxd[] = {
                 0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
                 0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
             };
diff --git a/libavformat/spdifdec.c b/libavformat/spdifdec.c
index 726a85c..6984350 100644
--- a/libavformat/spdifdec.c
+++ b/libavformat/spdifdec.c
@@ -154,10 +154,10 @@
 
     if (sync_codes >= 6)
         /* good amount of sync codes but with unexpected offsets */
-        return AVPROBE_SCORE_MAX / 2;
+        return AVPROBE_SCORE_EXTENSION;
 
     /* some sync codes were found */
-    return AVPROBE_SCORE_MAX / 8;
+    return AVPROBE_SCORE_EXTENSION / 4;
 }
 
 static int spdif_read_header(AVFormatContext *s)
diff --git a/libavformat/spdifenc.c b/libavformat/spdifenc.c
index 857c20d..210d63f 100644
--- a/libavformat/spdifenc.c
+++ b/libavformat/spdifenc.c
@@ -92,7 +92,7 @@
 { NULL },
 };
 
-static const AVClass class = {
+static const AVClass spdif_class = {
     .class_name     = "spdif",
     .item_name      = av_default_item_name,
     .option         = options,
@@ -395,15 +395,15 @@
 {
     IEC61937Context *ctx = s->priv_data;
     int mat_code_length = 0;
-    const char mat_end_code[16] = { 0xC3, 0xC2, 0xC0, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x11 };
+    static const char mat_end_code[16] = { 0xC3, 0xC2, 0xC0, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x11 };
 
     if (!ctx->hd_buf_count) {
-        const char mat_start_code[20] = { 0x07, 0x9E, 0x00, 0x03, 0x84, 0x01, 0x01, 0x01, 0x80, 0x00, 0x56, 0xA5, 0x3B, 0xF4, 0x81, 0x83, 0x49, 0x80, 0x77, 0xE0 };
+        static const char mat_start_code[20] = { 0x07, 0x9E, 0x00, 0x03, 0x84, 0x01, 0x01, 0x01, 0x80, 0x00, 0x56, 0xA5, 0x3B, 0xF4, 0x81, 0x83, 0x49, 0x80, 0x77, 0xE0 };
         mat_code_length = sizeof(mat_start_code) + BURST_HEADER_SIZE;
         memcpy(ctx->hd_buf, mat_start_code, sizeof(mat_start_code));
 
     } else if (ctx->hd_buf_count == 12) {
-        const char mat_middle_code[12] = { 0xC3, 0xC1, 0x42, 0x49, 0x3B, 0xFA, 0x82, 0x83, 0x49, 0x80, 0x77, 0xE0 };
+        static const char mat_middle_code[12] = { 0xC3, 0xC1, 0x42, 0x49, 0x3B, 0xFA, 0x82, 0x83, 0x49, 0x80, 0x77, 0xE0 };
         mat_code_length = sizeof(mat_middle_code) + MAT_MIDDLE_CODE_OFFSET;
         memcpy(&ctx->hd_buf[12 * TRUEHD_FRAME_OFFSET - BURST_HEADER_SIZE + MAT_MIDDLE_CODE_OFFSET],
                mat_middle_code, sizeof(mat_middle_code));
@@ -552,5 +552,5 @@
     .write_packet      = spdif_write_packet,
     .write_trailer     = spdif_write_trailer,
     .flags             = AVFMT_NOTIMESTAMPS,
-    .priv_class        = &class,
+    .priv_class        = &spdif_class,
 };
diff --git a/libavformat/srtdec.c b/libavformat/srtdec.c
index 76e06e4..dbf1866 100644
--- a/libavformat/srtdec.c
+++ b/libavformat/srtdec.c
@@ -63,10 +63,12 @@
             int64_t start = (hh1*3600LL + mm1*60LL + ss1) * 1000LL + ms1;
             int64_t end   = (hh2*3600LL + mm2*60LL + ss2) * 1000LL + ms2;
             *duration = end - start;
-            *buf += strcspn(*buf, "\n") + 1;
+            *buf += strcspn(*buf, "\n");
+            *buf += !!**buf;
             return start;
         }
-        *buf += strcspn(*buf, "\n") + 1;
+        *buf += strcspn(*buf, "\n");
+        *buf += !!**buf;
     }
     return AV_NOPTS_VALUE;
 }
diff --git a/libavformat/subviewer1dec.c b/libavformat/subviewer1dec.c
index 0dc1942..1b831b7 100644
--- a/libavformat/subviewer1dec.c
+++ b/libavformat/subviewer1dec.c
@@ -36,7 +36,7 @@
     const unsigned char *ptr = p->buf;
 
     if (strstr(ptr, "******** START SCRIPT ********"))
-        return AVPROBE_SCORE_MAX / 2;
+        return AVPROBE_SCORE_EXTENSION;
     return 0;
 }
 
diff --git a/libavformat/subviewerdec.c b/libavformat/subviewerdec.c
index 7cacd97..9e645d2 100644
--- a/libavformat/subviewerdec.c
+++ b/libavformat/subviewerdec.c
@@ -44,7 +44,7 @@
     if (AV_RB24(ptr) == 0xEFBBBF)
         ptr += 3;  /* skip UTF-8 BOM */
     if (sscanf(ptr, "%*u:%*u:%*u.%*u,%*u:%*u:%*u.%*u%c", &c) == 1)
-        return AVPROBE_SCORE_MAX/2;
+        return AVPROBE_SCORE_EXTENSION;
     if (!strncmp(ptr, "[INFORMATION]", 13))
         return AVPROBE_SCORE_MAX/3;
     return 0;
diff --git a/libavformat/swf.h b/libavformat/swf.h
index b9722c1..c1667b3 100644
--- a/libavformat/swf.h
+++ b/libavformat/swf.h
@@ -120,9 +120,6 @@
 #define VIDEO_ID 0
 #define SHAPE_ID  1
 
-#undef NDEBUG
-#include <assert.h>
-
 typedef struct SWFContext {
     int64_t duration_pos;
     int64_t tag_pos;
diff --git a/libavformat/swfenc.c b/libavformat/swfenc.c
index 7018362..8d9cf0c 100644
--- a/libavformat/swfenc.c
+++ b/libavformat/swfenc.c
@@ -234,7 +234,7 @@
     }
 
     if (!swf->audio_enc)
-        swf->samples_per_frame = (44100. * rate_base) / rate;
+        swf->samples_per_frame = (44100.0 * rate_base) / rate;
     else
         swf->samples_per_frame = (swf->audio_enc->sample_rate * rate_base) / rate;
 
diff --git a/libavformat/takdec.c b/libavformat/takdec.c
index 377c10c..2ed8a1e 100644
--- a/libavformat/takdec.c
+++ b/libavformat/takdec.c
@@ -19,8 +19,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/crc.h"
 #include "libavcodec/tak.h"
 #include "avformat.h"
+#include "avio_internal.h"
 #include "internal.h"
 #include "rawdec.h"
 #include "apetag.h"
@@ -33,10 +35,16 @@
 static int tak_probe(AVProbeData *p)
 {
     if (!memcmp(p->buf, "tBaK", 4))
-        return AVPROBE_SCORE_MAX / 2;
+        return AVPROBE_SCORE_EXTENSION;
     return 0;
 }
 
+static unsigned long tak_check_crc(unsigned long checksum, const uint8_t *buf,
+                                   unsigned int len)
+{
+    return av_crc(av_crc_get_table(AV_CRC_24_IEEE), checksum, buf, len);
+}
+
 static int tak_read_header(AVFormatContext *s)
 {
     TAKDemuxContext *tc = s->priv_data;
@@ -71,16 +79,27 @@
         case TAK_METADATA_STREAMINFO:
         case TAK_METADATA_LAST_FRAME:
         case TAK_METADATA_ENCODER:
-            buffer = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
+            if (size <= 3)
+                return AVERROR_INVALIDDATA;
+
+            buffer = av_malloc(size - 3 + FF_INPUT_BUFFER_PADDING_SIZE);
             if (!buffer)
                 return AVERROR(ENOMEM);
 
-            if (avio_read(pb, buffer, size) != size) {
+            ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U);
+            if (avio_read(pb, buffer, size - 3) != size - 3) {
                 av_freep(&buffer);
                 return AVERROR(EIO);
             }
+            if (ffio_get_checksum(s->pb) != avio_rb24(pb)) {
+                av_log(s, AV_LOG_ERROR, "%d metadata block CRC error.\n", type);
+                if (s->error_recognition & AV_EF_EXPLODE) {
+                    av_freep(&buffer);
+                    return AVERROR_INVALIDDATA;
+                }
+            }
 
-            init_get_bits(&gb, buffer, size * 8);
+            init_get_bits8(&gb, buffer, size - 3);
             break;
         case TAK_METADATA_MD5: {
             uint8_t md5[16];
@@ -88,8 +107,14 @@
 
             if (size != 19)
                 return AVERROR_INVALIDDATA;
+            ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U);
             avio_read(pb, md5, 16);
-            avio_skip(pb, 3);
+            if (ffio_get_checksum(s->pb) != avio_rb24(pb)) {
+                av_log(s, AV_LOG_ERROR, "MD5 metadata block CRC error.\n");
+                if (s->error_recognition & AV_EF_EXPLODE)
+                    return AVERROR_INVALIDDATA;
+            }
+
             av_log(s, AV_LOG_VERBOSE, "MD5=");
             for (i = 0; i < 16; i++)
                 av_log(s, AV_LOG_VERBOSE, "%02x", md5[i]);
@@ -127,7 +152,7 @@
             st->start_time                   = 0;
             avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
             st->codec->extradata             = buffer;
-            st->codec->extradata_size        = size;
+            st->codec->extradata_size        = size - 3;
             buffer                           = NULL;
         } else if (type == TAK_METADATA_LAST_FRAME) {
             if (size != 11)
@@ -155,7 +180,7 @@
         AVIOContext *pb = s->pb;
         int64_t size, left;
 
-        left = tc->data_end - avio_tell(s->pb);
+        left = tc->data_end - avio_tell(pb);
         size = FFMIN(left, 1024);
         if (size <= 0)
             return AVERROR_EOF;
diff --git a/libavformat/tcp.c b/libavformat/tcp.c
index 0d792e7..36af37a 100644
--- a/libavformat/tcp.c
+++ b/libavformat/tcp.c
@@ -34,6 +34,7 @@
     const AVClass *class;
     int fd;
     int listen;
+    int open_timeout;
     int rw_timeout;
     int listen_timeout;
 } TCPContext;
@@ -43,7 +44,7 @@
 #define E AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
 {"listen", "listen on port instead of connecting", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, D|E },
-{"timeout", "timeout of socket i/o operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D|E },
+{"timeout", "timeout of socket i/o operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D|E },
 {"listen_timeout", "connection awaiting timeout", OFFSET(listen_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D|E },
 {NULL}
 };
@@ -64,10 +65,9 @@
     const char *p;
     char buf[256];
     int ret;
-    socklen_t optlen;
     char hostname[1024],proto[1024],path[1024];
     char portstr[10];
-    h->rw_timeout = 5000000;
+    s->open_timeout = 5000000;
 
     av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname),
         &port, path, sizeof(path), uri);
@@ -88,7 +88,10 @@
             s->listen_timeout = strtol(buf, NULL, 10);
         }
     }
-    h->rw_timeout = s->rw_timeout;
+    if (s->rw_timeout >= 0) {
+        s->open_timeout =
+        h->rw_timeout   = s->rw_timeout;
+    }
     hints.ai_family = AF_UNSPEC;
     hints.ai_socktype = SOCK_STREAM;
     snprintf(portstr, sizeof(portstr), "%d", port);
@@ -108,89 +111,31 @@
     cur_ai = ai;
 
  restart:
-    ret = AVERROR(EIO);
-    fd = socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol);
-    if (fd < 0)
+    fd = ff_socket(cur_ai->ai_family,
+                   cur_ai->ai_socktype,
+                   cur_ai->ai_protocol);
+    if (fd < 0) {
+        ret = ff_neterrno();
         goto fail;
+    }
 
     if (s->listen) {
-        int fd1;
-        int reuse = 1;
-        struct pollfd lp = { fd, POLLIN, 0 };
-        setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
-        ret = bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
-        if (ret) {
-            ret = ff_neterrno();
+        if ((fd = ff_listen_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen,
+                                 s->listen_timeout, h)) < 0) {
+            ret = fd;
             goto fail1;
         }
-        ret = listen(fd, 1);
-        if (ret) {
-            ret = ff_neterrno();
-            goto fail1;
-        }
-        ret = poll(&lp, 1, s->listen_timeout >= 0 ? s->listen_timeout : -1);
-        if (ret <= 0) {
-            ret = AVERROR(ETIMEDOUT);
-            goto fail1;
-        }
-        fd1 = accept(fd, NULL, NULL);
-        if (fd1 < 0) {
-            ret = ff_neterrno();
-            goto fail1;
-        }
-        closesocket(fd);
-        fd = fd1;
-        ff_socket_nonblock(fd, 1);
     } else {
- redo:
-        ff_socket_nonblock(fd, 1);
-        ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
+        if ((ret = ff_listen_connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen,
+                                     s->open_timeout / 1000, h, cur_ai->ai_next)) < 0) {
+
+            if (ret == AVERROR_EXIT)
+                goto fail1;
+            else
+                goto fail;
+        }
     }
 
-    if (ret < 0) {
-        struct pollfd p = {fd, POLLOUT, 0};
-        int64_t wait_started;
-        ret = ff_neterrno();
-        if (ret == AVERROR(EINTR)) {
-            if (ff_check_interrupt(&h->interrupt_callback)) {
-                ret = AVERROR_EXIT;
-                goto fail1;
-            }
-            goto redo;
-        }
-        if (ret != AVERROR(EINPROGRESS) &&
-            ret != AVERROR(EAGAIN))
-            goto fail;
-
-        /* wait until we are connected or until abort */
-        wait_started = av_gettime();
-        do {
-            if (ff_check_interrupt(&h->interrupt_callback)) {
-                ret = AVERROR_EXIT;
-                goto fail1;
-            }
-            ret = poll(&p, 1, 100);
-            if (ret > 0)
-                break;
-        } while (!h->rw_timeout || (av_gettime() - wait_started < h->rw_timeout));
-        if (ret <= 0) {
-            ret = AVERROR(ETIMEDOUT);
-            goto fail;
-        }
-        /* test error */
-        optlen = sizeof(ret);
-        if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen))
-            ret = AVUNERROR(ff_neterrno());
-        if (ret != 0) {
-            char errbuf[100];
-            ret = AVERROR(ret);
-            av_strerror(ret, errbuf, sizeof(errbuf));
-            av_log(h, AV_LOG_ERROR,
-                   "TCP connection to %s:%d failed: %s\n",
-                   hostname, port, errbuf);
-            goto fail;
-        }
-    }
     h->is_streamed = 1;
     s->fd = fd;
     freeaddrinfo(ai);
@@ -202,6 +147,7 @@
         cur_ai = cur_ai->ai_next;
         if (fd >= 0)
             closesocket(fd);
+        ret = 0;
         goto restart;
     }
  fail1:
diff --git a/libavformat/tedcaptionsdec.c b/libavformat/tedcaptionsdec.c
index 048ba96..68063fa 100644
--- a/libavformat/tedcaptionsdec.c
+++ b/libavformat/tedcaptionsdec.c
@@ -153,7 +153,8 @@
 
 static int parse_boolean(AVIOContext *pb, int *cur_byte, int *result)
 {
-    const char *text[] = { "false", "true" }, *p;
+    static const char * const text[] = { "false", "true" };
+    const char *p;
     int i;
 
     skip_spaces(pb, cur_byte);
@@ -340,7 +341,7 @@
             count++;
     }
     return count == FF_ARRAY_ELEMS(tags) ? AVPROBE_SCORE_MAX :
-           count                         ? AVPROBE_SCORE_MAX / 2 : 0;
+           count                         ? AVPROBE_SCORE_EXTENSION : 0;
 }
 
 static int tedcaptions_read_seek(AVFormatContext *avf, int stream_index,
diff --git a/libavformat/tee.c b/libavformat/tee.c
index 10787ca..71f245e 100644
--- a/libavformat/tee.c
+++ b/libavformat/tee.c
@@ -1,5 +1,5 @@
 /*
- * Tee pesudo-muxer
+ * Tee pseudo-muxer
  * Copyright (c) 2012 Nicolas George
  *
  * This file is part of FFmpeg.
@@ -27,16 +27,26 @@
 
 #define MAX_SLAVES 16
 
+typedef struct {
+    AVFormatContext *avf;
+    AVBitStreamFilterContext **bsfs; ///< bitstream filters per stream
+
+    /** map from input to output streams indexes,
+     * disabled output streams are set to -1 */
+    int *stream_map;
+} TeeSlave;
+
 typedef struct TeeContext {
     const AVClass *class;
     unsigned nb_slaves;
-    AVFormatContext *slaves[MAX_SLAVES];
+    TeeSlave slaves[MAX_SLAVES];
 } TeeContext;
 
 static const char *const slave_delim     = "|";
 static const char *const slave_opt_open  = "[";
 static const char *const slave_opt_close = "]";
 static const char *const slave_opt_delim = ":]"; /* must have the close too */
+static const char *const slave_bsfs_spec_sep = "/";
 
 static const AVClass tee_muxer_class = {
     .class_name = "Tee muxer",
@@ -82,34 +92,103 @@
     return ret;
 }
 
-static int open_slave(AVFormatContext *avf, char *slave, AVFormatContext **ravf)
+/**
+ * Parse list of bitstream filters and add them to the list of filters
+ * pointed to by bsfs.
+ *
+ * The list must be specified in the form:
+ * BSFS ::= BSF[,BSFS]
+ */
+static int parse_bsfs(void *log_ctx, const char *bsfs_spec,
+                      AVBitStreamFilterContext **bsfs)
+{
+    char *bsf_name, *buf, *saveptr;
+    int ret = 0;
+
+    if (!(buf = av_strdup(bsfs_spec)))
+        return AVERROR(ENOMEM);
+
+    while (bsf_name = av_strtok(buf, ",", &saveptr)) {
+        AVBitStreamFilterContext *bsf = av_bitstream_filter_init(bsf_name);
+
+        if (!bsf) {
+            av_log(log_ctx, AV_LOG_ERROR,
+                   "Cannot initialize bitstream filter with name '%s', "
+                   "unknown filter or internal error happened\n",
+                   bsf_name);
+            ret = AVERROR_UNKNOWN;
+            goto end;
+        }
+
+        /* append bsf context to the list of bsf contexts */
+        *bsfs = bsf;
+        bsfs = &bsf->next;
+
+        buf = NULL;
+    }
+
+end:
+    av_free(buf);
+    return ret;
+}
+
+static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
 {
     int i, ret;
     AVDictionary *options = NULL;
     AVDictionaryEntry *entry;
     char *filename;
-    char *format = NULL;
+    char *format = NULL, *select = NULL;
     AVFormatContext *avf2 = NULL;
     AVStream *st, *st2;
+    int stream_count;
 
     if ((ret = parse_slave_options(avf, slave, &options, &filename)) < 0)
         return ret;
-    if ((entry = av_dict_get(options, "f", NULL, 0))) {
-        format = entry->value;
-        entry->value = NULL; /* prevent it from being freed */
-        av_dict_set(&options, "f", NULL, 0);
-    }
+
+#define STEAL_OPTION(option, field) do {                                \
+        if ((entry = av_dict_get(options, option, NULL, 0))) {          \
+            field = entry->value;                                       \
+            entry->value = NULL; /* prevent it from being freed */      \
+            av_dict_set(&options, option, NULL, 0);                     \
+        }                                                               \
+    } while (0)
+
+    STEAL_OPTION("f", format);
+    STEAL_OPTION("select", select);
 
     ret = avformat_alloc_output_context2(&avf2, NULL, format, filename);
     if (ret < 0)
-        goto fail;
-    av_free(format);
+        goto end;
 
+    tee_slave->stream_map = av_calloc(avf->nb_streams, sizeof(*tee_slave->stream_map));
+    if (!tee_slave->stream_map) {
+        ret = AVERROR(ENOMEM);
+        goto end;
+    }
+
+    stream_count = 0;
     for (i = 0; i < avf->nb_streams; i++) {
         st = avf->streams[i];
+        if (select) {
+            ret = avformat_match_stream_specifier(avf, avf->streams[i], select);
+            if (ret < 0) {
+                av_log(avf, AV_LOG_ERROR,
+                       "Invalid stream specifier '%s' for output '%s'\n",
+                       select, slave);
+                goto end;
+            }
+
+            if (ret == 0) { /* no match */
+                tee_slave->stream_map[i] = -1;
+                continue;
+            }
+        }
+        tee_slave->stream_map[i] = stream_count++;
+
         if (!(st2 = avformat_new_stream(avf2, NULL))) {
             ret = AVERROR(ENOMEM);
-            goto fail;
+            goto end;
         }
         st2->id = st->id;
         st2->r_frame_rate        = st->r_frame_rate;
@@ -122,34 +201,84 @@
         st2->avg_frame_rate      = st->avg_frame_rate;
         av_dict_copy(&st2->metadata, st->metadata, 0);
         if ((ret = avcodec_copy_context(st2->codec, st->codec)) < 0)
-            goto fail;
+            goto end;
     }
 
     if (!(avf2->oformat->flags & AVFMT_NOFILE)) {
         if ((ret = avio_open(&avf2->pb, filename, AVIO_FLAG_WRITE)) < 0) {
             av_log(avf, AV_LOG_ERROR, "Slave '%s': error opening: %s\n",
                    slave, av_err2str(ret));
-            goto fail;
+            goto end;
         }
     }
 
     if ((ret = avformat_write_header(avf2, &options)) < 0) {
         av_log(avf, AV_LOG_ERROR, "Slave '%s': error writing header: %s\n",
                slave, av_err2str(ret));
-        goto fail;
+        goto end;
     }
+
+    tee_slave->avf = avf2;
+    tee_slave->bsfs = av_calloc(avf2->nb_streams, sizeof(TeeSlave));
+    if (!tee_slave->bsfs) {
+        ret = AVERROR(ENOMEM);
+        goto end;
+    }
+
+    entry = NULL;
+    while (entry = av_dict_get(options, "bsfs", NULL, AV_DICT_IGNORE_SUFFIX)) {
+        const char *spec = entry->key + strlen("bsfs");
+        if (*spec) {
+            if (strspn(spec, slave_bsfs_spec_sep) != 1) {
+                av_log(avf, AV_LOG_ERROR,
+                       "Specifier separator in '%s' is '%c', but only characters '%s' "
+                       "are allowed\n", entry->key, *spec, slave_bsfs_spec_sep);
+                return AVERROR(EINVAL);
+            }
+            spec++; /* consume separator */
+        }
+
+        for (i = 0; i < avf2->nb_streams; i++) {
+            ret = avformat_match_stream_specifier(avf2, avf2->streams[i], spec);
+            if (ret < 0) {
+                av_log(avf, AV_LOG_ERROR,
+                       "Invalid stream specifier '%s' in bsfs option '%s' for slave "
+                       "output '%s'\n", spec, entry->key, filename);
+                goto end;
+            }
+
+            if (ret > 0) {
+                av_log(avf, AV_LOG_DEBUG, "spec:%s bsfs:%s matches stream %d of slave "
+                       "output '%s'\n", spec, entry->value, i, filename);
+                if (tee_slave->bsfs[i]) {
+                    av_log(avf, AV_LOG_WARNING,
+                           "Duplicate bsfs specification associated to stream %d of slave "
+                           "output '%s', filters will be ignored\n", i, filename);
+                    continue;
+                }
+                ret = parse_bsfs(avf, entry->value, &tee_slave->bsfs[i]);
+                if (ret < 0) {
+                    av_log(avf, AV_LOG_ERROR,
+                           "Error parsing bitstream filter sequence '%s' associated to "
+                           "stream %d of slave output '%s'\n", entry->value, i, filename);
+                    goto end;
+                }
+            }
+        }
+
+        av_dict_set(&options, entry->key, NULL, 0);
+    }
+
     if (options) {
         entry = NULL;
         while ((entry = av_dict_get(options, "", entry, AV_DICT_IGNORE_SUFFIX)))
             av_log(avf2, AV_LOG_ERROR, "Unknown option '%s'\n", entry->key);
         ret = AVERROR_OPTION_NOT_FOUND;
-        goto fail;
+        goto end;
     }
 
-    *ravf = avf2;
-    return 0;
-
-fail:
+end:
+    av_free(format);
     av_dict_free(&options);
     return ret;
 }
@@ -158,14 +287,49 @@
 {
     TeeContext *tee = avf->priv_data;
     AVFormatContext *avf2;
-    unsigned i;
+    unsigned i, j;
 
     for (i = 0; i < tee->nb_slaves; i++) {
-        avf2 = tee->slaves[i];
+        avf2 = tee->slaves[i].avf;
+
+        for (j = 0; j < avf2->nb_streams; j++) {
+            AVBitStreamFilterContext *bsf_next, *bsf = tee->slaves[i].bsfs[j];
+            while (bsf) {
+                bsf_next = bsf->next;
+                av_bitstream_filter_close(bsf);
+                bsf = bsf_next;
+            }
+        }
+        av_freep(&tee->slaves[i].stream_map);
+
         avio_close(avf2->pb);
         avf2->pb = NULL;
         avformat_free_context(avf2);
-        tee->slaves[i] = NULL;
+        tee->slaves[i].avf = NULL;
+    }
+}
+
+static void log_slave(TeeSlave *slave, void *log_ctx, int log_level)
+{
+    int i;
+    av_log(log_ctx, log_level, "filename:'%s' format:%s\n",
+           slave->avf->filename, slave->avf->oformat->name);
+    for (i = 0; i < slave->avf->nb_streams; i++) {
+        AVStream *st = slave->avf->streams[i];
+        AVBitStreamFilterContext *bsf = slave->bsfs[i];
+
+        av_log(log_ctx, log_level, "    stream:%d codec:%s type:%s",
+               i, avcodec_get_name(st->codec->codec_id),
+               av_get_media_type_string(st->codec->codec_type));
+        if (bsf) {
+            av_log(log_ctx, log_level, " bsfs:");
+            while (bsf) {
+                av_log(log_ctx, log_level, "%s%s",
+                       bsf->filter->name, bsf->next ? "," : "");
+                bsf = bsf->next;
+            }
+        }
+        av_log(log_ctx, log_level, "\n");
     }
 }
 
@@ -195,10 +359,20 @@
     for (i = 0; i < nb_slaves; i++) {
         if ((ret = open_slave(avf, slaves[i], &tee->slaves[i])) < 0)
             goto fail;
+        log_slave(&tee->slaves[i], avf, AV_LOG_VERBOSE);
         av_freep(&slaves[i]);
     }
 
     tee->nb_slaves = nb_slaves;
+
+    for (i = 0; i < avf->nb_streams; i++) {
+        int j, mapped = 0;
+        for (j = 0; j < tee->nb_slaves; j++)
+            mapped += tee->slaves[j].stream_map[i] >= 0;
+        if (!mapped)
+            av_log(avf, AV_LOG_WARNING, "Input stream #%d is not mapped "
+                   "to any slave.\n", i);
+    }
     return 0;
 
 fail:
@@ -208,6 +382,46 @@
     return ret;
 }
 
+static int filter_packet(void *log_ctx, AVPacket *pkt,
+                         AVFormatContext *fmt_ctx, AVBitStreamFilterContext *bsf_ctx)
+{
+    AVCodecContext *enc_ctx = fmt_ctx->streams[pkt->stream_index]->codec;
+    int ret;
+
+    while (bsf_ctx) {
+        AVPacket new_pkt = *pkt;
+        ret = av_bitstream_filter_filter(bsf_ctx, enc_ctx, NULL,
+                                             &new_pkt.data, &new_pkt.size,
+                                             pkt->data, pkt->size,
+                                             pkt->flags & AV_PKT_FLAG_KEY);
+        if (ret == 0 && new_pkt.data != pkt->data && new_pkt.destruct) {
+            if ((ret = av_copy_packet(&new_pkt, pkt)) < 0)
+                break;
+            ret = 1;
+        }
+
+        if (ret > 0) {
+            av_free_packet(pkt);
+            new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size,
+                                           av_buffer_default_free, NULL, 0);
+            if (!new_pkt.buf)
+                break;
+        }
+        *pkt = new_pkt;
+
+        bsf_ctx = bsf_ctx->next;
+    }
+
+    if (ret < 0) {
+        av_log(log_ctx, AV_LOG_ERROR,
+               "Failed to filter bitstream with filter %s for stream %d in file '%s' with codec %s\n",
+               bsf_ctx->filter->name, pkt->stream_index, fmt_ctx->filename,
+               avcodec_get_name(enc_ctx->codec_id));
+    }
+
+    return ret;
+}
+
 static int tee_write_trailer(AVFormatContext *avf)
 {
     TeeContext *tee = avf->priv_data;
@@ -216,7 +430,7 @@
     unsigned i;
 
     for (i = 0; i < tee->nb_slaves; i++) {
-        avf2 = tee->slaves[i];
+        avf2 = tee->slaves[i].avf;
         if ((ret = av_write_trailer(avf2)) < 0)
             if (!ret_all)
                 ret_all = ret;
@@ -238,27 +452,30 @@
     AVPacket pkt2;
     int ret_all = 0, ret;
     unsigned i, s;
+    int s2;
     AVRational tb, tb2;
 
     for (i = 0; i < tee->nb_slaves; i++) {
-        avf2 = tee->slaves[i];
+        avf2 = tee->slaves[i].avf;
         s = pkt->stream_index;
-        if (s >= avf2->nb_streams) {
-            if (!ret_all)
-                ret_all = AVERROR(EINVAL);
+        s2 = tee->slaves[i].stream_map[s];
+        if (s2 < 0)
             continue;
-        }
+
         if ((ret = av_copy_packet(&pkt2, pkt)) < 0 ||
             (ret = av_dup_packet(&pkt2))< 0)
             if (!ret_all) {
                 ret = ret_all;
                 continue;
             }
-        tb  = avf ->streams[s]->time_base;
-        tb2 = avf2->streams[s]->time_base;
+        tb  = avf ->streams[s ]->time_base;
+        tb2 = avf2->streams[s2]->time_base;
         pkt2.pts      = av_rescale_q(pkt->pts,      tb, tb2);
         pkt2.dts      = av_rescale_q(pkt->dts,      tb, tb2);
         pkt2.duration = av_rescale_q(pkt->duration, tb, tb2);
+        pkt2.stream_index = s2;
+
+        filter_packet(avf2, &pkt2, avf2, tee->slaves[i].bsfs[s2]);
         if ((ret = av_interleaved_write_frame(avf2, &pkt2)) < 0)
             if (!ret_all)
                 ret_all = ret;
diff --git a/libavformat/tta.c b/libavformat/tta.c
index 445389e..bbb6a22 100644
--- a/libavformat/tta.c
+++ b/libavformat/tta.c
@@ -20,9 +20,12 @@
  */
 
 #include "libavcodec/get_bits.h"
+#include "apetag.h"
 #include "avformat.h"
+#include "avio_internal.h"
 #include "internal.h"
 #include "id3v1.h"
+#include "libavutil/crc.h"
 #include "libavutil/dict.h"
 
 typedef struct {
@@ -31,12 +34,20 @@
     int last_frame_size;
 } TTAContext;
 
+static unsigned long tta_check_crc(unsigned long checksum, const uint8_t *buf,
+                                   unsigned int len)
+{
+    return av_crc(av_crc_get_table(AV_CRC_32_IEEE_LE), checksum, buf, len);
+}
+
 static int tta_probe(AVProbeData *p)
 {
-    const uint8_t *d = p->buf;
-
-    if (d[0] == 'T' && d[1] == 'T' && d[2] == 'A' && d[3] == '1')
-        return 80;
+    if (AV_RL32(&p->buf[0]) == MKTAG('T', 'T', 'A', '1') &&
+        (AV_RL16(&p->buf[4]) == 1 || AV_RL16(&p->buf[4]) == 2) &&
+        AV_RL16(&p->buf[6]) > 0 &&
+        AV_RL16(&p->buf[8]) > 0 &&
+        AV_RL32(&p->buf[10]) > 0)
+        return AVPROBE_SCORE_EXTENSION + 30;
     return 0;
 }
 
@@ -46,14 +57,14 @@
     AVStream *st;
     int i, channels, bps, samplerate;
     uint64_t framepos, start_offset;
-    uint32_t datalen;
+    uint32_t nb_samples, crc;
 
-    if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
-        ff_id3v1_read(s);
+    ff_id3v1_read(s);
 
     start_offset = avio_tell(s->pb);
+    ffio_init_checksum(s->pb, tta_check_crc, UINT32_MAX);
     if (avio_rl32(s->pb) != AV_RL32("TTA1"))
-        return -1; // not tta file
+        return AVERROR_INVALIDDATA;
 
     avio_skip(s->pb, 2); // FIXME: flags
     channels = avio_rl16(s->pb);
@@ -61,27 +72,31 @@
     samplerate = avio_rl32(s->pb);
     if(samplerate <= 0 || samplerate > 1000000){
         av_log(s, AV_LOG_ERROR, "nonsense samplerate\n");
-        return -1;
-    }
-
-    datalen = avio_rl32(s->pb);
-    if (!datalen) {
-        av_log(s, AV_LOG_ERROR, "invalid datalen\n");
         return AVERROR_INVALIDDATA;
     }
 
-    avio_skip(s->pb, 4); // header crc
+    nb_samples = avio_rl32(s->pb);
+    if (!nb_samples) {
+        av_log(s, AV_LOG_ERROR, "invalid number of samples\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    crc = ffio_get_checksum(s->pb) ^ UINT32_MAX;
+    if (crc != avio_rl32(s->pb)) {
+        av_log(s, AV_LOG_ERROR, "Header CRC error\n");
+        return AVERROR_INVALIDDATA;
+    }
 
     c->frame_size      = samplerate * 256 / 245;
-    c->last_frame_size = datalen % c->frame_size;
+    c->last_frame_size = nb_samples % c->frame_size;
     if (!c->last_frame_size)
         c->last_frame_size = c->frame_size;
-    c->totalframes = datalen / c->frame_size + (c->last_frame_size < c->frame_size);
+    c->totalframes = nb_samples / c->frame_size + (c->last_frame_size < c->frame_size);
     c->currentframe = 0;
 
     if(c->totalframes >= UINT_MAX/sizeof(uint32_t) || c->totalframes <= 0){
         av_log(s, AV_LOG_ERROR, "totalframes %d invalid\n", c->totalframes);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     st = avformat_new_stream(s, NULL);
@@ -90,17 +105,32 @@
 
     avpriv_set_pts_info(st, 64, 1, samplerate);
     st->start_time = 0;
-    st->duration = datalen;
+    st->duration = nb_samples;
 
     framepos = avio_tell(s->pb) + 4*c->totalframes + 4;
 
+    st->codec->extradata_size = avio_tell(s->pb) - start_offset;
+    st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!st->codec->extradata) {
+        st->codec->extradata_size = 0;
+        return AVERROR(ENOMEM);
+    }
+
+    avio_seek(s->pb, start_offset, SEEK_SET);
+    avio_read(s->pb, st->codec->extradata, st->codec->extradata_size);
+
+    ffio_init_checksum(s->pb, tta_check_crc, UINT32_MAX);
     for (i = 0; i < c->totalframes; i++) {
         uint32_t size = avio_rl32(s->pb);
         av_add_index_entry(st, framepos, i * c->frame_size, size, 0,
                            AVINDEX_KEYFRAME);
         framepos += size;
     }
-    avio_skip(s->pb, 4); // seektable crc
+    crc = ffio_get_checksum(s->pb) ^ UINT32_MAX;
+    if (crc != avio_rl32(s->pb)) {
+        av_log(s, AV_LOG_ERROR, "Seek table CRC error\n");
+        return AVERROR_INVALIDDATA;
+    }
 
     st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
     st->codec->codec_id = AV_CODEC_ID_TTA;
@@ -108,19 +138,11 @@
     st->codec->sample_rate = samplerate;
     st->codec->bits_per_coded_sample = bps;
 
-    st->codec->extradata_size = avio_tell(s->pb) - start_offset;
-    if(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)st->codec->extradata_size){
-        //this check is redundant as avio_read should fail
-        av_log(s, AV_LOG_ERROR, "extradata_size too large\n");
-        return -1;
+    if (s->pb->seekable) {
+        int64_t pos = avio_tell(s->pb);
+        ff_ape_parse_tag(s);
+        avio_seek(s->pb, pos, SEEK_SET);
     }
-    st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE);
-    if (!st->codec->extradata) {
-        st->codec->extradata_size = 0;
-        return AVERROR(ENOMEM);
-    }
-    avio_seek(s->pb, start_offset, SEEK_SET);
-    avio_read(s->pb, st->codec->extradata, st->codec->extradata_size);
 
     return 0;
 }
diff --git a/libavformat/udp.c b/libavformat/udp.c
index e8a01db..3c0d6bf 100644
--- a/libavformat/udp.c
+++ b/libavformat/udp.c
@@ -237,7 +237,7 @@
         int level = addr->sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
         struct addrinfo *sourceaddr = udp_resolve_host(sources[i], 0,
                                                        SOCK_DGRAM, AF_UNSPEC,
-                                                       AI_NUMERICHOST);
+                                                       0);
         if (!sourceaddr)
             return AVERROR(ENOENT);
 
@@ -267,7 +267,7 @@
         struct ip_mreq_source mreqs;
         struct addrinfo *sourceaddr = udp_resolve_host(sources[i], 0,
                                                        SOCK_DGRAM, AF_UNSPEC,
-                                                       AI_NUMERICHOST);
+                                                       0);
         if (!sourceaddr)
             return AVERROR(ENOENT);
         if (sourceaddr->ai_addr->sa_family != AF_INET) {
@@ -326,7 +326,7 @@
     if (res0 == 0)
         goto fail;
     for (res = res0; res; res=res->ai_next) {
-        udp_fd = socket(res->ai_family, SOCK_DGRAM, 0);
+        udp_fd = ff_socket(res->ai_family, SOCK_DGRAM, 0);
         if (udp_fd != -1) break;
         log_net_error(NULL, AV_LOG_ERROR, "socket");
     }
@@ -494,6 +494,27 @@
 }
 #endif
 
+static int parse_source_list(char *buf, char **sources, int *num_sources,
+                             int max_sources)
+{
+    char *source_start;
+
+    source_start = buf;
+    while (1) {
+        char *next = strchr(source_start, ',');
+        if (next)
+            *next = '\0';
+        sources[*num_sources] = av_strdup(source_start);
+        if (!sources[*num_sources])
+            return AVERROR(ENOMEM);
+        source_start = next + 1;
+        (*num_sources)++;
+        if (*num_sources >= max_sources || !next)
+            break;
+    }
+    return 0;
+}
+
 /* put it in UDP context */
 /* return non zero if error */
 static int udp_open(URLContext *h, const char *uri, int flags)
@@ -507,8 +528,8 @@
     struct sockaddr_storage my_addr;
     socklen_t len;
     int reuse_specified = 0;
-    int i, include = 0, num_sources = 0;
-    char *sources[32];
+    int i, num_include_sources = 0, num_exclude_sources = 0;
+    char *include_sources[32], *exclude_sources[32];
 
     h->is_streamed = 1;
 
@@ -562,31 +583,26 @@
         if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) {
             av_strlcpy(localaddr, buf, sizeof(localaddr));
         }
-        if (av_find_info_tag(buf, sizeof(buf), "sources", p))
-            include = 1;
-        if (include || av_find_info_tag(buf, sizeof(buf), "block", p)) {
-            char *source_start;
-
-            source_start = buf;
-            while (1) {
-                char *next = strchr(source_start, ',');
-                if (next)
-                    *next = '\0';
-                sources[num_sources] = av_strdup(source_start);
-                if (!sources[num_sources])
-                    goto fail;
-                source_start = next + 1;
-                num_sources++;
-                if (num_sources >= FF_ARRAY_ELEMS(sources) || !next)
-                    break;
-            }
+        if (av_find_info_tag(buf, sizeof(buf), "sources", p)) {
+            if (parse_source_list(buf, include_sources, &num_include_sources,
+                                  FF_ARRAY_ELEMS(include_sources)))
+                goto fail;
+        }
+        if (av_find_info_tag(buf, sizeof(buf), "block", p)) {
+            if (parse_source_list(buf, exclude_sources, &num_exclude_sources,
+                                  FF_ARRAY_ELEMS(exclude_sources)))
+                goto fail;
         }
         if (!is_output && av_find_info_tag(buf, sizeof(buf), "timeout", p))
             s->timeout = strtol(buf, NULL, 10);
     }
     /* handling needed to support options picking from both AVOption and URL */
     s->circular_buffer_size *= 188;
-    h->max_packet_size = s->packet_size;
+    if (flags & AVIO_FLAG_WRITE) {
+        h->max_packet_size = s->packet_size;
+    } else {
+        h->max_packet_size = UDP_MAX_PKT_SIZE;
+    }
     h->rw_timeout = s->timeout;
 
     /* fill the dest addr */
@@ -644,20 +660,20 @@
         }
         if (h->flags & AVIO_FLAG_READ) {
             /* input */
-            if (num_sources == 0 || !include) {
-                if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0)
-                    goto fail;
-
-                if (num_sources) {
-                    if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, sources, num_sources, 0) < 0)
-                        goto fail;
-                }
-            } else if (include && num_sources) {
-                if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, sources, num_sources, 1) < 0)
+            if (num_include_sources && num_exclude_sources) {
+                av_log(h, AV_LOG_ERROR, "Simultaneously including and excluding multicast sources is not supported\n");
+                goto fail;
+            }
+            if (num_include_sources) {
+                if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, include_sources, num_include_sources, 1) < 0)
                     goto fail;
             } else {
-                av_log(NULL, AV_LOG_ERROR, "invalid udp settings: inclusive multicast but no sources given\n");
-                goto fail;
+                if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0)
+                    goto fail;
+            }
+            if (num_exclude_sources) {
+                if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, exclude_sources, num_exclude_sources, 0) < 0)
+                    goto fail;
             }
         }
     }
@@ -686,8 +702,10 @@
         }
     }
 
-    for (i = 0; i < num_sources; i++)
-        av_freep(&sources[i]);
+    for (i = 0; i < num_include_sources; i++)
+        av_freep(&include_sources[i]);
+    for (i = 0; i < num_exclude_sources; i++)
+        av_freep(&exclude_sources[i]);
 
     s->udp_fd = udp_fd;
 
@@ -727,8 +745,10 @@
     if (udp_fd >= 0)
         closesocket(udp_fd);
     av_fifo_free(s->fifo);
-    for (i = 0; i < num_sources; i++)
-        av_freep(&sources[i]);
+    for (i = 0; i < num_include_sources; i++)
+        av_freep(&include_sources[i]);
+    for (i = 0; i < num_exclude_sources; i++)
+        av_freep(&exclude_sources[i]);
     return AVERROR(EIO);
 }
 
diff --git a/libavformat/unix.c b/libavformat/unix.c
new file mode 100644
index 0000000..0e61318
--- /dev/null
+++ b/libavformat/unix.c
@@ -0,0 +1,155 @@
+/*
+ * Unix socket protocol
+ * Copyright (c) 2013 Luca Barbato
+ *
+ * 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
+ */
+
+/**
+ * @file
+ *
+ * Unix socket url_protocol
+ *
+ */
+
+#include "libavutil/avstring.h"
+#include "libavutil/opt.h"
+#include "os_support.h"
+#include "network.h"
+#include <sys/un.h>
+#include "url.h"
+
+typedef struct UnixContext {
+    const AVClass *class;
+    struct sockaddr_un addr;
+    int timeout;
+    int listen;
+    int type;
+    int fd;
+} UnixContext;
+
+#define OFFSET(x) offsetof(UnixContext, x)
+#define ED AV_OPT_FLAG_DECODING_PARAM|AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption unix_options[] = {
+    { "listen",    "Open socket for listening",             OFFSET(listen),  AV_OPT_TYPE_INT,   { .i64 = 0 },                    0,       1, ED },
+    { "timeout",   "Timeout in ms",                         OFFSET(timeout), AV_OPT_TYPE_INT,   { .i64 = -1 },                  -1, INT_MAX, ED },
+    { "type",      "Socket type",                           OFFSET(type),    AV_OPT_TYPE_INT,   { .i64 = SOCK_STREAM },    INT_MIN, INT_MAX, ED, "type" },
+    { "stream",    "Stream (reliable stream-oriented)",     0,               AV_OPT_TYPE_CONST, { .i64 = SOCK_STREAM },    INT_MIN, INT_MAX, ED, "type" },
+    { "datagram",  "Datagram (unreliable packet-oriented)", 0,               AV_OPT_TYPE_CONST, { .i64 = SOCK_DGRAM },     INT_MIN, INT_MAX, ED, "type" },
+    { "seqpacket", "Seqpacket (reliable packet-oriented",   0,               AV_OPT_TYPE_CONST, { .i64 = SOCK_SEQPACKET }, INT_MIN, INT_MAX, ED, "type" },
+    { NULL }
+};
+
+static const AVClass unix_class = {
+    .class_name = "unix",
+    .item_name  = av_default_item_name,
+    .option     = unix_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+static int unix_open(URLContext *h, const char *filename, int flags)
+{
+    UnixContext *s = h->priv_data;
+    int fd, ret;
+
+    av_strstart(filename, "unix:", &filename);
+    s->addr.sun_family = AF_UNIX;
+    av_strlcpy(s->addr.sun_path, filename, sizeof(s->addr.sun_path));
+
+    if ((fd = ff_socket(AF_UNIX, s->type, 0)) < 0)
+        return ff_neterrno();
+
+    if (s->listen) {
+        fd = ff_listen_bind(fd, (struct sockaddr *)&s->addr,
+                            sizeof(s->addr), s->timeout, h);
+        if (fd < 0) {
+            ret = fd;
+            goto fail;
+        }
+    } else {
+        ret = ff_listen_connect(fd, (struct sockaddr *)&s->addr,
+                                sizeof(s->addr), s->timeout, h, 0);
+        if (ret < 0)
+            goto fail;
+    }
+
+    s->fd = fd;
+
+    return 0;
+
+fail:
+    if (s->listen && AVUNERROR(ret) != EADDRINUSE)
+        unlink(s->addr.sun_path);
+    if (fd >= 0)
+        closesocket(fd);
+    return ret;
+}
+
+static int unix_read(URLContext *h, uint8_t *buf, int size)
+{
+    UnixContext *s = h->priv_data;
+    int ret;
+
+    if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+        ret = ff_network_wait_fd(s->fd, 0);
+        if (ret < 0)
+            return ret;
+    }
+    ret = recv(s->fd, buf, size, 0);
+    return ret < 0 ? ff_neterrno() : ret;
+}
+
+static int unix_write(URLContext *h, const uint8_t *buf, int size)
+{
+    UnixContext *s = h->priv_data;
+    int ret;
+
+    if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+        ret = ff_network_wait_fd(s->fd, 1);
+        if (ret < 0)
+            return ret;
+    }
+    ret = send(s->fd, buf, size, 0);
+    return ret < 0 ? ff_neterrno() : ret;
+}
+
+static int unix_close(URLContext *h)
+{
+    UnixContext *s = h->priv_data;
+    if (s->listen)
+        unlink(s->addr.sun_path);
+    closesocket(s->fd);
+    return 0;
+}
+
+static int unix_get_file_handle(URLContext *h)
+{
+    UnixContext *s = h->priv_data;
+    return s->fd;
+}
+
+URLProtocol ff_unix_protocol = {
+    .name                = "unix",
+    .url_open            = unix_open,
+    .url_read            = unix_read,
+    .url_write           = unix_write,
+    .url_close           = unix_close,
+    .url_get_file_handle = unix_get_file_handle,
+    .priv_data_size      = sizeof(UnixContext),
+    .priv_data_class     = &unix_class,
+    .flags               = URL_PROTOCOL_FLAG_NETWORK,
+};
diff --git a/libavformat/url-test.c b/libavformat/url-test.c
index ee5f06e..a1da82e 100644
--- a/libavformat/url-test.c
+++ b/libavformat/url-test.c
@@ -18,7 +18,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "internal.h"
+#include "url.h"
 
 static void test(const char *base, const char *rel)
 {
diff --git a/libavformat/url.c b/libavformat/url.c
new file mode 100644
index 0000000..47e1584
--- /dev/null
+++ b/libavformat/url.c
@@ -0,0 +1,147 @@
+/*
+ * URL utility functions
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ *
+ * 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
+ */
+
+
+#include "avformat.h"
+#include "config.h"
+#include "url.h"
+#if CONFIG_NETWORK
+#include "network.h"
+#endif
+#include "libavutil/avstring.h"
+
+/**
+ * @file
+ * URL utility functions.
+ */
+
+int ff_url_join(char *str, int size, const char *proto,
+                const char *authorization, const char *hostname,
+                int port, const char *fmt, ...)
+{
+#if CONFIG_NETWORK
+    struct addrinfo hints = { 0 }, *ai;
+#endif
+
+    str[0] = '\0';
+    if (proto)
+        av_strlcatf(str, size, "%s://", proto);
+    if (authorization && authorization[0])
+        av_strlcatf(str, size, "%s@", authorization);
+#if CONFIG_NETWORK && defined(AF_INET6)
+    /* Determine if hostname is a numerical IPv6 address,
+     * properly escape it within [] in that case. */
+    hints.ai_flags = AI_NUMERICHOST;
+    if (!getaddrinfo(hostname, NULL, &hints, &ai)) {
+        if (ai->ai_family == AF_INET6) {
+            av_strlcat(str, "[", size);
+            av_strlcat(str, hostname, size);
+            av_strlcat(str, "]", size);
+        } else {
+            av_strlcat(str, hostname, size);
+        }
+        freeaddrinfo(ai);
+    } else
+#endif
+        /* Not an IPv6 address, just output the plain string. */
+        av_strlcat(str, hostname, size);
+
+    if (port >= 0)
+        av_strlcatf(str, size, ":%d", port);
+    if (fmt) {
+        va_list vl;
+        int len = strlen(str);
+
+        va_start(vl, fmt);
+        vsnprintf(str + len, size > len ? size - len : 0, fmt, vl);
+        va_end(vl);
+    }
+    return strlen(str);
+}
+
+void ff_make_absolute_url(char *buf, int size, const char *base,
+                          const char *rel)
+{
+    char *sep, *path_query;
+    /* Absolute path, relative to the current server */
+    if (base && strstr(base, "://") && rel[0] == '/') {
+        if (base != buf)
+            av_strlcpy(buf, base, size);
+        sep = strstr(buf, "://");
+        if (sep) {
+            /* Take scheme from base url */
+            if (rel[1] == '/') {
+                sep[1] = '\0';
+            } else {
+                /* Take scheme and host from base url */
+                sep += 3;
+                sep = strchr(sep, '/');
+                if (sep)
+                    *sep = '\0';
+            }
+        }
+        av_strlcat(buf, rel, size);
+        return;
+    }
+    /* If rel actually is an absolute url, just copy it */
+    if (!base || strstr(rel, "://") || rel[0] == '/') {
+        av_strlcpy(buf, rel, size);
+        return;
+    }
+    if (base != buf)
+        av_strlcpy(buf, base, size);
+
+    /* Strip off any query string from base */
+    path_query = strchr(buf, '?');
+    if (path_query != NULL)
+        *path_query = '\0';
+
+    /* Is relative path just a new query part? */
+    if (rel[0] == '?') {
+        av_strlcat(buf, rel, size);
+        return;
+    }
+
+    /* Remove the file name from the base url */
+    sep = strrchr(buf, '/');
+    if (sep)
+        sep[1] = '\0';
+    else
+        buf[0] = '\0';
+    while (av_strstart(rel, "../", NULL) && sep) {
+        /* Remove the path delimiter at the end */
+        sep[0] = '\0';
+        sep = strrchr(buf, '/');
+        /* If the next directory name to pop off is "..", break here */
+        if (!strcmp(sep ? &sep[1] : buf, "..")) {
+            /* Readd the slash we just removed */
+            av_strlcat(buf, "/", size);
+            break;
+        }
+        /* Cut off the directory name */
+        if (sep)
+            sep[1] = '\0';
+        else
+            buf[0] = '\0';
+        rel += 3;
+    }
+    av_strlcat(buf, rel, size);
+}
diff --git a/libavformat/url.h b/libavformat/url.h
index 5f75dc9..06dfda1 100644
--- a/libavformat/url.h
+++ b/libavformat/url.h
@@ -248,4 +248,41 @@
 int ff_udp_set_remote_url(URLContext *h, const char *uri);
 int ff_udp_get_local_port(URLContext *h);
 
+/**
+ * Assemble a URL string from components. This is the reverse operation
+ * of av_url_split.
+ *
+ * Note, this requires networking to be initialized, so the caller must
+ * ensure ff_network_init has been called.
+ *
+ * @see av_url_split
+ *
+ * @param str the buffer to fill with the url
+ * @param size the size of the str buffer
+ * @param proto the protocol identifier, if null, the separator
+ *              after the identifier is left out, too
+ * @param authorization an optional authorization string, may be null.
+ *                      An empty string is treated the same as a null string.
+ * @param hostname the host name string
+ * @param port the port number, left out from the string if negative
+ * @param fmt a generic format string for everything to add after the
+ *            host/port, may be null
+ * @return the number of characters written to the destination buffer
+ */
+int ff_url_join(char *str, int size, const char *proto,
+                const char *authorization, const char *hostname,
+                int port, const char *fmt, ...) av_printf_format(7, 8);
+
+/**
+ * Convert a relative url into an absolute url, given a base url.
+ *
+ * @param buf the buffer where output absolute url is written
+ * @param size the size of buf
+ * @param base the base url, may be equal to buf.
+ * @param rel the new url, which is interpreted relative to base
+ */
+void ff_make_absolute_url(char *buf, int size, const char *base,
+                          const char *rel);
+
+
 #endif /* AVFORMAT_URL_H */
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 04b61f7..dca4304 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -19,8 +19,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-/* #define DEBUG */
-
 #include "avformat.h"
 #include "avio_internal.h"
 #include "internal.h"
@@ -30,6 +28,7 @@
 #include "libavutil/avassert.h"
 #include "libavutil/opt.h"
 #include "libavutil/dict.h"
+#include "libavutil/internal.h"
 #include "libavutil/pixdesc.h"
 #include "metadata.h"
 #include "id3v2.h"
@@ -99,162 +98,8 @@
     return timestamp;
 }
 
-#define MAKE_ACCESSORS(str, name, type, field) \
-    type av_##name##_get_##field(const str *s) { return s->field; } \
-    void av_##name##_set_##field(str *s, type v) { s->field = v; }
-
 MAKE_ACCESSORS(AVStream, stream, AVRational, r_frame_rate)
 
-/** head of registered input format linked list */
-static AVInputFormat *first_iformat = NULL;
-/** head of registered output format linked list */
-static AVOutputFormat *first_oformat = NULL;
-
-AVInputFormat  *av_iformat_next(AVInputFormat  *f)
-{
-    if(f) return f->next;
-    else  return first_iformat;
-}
-
-AVOutputFormat *av_oformat_next(AVOutputFormat *f)
-{
-    if(f) return f->next;
-    else  return first_oformat;
-}
-
-void av_register_input_format(AVInputFormat *format)
-{
-    AVInputFormat **p;
-    p = &first_iformat;
-    while (*p != NULL) p = &(*p)->next;
-    *p = format;
-    format->next = NULL;
-}
-
-void av_register_output_format(AVOutputFormat *format)
-{
-    AVOutputFormat **p;
-    p = &first_oformat;
-    while (*p != NULL) p = &(*p)->next;
-    *p = format;
-    format->next = NULL;
-}
-
-int av_match_ext(const char *filename, const char *extensions)
-{
-    const char *ext, *p;
-    char ext1[32], *q;
-
-    if(!filename)
-        return 0;
-
-    ext = strrchr(filename, '.');
-    if (ext) {
-        ext++;
-        p = extensions;
-        for(;;) {
-            q = ext1;
-            while (*p != '\0' && *p != ',' && q-ext1<sizeof(ext1)-1)
-                *q++ = *p++;
-            *q = '\0';
-            if (!av_strcasecmp(ext1, ext))
-                return 1;
-            if (*p == '\0')
-                break;
-            p++;
-        }
-    }
-    return 0;
-}
-
-static int match_format(const char *name, const char *names)
-{
-    const char *p;
-    int len, namelen;
-
-    if (!name || !names)
-        return 0;
-
-    namelen = strlen(name);
-    while ((p = strchr(names, ','))) {
-        len = FFMAX(p - names, namelen);
-        if (!av_strncasecmp(name, names, len))
-            return 1;
-        names = p+1;
-    }
-    return !av_strcasecmp(name, names);
-}
-
-AVOutputFormat *av_guess_format(const char *short_name, const char *filename,
-                                const char *mime_type)
-{
-    AVOutputFormat *fmt = NULL, *fmt_found;
-    int score_max, score;
-
-    /* specific test for image sequences */
-#if CONFIG_IMAGE2_MUXER
-    if (!short_name && filename &&
-        av_filename_number_test(filename) &&
-        ff_guess_image2_codec(filename) != AV_CODEC_ID_NONE) {
-        return av_guess_format("image2", NULL, NULL);
-    }
-#endif
-    /* Find the proper file type. */
-    fmt_found = NULL;
-    score_max = 0;
-    while ((fmt = av_oformat_next(fmt))) {
-        score = 0;
-        if (fmt->name && short_name && match_format(short_name, fmt->name))
-            score += 100;
-        if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
-            score += 10;
-        if (filename && fmt->extensions &&
-            av_match_ext(filename, fmt->extensions)) {
-            score += 5;
-        }
-        if (score > score_max) {
-            score_max = score;
-            fmt_found = fmt;
-        }
-    }
-    return fmt_found;
-}
-
-enum AVCodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name,
-                            const char *filename, const char *mime_type, enum AVMediaType type){
-    if (!strcmp(fmt->name, "segment") || !strcmp(fmt->name, "ssegment")) {
-        fmt = av_guess_format(NULL, filename, NULL);
-    }
-
-    if(type == AVMEDIA_TYPE_VIDEO){
-        enum AVCodecID codec_id= AV_CODEC_ID_NONE;
-
-#if CONFIG_IMAGE2_MUXER
-        if(!strcmp(fmt->name, "image2") || !strcmp(fmt->name, "image2pipe")){
-            codec_id= ff_guess_image2_codec(filename);
-        }
-#endif
-        if(codec_id == AV_CODEC_ID_NONE)
-            codec_id= fmt->video_codec;
-        return codec_id;
-    }else if(type == AVMEDIA_TYPE_AUDIO)
-        return fmt->audio_codec;
-    else if (type == AVMEDIA_TYPE_SUBTITLE)
-        return fmt->subtitle_codec;
-    else
-        return AV_CODEC_ID_NONE;
-}
-
-AVInputFormat *av_find_input_format(const char *short_name)
-{
-    AVInputFormat *fmt = NULL;
-    while ((fmt = av_iformat_next(fmt))) {
-        if (match_format(short_name, fmt->name))
-            return fmt;
-    }
-    return NULL;
-}
-
 /* an arbitrarily chosen "sane" max packet size -- 50M */
 #define SANE_CHUNK_SIZE (50000000)
 
@@ -376,10 +221,10 @@
         if (fmt1->read_probe) {
             score = fmt1->read_probe(&lpd);
             if(fmt1->extensions && av_match_ext(lpd.filename, fmt1->extensions))
-                score = FFMAX(score, nodat ? AVPROBE_SCORE_MAX/4-1 : 1);
+                score = FFMAX(score, nodat ? AVPROBE_SCORE_EXTENSION / 2 - 1 : 1);
         } else if (fmt1->extensions) {
             if (av_match_ext(lpd.filename, fmt1->extensions)) {
-                score = 50;
+                score = AVPROBE_SCORE_EXTENSION;
             }
         }
         if (score > score_max) {
@@ -389,7 +234,7 @@
             fmt = NULL;
     }
     if(nodat)
-        score_max = FFMIN(AVPROBE_SCORE_MAX/4-1, score_max);
+        score_max = FFMIN(AVPROBE_SCORE_EXTENSION / 2 - 1, score_max);
     *score_ret= score_max;
 
     return fmt;
@@ -671,7 +516,8 @@
             goto fail;
 
     if (id3v2_extra_meta) {
-        if (!strcmp(s->iformat->name, "mp3") || !strcmp(s->iformat->name, "aac")) {
+        if (!strcmp(s->iformat->name, "mp3") || !strcmp(s->iformat->name, "aac") ||
+            !strcmp(s->iformat->name, "tta")) {
             if((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0)
                 goto fail;
         } else
@@ -876,7 +722,7 @@
     if ((frame_size = av_get_audio_frame_duration(enc, size)) > 0)
         return frame_size;
 
-    /* fallback to using frame_size if muxing */
+    /* Fall back on using frame_size if muxing. */
     if (enc->frame_size > 1)
         return enc->frame_size;
 
@@ -956,7 +802,7 @@
 static int has_decode_delay_been_guessed(AVStream *st)
 {
     if(st->codec->codec_id != AV_CODEC_ID_H264) return 1;
-    if(!st->info) // if we have left find_stream_info then nb_decoded_frames wont increase anymore for stream copy
+    if(!st->info) // if we have left find_stream_info then nb_decoded_frames won't increase anymore for stream copy
         return 1;
 #if CONFIG_H264_DECODER
     if(st->codec->has_b_frames &&
@@ -1168,7 +1014,9 @@
         pc && pc->pict_type != AV_PICTURE_TYPE_B)
         presentation_delayed = 1;
 
-    if(pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && st->pts_wrap_bits<63 && pkt->dts - (1LL<<(st->pts_wrap_bits-1)) > pkt->pts){
+    if (pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE &&
+        st->pts_wrap_bits < 63 &&
+        pkt->dts - (1LL << (st->pts_wrap_bits - 1)) > pkt->pts) {
         if(is_relative(st->cur_dts) || pkt->dts - (1LL<<(st->pts_wrap_bits-1)) > st->cur_dts) {
             pkt->dts -= 1LL<<st->pts_wrap_bits;
         } else
@@ -1344,6 +1192,13 @@
         if (!out_pkt.size)
             continue;
 
+        if (pkt->side_data) {
+            out_pkt.side_data       = pkt->side_data;
+            out_pkt.side_data_elems = pkt->side_data_elems;
+            pkt->side_data       = NULL;
+            pkt->side_data_elems = 0;
+        }
+
         /* set the duration */
         out_pkt.duration = 0;
         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
@@ -1383,8 +1238,10 @@
             out_pkt.buf   = pkt->buf;
             pkt->buf      = NULL;
 #if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
             out_pkt.destruct = pkt->destruct;
             pkt->destruct = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
         }
         if ((ret = av_dup_packet(&out_pkt)) < 0)
@@ -1889,14 +1746,50 @@
     return 0;
 }
 
+int ff_find_last_ts(AVFormatContext *s, int stream_index, int64_t *ts, int64_t *pos,
+                    int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ))
+{
+    int64_t step= 1024;
+    int64_t limit, ts_max;
+    int64_t filesize = avio_size(s->pb);
+    int64_t pos_max = filesize - 1;
+    do{
+        limit = pos_max;
+        pos_max = FFMAX(0, (pos_max) - step);
+        ts_max = ff_read_timestamp(s, stream_index, &pos_max, limit, read_timestamp);
+        step += step;
+    }while(ts_max == AV_NOPTS_VALUE && 2*limit > step);
+    if (ts_max == AV_NOPTS_VALUE)
+        return -1;
+
+    for(;;){
+        int64_t tmp_pos = pos_max + 1;
+        int64_t tmp_ts = ff_read_timestamp(s, stream_index, &tmp_pos, INT64_MAX, read_timestamp);
+        if(tmp_ts == AV_NOPTS_VALUE)
+            break;
+        ts_max  = tmp_ts;
+        pos_max = tmp_pos;
+        if(tmp_pos >= filesize)
+            break;
+    }
+
+    if (ts)
+        *ts = ts_max;
+    if (pos)
+        *pos = pos_max;
+
+    return 0;
+}
+
 int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts,
                       int64_t pos_min, int64_t pos_max, int64_t pos_limit,
                       int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret,
                       int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ))
 {
     int64_t pos, ts;
-    int64_t start_pos, filesize;
+    int64_t start_pos;
     int no_change;
+    int ret;
 
     av_dlog(s, "gen_seek: %d %s\n", stream_index, av_ts2str(target_ts));
 
@@ -1913,27 +1806,8 @@
     }
 
     if(ts_max == AV_NOPTS_VALUE){
-        int step= 1024;
-        filesize = avio_size(s->pb);
-        pos_max = filesize - 1;
-        do{
-            pos_max = FFMAX(0, pos_max - step);
-            ts_max = ff_read_timestamp(s, stream_index, &pos_max, pos_max + step, read_timestamp);
-            step += step;
-        }while(ts_max == AV_NOPTS_VALUE && pos_max > 0);
-        if (ts_max == AV_NOPTS_VALUE)
-            return -1;
-
-        for(;;){
-            int64_t tmp_pos= pos_max + 1;
-            int64_t tmp_ts= ff_read_timestamp(s, stream_index, &tmp_pos, INT64_MAX, read_timestamp);
-            if(tmp_ts == AV_NOPTS_VALUE)
-                break;
-            ts_max= tmp_ts;
-            pos_max= tmp_pos;
-            if(tmp_pos >= filesize)
-                break;
-        }
+        if ((ret = ff_find_last_ts(s, stream_index, &ts_max, &pos_max, read_timestamp)) < 0)
+            return ret;
         pos_limit= pos_max;
     }
 
@@ -2138,7 +2012,19 @@
 
 int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
 {
-    int ret = seek_frame_internal(s, stream_index, timestamp, flags);
+    int ret;
+
+    if (s->iformat->read_seek2 && !s->iformat->read_seek) {
+        int64_t min_ts = INT64_MIN, max_ts = INT64_MAX;
+        if ((flags & AVSEEK_FLAG_BACKWARD))
+            max_ts = timestamp;
+        else
+            min_ts = timestamp;
+        return avformat_seek_file(s, stream_index, min_ts, timestamp, max_ts,
+                                  flags & ~AVSEEK_FLAG_BACKWARD);
+    }
+
+    ret = seek_frame_internal(s, stream_index, timestamp, flags);
 
     if (ret >= 0)
         ret = avformat_queue_attached_pictures(s);
@@ -2155,6 +2041,7 @@
 
     if(s->seek2any>0)
         flags |= AVSEEK_FLAG_ANY;
+    flags &= ~AVSEEK_FLAG_BACKWARD;
 
     if (s->iformat->read_seek2) {
         int ret;
@@ -2182,8 +2069,8 @@
         //try to seek via read_timestamp()
     }
 
-    //Fallback to old API if new is not implemented but old is
-    //Note the old has somewhat different semantics
+    // Fall back on old API if new is not implemented but old is.
+    // Note the old API has somewhat different semantics.
     if (s->iformat->read_seek || 1) {
         int dir = (ts - (uint64_t)min_ts > (uint64_t)max_ts - ts ? AVSEEK_FLAG_BACKWARD : 0);
         int ret = av_seek_frame(s, stream_index, ts, flags | dir);
@@ -2750,7 +2637,7 @@
 
 int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
 {
-    int i, count, ret, j;
+    int i, count, ret = 0, j;
     int64_t read_size;
     AVStream *st;
     AVPacket pkt1, *pkt;
@@ -2892,11 +2779,15 @@
             break;
         }
 
-        if (ic->flags & AVFMT_FLAG_NOBUFFER) {
-            pkt = &pkt1;
-        } else {
+        if (ic->flags & AVFMT_FLAG_NOBUFFER)
+            free_packet_buffer(&ic->packet_buffer, &ic->packet_buffer_end);
+        {
             pkt = add_to_pktbuf(&ic->packet_buffer, &pkt1,
                                 &ic->packet_buffer_end);
+            if (!pkt) {
+                ret = AVERROR(ENOMEM);
+                goto find_stream_info_err;
+            }
             if ((ret = av_dup_packet(pkt)) < 0)
                 goto find_stream_info_err;
         }
@@ -2943,8 +2834,14 @@
             if (st->avg_frame_rate.num > 0)
                 t = FFMAX(t, av_rescale_q(st->codec_info_nb_frames, av_inv_q(st->avg_frame_rate), AV_TIME_BASE_Q));
 
+            if (   t==0
+                && st->codec_info_nb_frames>30
+                && st->info->fps_first_dts != AV_NOPTS_VALUE
+                && st->info->fps_last_dts  != AV_NOPTS_VALUE)
+                t = FFMAX(t, av_rescale_q(st->info->fps_last_dts - st->info->fps_first_dts, st->time_base, AV_TIME_BASE_Q));
+
             if (t >= ic->max_analyze_duration) {
-                av_log(ic, AV_LOG_WARNING, "max_analyze_duration %d reached at %"PRId64" microseconds\n", ic->max_analyze_duration, t);
+                av_log(ic, AV_LOG_VERBOSE, "max_analyze_duration %d reached at %"PRId64" microseconds\n", ic->max_analyze_duration, t);
                 break;
             }
             if (pkt->duration) {
@@ -2963,6 +2860,8 @@
 
                 if (!st->info->duration_error)
                     st->info->duration_error = av_mallocz(sizeof(st->info->duration_error[0])*2);
+                if (!st->info->duration_error)
+                    return AVERROR(ENOMEM);
 
 //                 if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
 //                     av_log(NULL, AV_LOG_ERROR, "%f\n", dts);
@@ -3017,9 +2916,7 @@
         int err = 0;
         av_init_packet(&empty_pkt);
 
-        ret = -1; /* we could not have all the codec parameters before EOF */
         for(i=0;i<ic->nb_streams;i++) {
-            const char *errmsg;
 
             st = ic->streams[i];
 
@@ -3036,17 +2933,6 @@
                         "decoding for stream %d failed\n", st->index);
                 }
             }
-
-            if (!has_codec_parameters(st, &errmsg)) {
-                char buf[256];
-                avcodec_string(buf, sizeof(buf), st->codec, 0);
-                av_log(ic, AV_LOG_WARNING,
-                       "Could not find codec parameters for stream %d (%s): %s\n"
-                       "Consider increasing the value for the 'analyzeduration' and 'probesize' options\n",
-                       i, buf, errmsg);
-            } else {
-                ret = 0;
-            }
         }
     }
 
@@ -3069,6 +2955,9 @@
                 int      best_fps = 0;
                 double best_error = 0.01;
 
+                if (st->info->codec_info_duration        >= INT64_MAX / st->time_base.num / 2||
+                    st->info->codec_info_duration_fields >= INT64_MAX / st->time_base.den)
+                    continue;
                 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
                           st->info->codec_info_duration_fields*(int64_t)st->time_base.den,
                           st->info->codec_info_duration*2*(int64_t)st->time_base.num, 60000);
@@ -3156,12 +3045,29 @@
     if(ic->probesize)
     estimate_timings(ic, old_offset);
 
+    if (ret >= 0 && ic->nb_streams)
+        ret = -1; /* we could not have all the codec parameters before EOF */
+    for(i=0;i<ic->nb_streams;i++) {
+        const char *errmsg;
+        st = ic->streams[i];
+        if (!has_codec_parameters(st, &errmsg)) {
+            char buf[256];
+            avcodec_string(buf, sizeof(buf), st->codec, 0);
+            av_log(ic, AV_LOG_WARNING,
+                   "Could not find codec parameters for stream %d (%s): %s\n"
+                   "Consider increasing the value for the 'analyzeduration' and 'probesize' options\n",
+                   i, buf, errmsg);
+        } else {
+            ret = 0;
+        }
+    }
+
     compute_chapters_end(ic);
 
  find_stream_info_err:
     for (i=0; i < ic->nb_streams; i++) {
         st = ic->streams[i];
-        if (ic->streams[i]->codec)
+        if (ic->streams[i]->codec && ic->streams[i]->codec->codec_type != AVMEDIA_TYPE_AUDIO)
             ic->streams[i]->codec->thread_count = 0;
         if (st->info)
             av_freep(&st->info->duration_error);
@@ -3803,27 +3709,11 @@
         av_hex_dump(f, pkt->data, pkt->size);
 }
 
-#if FF_API_PKT_DUMP
-void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload)
-{
-    AVRational tb = { 1, AV_TIME_BASE };
-    pkt_dump_internal(NULL, f, 0, pkt, dump_payload, tb);
-}
-#endif
-
 void av_pkt_dump2(FILE *f, AVPacket *pkt, int dump_payload, AVStream *st)
 {
     pkt_dump_internal(NULL, f, 0, pkt, dump_payload, st->time_base);
 }
 
-#if FF_API_PKT_DUMP
-void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt, int dump_payload)
-{
-    AVRational tb = { 1, AV_TIME_BASE };
-    pkt_dump_internal(avcl, NULL, level, pkt, dump_payload, tb);
-}
-#endif
-
 void av_pkt_dump_log2(void *avcl, int level, AVPacket *pkt, int dump_payload,
                       AVStream *st)
 {
@@ -3971,72 +3861,6 @@
     s->pts_wrap_bits = pts_wrap_bits;
 }
 
-int ff_url_join(char *str, int size, const char *proto,
-                const char *authorization, const char *hostname,
-                int port, const char *fmt, ...)
-{
-#if CONFIG_NETWORK
-    struct addrinfo hints = { 0 }, *ai;
-#endif
-
-    str[0] = '\0';
-    if (proto)
-        av_strlcatf(str, size, "%s://", proto);
-    if (authorization && authorization[0])
-        av_strlcatf(str, size, "%s@", authorization);
-#if CONFIG_NETWORK && defined(AF_INET6)
-    /* Determine if hostname is a numerical IPv6 address,
-     * properly escape it within [] in that case. */
-    hints.ai_flags = AI_NUMERICHOST;
-    if (!getaddrinfo(hostname, NULL, &hints, &ai)) {
-        if (ai->ai_family == AF_INET6) {
-            av_strlcat(str, "[", size);
-            av_strlcat(str, hostname, size);
-            av_strlcat(str, "]", size);
-        } else {
-            av_strlcat(str, hostname, size);
-        }
-        freeaddrinfo(ai);
-    } else
-#endif
-        /* Not an IPv6 address, just output the plain string. */
-        av_strlcat(str, hostname, size);
-
-    if (port >= 0)
-        av_strlcatf(str, size, ":%d", port);
-    if (fmt) {
-        va_list vl;
-        int len = strlen(str);
-
-        va_start(vl, fmt);
-        vsnprintf(str + len, size > len ? size - len : 0, fmt, vl);
-        va_end(vl);
-    }
-    return strlen(str);
-}
-
-int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt,
-                     AVFormatContext *src)
-{
-    AVPacket local_pkt;
-
-    local_pkt = *pkt;
-    local_pkt.stream_index = dst_stream;
-    if (pkt->pts != AV_NOPTS_VALUE)
-        local_pkt.pts = av_rescale_q(pkt->pts,
-                                     src->streams[pkt->stream_index]->time_base,
-                                     dst->streams[dst_stream]->time_base);
-    if (pkt->dts != AV_NOPTS_VALUE)
-        local_pkt.dts = av_rescale_q(pkt->dts,
-                                     src->streams[pkt->stream_index]->time_base,
-                                     dst->streams[dst_stream]->time_base);
-    if (pkt->duration)
-        local_pkt.duration = av_rescale_q(pkt->duration,
-                                          src->streams[pkt->stream_index]->time_base,
-                                          dst->streams[dst_stream]->time_base);
-    return av_write_frame(dst, &local_pkt);
-}
-
 void ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf,
                         void *context)
 {
@@ -4101,75 +3925,6 @@
     return -1;
 }
 
-void ff_make_absolute_url(char *buf, int size, const char *base,
-                          const char *rel)
-{
-    char *sep, *path_query;
-    /* Absolute path, relative to the current server */
-    if (base && strstr(base, "://") && rel[0] == '/') {
-        if (base != buf)
-            av_strlcpy(buf, base, size);
-        sep = strstr(buf, "://");
-        if (sep) {
-            /* Take scheme from base url */
-            if (rel[1] == '/') {
-                sep[1] = '\0';
-            } else {
-                /* Take scheme and host from base url */
-                sep += 3;
-                sep = strchr(sep, '/');
-                if (sep)
-                    *sep = '\0';
-            }
-        }
-        av_strlcat(buf, rel, size);
-        return;
-    }
-    /* If rel actually is an absolute url, just copy it */
-    if (!base || strstr(rel, "://") || rel[0] == '/') {
-        av_strlcpy(buf, rel, size);
-        return;
-    }
-    if (base != buf)
-        av_strlcpy(buf, base, size);
-
-    /* Strip off any query string from base */
-    path_query = strchr(buf, '?');
-    if (path_query != NULL)
-        *path_query = '\0';
-
-    /* Is relative path just a new query part? */
-    if (rel[0] == '?') {
-        av_strlcat(buf, rel, size);
-        return;
-    }
-
-    /* Remove the file name from the base url */
-    sep = strrchr(buf, '/');
-    if (sep)
-        sep[1] = '\0';
-    else
-        buf[0] = '\0';
-    while (av_strstart(rel, "../", NULL) && sep) {
-        /* Remove the path delimiter at the end */
-        sep[0] = '\0';
-        sep = strrchr(buf, '/');
-        /* If the next directory name to pop off is "..", break here */
-        if (!strcmp(sep ? &sep[1] : buf, "..")) {
-            /* Readd the slash we just removed */
-            av_strlcat(buf, "/", size);
-            break;
-        }
-        /* Cut off the directory name */
-        if (sep)
-            sep[1] = '\0';
-        else
-            buf[0] = '\0';
-        rel += 3;
-    }
-    av_strlcat(buf, rel, size);
-}
-
 int64_t ff_iso8601_to_unix_time(const char *datestr)
 {
     struct tm time1 = {0}, time2 = {0};
@@ -4259,15 +4014,6 @@
     return 0;
 }
 
-const struct AVCodecTag *avformat_get_riff_video_tags(void)
-{
-    return ff_codec_bmp_tags;
-}
-const struct AVCodecTag *avformat_get_riff_audio_tags(void)
-{
-    return ff_codec_wav_tags;
-}
-
 AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *stream, AVFrame *frame)
 {
     AVRational undef = {0, 1};
@@ -4462,57 +4208,3 @@
     memcpy(st->codec->extradata, data, size);
     st->codec->extradata_size = size;
 }
-
-static int match_host_pattern(const char *pattern, const char *hostname)
-{
-    int len_p, len_h;
-    if (!strcmp(pattern, "*"))
-        return 1;
-    // Skip a possible *. at the start of the pattern
-    if (pattern[0] == '*')
-        pattern++;
-    if (pattern[0] == '.')
-        pattern++;
-    len_p = strlen(pattern);
-    len_h = strlen(hostname);
-    if (len_p > len_h)
-        return 0;
-    // Simply check if the end of hostname is equal to 'pattern'
-    if (!strcmp(pattern, &hostname[len_h - len_p])) {
-        if (len_h == len_p)
-            return 1; // Exact match
-        if (hostname[len_h - len_p - 1] == '.')
-            return 1; // The matched substring is a domain and not just a substring of a domain
-    }
-    return 0;
-}
-
-int ff_http_match_no_proxy(const char *no_proxy, const char *hostname)
-{
-    char *buf, *start;
-    int ret = 0;
-    if (!no_proxy)
-        return 0;
-    if (!hostname)
-        return 0;
-    buf = av_strdup(no_proxy);
-    if (!buf)
-        return 0;
-    start = buf;
-    while (start) {
-        char *sep, *next = NULL;
-        start += strspn(start, " ,");
-        sep = start + strcspn(start, " ,");
-        if (*sep) {
-            next = sep + 1;
-            *sep = '\0';
-        }
-        if (match_host_pattern(start, hostname)) {
-            ret = 1;
-            break;
-        }
-        start = next;
-    }
-    av_free(buf);
-    return ret;
-}
diff --git a/libavformat/vc1test.c b/libavformat/vc1test.c
index e411a25..7c6bcde 100644
--- a/libavformat/vc1test.c
+++ b/libavformat/vc1test.c
@@ -39,7 +39,7 @@
     if (p->buf[3] != 0xC5 || AV_RL32(&p->buf[4]) != 4 || AV_RL32(&p->buf[20]) != 0xC)
         return 0;
 
-    return AVPROBE_SCORE_MAX/2;
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 static int vc1t_read_header(AVFormatContext *s)
diff --git a/libavformat/version.h b/libavformat/version.h
index 8fd08cf..1dfde22 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -30,8 +30,8 @@
 #include "libavutil/avutil.h"
 
 #define LIBAVFORMAT_VERSION_MAJOR 55
-#define LIBAVFORMAT_VERSION_MINOR  3
-#define LIBAVFORMAT_VERSION_MICRO 100
+#define LIBAVFORMAT_VERSION_MINOR 14
+#define LIBAVFORMAT_VERSION_MICRO 102
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                LIBAVFORMAT_VERSION_MINOR, \
@@ -49,12 +49,6 @@
  * the public API and may change, break or disappear at any time.
  */
 
-#ifndef FF_API_OLD_AVIO
-#define FF_API_OLD_AVIO                (LIBAVFORMAT_VERSION_MAJOR < 55)
-#endif
-#ifndef FF_API_PKT_DUMP
-#define FF_API_PKT_DUMP                (LIBAVFORMAT_VERSION_MAJOR < 54)
-#endif
 #ifndef FF_API_ALLOC_OUTPUT_CONTEXT
 #define FF_API_ALLOC_OUTPUT_CONTEXT    (LIBAVFORMAT_VERSION_MAJOR < 56)
 #endif
diff --git a/libavformat/vorbiscomment.c b/libavformat/vorbiscomment.c
index 9b38e6a..f17a0c1 100644
--- a/libavformat/vorbiscomment.c
+++ b/libavformat/vorbiscomment.c
@@ -34,6 +34,7 @@
     { "ALBUMARTIST", "album_artist"},
     { "TRACKNUMBER", "track"  },
     { "DISCNUMBER",  "disc"   },
+    { "DESCRIPTION", "comment" },
     { 0 }
 };
 
diff --git a/libavformat/vqf.c b/libavformat/vqf.c
index f1e6aaf..1ce5359 100644
--- a/libavformat/vqf.c
+++ b/libavformat/vqf.c
@@ -43,7 +43,7 @@
     if (!memcmp(probe_packet->buf + 4, "00052200", 8))
         return AVPROBE_SCORE_MAX;
 
-    return AVPROBE_SCORE_MAX/2;
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 static void add_metadata(AVFormatContext *s, uint32_t tag,
@@ -132,6 +132,11 @@
             rate_flag           = AV_RB32(comm_chunk + 8);
             avio_skip(s->pb, len-12);
 
+            if (st->codec->channels <= 0) {
+                av_log(s, AV_LOG_ERROR, "Invalid number of channels\n");
+                return AVERROR_INVALIDDATA;
+            }
+
             st->codec->bit_rate              = read_bitrate*1000;
             break;
         case MKTAG('D','S','I','Z'): // size of compressed data
diff --git a/libavformat/w64.c b/libavformat/w64.c
index 7bf5502..ef2d90a 100644
--- a/libavformat/w64.c
+++ b/libavformat/w64.c
@@ -20,20 +20,31 @@
 
 #include "w64.h"
 
-const uint8_t ff_w64_guid_riff[16] = { 'r', 'i', 'f', 'f',
-    0x2E, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 };
+const uint8_t ff_w64_guid_riff[16] = {
+    'r', 'i', 'f', 'f',
+    0x2E, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
+};
 
-const uint8_t ff_w64_guid_wave[16] = { 'w', 'a', 'v', 'e',
-    0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
+const uint8_t ff_w64_guid_wave[16] = {
+    'w', 'a', 'v', 'e',
+    0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
+};
 
-const uint8_t ff_w64_guid_fmt [16] = { 'f', 'm', 't', ' ',
-    0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
+const uint8_t ff_w64_guid_fmt [16] = {
+    'f', 'm', 't', ' ',
+    0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
+};
 
 const uint8_t ff_w64_guid_fact[16] = { 'f', 'a', 'c', 't',
-    0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
+    0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
+};
 
-const uint8_t ff_w64_guid_data[16] = { 'd', 'a', 't', 'a',
-    0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
+const uint8_t ff_w64_guid_data[16] = {
+    'd', 'a', 't', 'a',
+    0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
+};
 
-const uint8_t ff_w64_guid_summarylist[16] = { 0xBC, 0x94, 0x5F, 0x92,
-    0x5A, 0x52, 0xD2, 0x11, 0x86, 0xDC, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
+const uint8_t ff_w64_guid_summarylist[16] = {
+    0xBC, 0x94, 0x5F, 0x92,
+    0x5A, 0x52, 0xD2, 0x11, 0x86, 0xDC, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
+};
diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c
index 14c52f8..d5b3b9e 100644
--- a/libavformat/wavdec.c
+++ b/libavformat/wavdec.c
@@ -25,17 +25,18 @@
 
 #include "libavutil/avassert.h"
 #include "libavutil/dict.h"
+#include "libavutil/intreadwrite.h"
 #include "libavutil/log.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
 #include "avformat.h"
-#include "internal.h"
+#include "avio.h"
 #include "avio_internal.h"
+#include "internal.h"
+#include "metadata.h"
 #include "pcm.h"
 #include "riff.h"
 #include "w64.h"
-#include "avio.h"
-#include "metadata.h"
 #include "spdif.h"
 
 typedef struct WAVDemuxContext {
@@ -51,9 +52,11 @@
     int audio_eof;
     int ignore_length;
     int spdif;
+    int smv_cur_pt;
+    int smv_given_first;
+    int unaligned; // e.g. if an odd number of bytes ID3 tag was prepended
 } WAVDemuxContext;
 
-
 #if CONFIG_WAV_DEMUXER
 
 static int64_t next_tag(AVIOContext *pb, uint32_t *tag)
@@ -62,19 +65,27 @@
     return avio_rl32(pb);
 }
 
+/* RIFF chunks are always at even offsets relative to where they start. */
+static int64_t wav_seek_tag(WAVDemuxContext * wav, AVIOContext *s, int64_t offset, int whence)
+{
+    offset += offset < INT64_MAX && offset + wav->unaligned & 1;
+
+    return avio_seek(s, offset, whence);
+}
+
 /* return the size of the found tag */
-static int64_t find_tag(AVIOContext *pb, uint32_t tag1)
+static int64_t find_tag(WAVDemuxContext * wav, AVIOContext *pb, uint32_t tag1)
 {
     unsigned int tag;
     int64_t size;
 
     for (;;) {
         if (url_feof(pb))
-            return -1;
+            return AVERROR_EOF;
         size = next_tag(pb, &tag);
         if (tag == tag1)
             break;
-        avio_skip(pb, size + (size & 1));
+        wav_seek_tag(wav, pb, size, SEEK_CUR);
     }
     return size;
 }
@@ -86,11 +97,9 @@
         return 0;
     if (!memcmp(p->buf + 8, "WAVE", 4)) {
         if (!memcmp(p->buf, "RIFF", 4))
-            /*
-              Since ACT demuxer has standard WAV header at top of it's own,
-              returning score is decreased to avoid probe conflict
-              between ACT and WAV.
-            */
+            /* Since the ACT demuxer has a standard WAV header at the top of
+             * its own, the returned score is decreased to avoid a probe
+             * conflict between ACT and WAV. */
             return AVPROBE_SCORE_MAX - 1;
         else if (!memcmp(p->buf,      "RF64", 4) &&
                  !memcmp(p->buf + 12, "ds64", 4))
@@ -102,7 +111,7 @@
 static void handle_stream_probing(AVStream *st)
 {
     if (st->codec->codec_id == AV_CODEC_ID_PCM_S16LE) {
-        st->request_probe = AVPROBE_SCORE_MAX/2;
+        st->request_probe = AVPROBE_SCORE_EXTENSION;
         st->probe_packets = FFMIN(st->probe_packets, 4);
     }
 }
@@ -173,16 +182,22 @@
 
         if (umid_mask) {
             /* the string formatting below is per SMPTE 330M-2004 Annex C */
-            if (umid_parts[4] == 0 && umid_parts[5] == 0 && umid_parts[6] == 0 && umid_parts[7] == 0) {
+            if (umid_parts[4] == 0 && umid_parts[5] == 0 &&
+                umid_parts[6] == 0 && umid_parts[7] == 0) {
                 /* basic UMID */
-                snprintf(temp, sizeof(temp), "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
-                         umid_parts[0], umid_parts[1], umid_parts[2], umid_parts[3]);
+                snprintf(temp, sizeof(temp),
+                         "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
+                         umid_parts[0], umid_parts[1],
+                         umid_parts[2], umid_parts[3]);
             } else {
                 /* extended UMID */
-                snprintf(temp, sizeof(temp), "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64
-                                               "%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
-                         umid_parts[0], umid_parts[1], umid_parts[2], umid_parts[3],
-                         umid_parts[4], umid_parts[5], umid_parts[6], umid_parts[7]);
+                snprintf(temp, sizeof(temp),
+                         "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64
+                         "%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
+                         umid_parts[0], umid_parts[1],
+                         umid_parts[2], umid_parts[3],
+                         umid_parts[4], umid_parts[5],
+                         umid_parts[6], umid_parts[7]);
             }
 
             if ((ret = av_dict_set(&s->metadata, "umid", temp, 0)) < 0)
@@ -197,7 +212,7 @@
         /* CodingHistory present */
         size -= 602;
 
-        if (!(coding_history = av_malloc(size+1)))
+        if (!(coding_history = av_malloc(size + 1)))
             return AVERROR(ENOMEM);
 
         if ((ret = avio_read(s->pb, coding_history, size)) < 0)
@@ -213,26 +228,28 @@
 }
 
 static const AVMetadataConv wav_metadata_conv[] = {
-    {"description",      "comment"      },
-    {"originator",       "encoded_by"   },
-    {"origination_date", "date"         },
-    {"origination_time", "creation_time"},
-    {0},
+    { "description",      "comment"       },
+    { "originator",       "encoded_by"    },
+    { "origination_date", "date"          },
+    { "origination_time", "creation_time" },
+    { 0 },
 };
 
 /* wav input */
 static int wav_read_header(AVFormatContext *s)
 {
     int64_t size, av_uninit(data_size);
-    int64_t sample_count=0;
+    int64_t sample_count = 0;
     int rf64;
     uint32_t tag;
-    AVIOContext *pb = s->pb;
-    AVStream *st = NULL;
+    AVIOContext *pb      = s->pb;
+    AVStream *st         = NULL;
     WAVDemuxContext *wav = s->priv_data;
     int ret, got_fmt = 0;
     int64_t next_tag_ofs, data_ofs = -1;
 
+    wav->unaligned = avio_tell(s->pb) & 1;
+
     wav->smv_data_ofs = -1;
 
     /* check RIFF header */
@@ -240,21 +257,23 @@
 
     rf64 = tag == MKTAG('R', 'F', '6', '4');
     if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F'))
-        return -1;
+        return AVERROR_INVALIDDATA;
     avio_rl32(pb); /* file size */
     tag = avio_rl32(pb);
     if (tag != MKTAG('W', 'A', 'V', 'E'))
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     if (rf64) {
         if (avio_rl32(pb) != MKTAG('d', 's', '6', '4'))
-            return -1;
+            return AVERROR_INVALIDDATA;
         size = avio_rl32(pb);
         if (size < 24)
-            return -1;
+            return AVERROR_INVALIDDATA;
         avio_rl64(pb); /* RIFF size */
-        data_size = avio_rl64(pb);
+
+        data_size    = avio_rl64(pb);
         sample_count = avio_rl64(pb);
+
         if (data_size < 0 || sample_count < 0) {
             av_log(s, AV_LOG_ERROR, "negative data_size and/or sample_count in "
                    "ds64: data_size = %"PRId64", sample_count = %"PRId64"\n",
@@ -267,7 +286,7 @@
 
     for (;;) {
         AVStream *vst;
-        size = next_tag(pb, &tag);
+        size         = next_tag(pb, &tag);
         next_tag_ofs = avio_tell(pb) + size;
 
         if (url_feof(pb))
@@ -285,14 +304,15 @@
             break;
         case MKTAG('d', 'a', 't', 'a'):
             if (!got_fmt) {
-                av_log(s, AV_LOG_ERROR, "found no 'fmt ' tag before the 'data' tag\n");
+                av_log(s, AV_LOG_ERROR,
+                       "found no 'fmt ' tag before the 'data' tag\n");
                 return AVERROR_INVALIDDATA;
             }
 
             if (rf64) {
                 next_tag_ofs = wav->data_end = avio_tell(pb) + data_size;
             } else {
-                data_size = size;
+                data_size    = size;
                 next_tag_ofs = wav->data_end = size ? next_tag_ofs : INT64_MAX;
             }
 
@@ -304,11 +324,11 @@
             if (!pb->seekable || (!rf64 && !size))
                 goto break_loop;
             break;
-        case MKTAG('f','a','c','t'):
+        case MKTAG('f', 'a', 'c', 't'):
             if (!sample_count)
                 sample_count = avio_rl32(pb);
             break;
-        case MKTAG('b','e','x','t'):
+        case MKTAG('b', 'e', 'x', 't'):
             if ((ret = wav_parse_bext_tag(s, size)) < 0)
                 return ret;
             break;
@@ -323,15 +343,23 @@
                 goto break_loop;
             }
             av_log(s, AV_LOG_DEBUG, "Found SMV data\n");
+            wav->smv_given_first = 0;
             vst = avformat_new_stream(s, NULL);
             if (!vst)
                 return AVERROR(ENOMEM);
             avio_r8(pb);
             vst->id = 1;
             vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
-            vst->codec->codec_id = AV_CODEC_ID_MJPEG;
+            vst->codec->codec_id = AV_CODEC_ID_SMVJPEG;
             vst->codec->width  = avio_rl24(pb);
             vst->codec->height = avio_rl24(pb);
+            vst->codec->extradata_size = 4;
+            vst->codec->extradata = av_malloc(vst->codec->extradata_size +
+                                              FF_INPUT_BUFFER_PADDING_SIZE);
+            if (!vst->codec->extradata) {
+                av_log(s, AV_LOG_ERROR, "Could not allocate extradata.\n");
+                return AVERROR(ENOMEM);
+            }
             size = avio_rl24(pb);
             wav->smv_data_ofs = avio_tell(pb) + (size - 5) * 3;
             avio_rl24(pb);
@@ -341,6 +369,8 @@
             avio_rl24(pb);
             avio_rl24(pb);
             wav->smv_frames_per_jpeg = avio_rl24(pb);
+            AV_WL32(vst->codec->extradata, wav->smv_frames_per_jpeg);
+            wav->smv_cur_pt = 0;
             goto break_loop;
         case MKTAG('L', 'I', 'S', 'T'):
             if (size < 4) {
@@ -354,15 +384,13 @@
             break;
         }
 
-        /* skip padding byte */
-        next_tag_ofs += (next_tag_ofs < INT64_MAX && next_tag_ofs & 1);
-
         /* seek to next tag unless we know that we'll run into EOF */
         if ((avio_size(pb) > 0 && next_tag_ofs >= avio_size(pb)) ||
-            avio_seek(pb, next_tag_ofs, SEEK_SET) < 0) {
+            wav_seek_tag(wav, pb, next_tag_ofs, SEEK_SET) < 0) {
             break;
         }
     }
+
 break_loop:
     if (data_ofs < 0) {
         av_log(s, AV_LOG_ERROR, "no 'data' tag found\n");
@@ -371,8 +399,11 @@
 
     avio_seek(pb, data_ofs, SEEK_SET);
 
-    if (!sample_count && st->codec->channels && av_get_bits_per_sample(st->codec->codec_id) && wav->data_end <= avio_size(pb))
-        sample_count = (data_size<<3) / (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id));
+    if (!sample_count && st->codec->channels &&
+        av_get_bits_per_sample(st->codec->codec_id) && wav->data_end <= avio_size(pb))
+        sample_count = (data_size << 3) /
+                       (st->codec->channels *
+                        (uint64_t)av_get_bits_per_sample(st->codec->codec_id));
     if (sample_count)
         st->duration = sample_count;
 
@@ -382,7 +413,8 @@
     return 0;
 }
 
-/** Find chunk with w64 GUID by skipping over other chunks
+/**
+ * Find chunk with w64 GUID by skipping over other chunks.
  * @return the size of the found chunk
  */
 static int64_t find_guid(AVIOContext *pb, const uint8_t guid1[16])
@@ -394,18 +426,17 @@
         avio_read(pb, guid, 16);
         size = avio_rl64(pb);
         if (size <= 24)
-            return -1;
+            return AVERROR_INVALIDDATA;
         if (!memcmp(guid, guid1, 16))
             return size;
         avio_skip(pb, FFALIGN(size, INT64_C(8)) - 24);
     }
-    return -1;
+    return AVERROR_EOF;
 }
 
 #define MAX_SIZE 4096
 
-static int wav_read_packet(AVFormatContext *s,
-                           AVPacket *pkt)
+static int wav_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     int ret, size;
     int64_t left;
@@ -417,7 +448,7 @@
         enum AVCodecID codec;
         ret = ff_spdif_probe(s->pb->buffer, s->pb->buf_end - s->pb->buffer,
                              &codec);
-        if (ret > AVPROBE_SCORE_MAX / 2) {
+        if (ret > AVPROBE_SCORE_EXTENSION) {
             s->streams[0]->codec->codec_id = codec;
             wav->spdif = 1;
         } else {
@@ -432,10 +463,13 @@
 smv_retry:
         audio_dts = s->streams[0]->cur_dts;
         video_dts = s->streams[1]->cur_dts;
+
         if (audio_dts != AV_NOPTS_VALUE && video_dts != AV_NOPTS_VALUE) {
-            audio_dts = av_rescale_q(audio_dts, s->streams[0]->time_base, AV_TIME_BASE_Q);
-            video_dts = av_rescale_q(video_dts, s->streams[1]->time_base, AV_TIME_BASE_Q);
-            wav->smv_last_stream = video_dts >= audio_dts;
+            /*We always return a video frame first to get the pixel format first*/
+            wav->smv_last_stream = wav->smv_given_first ?
+                av_compare_ts(video_dts, s->streams[1]->time_base,
+                              audio_dts, s->streams[0]->time_base) > 0 : 0;
+            wav->smv_given_first = 1;
         }
         wav->smv_last_stream = !wav->smv_last_stream;
         wav->smv_last_stream |= wav->audio_eof;
@@ -453,8 +487,13 @@
             if (ret < 0)
                 goto smv_out;
             pkt->pos -= 3;
-            pkt->pts = wav->smv_block * wav->smv_frames_per_jpeg;
-            wav->smv_block++;
+            pkt->pts = wav->smv_block * wav->smv_frames_per_jpeg + wav->smv_cur_pt;
+            wav->smv_cur_pt++;
+            if (wav->smv_frames_per_jpeg > 0)
+                wav->smv_cur_pt %= wav->smv_frames_per_jpeg;
+            if (!wav->smv_cur_pt)
+                wav->smv_block++;
+
             pkt->stream_index = 1;
 smv_out:
             avio_seek(s->pb, old_pos, SEEK_SET);
@@ -470,19 +509,19 @@
 
     left = wav->data_end - avio_tell(s->pb);
     if (wav->ignore_length)
-        left= INT_MAX;
-    if (left <= 0){
+        left = INT_MAX;
+    if (left <= 0) {
         if (CONFIG_W64_DEMUXER && wav->w64)
             left = find_guid(s->pb, ff_w64_guid_data) - 24;
         else
-            left = find_tag(s->pb, MKTAG('d', 'a', 't', 'a'));
+            left = find_tag(wav, s->pb, MKTAG('d', 'a', 't', 'a'));
         if (left < 0) {
             wav->audio_eof = 1;
             if (wav->smv_data_ofs > 0 && !wav->smv_eof)
                 goto smv_retry;
             return AVERROR_EOF;
         }
-        wav->data_end= avio_tell(s->pb) + left;
+        wav->data_end = avio_tell(s->pb) + left;
     }
 
     size = MAX_SIZE;
@@ -513,7 +552,10 @@
             smv_timestamp = av_rescale_q(timestamp, s->streams[0]->time_base, s->streams[1]->time_base);
         else
             timestamp = av_rescale_q(smv_timestamp, s->streams[1]->time_base, s->streams[0]->time_base);
-        wav->smv_block = smv_timestamp / wav->smv_frames_per_jpeg;
+        if (wav->smv_frames_per_jpeg > 0) {
+            wav->smv_block = smv_timestamp / wav->smv_frames_per_jpeg;
+            wav->smv_cur_pt = smv_timestamp % wav->smv_frames_per_jpeg;
+        }
     }
 
     st = s->streams[0];
@@ -552,12 +594,11 @@
     .read_packet    = wav_read_packet,
     .read_seek      = wav_read_seek,
     .flags          = AVFMT_GENERIC_INDEX,
-    .codec_tag      = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 },
+    .codec_tag      = (const AVCodecTag * const []) { ff_codec_wav_tags,  0 },
     .priv_class     = &wav_demuxer_class,
 };
 #endif /* CONFIG_WAV_DEMUXER */
 
-
 #if CONFIG_W64_DEMUXER
 static int w64_probe(AVProbeData *p)
 {
@@ -573,23 +614,24 @@
 static int w64_read_header(AVFormatContext *s)
 {
     int64_t size, data_ofs = 0;
-    AVIOContext *pb  = s->pb;
-    WAVDemuxContext    *wav = s->priv_data;
+    AVIOContext *pb      = s->pb;
+    WAVDemuxContext *wav = s->priv_data;
     AVStream *st;
     uint8_t guid[16];
     int ret;
 
     avio_read(pb, guid, 16);
     if (memcmp(guid, ff_w64_guid_riff, 16))
-        return -1;
+        return AVERROR_INVALIDDATA;
 
-    if (avio_rl64(pb) < 16 + 8 + 16 + 8 + 16 + 8) /* riff + wave + fmt + sizes */
-        return -1;
+    /* riff + wave + fmt + sizes */
+    if (avio_rl64(pb) < 16 + 8 + 16 + 8 + 16 + 8)
+        return AVERROR_INVALIDDATA;
 
     avio_read(pb, guid, 16);
     if (memcmp(guid, ff_w64_guid_wave, 16)) {
         av_log(s, AV_LOG_ERROR, "could not find wave guid\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     wav->w64 = 1;
@@ -685,6 +727,6 @@
     .read_packet    = wav_read_packet,
     .read_seek      = wav_read_seek,
     .flags          = AVFMT_GENERIC_INDEX,
-    .codec_tag      = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 },
+    .codec_tag      = (const AVCodecTag * const []) { ff_codec_wav_tags, 0 },
 };
 #endif /* CONFIG_W64_DEMUXER */
diff --git a/libavformat/webvttdec.c b/libavformat/webvttdec.c
index 694a020..0654485 100644
--- a/libavformat/webvttdec.c
+++ b/libavformat/webvttdec.c
@@ -29,9 +29,12 @@
 #include "subtitles.h"
 #include "libavutil/bprint.h"
 #include "libavutil/intreadwrite.h"
+#include "libavutil/opt.h"
 
 typedef struct {
+    const AVClass *class;
     FFDemuxSubtitlesQueue q;
+    int kind;
 } WebVTTContext;
 
 static int webvtt_probe(AVProbeData *p)
@@ -66,6 +69,7 @@
     avpriv_set_pts_info(st, 64, 1, 1000);
     st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
     st->codec->codec_id   = AV_CODEC_ID_WEBVTT;
+    st->disposition |= webvtt->kind;
 
     av_bprint_init(&header, 0, AV_BPRINT_SIZE_UNLIMITED);
     av_bprint_init(&cue,    0, AV_BPRINT_SIZE_UNLIMITED);
@@ -74,8 +78,8 @@
         int i;
         int64_t pos;
         AVPacket *sub;
-        const char *p, *identifier;
-        //const char *settings = NULL;
+        const char *p, *identifier, *settings;
+        int identifier_len, settings_len;
         int64_t ts_start, ts_end;
 
         ff_subtitles_read_chunk(s->pb, &cue);
@@ -92,15 +96,23 @@
             continue;
 
         /* optional cue identifier (can be a number like in SRT or some kind of
-         * chaptering id), silently skip it */
-        for (i = 0; p[i] && p[i] != '\n'; i++) {
+         * chaptering id) */
+        for (i = 0; p[i] && p[i] != '\n' && p[i] != '\r'; i++) {
             if (!strncmp(p + i, "-->", 3)) {
                 identifier = NULL;
                 break;
             }
         }
-        if (identifier)
-            p += strcspn(p, "\n");
+        if (!identifier)
+            identifier_len = 0;
+        else {
+            identifier_len = strcspn(p, "\r\n");
+            p += identifier_len;
+            if (*p == '\r')
+                p++;
+            if (*p == '\n')
+                p++;
+        }
 
         /* cue timestamps */
         if ((ts_start = read_ts(p)) == AV_NOPTS_VALUE)
@@ -112,14 +124,15 @@
         if ((ts_end = read_ts(p)) == AV_NOPTS_VALUE)
             break;
 
-        /* optional cue settings, TODO: store in side_data */
+        /* optional cue settings */
         p += strcspn(p, "\n\t ");
         while (*p == '\t' || *p == ' ')
             p++;
-        if (*p != '\n') {
-            //settings = p;
-            p += strcspn(p, "\n");
-        }
+        settings = p;
+        settings_len = strcspn(p, "\r\n");
+        p += settings_len;
+        if (*p == '\r')
+            p++;
         if (*p == '\n')
             p++;
 
@@ -132,6 +145,20 @@
         sub->pos = pos;
         sub->pts = ts_start;
         sub->duration = ts_end - ts_start;
+
+#define SET_SIDE_DATA(name, type) do {                                  \
+    if (name##_len) {                                                   \
+        uint8_t *buf = av_packet_new_side_data(sub, type, name##_len);  \
+        if (!buf) {                                                     \
+            res = AVERROR(ENOMEM);                                      \
+            goto end;                                                   \
+        }                                                               \
+        memcpy(buf, name, name##_len);                                  \
+    }                                                                   \
+} while (0)
+
+        SET_SIDE_DATA(identifier, AV_PKT_DATA_WEBVTT_IDENTIFIER);
+        SET_SIDE_DATA(settings,   AV_PKT_DATA_WEBVTT_SETTINGS);
     }
 
     ff_subtitles_queue_finalize(&webvtt->q);
@@ -163,6 +190,25 @@
     return 0;
 }
 
+#define OFFSET(x) offsetof(WebVTTContext, x)
+#define KIND_FLAGS AV_OPT_FLAG_SUBTITLE_PARAM
+
+static const AVOption options[] = {
+    { "kind", "Set kind of WebVTT track", OFFSET(kind), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, KIND_FLAGS, "webvtt_kind" },
+        { "subtitles",    "WebVTT subtitles kind",    0, AV_OPT_TYPE_CONST, { .i64 = 0 },                           INT_MIN, INT_MAX, 0, "webvtt_kind" },
+        { "captions",     "WebVTT captions kind",     0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CAPTIONS },     INT_MIN, INT_MAX, 0, "webvtt_kind" },
+        { "descriptions", "WebVTT descriptions kind", 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DESCRIPTIONS }, INT_MIN, INT_MAX, 0, "webvtt_kind" },
+        { "metadata",     "WebVTT metadata kind",     0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_METADATA },     INT_MIN, INT_MAX, 0, "webvtt_kind" },
+    { NULL }
+};
+
+static const AVClass webvtt_demuxer_class = {
+    .class_name  = "WebVTT demuxer",
+    .item_name   = av_default_item_name,
+    .option      = options,
+    .version     = LIBAVUTIL_VERSION_INT,
+};
+
 AVInputFormat ff_webvtt_demuxer = {
     .name           = "webvtt",
     .long_name      = NULL_IF_CONFIG_SMALL("WebVTT subtitle"),
@@ -173,4 +219,5 @@
     .read_seek2     = webvtt_read_seek,
     .read_close     = webvtt_read_close,
     .extensions     = "vtt",
+    .priv_class     = &webvtt_demuxer_class,
 };
diff --git a/libavformat/webvttenc.c b/libavformat/webvttenc.c
new file mode 100644
index 0000000..bd19a83
--- /dev/null
+++ b/libavformat/webvttenc.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2013 Matthew Heaney
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * WebVTT subtitle muxer
+ * @see http://dev.w3.org/html5/webvtt/
+ */
+
+#include "avformat.h"
+#include "internal.h"
+
+static void webvtt_write_time(AVIOContext *pb, int64_t millisec)
+{
+    int64_t sec, min, hour;
+    sec = millisec / 1000;
+    millisec -= 1000 * sec;
+    min = sec / 60;
+    sec -= 60 * min;
+    hour = min / 60;
+    min -= 60 * hour;
+
+    if (hour > 0)
+        avio_printf(pb, "%"PRId64":", hour);
+
+    avio_printf(pb, "%02"PRId64":%02"PRId64".%03"PRId64"", min, sec, millisec);
+}
+
+static int webvtt_write_header(AVFormatContext *ctx)
+{
+    AVStream     *s = ctx->streams[0];
+    AVIOContext *pb = ctx->pb;
+
+    avpriv_set_pts_info(s, 64, 1, 1000);
+
+    avio_printf(pb, "WEBVTT\n");
+    avio_flush(pb);
+
+    return 0;
+}
+
+static int webvtt_write_packet(AVFormatContext *ctx, AVPacket *pkt)
+{
+    AVIOContext  *pb = ctx->pb;
+    int id_size, settings_size;
+    uint8_t *id, *settings;
+
+    avio_printf(pb, "\n");
+
+    id = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_IDENTIFIER,
+                                 &id_size);
+
+    if (id && id_size > 0)
+        avio_printf(pb, "%.*s\n", id_size, id);
+
+    webvtt_write_time(pb, pkt->pts);
+    avio_printf(pb, " --> ");
+    webvtt_write_time(pb, pkt->pts + pkt->duration);
+
+    settings = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_SETTINGS,
+                                       &settings_size);
+
+    if (settings && settings_size > 0)
+        avio_printf(pb, " %.*s", settings_size, settings);
+
+    avio_printf(pb, "\n");
+
+    avio_write(pb, pkt->data, pkt->size);
+    avio_printf(pb, "\n");
+
+    return 0;
+}
+
+AVOutputFormat ff_webvtt_muxer = {
+    .name              = "webvtt",
+    .long_name         = NULL_IF_CONFIG_SMALL("WebVTT subtitle"),
+    .extensions        = "vtt",
+    .mime_type         = "text/vtt",
+    .subtitle_codec    = AV_CODEC_ID_WEBVTT,
+    .write_header      = webvtt_write_header,
+    .write_packet      = webvtt_write_packet,
+};
diff --git a/libavformat/westwood_aud.c b/libavformat/westwood_aud.c
index d666117..f2bd3a1 100644
--- a/libavformat/westwood_aud.c
+++ b/libavformat/westwood_aud.c
@@ -77,7 +77,7 @@
         return 0;
 
     /* return 1/2 certainty since this file check is a little sketchy */
-    return AVPROBE_SCORE_MAX / 2;
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 static int wsaud_read_header(AVFormatContext *s)
diff --git a/libavformat/westwood_vqa.c b/libavformat/westwood_vqa.c
index c996dad..d8791da 100644
--- a/libavformat/westwood_vqa.c
+++ b/libavformat/westwood_vqa.c
@@ -101,12 +101,13 @@
     avio_seek(pb, 20, SEEK_SET);
 
     /* the VQA header needs to go to the decoder */
-    st->codec->extradata_size = VQA_HEADER_SIZE;
     st->codec->extradata = av_mallocz(VQA_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!st->codec->extradata)
+        return AVERROR(ENOMEM);
+    st->codec->extradata_size = VQA_HEADER_SIZE;
     header = (unsigned char *)st->codec->extradata;
     if (avio_read(pb, st->codec->extradata, VQA_HEADER_SIZE) !=
         VQA_HEADER_SIZE) {
-        av_free(st->codec->extradata);
         return AVERROR(EIO);
     }
     st->codec->width = AV_RL16(&header[6]);
diff --git a/libavformat/wtv.h b/libavformat/wtv.h
index efe90d6..51ac626 100644
--- a/libavformat/wtv.h
+++ b/libavformat/wtv.h
@@ -25,7 +25,7 @@
 #include "riff.h"
 #include "asf.h"
 
-#define WTV_SECTOR_BITS    12
+#define WTV_SECTOR_BITS    INT64_C(12)
 #define WTV_SECTOR_SIZE    (1 << WTV_SECTOR_BITS)
 #define WTV_BIGSECTOR_BITS 18
 #define WTV_PAD8(x) (((x) + 7) & ~7)
diff --git a/libavformat/wtvdec.c b/libavformat/wtvdec.c
index e423370..551242d 100644
--- a/libavformat/wtvdec.c
+++ b/libavformat/wtvdec.c
@@ -47,11 +47,11 @@
  */
 
 typedef struct {
-    AVIOContext *pb_filesystem;  /** file system (AVFormatContext->pb) */
+    AVIOContext *pb_filesystem;  /**< file system (AVFormatContext->pb) */
 
-    int sector_bits;     /** sector shift bits; used to convert sector number into pb_filesystem offset */
-    uint32_t *sectors;   /** file allocation table */
-    int nb_sectors;      /** number of sectors */
+    int sector_bits;     /**< sector shift bits; used to convert sector number into pb_filesystem offset */
+    uint32_t *sectors;   /**< file allocation table */
+    int nb_sectors;      /**< number of sectors */
 
     int error;
     int64_t position;
@@ -88,7 +88,7 @@
             int i = wf->position >> wf->sector_bits;
             if (i >= wf->nb_sectors ||
                 (wf->sectors[i] != wf->sectors[i - 1] + (1 << (wf->sector_bits - WTV_SECTOR_BITS)) &&
-                avio_seek(pb, (int64_t)wf->sectors[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)) {
+                avio_seek(pb, wf->sectors[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)) {
                 wf->error = 1;
                 break;
             }
@@ -113,7 +113,7 @@
         offset = wf->length;
 
     wf->error = offset < 0 || offset >= wf->length ||
-                avio_seek(pb, ((int64_t)wf->sectors[offset >> wf->sector_bits] << WTV_SECTOR_BITS)
+                avio_seek(pb, (wf->sectors[offset >> wf->sector_bits] << WTV_SECTOR_BITS)
                               + (offset & ((1 << wf->sector_bits) - 1)), SEEK_SET) < 0;
     wf->position = offset;
     return offset;
@@ -183,7 +183,7 @@
         }
         wf->nb_sectors = 0;
         for (i = 0; i < nb_sectors1; i++) {
-            if (avio_seek(s->pb, (int64_t)sectors1[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)
+            if (avio_seek(s->pb, sectors1[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)
                 break;
             wf->nb_sectors += read_ints(s->pb, wf->sectors + i * WTV_SECTOR_SIZE / 4, WTV_SECTOR_SIZE / 4);
         }
@@ -213,7 +213,7 @@
 
     /* seek to initial sector */
     wf->position = 0;
-    if (avio_seek(s->pb, (int64_t)wf->sectors[0] << WTV_SECTOR_BITS, SEEK_SET) < 0) {
+    if (avio_seek(s->pb, wf->sectors[0] << WTV_SECTOR_BITS, SEEK_SET) < 0) {
         av_free(wf->sectors);
         av_free(wf);
         return NULL;
@@ -306,10 +306,10 @@
 } WtvStream;
 
 typedef struct {
-    AVIOContext *pb;       /** timeline file */
+    AVIOContext *pb;       /**< timeline file */
     int64_t epoch;
-    int64_t pts;             /** pts for next data chunk */
-    int64_t last_valid_pts;  /** latest valid pts, used for interative seeking */
+    int64_t pts;             /**< pts for next data chunk */
+    int64_t last_valid_pts;  /**< latest valid pts, used for interative seeking */
 
     /* maintain private seek index, as the AVIndexEntry->pos is relative to the
        start of the 'timeline' file, not the file system (AVFormatContext->pb) */
@@ -436,6 +436,7 @@
     av_dict_set(&st->metadata, "title", description, 0);
     st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
     st->codec->codec_id   = AV_CODEC_ID_MJPEG;
+    st->id = -1;
     ret = av_get_packet(pb, &st->attached_pic, filesize);
     if (ret < 0)
         goto done;
diff --git a/libavformat/wtvenc.c b/libavformat/wtvenc.c
index 410a2dc..04e6cc2 100644
--- a/libavformat/wtvenc.c
+++ b/libavformat/wtvenc.c
@@ -28,6 +28,7 @@
 #include "libavutil/intreadwrite.h"
 #include "libavutil/avassert.h"
 #include "avformat.h"
+#include "avio_internal.h"
 #include "internal.h"
 #include "wtv.h"
 #include "asf.h"
@@ -87,10 +88,10 @@
 typedef struct {
     int64_t timeline_start_pos;
     WtvFile file[WTV_FILES];
-    int64_t serial;         /** chunk serial number */
-    int64_t last_chunk_pos; /** last chunk position */
-    int64_t last_timestamp_pos; /** last timestamp chunk position */
-    int64_t first_index_pos;    /** first index_chunk position */
+    int64_t serial;         /**< chunk serial number */
+    int64_t last_chunk_pos; /**< last chunk position */
+    int64_t last_timestamp_pos; /**< last timestamp chunk position */
+    int64_t first_index_pos;    /**< first index_chunk position */
 
     WtvChunkEntry index[MAX_NB_INDEX];
     int nb_index;
@@ -127,12 +128,7 @@
     WTVHeaderWriteFunc *write_header;
 } WTVRootEntryTable;
 
-static int write_pad(AVIOContext *pb, int size)
-{
-    for (; size > 0; size--)
-        avio_w8(pb, 0);
-    return 0;
-}
+#define write_pad(pb, size) ffio_fill(pb, 0, size)
 
 static const ff_asf_guid *get_codec_guid(enum AVCodecID id, const AVCodecGuid *av_guid)
 {
diff --git a/libavformat/wv.c b/libavformat/wv.c
index 97a6c1f..0f4f807 100644
--- a/libavformat/wv.c
+++ b/libavformat/wv.c
@@ -1,6 +1,5 @@
 /*
- * WavPack demuxer
- * Copyright (c) 2006,2011 Konstantin Shishkov
+ * WavPack shared functions
  *
  * This file is part of FFmpeg.
  *
@@ -19,379 +18,35 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/channel_layout.h"
+#include <stdint.h>
+#include <string.h>
+
+#include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
-#include "libavutil/dict.h"
-#include "avformat.h"
-#include "internal.h"
-#include "apetag.h"
-#include "id3v1.h"
 
-// specs say that maximum block size is 1Mb
-#define WV_BLOCK_LIMIT 1047576
+#include "wv.h"
 
-#define WV_EXTRA_SIZE 12
-
-#define WV_START_BLOCK  0x0800
-#define WV_END_BLOCK    0x1000
-#define WV_SINGLE_BLOCK (WV_START_BLOCK | WV_END_BLOCK)
-
-enum WV_FLAGS {
-    WV_MONO   = 0x0004,
-    WV_HYBRID = 0x0008,
-    WV_JOINT  = 0x0010,
-    WV_CROSSD = 0x0020,
-    WV_HSHAPE = 0x0040,
-    WV_FLOAT  = 0x0080,
-    WV_INT32  = 0x0100,
-    WV_HBR    = 0x0200,
-    WV_HBAL   = 0x0400,
-    WV_MCINIT = 0x0800,
-    WV_MCEND  = 0x1000,
-};
-
-static const int wv_rates[16] = {
-     6000,  8000,  9600, 11025, 12000, 16000,  22050, 24000,
-    32000, 44100, 48000, 64000, 88200, 96000, 192000,    -1
-};
-
-typedef struct {
-    uint32_t blksize, flags;
-    int rate, chan, bpp;
-    uint32_t chmask;
-    uint32_t samples, soff;
-    int multichannel;
-    int block_parsed;
-    uint8_t extra[WV_EXTRA_SIZE];
-    int64_t pos;
-
-    int64_t apetag_start;
-} WVContext;
-
-static int wv_probe(AVProbeData *p)
+int ff_wv_parse_header(WvHeader *wv, const uint8_t *data)
 {
-    /* check file header */
-    if (p->buf_size <= 32)
-        return 0;
-    if (p->buf[0] == 'w' && p->buf[1] == 'v' &&
-        p->buf[2] == 'p' && p->buf[3] == 'k')
-        return AVPROBE_SCORE_MAX;
-    else
-        return 0;
-}
+    memset(wv, 0, sizeof(*wv));
 
-static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb,
-                                int append)
-{
-    WVContext *wc = ctx->priv_data;
-    uint32_t tag, ver;
-    int size;
-    int rate, bpp, chan;
-    uint32_t chmask;
-
-    wc->pos = avio_tell(pb);
-
-    /* don't return bogus packets with the ape tag data */
-    if (wc->apetag_start && wc->pos >= wc->apetag_start)
-        return AVERROR_EOF;
-
-    if (!append) {
-        tag = avio_rl32(pb);
-        if (tag != MKTAG('w', 'v', 'p', 'k'))
-            return AVERROR_INVALIDDATA;
-        size = avio_rl32(pb);
-        if (size < 24 || size > WV_BLOCK_LIMIT) {
-            av_log(ctx, AV_LOG_ERROR, "Incorrect block size %i\n", size);
-            return AVERROR_INVALIDDATA;
-        }
-        wc->blksize = size;
-        ver = avio_rl16(pb);
-        if (ver < 0x402 || ver > 0x410) {
-            av_log(ctx, AV_LOG_ERROR, "Unsupported version %03X\n", ver);
-            return AVERROR_PATCHWELCOME;
-        }
-        avio_r8(pb); // track no
-        avio_r8(pb); // track sub index
-        wc->samples = avio_rl32(pb); // total samples in file
-        wc->soff    = avio_rl32(pb); // offset in samples of current block
-        avio_read(pb, wc->extra, WV_EXTRA_SIZE);
-    } else {
-        size = wc->blksize;
-    }
-    wc->flags = AV_RL32(wc->extra + 4);
-    /* Blocks with zero samples don't contain actual audio information
-     * and should be ignored */
-    if (!AV_RN32(wc->extra))
-        return 0;
-    // parse flags
-    bpp    = ((wc->flags & 3) + 1) << 3;
-    chan   = 1 + !(wc->flags & WV_MONO);
-    chmask = wc->flags & WV_MONO ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
-    rate   = wv_rates[(wc->flags >> 23) & 0xF];
-    wc->multichannel = !!((wc->flags & WV_SINGLE_BLOCK) != WV_SINGLE_BLOCK);
-    if (wc->multichannel) {
-        chan   = wc->chan;
-        chmask = wc->chmask;
-    }
-    if ((rate == -1 || !chan) && !wc->block_parsed) {
-        int64_t block_end = avio_tell(pb) + wc->blksize - 24;
-        if (!pb->seekable) {
-            av_log(ctx, AV_LOG_ERROR,
-                   "Cannot determine additional parameters\n");
-            return AVERROR_INVALIDDATA;
-        }
-        while (avio_tell(pb) < block_end) {
-            int id, size;
-            id   = avio_r8(pb);
-            size = (id & 0x80) ? avio_rl24(pb) : avio_r8(pb);
-            size <<= 1;
-            if (id & 0x40)
-                size--;
-            switch (id & 0x3F) {
-            case 0xD:
-                if (size <= 1) {
-                    av_log(ctx, AV_LOG_ERROR,
-                           "Insufficient channel information\n");
-                    return AVERROR_INVALIDDATA;
-                }
-                chan = avio_r8(pb);
-                switch (size - 2) {
-                case 0:
-                    chmask = avio_r8(pb);
-                    break;
-                case 1:
-                    chmask = avio_rl16(pb);
-                    break;
-                case 2:
-                    chmask = avio_rl24(pb);
-                    break;
-                case 3:
-                    chmask = avio_rl32(pb);
-                    break;
-                case 5:
-                    avio_skip(pb, 1);
-                    chan  |= (avio_r8(pb) & 0xF) << 8;
-                    chmask = avio_rl24(pb);
-                    break;
-                default:
-                    av_log(ctx, AV_LOG_ERROR,
-                           "Invalid channel info size %d\n", size);
-                    return AVERROR_INVALIDDATA;
-                }
-                break;
-            case 0x27:
-                rate = avio_rl24(pb);
-                break;
-            default:
-                avio_skip(pb, size);
-            }
-            if (id & 0x40)
-                avio_skip(pb, 1);
-        }
-        if (rate == -1) {
-            av_log(ctx, AV_LOG_ERROR,
-                   "Cannot determine custom sampling rate\n");
-            return AVERROR_INVALIDDATA;
-        }
-        avio_seek(pb, block_end - wc->blksize + 24, SEEK_SET);
-    }
-    if (!wc->bpp)
-        wc->bpp    = bpp;
-    if (!wc->chan)
-        wc->chan   = chan;
-    if (!wc->chmask)
-        wc->chmask = chmask;
-    if (!wc->rate)
-        wc->rate   = rate;
-
-    if (wc->flags && bpp != wc->bpp) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Bits per sample differ, this block: %i, header block: %i\n",
-               bpp, wc->bpp);
+    if (AV_RL32(data) != MKTAG('w', 'v', 'p', 'k'))
         return AVERROR_INVALIDDATA;
-    }
-    if (wc->flags && !wc->multichannel && chan != wc->chan) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Channels differ, this block: %i, header block: %i\n",
-               chan, wc->chan);
+
+    wv->blocksize     = AV_RL32(data + 4);
+    if (wv->blocksize < 24 || wv->blocksize > WV_BLOCK_LIMIT)
         return AVERROR_INVALIDDATA;
-    }
-    if (wc->flags && rate != -1 && rate != wc->rate) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Sampling rate differ, this block: %i, header block: %i\n",
-               rate, wc->rate);
-        return AVERROR_INVALIDDATA;
-    }
-    wc->blksize = size - 24;
-    return 0;
-}
+    wv->blocksize -= 24;
 
-static int wv_read_header(AVFormatContext *s)
-{
-    AVIOContext *pb = s->pb;
-    WVContext *wc = s->priv_data;
-    AVStream *st;
-    int ret;
+    wv->version       = AV_RL16(data + 8);
+    wv->total_samples = AV_RL32(data + 12);
+    wv->block_idx     = AV_RL32(data + 16);
+    wv->samples       = AV_RL32(data + 20);
+    wv->flags         = AV_RL32(data + 24);
+    wv->crc           = AV_RL32(data + 28);
 
-    wc->block_parsed = 0;
-    for (;;) {
-        if ((ret = wv_read_block_header(s, pb, 0)) < 0)
-            return ret;
-        if (!AV_RN32(wc->extra))
-            avio_skip(pb, wc->blksize - 24);
-        else
-            break;
-    }
-
-    /* now we are ready: build format streams */
-    st = avformat_new_stream(s, NULL);
-    if (!st)
-        return AVERROR(ENOMEM);
-    st->codec->codec_type            = AVMEDIA_TYPE_AUDIO;
-    st->codec->codec_id              = AV_CODEC_ID_WAVPACK;
-    st->codec->channels              = wc->chan;
-    st->codec->channel_layout        = wc->chmask;
-    st->codec->sample_rate           = wc->rate;
-    st->codec->bits_per_coded_sample = wc->bpp;
-    avpriv_set_pts_info(st, 64, 1, wc->rate);
-    st->start_time = 0;
-    if (wc->samples != 0xFFFFFFFFu)
-        st->duration = wc->samples;
-
-    if (s->pb->seekable) {
-        int64_t cur = avio_tell(s->pb);
-        wc->apetag_start = ff_ape_parse_tag(s);
-        if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
-            ff_id3v1_read(s);
-        avio_seek(s->pb, cur, SEEK_SET);
-    }
+    wv->initial = !!(wv->flags & WV_FLAG_INITIAL_BLOCK);
+    wv->final   = !!(wv->flags & WV_FLAG_FINAL_BLOCK);
 
     return 0;
 }
-
-static int wv_read_packet(AVFormatContext *s, AVPacket *pkt)
-{
-    WVContext *wc = s->priv_data;
-    int ret;
-    int size, ver, off;
-    int64_t pos;
-    uint32_t block_samples;
-
-    if (url_feof(s->pb))
-        return AVERROR_EOF;
-    if (wc->block_parsed) {
-        if ((ret = wv_read_block_header(s, s->pb, 0)) < 0)
-            return ret;
-    }
-
-    pos = wc->pos;
-    off = wc->multichannel ? 4 : 0;
-    if (av_new_packet(pkt, wc->blksize + WV_EXTRA_SIZE + off) < 0)
-        return AVERROR(ENOMEM);
-    if (wc->multichannel)
-        AV_WL32(pkt->data, wc->blksize + WV_EXTRA_SIZE + 12);
-    memcpy(pkt->data + off, wc->extra, WV_EXTRA_SIZE);
-    ret = avio_read(s->pb, pkt->data + WV_EXTRA_SIZE + off, wc->blksize);
-    if (ret != wc->blksize) {
-        av_free_packet(pkt);
-        return AVERROR(EIO);
-    }
-    while (!(wc->flags & WV_END_BLOCK)) {
-        if (avio_rl32(s->pb) != MKTAG('w', 'v', 'p', 'k')) {
-            av_free_packet(pkt);
-            return AVERROR_INVALIDDATA;
-        }
-        if ((ret = av_append_packet(s->pb, pkt, 4)) < 0) {
-            av_free_packet(pkt);
-            return ret;
-        }
-        size = AV_RL32(pkt->data + pkt->size - 4);
-        if (size < 24 || size > WV_BLOCK_LIMIT) {
-            av_free_packet(pkt);
-            av_log(s, AV_LOG_ERROR, "Incorrect block size %d\n", size);
-            return AVERROR_INVALIDDATA;
-        }
-        wc->blksize = size;
-        ver         = avio_rl16(s->pb);
-        if (ver < 0x402 || ver > 0x410) {
-            av_free_packet(pkt);
-            av_log(s, AV_LOG_ERROR, "Unsupported version %03X\n", ver);
-            return AVERROR_PATCHWELCOME;
-        }
-        avio_r8(s->pb); // track no
-        avio_r8(s->pb); // track sub index
-        wc->samples = avio_rl32(s->pb); // total samples in file
-        wc->soff    = avio_rl32(s->pb); // offset in samples of current block
-        if ((ret = av_append_packet(s->pb, pkt, WV_EXTRA_SIZE)) < 0) {
-            av_free_packet(pkt);
-            return ret;
-        }
-        memcpy(wc->extra, pkt->data + pkt->size - WV_EXTRA_SIZE, WV_EXTRA_SIZE);
-
-        if ((ret = wv_read_block_header(s, s->pb, 1)) < 0) {
-            av_free_packet(pkt);
-            return ret;
-        }
-        ret = av_append_packet(s->pb, pkt, wc->blksize);
-        if (ret < 0) {
-            av_free_packet(pkt);
-            return ret;
-        }
-    }
-    pkt->stream_index = 0;
-    wc->block_parsed  = 1;
-    pkt->pts          = wc->soff;
-    block_samples     = AV_RL32(wc->extra);
-    if (block_samples > INT32_MAX)
-        av_log(s, AV_LOG_WARNING,
-               "Too many samples in block: %"PRIu32"\n", block_samples);
-    else
-        pkt->duration = block_samples;
-
-    av_add_index_entry(s->streams[0], pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME);
-    return 0;
-}
-
-static int wv_read_seek(AVFormatContext *s, int stream_index,
-                        int64_t timestamp, int flags)
-{
-    AVStream  *st = s->streams[stream_index];
-    WVContext *wc = s->priv_data;
-    AVPacket pkt1, *pkt = &pkt1;
-    int ret;
-    int index = av_index_search_timestamp(st, timestamp, flags);
-    int64_t pos, pts;
-
-    /* if found, seek there */
-    if (index >= 0 &&
-        timestamp <= st->index_entries[st->nb_index_entries - 1].timestamp) {
-        wc->block_parsed = 1;
-        avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET);
-        return 0;
-    }
-    /* if timestamp is out of bounds, return error */
-    if (timestamp < 0 || timestamp >= s->duration)
-        return AVERROR(EINVAL);
-
-    pos = avio_tell(s->pb);
-    do {
-        ret = av_read_frame(s, pkt);
-        if (ret < 0) {
-            avio_seek(s->pb, pos, SEEK_SET);
-            return ret;
-        }
-        pts = pkt->pts;
-        av_free_packet(pkt);
-    } while(pts < timestamp);
-    return 0;
-}
-
-AVInputFormat ff_wv_demuxer = {
-    .name           = "wv",
-    .long_name      = NULL_IF_CONFIG_SMALL("WavPack"),
-    .priv_data_size = sizeof(WVContext),
-    .read_probe     = wv_probe,
-    .read_header    = wv_read_header,
-    .read_packet    = wv_read_packet,
-    .read_seek      = wv_read_seek,
-};
diff --git a/libavformat/wv.h b/libavformat/wv.h
new file mode 100644
index 0000000..07d2e1b
--- /dev/null
+++ b/libavformat/wv.h
@@ -0,0 +1,56 @@
+/*
+ * WavPack shared functions
+ *
+ * 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
+ */
+
+#ifndef AVFORMAT_WV_H
+#define AVFORMAT_WV_H
+
+#include <stdint.h>
+
+#define WV_HEADER_SIZE 32
+
+#define WV_FLAG_INITIAL_BLOCK (1 << 11)
+#define WV_FLAG_FINAL_BLOCK   (1 << 12)
+
+// specs say that maximum block size is 1Mb
+#define WV_BLOCK_LIMIT 1048576
+
+typedef struct WvHeader {
+    uint32_t blocksize;     //< size of the block data (excluding the header)
+    uint16_t version;       //< bitstream version
+    uint32_t total_samples; //< total number of samples in the stream
+    uint32_t block_idx;     //< index of the first sample in this block
+    uint32_t samples;       //< number of samples in this block
+    uint32_t flags;
+    uint32_t crc;
+
+    int initial, final;
+} WvHeader;
+
+/**
+ * Parse a WavPack block header.
+ *
+ * @param wv   this struct will be filled with parse header information
+ * @param data header data, must be WV_HEADER_SIZE bytes long
+ *
+ * @return 0 on success, a negative AVERROR code on failure
+ */
+int ff_wv_parse_header(WvHeader *wv, const uint8_t *data);
+
+#endif /* AVFORMAT_WV_H */
diff --git a/libavformat/wvdec.c b/libavformat/wvdec.c
new file mode 100644
index 0000000..4eaec40
--- /dev/null
+++ b/libavformat/wvdec.c
@@ -0,0 +1,354 @@
+/*
+ * WavPack demuxer
+ * Copyright (c) 2006,2011 Konstantin Shishkov
+ *
+ * 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
+ */
+
+#include "libavutil/channel_layout.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/dict.h"
+#include "avformat.h"
+#include "internal.h"
+#include "apetag.h"
+#include "id3v1.h"
+#include "wv.h"
+
+enum WV_FLAGS {
+    WV_MONO   = 0x0004,
+    WV_HYBRID = 0x0008,
+    WV_JOINT  = 0x0010,
+    WV_CROSSD = 0x0020,
+    WV_HSHAPE = 0x0040,
+    WV_FLOAT  = 0x0080,
+    WV_INT32  = 0x0100,
+    WV_HBR    = 0x0200,
+    WV_HBAL   = 0x0400,
+    WV_MCINIT = 0x0800,
+    WV_MCEND  = 0x1000,
+};
+
+static const int wv_rates[16] = {
+     6000,  8000,  9600, 11025, 12000, 16000,  22050, 24000,
+    32000, 44100, 48000, 64000, 88200, 96000, 192000,    -1
+};
+
+typedef struct {
+    uint8_t block_header[WV_HEADER_SIZE];
+    WvHeader header;
+    int rate, chan, bpp;
+    uint32_t chmask;
+    int multichannel;
+    int block_parsed;
+    int64_t pos;
+
+    int64_t apetag_start;
+} WVContext;
+
+static int wv_probe(AVProbeData *p)
+{
+    /* check file header */
+    if (p->buf_size <= 32)
+        return 0;
+    if (AV_RL32(&p->buf[0]) == MKTAG('w', 'v', 'p', 'k') &&
+        AV_RL32(&p->buf[4]) >= 24 &&
+        AV_RL32(&p->buf[4]) <= WV_BLOCK_LIMIT &&
+        AV_RL16(&p->buf[8]) >= 0x402 &&
+        AV_RL16(&p->buf[8]) <= 0x410)
+        return AVPROBE_SCORE_MAX;
+    else
+        return 0;
+}
+
+static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb)
+{
+    WVContext *wc = ctx->priv_data;
+    int ret;
+    int rate, bpp, chan;
+    uint32_t chmask, flags;
+
+    wc->pos = avio_tell(pb);
+
+    /* don't return bogus packets with the ape tag data */
+    if (wc->apetag_start && wc->pos >= wc->apetag_start)
+        return AVERROR_EOF;
+
+    ret = avio_read(pb, wc->block_header, WV_HEADER_SIZE);
+    if (ret != WV_HEADER_SIZE)
+        return (ret < 0) ? ret : AVERROR_EOF;
+
+    ret = ff_wv_parse_header(&wc->header, wc->block_header);
+    if (ret < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid block header.\n");
+        return ret;
+    }
+
+    if (wc->header.version < 0x402 || wc->header.version > 0x410) {
+        av_log(ctx, AV_LOG_ERROR, "Unsupported version %03X\n", wc->header.version);
+        return AVERROR_PATCHWELCOME;
+    }
+
+    /* Blocks with zero samples don't contain actual audio information
+     * and should be ignored */
+    if (!wc->header.samples)
+        return 0;
+    // parse flags
+    flags  = wc->header.flags;
+    bpp    = ((flags & 3) + 1) << 3;
+    chan   = 1 + !(flags & WV_MONO);
+    chmask = flags & WV_MONO ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
+    rate   = wv_rates[(flags >> 23) & 0xF];
+    wc->multichannel = !(wc->header.initial && wc->header.final);
+    if (wc->multichannel) {
+        chan   = wc->chan;
+        chmask = wc->chmask;
+    }
+    if ((rate == -1 || !chan) && !wc->block_parsed) {
+        int64_t block_end = avio_tell(pb) + wc->header.blocksize;
+        if (!pb->seekable) {
+            av_log(ctx, AV_LOG_ERROR,
+                   "Cannot determine additional parameters\n");
+            return AVERROR_INVALIDDATA;
+        }
+        while (avio_tell(pb) < block_end) {
+            int id, size;
+            id   = avio_r8(pb);
+            size = (id & 0x80) ? avio_rl24(pb) : avio_r8(pb);
+            size <<= 1;
+            if (id & 0x40)
+                size--;
+            switch (id & 0x3F) {
+            case 0xD:
+                if (size <= 1) {
+                    av_log(ctx, AV_LOG_ERROR,
+                           "Insufficient channel information\n");
+                    return AVERROR_INVALIDDATA;
+                }
+                chan = avio_r8(pb);
+                switch (size - 2) {
+                case 0:
+                    chmask = avio_r8(pb);
+                    break;
+                case 1:
+                    chmask = avio_rl16(pb);
+                    break;
+                case 2:
+                    chmask = avio_rl24(pb);
+                    break;
+                case 3:
+                    chmask = avio_rl32(pb);
+                    break;
+                case 5:
+                    avio_skip(pb, 1);
+                    chan  |= (avio_r8(pb) & 0xF) << 8;
+                    chmask = avio_rl24(pb);
+                    break;
+                default:
+                    av_log(ctx, AV_LOG_ERROR,
+                           "Invalid channel info size %d\n", size);
+                    return AVERROR_INVALIDDATA;
+                }
+                break;
+            case 0x27:
+                rate = avio_rl24(pb);
+                break;
+            default:
+                avio_skip(pb, size);
+            }
+            if (id & 0x40)
+                avio_skip(pb, 1);
+        }
+        if (rate == -1) {
+            av_log(ctx, AV_LOG_ERROR,
+                   "Cannot determine custom sampling rate\n");
+            return AVERROR_INVALIDDATA;
+        }
+        avio_seek(pb, block_end - wc->header.blocksize, SEEK_SET);
+    }
+    if (!wc->bpp)
+        wc->bpp    = bpp;
+    if (!wc->chan)
+        wc->chan   = chan;
+    if (!wc->chmask)
+        wc->chmask = chmask;
+    if (!wc->rate)
+        wc->rate   = rate;
+
+    if (flags && bpp != wc->bpp) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Bits per sample differ, this block: %i, header block: %i\n",
+               bpp, wc->bpp);
+        return AVERROR_INVALIDDATA;
+    }
+    if (flags && !wc->multichannel && chan != wc->chan) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Channels differ, this block: %i, header block: %i\n",
+               chan, wc->chan);
+        return AVERROR_INVALIDDATA;
+    }
+    if (flags && rate != -1 && rate != wc->rate) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Sampling rate differ, this block: %i, header block: %i\n",
+               rate, wc->rate);
+        return AVERROR_INVALIDDATA;
+    }
+    return 0;
+}
+
+static int wv_read_header(AVFormatContext *s)
+{
+    AVIOContext *pb = s->pb;
+    WVContext *wc = s->priv_data;
+    AVStream *st;
+    int ret;
+
+    wc->block_parsed = 0;
+    for (;;) {
+        if ((ret = wv_read_block_header(s, pb)) < 0)
+            return ret;
+        if (!wc->header.samples)
+            avio_skip(pb, wc->header.blocksize);
+        else
+            break;
+    }
+
+    /* now we are ready: build format streams */
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+    st->codec->codec_type            = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_id              = AV_CODEC_ID_WAVPACK;
+    st->codec->channels              = wc->chan;
+    st->codec->channel_layout        = wc->chmask;
+    st->codec->sample_rate           = wc->rate;
+    st->codec->bits_per_coded_sample = wc->bpp;
+    avpriv_set_pts_info(st, 64, 1, wc->rate);
+    st->start_time = 0;
+    if (wc->header.total_samples != 0xFFFFFFFFu)
+        st->duration = wc->header.total_samples;
+
+    if (s->pb->seekable) {
+        int64_t cur = avio_tell(s->pb);
+        wc->apetag_start = ff_ape_parse_tag(s);
+        if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
+            ff_id3v1_read(s);
+        avio_seek(s->pb, cur, SEEK_SET);
+    }
+
+    return 0;
+}
+
+static int wv_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    WVContext *wc = s->priv_data;
+    int ret;
+    int off;
+    int64_t pos;
+    uint32_t block_samples;
+
+    if (url_feof(s->pb))
+        return AVERROR_EOF;
+    if (wc->block_parsed) {
+        if ((ret = wv_read_block_header(s, s->pb)) < 0)
+            return ret;
+    }
+
+    pos = wc->pos;
+    if (av_new_packet(pkt, wc->header.blocksize + WV_HEADER_SIZE) < 0)
+        return AVERROR(ENOMEM);
+    memcpy(pkt->data, wc->block_header, WV_HEADER_SIZE);
+    ret = avio_read(s->pb, pkt->data + WV_HEADER_SIZE, wc->header.blocksize);
+    if (ret != wc->header.blocksize) {
+        av_free_packet(pkt);
+        return AVERROR(EIO);
+    }
+    while (!(wc->header.flags & WV_FLAG_FINAL_BLOCK)) {
+        if ((ret = wv_read_block_header(s, s->pb)) < 0) {
+            av_free_packet(pkt);
+            return ret;
+        }
+
+        off = pkt->size;
+        if ((ret = av_grow_packet(pkt, WV_HEADER_SIZE + wc->header.blocksize)) < 0) {
+            av_free_packet(pkt);
+            return ret;
+        }
+        memcpy(pkt->data + off, wc->block_header, WV_HEADER_SIZE);
+
+        ret = avio_read(s->pb, pkt->data + off + WV_HEADER_SIZE, wc->header.blocksize);
+        if (ret != wc->header.blocksize) {
+            av_free_packet(pkt);
+            return (ret < 0) ? ret : AVERROR_EOF;
+        }
+    }
+    pkt->stream_index = 0;
+    wc->block_parsed  = 1;
+    pkt->pts          = wc->header.block_idx;
+    block_samples     = wc->header.samples;
+    if (block_samples > INT32_MAX)
+        av_log(s, AV_LOG_WARNING,
+               "Too many samples in block: %"PRIu32"\n", block_samples);
+    else
+        pkt->duration = block_samples;
+
+    av_add_index_entry(s->streams[0], pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME);
+    return 0;
+}
+
+static int wv_read_seek(AVFormatContext *s, int stream_index,
+                        int64_t timestamp, int flags)
+{
+    AVStream  *st = s->streams[stream_index];
+    WVContext *wc = s->priv_data;
+    AVPacket pkt1, *pkt = &pkt1;
+    int ret;
+    int index = av_index_search_timestamp(st, timestamp, flags);
+    int64_t pos, pts;
+
+    /* if found, seek there */
+    if (index >= 0 &&
+        timestamp <= st->index_entries[st->nb_index_entries - 1].timestamp) {
+        wc->block_parsed = 1;
+        avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET);
+        return 0;
+    }
+    /* if timestamp is out of bounds, return error */
+    if (timestamp < 0 || timestamp >= s->duration)
+        return AVERROR(EINVAL);
+
+    pos = avio_tell(s->pb);
+    do {
+        ret = av_read_frame(s, pkt);
+        if (ret < 0) {
+            avio_seek(s->pb, pos, SEEK_SET);
+            return ret;
+        }
+        pts = pkt->pts;
+        av_free_packet(pkt);
+    } while(pts < timestamp);
+    return 0;
+}
+
+AVInputFormat ff_wv_demuxer = {
+    .name           = "wv",
+    .long_name      = NULL_IF_CONFIG_SMALL("WavPack"),
+    .priv_data_size = sizeof(WVContext),
+    .read_probe     = wv_probe,
+    .read_header    = wv_read_header,
+    .read_packet    = wv_read_packet,
+    .read_seek      = wv_read_seek,
+};
diff --git a/libavformat/wvenc.c b/libavformat/wvenc.c
index c33d430..b0d74ca 100644
--- a/libavformat/wvenc.c
+++ b/libavformat/wvenc.c
@@ -1,5 +1,6 @@
 /*
  * WavPack muxer
+ * Copyright (c) 2013 Konstantin Shishkov <kostya.shishkov@gmail.com>
  * Copyright (c) 2012 Paul B Mahol
  *
  * This file is part of FFmpeg.
@@ -19,125 +20,72 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/intreadwrite.h"
-#include "avformat.h"
-#include "internal.h"
-#include "avio_internal.h"
+#include "libavutil/attributes.h"
+
 #include "apetag.h"
+#include "avformat.h"
+#include "wv.h"
 
-#define WV_EXTRA_SIZE 12
-#define WV_END_BLOCK  0x1000
+typedef struct WvMuxContext {
+    int64_t samples;
+} WvMuxContext;
 
-typedef struct{
-    uint32_t duration;
-} WVMuxContext;
-
-static int write_header(AVFormatContext *s)
+static av_cold int wv_write_header(AVFormatContext *ctx)
 {
-    AVCodecContext *codec = s->streams[0]->codec;
-
-    if (s->nb_streams > 1) {
-        av_log(s, AV_LOG_ERROR, "only one stream is supported\n");
+    if (ctx->nb_streams > 1 ||
+        ctx->streams[0]->codec->codec_id != AV_CODEC_ID_WAVPACK) {
+        av_log(ctx, AV_LOG_ERROR, "This muxer only supports a single WavPack stream.\n");
         return AVERROR(EINVAL);
     }
-    if (codec->codec_id != AV_CODEC_ID_WAVPACK) {
-        av_log(s, AV_LOG_ERROR, "unsupported codec\n");
-        return AVERROR(EINVAL);
-    }
-    if (codec->extradata_size > 0) {
-        avpriv_report_missing_feature(s, "remuxing from matroska container");
-        return AVERROR_PATCHWELCOME;
-    }
-    avpriv_set_pts_info(s->streams[0], 64, 1, codec->sample_rate);
-
-    return 0;
-}
-
-static int write_packet(AVFormatContext *s, AVPacket *pkt)
-{
-    WVMuxContext *wc = s->priv_data;
-    AVCodecContext *codec = s->streams[0]->codec;
-    AVIOContext *pb = s->pb;
-    uint64_t size;
-    uint32_t flags;
-    uint32_t left = pkt->size;
-    uint8_t *ptr = pkt->data;
-    int off = codec->channels > 2 ? 4 : 0;
-
-    /* FIXME: Simplify decoder/demuxer so bellow code can support midstream
-     *        change of stream parameters */
-    wc->duration += pkt->duration;
-    ffio_wfourcc(pb, "wvpk");
-    if (off) {
-        size = AV_RL32(pkt->data);
-        if (size <= 12)
-            return AVERROR_INVALIDDATA;
-        size -= 12;
-    } else {
-        size = pkt->size;
-    }
-
-    if (size + off > left)
-        return AVERROR_INVALIDDATA;
-
-    avio_wl32(pb, size + 12);
-    avio_wl16(pb, 0x410);
-    avio_w8(pb, 0);
-    avio_w8(pb, 0);
-    avio_wl32(pb, -1);
-    avio_wl32(pb, pkt->pts);
-    ptr += off; left -= off;
-    flags = AV_RL32(ptr + 4);
-    avio_write(pb, ptr, size);
-    ptr += size; left -= size;
-
-    while (!(flags & WV_END_BLOCK) &&
-            (left >= 4 + WV_EXTRA_SIZE)) {
-        ffio_wfourcc(pb, "wvpk");
-        size = AV_RL32(ptr);
-        ptr += 4; left -= 4;
-        if (size < 24 || size - 24 > left)
-            return AVERROR_INVALIDDATA;
-        avio_wl32(pb, size);
-        avio_wl16(pb, 0x410);
-        avio_w8(pb, 0);
-        avio_w8(pb, 0);
-        avio_wl32(pb, -1);
-        avio_wl32(pb, pkt->pts);
-        flags = AV_RL32(ptr + 4);
-        avio_write(pb, ptr, WV_EXTRA_SIZE);
-        ptr += WV_EXTRA_SIZE; left -= WV_EXTRA_SIZE;
-        avio_write(pb, ptr, size - 24);
-        ptr += size - 24; left -= size - 24;
-    }
 
     return 0;
 }
 
-static int write_trailer(AVFormatContext *s)
+static int wv_write_packet(AVFormatContext *ctx, AVPacket *pkt)
 {
-    WVMuxContext *wc = s->priv_data;
-    AVIOContext *pb = s->pb;
+    WvMuxContext *s = ctx->priv_data;
+    WvHeader header;
+    int ret;
 
-    ff_ape_write(s);
+    if (pkt->size < WV_HEADER_SIZE ||
+        (ret = ff_wv_parse_header(&header, pkt->data)) < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid WavPack packet.\n");
+        return AVERROR(EINVAL);
+    }
+    s->samples += header.samples;
 
-    if (pb->seekable) {
-        avio_seek(pb, 12, SEEK_SET);
-        avio_wl32(pb, wc->duration);
-        avio_flush(pb);
+    avio_write(ctx->pb, pkt->data, pkt->size);
+
+    return 0;
+}
+
+static av_cold int wv_write_trailer(AVFormatContext *ctx)
+{
+    WvMuxContext *s = ctx->priv_data;
+
+    /* update total number of samples in the first block */
+    if (ctx->pb->seekable && s->samples &&
+        s->samples < UINT32_MAX) {
+        int64_t pos = avio_tell(ctx->pb);
+        avio_seek(ctx->pb, 12, SEEK_SET);
+        avio_wl32(ctx->pb, s->samples);
+        avio_seek(ctx->pb, pos, SEEK_SET);
     }
 
+    ff_ape_write_tag(ctx);
     return 0;
 }
 
 AVOutputFormat ff_wv_muxer = {
     .name              = "wv",
-    .long_name         = NULL_IF_CONFIG_SMALL("WavPack"),
-    .priv_data_size    = sizeof(WVMuxContext),
+    .long_name         = NULL_IF_CONFIG_SMALL("raw WavPack"),
+    .mime_type         = "audio/x-wavpack",
     .extensions        = "wv",
+    .priv_data_size    = sizeof(WvMuxContext),
     .audio_codec       = AV_CODEC_ID_WAVPACK,
     .video_codec       = AV_CODEC_ID_NONE,
-    .write_header      = write_header,
-    .write_packet      = write_packet,
-    .write_trailer     = write_trailer,
+    .write_header      = wv_write_header,
+    .write_packet      = wv_write_packet,
+    .write_trailer     = wv_write_trailer,
+    .flags             = AVFMT_NOTIMESTAMPS,
 };
diff --git a/libavformat/xa.c b/libavformat/xa.c
index e3d36e6..43661de 100644
--- a/libavformat/xa.c
+++ b/libavformat/xa.c
@@ -59,7 +59,7 @@
     if (!channels || channels > 8 || !srate || srate > 192000 ||
         bits_per_sample < 4 || bits_per_sample > 32)
         return 0;
-    return AVPROBE_SCORE_MAX/2;
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 static int xa_read_header(AVFormatContext *s)
@@ -84,6 +84,9 @@
     avio_skip(pb, 2);       /* Skip block align */
     avio_skip(pb, 2);       /* Skip bits-per-sample */
 
+    if (!st->codec->channels || !st->codec->sample_rate)
+        return AVERROR_INVALIDDATA;
+
     st->codec->bit_rate = av_clip(15LL * st->codec->channels * 8 *
                                   st->codec->sample_rate / 28, 0, INT_MAX);
 
diff --git a/libavformat/yuv4mpeg.c b/libavformat/yuv4mpeg.c
index bf48230..a6d8346 100644
--- a/libavformat/yuv4mpeg.c
+++ b/libavformat/yuv4mpeg.c
@@ -217,8 +217,8 @@
         // Adjust for smaller Cb and Cr planes
         av_pix_fmt_get_chroma_sub_sample(st->codec->pix_fmt, &h_chroma_shift,
                                          &v_chroma_shift);
-        width  >>= h_chroma_shift;
-        height >>= v_chroma_shift;
+        width  = FF_CEIL_RSHIFT(width,  h_chroma_shift);
+        height = FF_CEIL_RSHIFT(height, v_chroma_shift);
 
         ptr1 = picture->data[1];
         ptr2 = picture->data[2];
diff --git a/libavresample/audio_mix.c b/libavresample/audio_mix.c
index b69bfbc..e6f9417 100644
--- a/libavresample/audio_mix.c
+++ b/libavresample/audio_mix.c
@@ -282,7 +282,7 @@
     }
 }
 
-static int mix_function_init(AudioMix *am)
+static av_cold int mix_function_init(AudioMix *am)
 {
     am->func_descr = am->func_descr_generic = "n/a";
     am->mix = am->mix_generic = NULL;
diff --git a/libavresample/avresample-test.c b/libavresample/avresample-test.c
index 81e9bf0..697b4ba 100644
--- a/libavresample/avresample-test.c
+++ b/libavresample/avresample-test.c
@@ -91,7 +91,7 @@
 
     k = 0;
 
-    /* 1 second of single freq sinus at 1000 Hz */
+    /* 1 second of single freq sine at 1000 Hz */
     a = 0;
     for (i = 0; i < 1 * sample_rate && k < nb_samples; i++, k++) {
         v = sin(a) * 0.30;
diff --git a/libavresample/dither.c b/libavresample/dither.c
index f24bf5c..17de829 100644
--- a/libavresample/dither.c
+++ b/libavresample/dither.c
@@ -31,6 +31,7 @@
 #include <math.h>
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
 #include "libavutil/lfg.h"
 #include "libavutil/mem.h"
@@ -325,8 +326,8 @@
     av_freep(cp);
 }
 
-static void dither_init(DitherDSPContext *ddsp,
-                        enum AVResampleDitherMethod method)
+static av_cold void dither_init(DitherDSPContext *ddsp,
+                                enum AVResampleDitherMethod method)
 {
     ddsp->quantize      = quantize_c;
     ddsp->ptr_align     = 1;
diff --git a/libavresample/options.c b/libavresample/options.c
index 39c415b..7859ec6 100644
--- a/libavresample/options.c
+++ b/libavresample/options.c
@@ -33,7 +33,7 @@
 #define OFFSET(x) offsetof(AVAudioResampleContext, x)
 #define PARAM AV_OPT_FLAG_AUDIO_PARAM
 
-static const AVOption options[] = {
+static const AVOption avresample_options[] = {
     { "in_channel_layout",      "Input Channel Layout",     OFFSET(in_channel_layout),      AV_OPT_TYPE_INT64,  { .i64 = 0              }, INT64_MIN,            INT64_MAX,              PARAM },
     { "in_sample_fmt",          "Input Sample Format",      OFFSET(in_sample_fmt),          AV_OPT_TYPE_INT,    { .i64 = AV_SAMPLE_FMT_S16 }, AV_SAMPLE_FMT_U8,     AV_SAMPLE_FMT_NB-1,     PARAM },
     { "in_sample_rate",         "Input Sample Rate",        OFFSET(in_sample_rate),         AV_OPT_TYPE_INT,    { .i64 = 48000          }, 1,                    INT_MAX,                PARAM },
@@ -87,7 +87,7 @@
 static const AVClass av_resample_context_class = {
     .class_name = "AVAudioResampleContext",
     .item_name  = av_default_item_name,
-    .option     = options,
+    .option     = avresample_options,
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
diff --git a/libavresample/version.h b/libavresample/version.h
index 387d097..3cc4441 100644
--- a/libavresample/version.h
+++ b/libavresample/version.h
@@ -19,6 +19,12 @@
 #ifndef AVRESAMPLE_VERSION_H
 #define AVRESAMPLE_VERSION_H
 
+/**
+ * @file
+ * @ingroup lavr
+ * Libavresample version macros.
+ */
+
 #define LIBAVRESAMPLE_VERSION_MAJOR  1
 #define LIBAVRESAMPLE_VERSION_MINOR  1
 #define LIBAVRESAMPLE_VERSION_MICRO  0
diff --git a/libavresample/x86/audio_convert_init.c b/libavresample/x86/audio_convert_init.c
index 2110445..d85ca84 100644
--- a/libavresample/x86/audio_convert_init.c
+++ b/libavresample/x86/audio_convert_init.c
@@ -145,15 +145,15 @@
 
 av_cold void ff_audio_convert_init_x86(AudioConvert *ac)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (EXTERNAL_MMX(mm_flags)) {
+    if (EXTERNAL_MMX(cpu_flags)) {
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32,
                                   0, 1, 8, "MMX", ff_conv_s32_to_s16_mmx);
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
                                   6, 1, 4, "MMX", ff_conv_fltp_to_flt_6ch_mmx);
     }
-    if (EXTERNAL_SSE(mm_flags)) {
+    if (EXTERNAL_SSE(cpu_flags)) {
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP,
                                   6, 1, 2, "SSE", ff_conv_fltp_to_s16_6ch_sse);
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
@@ -161,8 +161,8 @@
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT,
                                   2, 16, 4, "SSE", ff_conv_flt_to_fltp_2ch_sse);
     }
-    if (EXTERNAL_SSE2(mm_flags)) {
-        if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW)) {
+    if (EXTERNAL_SSE2(cpu_flags)) {
+        if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW)) {
             ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32,
                                       0, 16, 16, "SSE2", ff_conv_s32_to_s16_sse2);
             ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P,
@@ -206,7 +206,7 @@
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT,
                                   6, 16, 4, "SSE2", ff_conv_flt_to_fltp_6ch_sse2);
     }
-    if (EXTERNAL_SSSE3(mm_flags)) {
+    if (EXTERNAL_SSSE3(cpu_flags)) {
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16P,
                                   6, 16, 4, "SSSE3", ff_conv_s16p_to_flt_6ch_ssse3);
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP,
@@ -220,13 +220,13 @@
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_FLT,
                                   6, 16, 4, "SSSE3", ff_conv_flt_to_s16p_6ch_ssse3);
     }
-    if (EXTERNAL_SSE4(mm_flags)) {
+    if (EXTERNAL_SSE4(cpu_flags)) {
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16,
                                   0, 16, 8, "SSE4", ff_conv_s16_to_flt_sse4);
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
                                   6, 16, 4, "SSE4", ff_conv_fltp_to_flt_6ch_sse4);
     }
-    if (EXTERNAL_AVX(mm_flags)) {
+    if (EXTERNAL_AVX(cpu_flags)) {
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32,
                                   0, 32, 16, "AVX", ff_conv_s32_to_flt_avx);
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT,
diff --git a/libavresample/x86/audio_mix_init.c b/libavresample/x86/audio_mix_init.c
index 9b977f8..932f6f2 100644
--- a/libavresample/x86/audio_mix_init.c
+++ b/libavresample/x86/audio_mix_init.c
@@ -106,7 +106,7 @@
 DEFINE_MIX_3_8_TO_1_2(8)
 
 #define SET_MIX_3_8_TO_1_2(chan)                                            \
-    if (EXTERNAL_SSE(mm_flags)) {                                           \
+    if (EXTERNAL_SSE(cpu_flags)) {                                          \
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,\
                               chan, 1, 16, 4, "SSE",                        \
                               ff_mix_ ## chan ## _to_1_fltp_flt_sse);       \
@@ -114,7 +114,7 @@
                               chan, 2, 16, 4, "SSE",                        \
                               ff_mix_## chan ##_to_2_fltp_flt_sse);         \
     }                                                                       \
-    if (EXTERNAL_SSE2(mm_flags)) {                                          \
+    if (EXTERNAL_SSE2(cpu_flags)) {                                         \
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,\
                               chan, 1, 16, 8, "SSE2",                       \
                               ff_mix_ ## chan ## _to_1_s16p_flt_sse2);      \
@@ -122,7 +122,7 @@
                               chan, 2, 16, 8, "SSE2",                       \
                               ff_mix_ ## chan ## _to_2_s16p_flt_sse2);      \
     }                                                                       \
-    if (EXTERNAL_SSE4(mm_flags)) {                                          \
+    if (EXTERNAL_SSE4(cpu_flags)) {                                         \
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,\
                               chan, 1, 16, 8, "SSE4",                       \
                               ff_mix_ ## chan ## _to_1_s16p_flt_sse4);      \
@@ -130,7 +130,7 @@
                               chan, 2, 16, 8, "SSE4",                       \
                               ff_mix_ ## chan ## _to_2_s16p_flt_sse4);      \
     }                                                                       \
-    if (EXTERNAL_AVX(mm_flags)) {                                           \
+    if (EXTERNAL_AVX(cpu_flags)) {                                          \
         int ptr_align = 32;                                                 \
         int smp_align = 8;                                                  \
         if (ARCH_X86_32 || chan >= 6) {                                     \
@@ -150,7 +150,7 @@
                               chan, 2, 16, 8, "AVX",                        \
                               ff_mix_ ## chan ## _to_2_s16p_flt_avx);       \
     }                                                                       \
-    if (EXTERNAL_FMA4(mm_flags)) {                                          \
+    if (EXTERNAL_FMA4(cpu_flags)) {                                         \
         int ptr_align = 32;                                                 \
         int smp_align = 8;                                                  \
         if (ARCH_X86_32 || chan >= 6) {                                     \
@@ -174,15 +174,15 @@
 av_cold void ff_audio_mix_init_x86(AudioMix *am)
 {
 #if HAVE_YASM
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (EXTERNAL_SSE(mm_flags)) {
+    if (EXTERNAL_SSE(cpu_flags)) {
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
                               2, 1, 16, 8, "SSE", ff_mix_2_to_1_fltp_flt_sse);
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
                               1, 2, 16, 4, "SSE", ff_mix_1_to_2_fltp_flt_sse);
     }
-    if (EXTERNAL_SSE2(mm_flags)) {
+    if (EXTERNAL_SSE2(cpu_flags)) {
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
                               2, 1, 16, 8, "SSE2", ff_mix_2_to_1_s16p_flt_sse2);
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_Q8,
@@ -190,13 +190,13 @@
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
                               1, 2, 16, 8, "SSE2", ff_mix_1_to_2_s16p_flt_sse2);
     }
-    if (EXTERNAL_SSE4(mm_flags)) {
+    if (EXTERNAL_SSE4(cpu_flags)) {
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
                               2, 1, 16, 8, "SSE4", ff_mix_2_to_1_s16p_flt_sse4);
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
                               1, 2, 16, 8, "SSE4", ff_mix_1_to_2_s16p_flt_sse4);
     }
-    if (EXTERNAL_AVX(mm_flags)) {
+    if (EXTERNAL_AVX(cpu_flags)) {
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
                               2, 1, 32, 16, "AVX", ff_mix_2_to_1_fltp_flt_avx);
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
diff --git a/libavresample/x86/dither_init.c b/libavresample/x86/dither_init.c
index e9411c5..816d4b0 100644
--- a/libavresample/x86/dither_init.c
+++ b/libavresample/x86/dither_init.c
@@ -34,26 +34,26 @@
 av_cold void ff_dither_init_x86(DitherDSPContext *ddsp,
                                 enum AVResampleDitherMethod method)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (EXTERNAL_SSE2(mm_flags)) {
+    if (EXTERNAL_SSE2(cpu_flags)) {
         ddsp->quantize      = ff_quantize_sse2;
         ddsp->ptr_align     = 16;
         ddsp->samples_align = 8;
     }
 
     if (method == AV_RESAMPLE_DITHER_RECTANGULAR) {
-        if (EXTERNAL_SSE2(mm_flags)) {
+        if (EXTERNAL_SSE2(cpu_flags)) {
             ddsp->dither_int_to_float = ff_dither_int_to_float_rectangular_sse2;
         }
-        if (EXTERNAL_AVX(mm_flags)) {
+        if (EXTERNAL_AVX(cpu_flags)) {
             ddsp->dither_int_to_float = ff_dither_int_to_float_rectangular_avx;
         }
     } else {
-        if (EXTERNAL_SSE2(mm_flags)) {
+        if (EXTERNAL_SSE2(cpu_flags)) {
             ddsp->dither_int_to_float = ff_dither_int_to_float_triangular_sse2;
         }
-        if (EXTERNAL_AVX(mm_flags)) {
+        if (EXTERNAL_AVX(cpu_flags)) {
             ddsp->dither_int_to_float = ff_dither_int_to_float_triangular_avx;
         }
     }
diff --git a/libavutil/Makefile b/libavutil/Makefile
index 33f82ed..5006767 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -34,6 +34,7 @@
           mathematics.h                                                 \
           md5.h                                                         \
           mem.h                                                         \
+          murmur3.h                                                     \
           dict.h                                                        \
           old_pix_fmts.h                                                \
           opt.h                                                         \
@@ -42,8 +43,10 @@
           pixfmt.h                                                      \
           random_seed.h                                                 \
           rational.h                                                    \
+          ripemd.h                                                      \
           samplefmt.h                                                   \
           sha.h                                                         \
+          sha512.h                                                      \
           time.h                                                        \
           timecode.h                                                    \
           timestamp.h                                                   \
@@ -78,8 +81,10 @@
        eval.o                                                           \
        fifo.o                                                           \
        file.o                                                           \
+       file_open.o                                                      \
        float_dsp.o                                                      \
        frame.o                                                          \
+       hash.o                                                           \
        hmac.o                                                           \
        imgutils.o                                                       \
        intfloat_readwrite.o                                             \
@@ -91,6 +96,7 @@
        mathematics.o                                                    \
        md5.o                                                            \
        mem.o                                                            \
+       murmur3.o                                                        \
        dict.o                                                           \
        opt.o                                                            \
        parseutils.o                                                     \
@@ -98,8 +104,10 @@
        random_seed.o                                                    \
        rational.o                                                       \
        rc4.o                                                            \
+       ripemd.o                                                         \
        samplefmt.o                                                      \
        sha.o                                                            \
+       sha512.o                                                         \
        time.o                                                           \
        timecode.o                                                       \
        tree.o                                                           \
@@ -108,7 +116,7 @@
        xtea.o                                                           \
 
 OBJS-$(CONFIG_LZO)                      += lzo.o
-OBJS-$(CONFIG_OPENCL)                   += opencl.o
+OBJS-$(CONFIG_OPENCL)                   += opencl.o opencl_internal.o
 
 OBJS += $(COMPAT_OBJS:%=../compat/%)
 
@@ -137,17 +145,20 @@
             lfg                                                         \
             lls                                                         \
             md5                                                         \
+            murmur3                                                     \
             opt                                                         \
             pca                                                         \
             parseutils                                                  \
             random_seed                                                 \
             rational                                                    \
+            ripemd                                                      \
             sha                                                         \
+            sha512                                                      \
             tree                                                        \
             xtea                                                        \
 
 TESTPROGS-$(HAVE_LZO1X_999_COMPRESS) += lzo
 
-TOOLS = ffeval ffescape
+TOOLS = ffhash ffeval ffescape
 
 $(SUBDIR)lzo-test$(EXESUF): ELIBS = -llzo2
diff --git a/libavutil/adler32.h b/libavutil/adler32.h
index e926ef6..8c08d2b 100644
--- a/libavutil/adler32.h
+++ b/libavutil/adler32.h
@@ -25,7 +25,12 @@
 #include "attributes.h"
 
 /**
+ * @defgroup lavu_adler32 Adler32
  * @ingroup lavu_crypto
+ * @{
+ */
+
+/**
  * Calculate the Adler32 checksum of a buffer.
  *
  * Passing the return value to a subsequent av_adler32_update() call
@@ -40,4 +45,8 @@
 unsigned long av_adler32_update(unsigned long adler, const uint8_t *buf,
                                 unsigned int len) av_pure;
 
+/**
+ * @}
+ */
+
 #endif /* AVUTIL_ADLER32_H */
diff --git a/libavutil/arm/asm.S b/libavutil/arm/asm.S
index 6061e47..9cdcce9 100644
--- a/libavutil/arm/asm.S
+++ b/libavutil/arm/asm.S
@@ -291,7 +291,7 @@
 .endm
 
 #if HAVE_VFP_ARGS
-        .eabi_attribute 28, 1
+ELF     .eabi_attribute 28, 1
 #   define VFP
 #   define NOVFP @
 #else
diff --git a/libavutil/arm/cpu.h b/libavutil/arm/cpu.h
index 91c959a..b45f30b 100644
--- a/libavutil/arm/cpu.h
+++ b/libavutil/arm/cpu.h
@@ -29,4 +29,4 @@
 #define have_vfpv3(flags)   (HAVE_VFPV3   && ((flags) & AV_CPU_FLAG_VFPV3))
 #define have_neon(flags)    (HAVE_NEON    && ((flags) & AV_CPU_FLAG_NEON))
 
-#endif
+#endif /* AVUTIL_ARM_CPU_H */
diff --git a/libavutil/arm/float_dsp_init_arm.c b/libavutil/arm/float_dsp_init_arm.c
index f721344..94d9c2b 100644
--- a/libavutil/arm/float_dsp_init_arm.c
+++ b/libavutil/arm/float_dsp_init_arm.c
@@ -18,11 +18,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/float_dsp.h"
 #include "cpu.h"
 #include "float_dsp_arm.h"
 
-void ff_float_dsp_init_arm(AVFloatDSPContext *fdsp)
+av_cold void ff_float_dsp_init_arm(AVFloatDSPContext *fdsp)
 {
     int cpu_flags = av_get_cpu_flags();
 
diff --git a/libavutil/arm/float_dsp_init_neon.c b/libavutil/arm/float_dsp_init_neon.c
index a7245ad9..617bf5d 100644
--- a/libavutil/arm/float_dsp_init_neon.c
+++ b/libavutil/arm/float_dsp_init_neon.c
@@ -21,6 +21,7 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/float_dsp.h"
 #include "float_dsp_arm.h"
 
@@ -45,7 +46,7 @@
 
 float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len);
 
-void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp)
+av_cold void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp)
 {
     fdsp->vector_fmul = ff_vector_fmul_neon;
     fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_neon;
diff --git a/libavutil/arm/float_dsp_init_vfp.c b/libavutil/arm/float_dsp_init_vfp.c
index f7e2f54..21db094 100644
--- a/libavutil/arm/float_dsp_init_vfp.c
+++ b/libavutil/arm/float_dsp_init_vfp.c
@@ -18,6 +18,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/float_dsp.h"
 #include "cpu.h"
 #include "float_dsp_arm.h"
@@ -28,7 +29,7 @@
 void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
                                 const float *src1, int len);
 
-void ff_float_dsp_init_vfp(AVFloatDSPContext *fdsp)
+av_cold void ff_float_dsp_init_vfp(AVFloatDSPContext *fdsp)
 {
     int cpu_flags = av_get_cpu_flags();
 
diff --git a/libavutil/avstring.c b/libavutil/avstring.c
index cf9be2a..eed58fa 100644
--- a/libavutil/avstring.c
+++ b/libavutil/avstring.c
@@ -312,7 +312,7 @@
 int main(void)
 {
     int i;
-    const char *strings[] = {
+    static const char * const strings[] = {
         "''",
         "",
         ":",
diff --git a/libavutil/avutil.h b/libavutil/avutil.h
index 6f307d6..4986f4f 100644
--- a/libavutil/avutil.h
+++ b/libavutil/avutil.h
@@ -35,13 +35,46 @@
  * provided by FFmpeg.
  *
  * @li @ref libavc "libavcodec" encoding/decoding library
- * @li @ref lavfi "libavfilter" graph based frame editing library
+ * @li @ref lavfi "libavfilter" graph-based frame editing library
  * @li @ref libavf "libavformat" I/O and muxing/demuxing library
  * @li @ref lavd "libavdevice" special devices muxing/demuxing library
  * @li @ref lavu "libavutil" common utility library
  * @li @ref lswr "libswresample" audio resampling, format conversion and mixing
  * @li @ref lpp  "libpostproc" post processing library
  * @li @ref lsws "libswscale" color conversion and scaling library
+ *
+ * @section ffmpeg_versioning Versioning and compatibility
+ *
+ * Each of the FFmpeg libraries contains a version.h header, which defines a
+ * major, minor and micro version number with the
+ * <em>LIBRARYNAME_VERSION_{MAJOR,MINOR,MICRO}</em> macros. The major version
+ * number is incremented with backward incompatible changes - e.g. removing
+ * parts of the public API, reordering public struct members, etc. The minor
+ * version number is incremented for backward compatible API changes or major
+ * new features - e.g. adding a new public function or a new decoder. The micro
+ * version number is incremented for smaller changes that a calling program
+ * might still want to check for - e.g. changing behavior in a previously
+ * unspecified situation.
+ *
+ * FFmpeg guarantees backward API and ABI compatibility for each library as long
+ * as its major version number is unchanged. This means that no public symbols
+ * will be removed or renamed. Types and names of the public struct members and
+ * values of public macros and enums will remain the same (unless they were
+ * explicitly declared as not part of the public API). Documented behavior will
+ * not change.
+ *
+ * In other words, any correct program that works with a given FFmpeg snapshot
+ * should work just as well without any changes with any later snapshot with the
+ * same major versions. This applies to both rebuilding the program against new
+ * FFmpeg versions or to replacing the dynamic FFmpeg libraries that a program
+ * links against.
+ *
+ * However, new public symbols may be added and new members may be appended to
+ * public structs whose size is not part of public ABI (most public structs in
+ * FFmpeg). New macros and enum values may be added. Behavior in undocumented
+ * situations may change slightly (and be documented). All those are accompanied
+ * by an entry in doc/APIchanges and incrementing either the minor or micro
+ * version number.
  */
 
 /**
diff --git a/libavutil/bprint.c b/libavutil/bprint.c
index fd7611a..cd91bc4 100644
--- a/libavutil/bprint.c
+++ b/libavutil/bprint.c
@@ -26,6 +26,7 @@
 #include "avstring.h"
 #include "bprint.h"
 #include "common.h"
+#include "compat/va_copy.h"
 #include "error.h"
 #include "mem.h"
 
@@ -113,6 +114,29 @@
     av_bprint_grow(buf, extra_len);
 }
 
+void av_vbprintf(AVBPrint *buf, const char *fmt, va_list vl_arg)
+{
+    unsigned room;
+    char *dst;
+    int extra_len;
+    va_list vl;
+
+    while (1) {
+        room = av_bprint_room(buf);
+        dst = room ? buf->str + buf->len : NULL;
+        va_copy(vl, vl_arg);
+        extra_len = vsnprintf(dst, room, fmt, vl);
+        va_end(vl);
+        if (extra_len <= 0)
+            return;
+        if (extra_len < room)
+            break;
+        if (av_bprint_alloc(buf, extra_len))
+            break;
+    }
+    av_bprint_grow(buf, extra_len);
+}
+
 void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
 {
     unsigned room, real_n;
diff --git a/libavutil/bprint.h b/libavutil/bprint.h
index df78916..bb1de25 100644
--- a/libavutil/bprint.h
+++ b/libavutil/bprint.h
@@ -21,6 +21,8 @@
 #ifndef AVUTIL_BPRINT_H
 #define AVUTIL_BPRINT_H
 
+#include <stdarg.h>
+
 #include "attributes.h"
 #include "avstring.h"
 
@@ -74,10 +76,10 @@
  */
 typedef struct AVBPrint {
     FF_PAD_STRUCTURE(1024,
-    char *str;         /** string so far */
-    unsigned len;      /** length so far */
-    unsigned size;     /** allocated memory */
-    unsigned size_max; /** maximum allocated memory */
+    char *str;         /**< string so far */
+    unsigned len;      /**< length so far */
+    unsigned size;     /**< allocated memory */
+    unsigned size_max; /**< maximum allocated memory */
     char reserved_internal_buffer[1];
     )
 } AVBPrint;
@@ -122,6 +124,11 @@
 void av_bprintf(AVBPrint *buf, const char *fmt, ...) av_printf_format(2, 3);
 
 /**
+ * Append a formatted string to a print buffer.
+ */
+void av_vbprintf(AVBPrint *buf, const char *fmt, va_list vl_arg);
+
+/**
  * Append char c n times to a print buffer.
  */
 void av_bprint_chars(AVBPrint *buf, char c, unsigned n);
diff --git a/libavutil/buffer.c b/libavutil/buffer.c
index a5fc8d7..e9bf54b 100644
--- a/libavutil/buffer.c
+++ b/libavutil/buffer.c
@@ -288,7 +288,7 @@
     AVBufferPool *pool = buf->pool;
 
     if(CONFIG_MEMORY_POISONING)
-        memset(buf->data, 0x2a, pool->size);
+        memset(buf->data, FF_MEMORY_POISON, pool->size);
 
     add_to_pool(buf);
     if (!avpriv_atomic_int_add_and_fetch(&pool->refcount, -1))
diff --git a/libavutil/buffer.h b/libavutil/buffer.h
index bcd1130..b4399fd 100644
--- a/libavutil/buffer.h
+++ b/libavutil/buffer.h
@@ -121,7 +121,7 @@
  * If this function fails, data is left untouched.
  * @param data   data array
  * @param size   size of data in bytes
- * @param free   a callback for freeing data
+ * @param free   a callback for freeing this buffer's data
  * @param opaque parameter to be got for processing or passed to free
  * @param flags  a combination of AV_BUFFER_FLAG_*
  *
diff --git a/libavutil/common.h b/libavutil/common.h
index e303c25..c7c32fd 100644
--- a/libavutil/common.h
+++ b/libavutil/common.h
@@ -48,6 +48,9 @@
 #define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b))
 /* assume b>0 */
 #define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b))
+/* assume a>0 and b>0 */
+#define FF_CEIL_RSHIFT(a,b) (!av_builtin_constant_p(b) ? -((-(a)) >> (b)) \
+                                                       : ((a) + (1<<(b)) - 1) >> (b))
 #define FFUDIV(a,b) (((a)>0 ?(a):(a)-(b)+1) / (b))
 #define FFUMOD(a,b) ((a)-(b)*FFUDIV(a,b))
 #define FFABS(a) ((a) >= 0 ? (a) : (-(a)))
@@ -297,7 +300,7 @@
     val= GET_BYTE;\
     {\
         uint32_t top = (val & 128) >> 1;\
-        if ((val & 0xc0) == 0x80)\
+        if ((val & 0xc0) == 0x80 || val >= 0xFE)\
             ERROR\
         while (val & top) {\
             int tmp= GET_BYTE - 128;\
diff --git a/libavutil/cpu.c b/libavutil/cpu.c
index a1d1547..cdea209 100644
--- a/libavutil/cpu.c
+++ b/libavutil/cpu.c
@@ -19,6 +19,28 @@
 #include "cpu.h"
 #include "config.h"
 #include "opt.h"
+#include "common.h"
+
+#if HAVE_SCHED_GETAFFINITY
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+#include <sched.h>
+#endif
+#if HAVE_GETPROCESSAFFINITYMASK
+#include <windows.h>
+#endif
+#if HAVE_SYSCTL
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#endif
+#if HAVE_SYSCONF
+#include <unistd.h>
+#endif
 
 static int flags, checked;
 
@@ -173,6 +195,43 @@
 
     return av_opt_eval_flags(&pclass, &cpuflags_opts[0], s, flags);
 }
+
+int av_cpu_count(void)
+{
+    static volatile int printed;
+
+    int nb_cpus = 1;
+#if HAVE_SCHED_GETAFFINITY && defined(CPU_COUNT)
+    cpu_set_t cpuset;
+
+    CPU_ZERO(&cpuset);
+
+    if (!sched_getaffinity(0, sizeof(cpuset), &cpuset))
+        nb_cpus = CPU_COUNT(&cpuset);
+#elif HAVE_GETPROCESSAFFINITYMASK
+    DWORD_PTR proc_aff, sys_aff;
+    if (GetProcessAffinityMask(GetCurrentProcess(), &proc_aff, &sys_aff))
+        nb_cpus = av_popcount64(proc_aff);
+#elif HAVE_SYSCTL && defined(HW_NCPU)
+    int mib[2] = { CTL_HW, HW_NCPU };
+    size_t len = sizeof(nb_cpus);
+
+    if (sysctl(mib, 2, &nb_cpus, &len, NULL, 0) == -1)
+        nb_cpus = 0;
+#elif HAVE_SYSCONF && defined(_SC_NPROC_ONLN)
+    nb_cpus = sysconf(_SC_NPROC_ONLN);
+#elif HAVE_SYSCONF && defined(_SC_NPROCESSORS_ONLN)
+    nb_cpus = sysconf(_SC_NPROCESSORS_ONLN);
+#endif
+
+    if (!printed) {
+        av_log(NULL, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus);
+        printed = 1;
+    }
+
+    return nb_cpus;
+}
+
 #ifdef TEST
 
 #include <stdio.h>
diff --git a/libavutil/cpu.h b/libavutil/cpu.h
index c8f34e0..df8ef87 100644
--- a/libavutil/cpu.h
+++ b/libavutil/cpu.h
@@ -100,6 +100,11 @@
  */
 int av_parse_cpu_caps(unsigned *flags, const char *s);
 
+/**
+ * @return the number of logical CPU cores present.
+ */
+int av_cpu_count(void);
+
 /* The following CPU-specific functions shall not be called directly. */
 int ff_get_cpu_flags_arm(void);
 int ff_get_cpu_flags_ppc(void);
diff --git a/libavutil/crc.c b/libavutil/crc.c
index 9ee5efe..b429fe1 100644
--- a/libavutil/crc.c
+++ b/libavutil/crc.c
@@ -119,6 +119,45 @@
         0x176E, 0x367E, 0x554E, 0x745E, 0x932E, 0xB23E, 0xD10E, 0xF01E,
         0x0001
     },
+    [AV_CRC_24_IEEE] = {
+        0x000000, 0xFB4C86, 0x0DD58A, 0xF6990C, 0xE1E693, 0x1AAA15, 0xEC3319,
+        0x177F9F, 0x3981A1, 0xC2CD27, 0x34542B, 0xCF18AD, 0xD86732, 0x232BB4,
+        0xD5B2B8, 0x2EFE3E, 0x894EC5, 0x720243, 0x849B4F, 0x7FD7C9, 0x68A856,
+        0x93E4D0, 0x657DDC, 0x9E315A, 0xB0CF64, 0x4B83E2, 0xBD1AEE, 0x465668,
+        0x5129F7, 0xAA6571, 0x5CFC7D, 0xA7B0FB, 0xE9D10C, 0x129D8A, 0xE40486,
+        0x1F4800, 0x08379F, 0xF37B19, 0x05E215, 0xFEAE93, 0xD050AD, 0x2B1C2B,
+        0xDD8527, 0x26C9A1, 0x31B63E, 0xCAFAB8, 0x3C63B4, 0xC72F32, 0x609FC9,
+        0x9BD34F, 0x6D4A43, 0x9606C5, 0x81795A, 0x7A35DC, 0x8CACD0, 0x77E056,
+        0x591E68, 0xA252EE, 0x54CBE2, 0xAF8764, 0xB8F8FB, 0x43B47D, 0xB52D71,
+        0x4E61F7, 0xD2A319, 0x29EF9F, 0xDF7693, 0x243A15, 0x33458A, 0xC8090C,
+        0x3E9000, 0xC5DC86, 0xEB22B8, 0x106E3E, 0xE6F732, 0x1DBBB4, 0x0AC42B,
+        0xF188AD, 0x0711A1, 0xFC5D27, 0x5BEDDC, 0xA0A15A, 0x563856, 0xAD74D0,
+        0xBA0B4F, 0x4147C9, 0xB7DEC5, 0x4C9243, 0x626C7D, 0x9920FB, 0x6FB9F7,
+        0x94F571, 0x838AEE, 0x78C668, 0x8E5F64, 0x7513E2, 0x3B7215, 0xC03E93,
+        0x36A79F, 0xCDEB19, 0xDA9486, 0x21D800, 0xD7410C, 0x2C0D8A, 0x02F3B4,
+        0xF9BF32, 0x0F263E, 0xF46AB8, 0xE31527, 0x1859A1, 0xEEC0AD, 0x158C2B,
+        0xB23CD0, 0x497056, 0xBFE95A, 0x44A5DC, 0x53DA43, 0xA896C5, 0x5E0FC9,
+        0xA5434F, 0x8BBD71, 0x70F1F7, 0x8668FB, 0x7D247D, 0x6A5BE2, 0x911764,
+        0x678E68, 0x9CC2EE, 0xA44733, 0x5F0BB5, 0xA992B9, 0x52DE3F, 0x45A1A0,
+        0xBEED26, 0x48742A, 0xB338AC, 0x9DC692, 0x668A14, 0x901318, 0x6B5F9E,
+        0x7C2001, 0x876C87, 0x71F58B, 0x8AB90D, 0x2D09F6, 0xD64570, 0x20DC7C,
+        0xDB90FA, 0xCCEF65, 0x37A3E3, 0xC13AEF, 0x3A7669, 0x148857, 0xEFC4D1,
+        0x195DDD, 0xE2115B, 0xF56EC4, 0x0E2242, 0xF8BB4E, 0x03F7C8, 0x4D963F,
+        0xB6DAB9, 0x4043B5, 0xBB0F33, 0xAC70AC, 0x573C2A, 0xA1A526, 0x5AE9A0,
+        0x74179E, 0x8F5B18, 0x79C214, 0x828E92, 0x95F10D, 0x6EBD8B, 0x982487,
+        0x636801, 0xC4D8FA, 0x3F947C, 0xC90D70, 0x3241F6, 0x253E69, 0xDE72EF,
+        0x28EBE3, 0xD3A765, 0xFD595B, 0x0615DD, 0xF08CD1, 0x0BC057, 0x1CBFC8,
+        0xE7F34E, 0x116A42, 0xEA26C4, 0x76E42A, 0x8DA8AC, 0x7B31A0, 0x807D26,
+        0x9702B9, 0x6C4E3F, 0x9AD733, 0x619BB5, 0x4F658B, 0xB4290D, 0x42B001,
+        0xB9FC87, 0xAE8318, 0x55CF9E, 0xA35692, 0x581A14, 0xFFAAEF, 0x04E669,
+        0xF27F65, 0x0933E3, 0x1E4C7C, 0xE500FA, 0x1399F6, 0xE8D570, 0xC62B4E,
+        0x3D67C8, 0xCBFEC4, 0x30B242, 0x27CDDD, 0xDC815B, 0x2A1857, 0xD154D1,
+        0x9F3526, 0x6479A0, 0x92E0AC, 0x69AC2A, 0x7ED3B5, 0x859F33, 0x73063F,
+        0x884AB9, 0xA6B487, 0x5DF801, 0xAB610D, 0x502D8B, 0x475214, 0xBC1E92,
+        0x4A879E, 0xB1CB18, 0x167BE3, 0xED3765, 0x1BAE69, 0xE0E2EF, 0xF79D70,
+        0x0CD1F6, 0xFA48FA, 0x01047C, 0x2FFA42, 0xD4B6C4, 0x222FC8, 0xD9634E,
+        0xCE1CD1, 0x355057, 0xC3C95B, 0x3885DD, 0x000001,
+    },
     [AV_CRC_32_IEEE] = {
         0x00000000, 0xB71DC104, 0x6E3B8209, 0xD926430D, 0xDC760413, 0x6B6BC517,
         0xB24D861A, 0x0550471E, 0xB8ED0826, 0x0FF0C922, 0xD6D68A2F, 0x61CB4B2B,
@@ -211,6 +250,11 @@
     },
 };
 #else
+#if CONFIG_SMALL
+#define CRC_TABLE_SIZE 257
+#else
+#define CRC_TABLE_SIZE 1024
+#endif
 static struct {
     uint8_t  le;
     uint8_t  bits;
@@ -219,10 +263,11 @@
     [AV_CRC_8_ATM]      = { 0,  8,       0x07 },
     [AV_CRC_16_ANSI]    = { 0, 16,     0x8005 },
     [AV_CRC_16_CCITT]   = { 0, 16,     0x1021 },
+    [AV_CRC_24_IEEE]    = { 0, 24,   0x864CFB },
     [AV_CRC_32_IEEE]    = { 0, 32, 0x04C11DB7 },
     [AV_CRC_32_IEEE_LE] = { 1, 32, 0xEDB88320 },
 };
-static AVCRC av_crc_table[AV_CRC_MAX][257];
+static AVCRC av_crc_table[AV_CRC_MAX][CRC_TABLE_SIZE];
 #endif
 
 int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size)
@@ -302,8 +347,9 @@
 {
     uint8_t buf[1999];
     int i;
-    int p[4][3] = { { AV_CRC_32_IEEE_LE, 0xEDB88320, 0x3D5CDD04 },
+    int p[5][3] = { { AV_CRC_32_IEEE_LE, 0xEDB88320, 0x3D5CDD04 },
                     { AV_CRC_32_IEEE   , 0x04C11DB7, 0xC0F5BAE0 },
+                    { AV_CRC_24_IEEE   , 0x864CFB  , 0xB704CE   },
                     { AV_CRC_16_ANSI   , 0x8005    , 0x1FBB     },
                     { AV_CRC_8_ATM     , 0x07      , 0xE3       }
     };
@@ -312,7 +358,7 @@
     for (i = 0; i < sizeof(buf); i++)
         buf[i] = i + i * i;
 
-    for (i = 0; i < 4; i++) {
+    for (i = 0; i < 5; i++) {
         ctx = av_crc_get_table(p[i][0]);
         printf("crc %08X = %X\n", p[i][1], av_crc(ctx, 0, buf, sizeof(buf)));
     }
diff --git a/libavutil/crc.h b/libavutil/crc.h
index 2bdfca8..f4219ca 100644
--- a/libavutil/crc.h
+++ b/libavutil/crc.h
@@ -25,6 +25,12 @@
 #include <stddef.h>
 #include "attributes.h"
 
+/**
+ * @defgroup lavu_crc32 CRC32
+ * @ingroup lavu_crypto
+ * @{
+ */
+
 typedef uint32_t AVCRC;
 
 typedef enum {
@@ -33,6 +39,7 @@
     AV_CRC_16_CCITT,
     AV_CRC_32_IEEE,
     AV_CRC_32_IEEE_LE,  /*< reversed bitorder version of AV_CRC_32_IEEE */
+    AV_CRC_24_IEEE = 12,
     AV_CRC_MAX,         /*< Not part of public API! Do not use outside libavutil. */
 }AVCRCId;
 
@@ -71,4 +78,8 @@
 uint32_t av_crc(const AVCRC *ctx, uint32_t crc,
                 const uint8_t *buffer, size_t length) av_pure;
 
+/**
+ * @}
+ */
+
 #endif /* AVUTIL_CRC_H */
diff --git a/libavutil/eval.c b/libavutil/eval.c
index 3abc3e5..635e538 100644
--- a/libavutil/eval.c
+++ b/libavutil/eval.c
@@ -27,6 +27,7 @@
  */
 
 #include <float.h>
+#include "attributes.h"
 #include "avutil.h"
 #include "common.h"
 #include "eval.h"
@@ -52,7 +53,7 @@
     double *var;
 } Parser;
 
-static const AVClass class = { "Eval", av_default_item_name, NULL, LIBAVUTIL_VERSION_INT, offsetof(Parser,log_offset), offsetof(Parser,log_ctx) };
+static const AVClass eval_class = { "Eval", av_default_item_name, NULL, LIBAVUTIL_VERSION_INT, offsetof(Parser,log_offset), offsetof(Parser,log_ctx) };
 
 static const int8_t si_prefixes['z' - 'E' + 1] = {
     ['y'-'E']= -24,
@@ -487,7 +488,7 @@
        for example, -3dB is not the same as -(3dB) */
     if (*p->s == '-') {
         char *next;
-        double av_unused v = strtod(p->s, &next);
+        double av_unused ignored = strtod(p->s, &next);
         if (next != p->s && next[0] == 'd' && next[1] == 'B') {
             *sign = 0;
             return parse_primary(e, p);
@@ -657,7 +658,7 @@
         if (!av_isspace(*s++)) *wp++ = s[-1];
     *wp++ = 0;
 
-    p.class      = &class;
+    p.class      = &eval_class;
     p.stack_index=100;
     p.s= w;
     p.const_names = const_names;
diff --git a/libavutil/fifo.c b/libavutil/fifo.c
index bafa9e9..eb1c128 100644
--- a/libavutil/fifo.c
+++ b/libavutil/fifo.c
@@ -24,11 +24,11 @@
 
 AVFifoBuffer *av_fifo_alloc(unsigned int size)
 {
-    AVFifoBuffer *f= av_mallocz(sizeof(AVFifoBuffer));
+    AVFifoBuffer *f = av_mallocz(sizeof(AVFifoBuffer));
     if (!f)
         return NULL;
     f->buffer = av_malloc(size);
-    f->end = f->buffer + size;
+    f->end    = f->buffer + size;
     av_fifo_reset(f);
     if (!f->buffer)
         av_freep(&f);
@@ -64,7 +64,7 @@
     unsigned int old_size = f->end - f->buffer;
 
     if (old_size < new_size) {
-        int len = av_fifo_size(f);
+        int len          = av_fifo_size(f);
         AVFifoBuffer *f2 = av_fifo_alloc(new_size);
 
         if (!f2)
@@ -92,8 +92,10 @@
     return 0;
 }
 
-// src must NOT be const as it can be a context for func that may need updating (like a pointer or byte counter)
-int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int))
+/* src must NOT be const as it can be a context for func that may need
+ * updating (like a pointer or byte counter) */
+int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size,
+                          int (*func)(void *, void *, int))
 {
     int total = size;
     uint32_t wndx= f->wndx;
@@ -106,30 +108,31 @@
                 break;
         } else {
             memcpy(wptr, src, len);
-            src = (uint8_t*)src + len;
+            src = (uint8_t *)src + len;
         }
 // Write memory barrier needed for SMP here in theory
         wptr += len;
         if (wptr >= f->end)
             wptr = f->buffer;
-        wndx += len;
-        size -= len;
+        wndx    += len;
+        size    -= len;
     } while (size > 0);
     f->wndx= wndx;
     f->wptr= wptr;
     return total - size;
 }
 
-
-int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int))
+int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size,
+                         void (*func)(void *, void *, int))
 {
 // Read memory barrier needed for SMP here in theory
     do {
         int len = FFMIN(f->end - f->rptr, buf_size);
-        if(func) func(dest, f->rptr, len);
-        else{
+        if (func)
+            func(dest, f->rptr, len);
+        else {
             memcpy(dest, f->rptr, len);
-            dest = (uint8_t*)dest + len;
+            dest = (uint8_t *)dest + len;
         }
 // memory barrier needed for SMP here in theory
         av_fifo_drain(f, len);
@@ -160,9 +163,9 @@
         av_fifo_generic_write(fifo, &i, sizeof(int), NULL);
 
     /* peek at FIFO */
-    n = av_fifo_size(fifo)/sizeof(int);
-    for (i = -n+1; i < n; i++) {
-        int *v = (int *)av_fifo_peek2(fifo, i*sizeof(int));
+    n = av_fifo_size(fifo) / sizeof(int);
+    for (i = -n + 1; i < n; i++) {
+        int *v = (int *)av_fifo_peek2(fifo, i * sizeof(int));
         printf("%d: %d\n", i, *v);
     }
     printf("\n");
diff --git a/libavutil/file.c b/libavutil/file.c
index 41850f8..45fe853 100644
--- a/libavutil/file.c
+++ b/libavutil/file.c
@@ -18,6 +18,7 @@
 
 #include "config.h"
 #include "file.h"
+#include "internal.h"
 #include "log.h"
 #include "mem.h"
 #include <fcntl.h>
@@ -49,7 +50,7 @@
                 int log_offset, void *log_ctx)
 {
     FileLogContext file_log_ctx = { &file_log_ctx_class, log_offset, log_ctx };
-    int err, fd = open(filename, O_RDONLY);
+    int err, fd = avpriv_open(filename, O_RDONLY);
     struct stat st;
     av_unused void *ptr;
     off_t off_size;
diff --git a/libavutil/file.h b/libavutil/file.h
index b47ef80..a7364fe 100644
--- a/libavutil/file.h
+++ b/libavutil/file.h
@@ -58,7 +58,7 @@
  * @return file descriptor of opened file (or -1 on error)
  * and opened file name in **filename.
  * @note On very old libcs it is necessary to set a secure umask before
- *       calling this, av_tempfile() cant call umask itself as it is used in
+ *       calling this, av_tempfile() can't call umask itself as it is used in
  *       libraries and could interfere with the calling application.
  */
 int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx);
diff --git a/libavutil/file_open.c b/libavutil/file_open.c
new file mode 100644
index 0000000..ddb1c51
--- /dev/null
+++ b/libavutil/file_open.c
@@ -0,0 +1,93 @@
+/*
+ * 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
+ */
+
+#include "config.h"
+#include "internal.h"
+#include "mem.h"
+#include <stdarg.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_IO_H
+#include <io.h>
+#endif
+
+#if defined(_WIN32) && !defined(__MINGW32CE__)
+#undef open
+#undef lseek
+#undef stat
+#undef fstat
+#include <windows.h>
+#include <share.h>
+#include <errno.h>
+
+static int win32_open(const char *filename_utf8, int oflag, int pmode)
+{
+    int fd;
+    int num_chars;
+    wchar_t *filename_w;
+
+    /* convert UTF-8 to wide chars */
+    num_chars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filename_utf8, -1, NULL, 0);
+    if (num_chars <= 0)
+        goto fallback;
+    filename_w = av_mallocz(sizeof(wchar_t) * num_chars);
+    if (!filename_w) {
+        errno = ENOMEM;
+        return -1;
+    }
+    MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, filename_w, num_chars);
+
+    fd = _wsopen(filename_w, oflag, SH_DENYNO, pmode);
+    av_freep(&filename_w);
+
+    if (fd != -1 || (oflag & O_CREAT))
+        return fd;
+
+fallback:
+    /* filename may be in CP_ACP */
+    return _sopen(filename_utf8, oflag, SH_DENYNO, pmode);
+}
+#define open win32_open
+#endif
+
+int avpriv_open(const char *filename, int flags, ...)
+{
+    int fd;
+    unsigned int mode = 0;
+    va_list ap;
+
+    va_start(ap, flags);
+    if (flags & O_CREAT)
+        mode = va_arg(ap, unsigned int);
+    va_end(ap);
+
+#ifdef O_CLOEXEC
+    flags |= O_CLOEXEC;
+#endif
+
+    fd = open(filename, flags, mode);
+#if HAVE_FCNTL
+    if (fd != -1)
+        fcntl(fd, F_SETFD, FD_CLOEXEC);
+#endif
+
+    return fd;
+}
diff --git a/libavutil/float_dsp.c b/libavutil/float_dsp.c
index 7641313..64bd2e6 100644
--- a/libavutil/float_dsp.c
+++ b/libavutil/float_dsp.c
@@ -20,7 +20,7 @@
  */
 
 #include "config.h"
-
+#include "libavutil/attributes.h"
 #include "float_dsp.h"
 
 static void vector_fmul_c(float *dst, const float *src0, const float *src1,
@@ -115,7 +115,7 @@
     return p;
 }
 
-void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact)
+av_cold void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact)
 {
     fdsp->vector_fmul = vector_fmul_c;
     fdsp->vector_fmac_scalar = vector_fmac_scalar_c;
diff --git a/libavutil/frame.c b/libavutil/frame.c
index ca6814c..b0fdd49 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -27,10 +27,6 @@
 #include "mem.h"
 #include "samplefmt.h"
 
-#define MAKE_ACCESSORS(str, name, type, field) \
-    type av_##name##_get_##field(const str *s) { return s->field; } \
-    void av_##name##_set_##field(str *s, type v) { s->field = v; }
-
 MAKE_ACCESSORS(AVFrame, frame, int64_t, best_effort_timestamp)
 MAKE_ACCESSORS(AVFrame, frame, int64_t, pkt_duration)
 MAKE_ACCESSORS(AVFrame, frame, int64_t, pkt_pos)
@@ -40,6 +36,8 @@
 MAKE_ACCESSORS(AVFrame, frame, AVDictionary *, metadata)
 MAKE_ACCESSORS(AVFrame, frame, int,     decode_error_flags)
 MAKE_ACCESSORS(AVFrame, frame, int,     pkt_size)
+MAKE_ACCESSORS(AVFrame, frame, enum AVColorSpace, colorspace)
+MAKE_ACCESSORS(AVFrame, frame, enum AVColorRange, color_range)
 
 #define CHECK_CHANNELS_CONSISTENCY(frame) \
     av_assert2(!(frame)->channel_layout || \
@@ -89,6 +87,7 @@
     frame->key_frame           = 1;
     frame->sample_aspect_ratio = (AVRational){ 0, 1 };
     frame->format              = -1; /* unknown */
+    frame->colorspace          = AVCOL_SPC_UNSPECIFIED;
     frame->extended_data       = frame->data;
 }
 
@@ -126,10 +125,14 @@
         return ret;
 
     if (!frame->linesize[0]) {
-        ret = av_image_fill_linesizes(frame->linesize, frame->format,
-                                      frame->width);
-        if (ret < 0)
-            return ret;
+        for(i=1; i<=align; i+=i) {
+            ret = av_image_fill_linesizes(frame->linesize, frame->format,
+                                          FFALIGN(frame->width, i));
+            if (ret < 0)
+                return ret;
+            if (!(frame->linesize[0] & (align-1)))
+                break;
+        }
 
         for (i = 0; i < 4 && frame->linesize[i]; i++)
             frame->linesize[i] = FFALIGN(frame->linesize[i], align);
@@ -138,7 +141,7 @@
     for (i = 0; i < 4 && frame->linesize[i]; i++) {
         int h = FFALIGN(frame->height, 32);
         if (i == 1 || i == 2)
-            h = -((-h) >> desc->log2_chroma_h);
+            h = FF_CEIL_RSHIFT(h, desc->log2_chroma_h);
 
         frame->buf[i] = av_buffer_alloc(frame->linesize[i] * h + 16);
         if (!frame->buf[i])
@@ -146,7 +149,7 @@
 
         frame->data[i] = frame->buf[i]->data;
     }
-    if (desc->flags & PIX_FMT_PAL || desc->flags & PIX_FMT_PSEUDOPAL) {
+    if (desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) {
         av_buffer_unref(&frame->buf[1]);
         frame->buf[1] = av_buffer_alloc(1024);
         if (!frame->buf[1])
@@ -219,7 +222,7 @@
 
     if (frame->width > 0 && frame->height > 0)
         return get_video_buffer(frame, align);
-    else if (frame->nb_samples > 0 && frame->channel_layout)
+    else if (frame->nb_samples > 0 && (frame->channel_layout || frame->channels > 0))
         return get_audio_buffer(frame, align);
 
     return AVERROR(EINVAL);
@@ -259,7 +262,9 @@
     }
 
     /* ref the buffers */
-    for (i = 0; i < FF_ARRAY_ELEMS(src->buf) && src->buf[i]; i++) {
+    for (i = 0; i < FF_ARRAY_ELEMS(src->buf); i++) {
+        if (!src->buf[i])
+            continue;
         dst->buf[i] = av_buffer_ref(src->buf[i]);
         if (!dst->buf[i]) {
             ret = AVERROR(ENOMEM);
@@ -366,8 +371,9 @@
     if (!frame->buf[0])
         return 0;
 
-    for (i = 0; i < FF_ARRAY_ELEMS(frame->buf) && frame->buf[i]; i++)
-        ret &= !!av_buffer_is_writable(frame->buf[i]);
+    for (i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++)
+        if (frame->buf[i])
+            ret &= !!av_buffer_is_writable(frame->buf[i]);
     for (i = 0; i < frame->nb_extended_buf; i++)
         ret &= !!av_buffer_is_writable(frame->extended_buf[i]);
 
@@ -449,6 +455,8 @@
     dst->coded_picture_number = src->coded_picture_number;
     dst->display_picture_number = src->display_picture_number;
     dst->decode_error_flags  = src->decode_error_flags;
+    dst->colorspace          = src->colorspace;
+    dst->color_range         = src->color_range;
 
     av_dict_copy(&dst->metadata, src->metadata, 0);
 
@@ -550,7 +558,7 @@
     return ret;
 }
 
-AVFrameSideData *av_frame_get_side_data(AVFrame *frame,
+AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
                                         enum AVFrameSideDataType type)
 {
     int i;
diff --git a/libavutil/frame.h b/libavutil/frame.h
index a24c299..320b1b8 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -30,6 +30,26 @@
 #include "rational.h"
 #include "samplefmt.h"
 
+enum AVColorSpace{
+    AVCOL_SPC_RGB         = 0,
+    AVCOL_SPC_BT709       = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
+    AVCOL_SPC_UNSPECIFIED = 2,
+    AVCOL_SPC_FCC         = 4,
+    AVCOL_SPC_BT470BG     = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
+    AVCOL_SPC_SMPTE170M   = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
+    AVCOL_SPC_SMPTE240M   = 7,
+    AVCOL_SPC_YCOCG       = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
+    AVCOL_SPC_NB             , ///< Not part of ABI
+};
+#define AVCOL_SPC_YCGCO AVCOL_SPC_YCOCG
+
+enum AVColorRange{
+    AVCOL_RANGE_UNSPECIFIED = 0,
+    AVCOL_RANGE_MPEG        = 1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges
+    AVCOL_RANGE_JPEG        = 2, ///< the normal     2^n-1   "JPEG" YUV ranges
+    AVCOL_RANGE_NB             , ///< Not part of ABI
+};
+
 enum AVFrameSideDataType {
     /**
      * The data is the AVPanScan struct defined in libavcodec.
@@ -435,6 +455,25 @@
     int pkt_size;
 
     /**
+     * YUV colorspace type.
+     * It must be accessed using av_frame_get_colorspace() and
+     * av_frame_set_colorspace().
+     * - encoding: Set by user
+     * - decoding: Set by libavcodec
+     */
+    enum AVColorSpace colorspace;
+
+    /**
+     * MPEG vs JPEG YUV range.
+     * It must be accessed using av_frame_get_color_range() and
+     * av_frame_set_color_range().
+     * - encoding: Set by user
+     * - decoding: Set by libavcodec
+     */
+    enum AVColorRange color_range;
+
+
+    /**
      * Not to be accessed directly from outside libavutil
      */
     AVBufferRef *qp_table_buf;
@@ -466,6 +505,10 @@
 AVDictionary **avpriv_frame_get_metadatap(AVFrame *frame);
 int8_t *av_frame_get_qp_table(AVFrame *f, int *stride, int *type);
 int av_frame_set_qp_table(AVFrame *f, AVBufferRef *buf, int stride, int type);
+enum AVColorSpace av_frame_get_colorspace(const AVFrame *frame);
+void    av_frame_set_colorspace(AVFrame *frame, enum AVColorSpace val);
+enum AVColorRange av_frame_get_color_range(const AVFrame *frame);
+void    av_frame_set_color_range(AVFrame *frame, enum AVColorRange val);
 
 /**
  * Allocate an AVFrame and set its fields to default values.  The resulting
@@ -489,7 +532,7 @@
 void av_frame_free(AVFrame **frame);
 
 /**
- * Setup a new reference to the data described by an given frame.
+ * Setup a new reference to the data described by a given frame.
  *
  * Copy frame properties from src to dst and create a new reference for each
  * AVBufferRef from src.
@@ -603,7 +646,7 @@
  * @return a pointer to the side data of a given type on success, NULL if there
  * is no side data with such type in this frame.
  */
-AVFrameSideData *av_frame_get_side_data(AVFrame *frame,
+AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
                                         enum AVFrameSideDataType type);
 
 #endif /* AVUTIL_FRAME_H */
diff --git a/libavutil/hash.c b/libavutil/hash.c
new file mode 100644
index 0000000..a8cf80b
--- /dev/null
+++ b/libavutil/hash.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2013 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
+ *
+ * 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
+ */
+#include <stdint.h>
+#include "hash.h"
+
+#include "adler32.h"
+#include "crc.h"
+#include "md5.h"
+#include "murmur3.h"
+#include "ripemd.h"
+#include "sha.h"
+#include "sha512.h"
+
+#include "avstring.h"
+#include "error.h"
+#include "intreadwrite.h"
+#include "mem.h"
+
+enum hashtype {
+    MD5,
+    MURMUR3,
+    RIPEMD128,
+    RIPEMD160,
+    RIPEMD256,
+    RIPEMD320,
+    SHA160,
+    SHA224,
+    SHA256,
+    SHA512_224,
+    SHA512_256,
+    SHA384,
+    SHA512,
+    CRC32,
+    ADLER32,
+    NUM_HASHES
+};
+
+typedef struct AVHashContext {
+    void *ctx;
+    enum hashtype type;
+    const AVCRC *crctab;
+    uint32_t crc;
+} AVHashContext;
+
+struct {
+    const char *name;
+    int size;
+} hashdesc[] = {
+    [MD5]     = {"MD5",     16},
+    [MURMUR3] = {"murmur3", 16},
+    [RIPEMD128] = {"RIPEMD128", 16},
+    [RIPEMD160] = {"RIPEMD160", 20},
+    [RIPEMD256] = {"RIPEMD256", 32},
+    [RIPEMD320] = {"RIPEMD320", 40},
+    [SHA160]  = {"SHA160",  20},
+    [SHA224]  = {"SHA224",  28},
+    [SHA256]  = {"SHA256",  32},
+    [SHA512_224]  = {"SHA512/224",  28},
+    [SHA512_256]  = {"SHA512/256",  32},
+    [SHA384]  = {"SHA384",  48},
+    [SHA512]  = {"SHA512",  64},
+    [CRC32]   = {"CRC32",    4},
+    [ADLER32] = {"adler32",  4},
+};
+
+const char *av_hash_names(int i)
+{
+    if (i < 0 || i >= NUM_HASHES) return NULL;
+    return hashdesc[i].name;
+}
+
+const char *av_hash_get_name(const AVHashContext *ctx)
+{
+    return hashdesc[ctx->type].name;
+}
+
+int av_hash_get_size(const AVHashContext *ctx)
+{
+    return hashdesc[ctx->type].size;
+}
+
+int av_hash_alloc(AVHashContext **ctx, const char *name)
+{
+    AVHashContext *res;
+    int i;
+    *ctx = NULL;
+    for (i = 0; i < NUM_HASHES; i++)
+        if (av_strcasecmp(name, hashdesc[i].name) == 0)
+            break;
+    if (i >= NUM_HASHES) return AVERROR(EINVAL);
+    res = av_mallocz(sizeof(*res));
+    if (!res) return AVERROR(ENOMEM);
+    res->type = i;
+    switch (i) {
+    case MD5:     res->ctx = av_md5_alloc(); break;
+    case MURMUR3: res->ctx = av_murmur3_alloc(); break;
+    case RIPEMD128:
+    case RIPEMD160:
+    case RIPEMD256:
+    case RIPEMD320: res->ctx = av_ripemd_alloc(); break;
+    case SHA160:
+    case SHA224:
+    case SHA256:  res->ctx = av_sha_alloc(); break;
+    case SHA512_224:
+    case SHA512_256:
+    case SHA384:
+    case SHA512:  res->ctx = av_sha512_alloc(); break;
+    case CRC32:   res->crctab = av_crc_get_table(AV_CRC_32_IEEE_LE); break;
+    case ADLER32: break;
+    }
+    if (i != ADLER32 && i != CRC32 && !res->ctx) {
+        av_free(res);
+        return AVERROR(ENOMEM);
+    }
+    *ctx = res;
+    return 0;
+}
+
+void av_hash_init(AVHashContext *ctx)
+{
+    switch (ctx->type) {
+    case MD5:     av_md5_init(ctx->ctx); break;
+    case MURMUR3: av_murmur3_init(ctx->ctx); break;
+    case RIPEMD128: av_ripemd_init(ctx->ctx, 128); break;
+    case RIPEMD160: av_ripemd_init(ctx->ctx, 160); break;
+    case RIPEMD256: av_ripemd_init(ctx->ctx, 256); break;
+    case RIPEMD320: av_ripemd_init(ctx->ctx, 320); break;
+    case SHA160:  av_sha_init(ctx->ctx, 160); break;
+    case SHA224:  av_sha_init(ctx->ctx, 224); break;
+    case SHA256:  av_sha_init(ctx->ctx, 256); break;
+    case SHA512_224:  av_sha512_init(ctx->ctx, 224); break;
+    case SHA512_256:  av_sha512_init(ctx->ctx, 256); break;
+    case SHA384:  av_sha512_init(ctx->ctx, 384); break;
+    case SHA512:  av_sha512_init(ctx->ctx, 512); break;
+    case CRC32:   ctx->crc = UINT32_MAX; break;
+    case ADLER32: ctx->crc = 1; break;
+    }
+}
+
+void av_hash_update(AVHashContext *ctx, const uint8_t *src, int len)
+{
+    switch (ctx->type) {
+    case MD5:     av_md5_update(ctx->ctx, src, len); break;
+    case MURMUR3: av_murmur3_update(ctx->ctx, src, len); break;
+    case RIPEMD128:
+    case RIPEMD160:
+    case RIPEMD256:
+    case RIPEMD320: av_ripemd_update(ctx->ctx, src, len); break;
+    case SHA160:
+    case SHA224:
+    case SHA256:  av_sha_update(ctx->ctx, src, len); break;
+    case SHA512_224:
+    case SHA512_256:
+    case SHA384:
+    case SHA512:  av_sha512_update(ctx->ctx, src, len); break;
+    case CRC32:   ctx->crc = av_crc(ctx->crctab, ctx->crc, src, len); break;
+    case ADLER32: ctx->crc = av_adler32_update(ctx->crc, src, len); break;
+    }
+}
+
+void av_hash_final(AVHashContext *ctx, uint8_t *dst)
+{
+    switch (ctx->type) {
+    case MD5:     av_md5_final(ctx->ctx, dst); break;
+    case MURMUR3: av_murmur3_final(ctx->ctx, dst); break;
+    case RIPEMD128:
+    case RIPEMD160:
+    case RIPEMD256:
+    case RIPEMD320: av_ripemd_final(ctx->ctx, dst); break;
+    case SHA160:
+    case SHA224:
+    case SHA256:  av_sha_final(ctx->ctx, dst); break;
+    case SHA512_224:
+    case SHA512_256:
+    case SHA384:
+    case SHA512:  av_sha512_final(ctx->ctx, dst); break;
+    case CRC32:   AV_WB32(dst, ctx->crc ^ UINT32_MAX); break;
+    case ADLER32: AV_WB32(dst, ctx->crc); break;
+    }
+}
+
+void av_hash_freep(AVHashContext **ctx)
+{
+    if (*ctx)
+        av_freep(&(*ctx)->ctx);
+    av_freep(ctx);
+}
diff --git a/libavutil/hash.h b/libavutil/hash.h
new file mode 100644
index 0000000..9bf715e
--- /dev/null
+++ b/libavutil/hash.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2013 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
+ *
+ * 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
+ */
+
+#ifndef AVUTIL_HASH_H
+#define AVUTIL_HASH_H
+
+#include <stdint.h>
+
+struct AVHashContext;
+
+/**
+ * Allocate a hash context for the algorithm specified by name.
+ *
+ * @return  >= 0 for success, a negative error code for failure
+ * @note  The context is not initialized, you must call av_hash_init().
+ */
+int av_hash_alloc(struct AVHashContext **ctx, const char *name);
+
+/**
+ * Get the names of available hash algorithms.
+ *
+ * This function can be used to enumerate the algorithms.
+ *
+ * @param i  index of the hash algorithm, starting from 0
+ * @return   a pointer to a static string or NULL if i is out of range
+ */
+const char *av_hash_names(int i);
+
+/**
+ * Get the name of the algorithm corresponding to the given hash context.
+ */
+const char *av_hash_get_name(const struct AVHashContext *ctx);
+
+/**
+ * Maximum value that av_hash_get_size will currently return.
+ *
+ * You can use this if you absolutely want or need to use static allocation
+ * and are fine with not supporting hashes newly added to libavutil without
+ * recompilation.
+ * Note that you still need to check against av_hash_get_size, adding new hashes
+ * with larger sizes will not be considered an ABI change and should not cause
+ * your code to overflow a buffer.
+ */
+#define AV_HASH_MAX_SIZE 64
+
+/**
+ * Get the size of the resulting hash value in bytes.
+ *
+ * The pointer passed to av_hash_final have space for at least this many bytes.
+ */
+int av_hash_get_size(const struct AVHashContext *ctx);
+
+/**
+ * Initialize or reset a hash context.
+ */
+void av_hash_init(struct AVHashContext *ctx);
+
+/**
+ * Update a hash context with additional data.
+ */
+void av_hash_update(struct AVHashContext *ctx, const uint8_t *src, int len);
+
+/**
+ * Finalize a hash context and compute the actual hash value.
+ */
+void av_hash_final(struct AVHashContext *ctx, uint8_t *dst);
+
+/**
+ * Free hash context.
+ */
+void av_hash_freep(struct AVHashContext **ctx);
+
+#endif /* AVUTIL_HASH_H */
diff --git a/libavutil/hmac.c b/libavutil/hmac.c
index e5f1434..02bdc18 100644
--- a/libavutil/hmac.c
+++ b/libavutil/hmac.c
@@ -20,13 +20,15 @@
 
 #include <string.h>
 
+#include "attributes.h"
 #include "hmac.h"
 #include "md5.h"
 #include "sha.h"
+#include "sha512.h"
 #include "mem.h"
 
-#define MAX_HASHLEN 20
-#define MAX_BLOCKLEN 64
+#define MAX_HASHLEN 64
+#define MAX_BLOCKLEN 128
 
 struct AVHMAC {
     void *hash;
@@ -38,11 +40,24 @@
     int keylen;
 };
 
-static void sha1_init(void *ctx)
-{
-    av_sha_init(ctx, 160);
+#define DEFINE_SHA(bits)                           \
+static av_cold void sha ## bits ##_init(void *ctx) \
+{                                                  \
+    av_sha_init(ctx, bits);                        \
 }
 
+#define DEFINE_SHA512(bits)                        \
+static av_cold void sha ## bits ##_init(void *ctx) \
+{                                                  \
+    av_sha512_init(ctx, bits);                     \
+}
+
+DEFINE_SHA(160)
+DEFINE_SHA(224)
+DEFINE_SHA(256)
+DEFINE_SHA512(384)
+DEFINE_SHA512(512)
+
 AVHMAC *av_hmac_alloc(enum AVHMACType type)
 {
     AVHMAC *c = av_mallocz(sizeof(*c));
@@ -52,19 +67,51 @@
     case AV_HMAC_MD5:
         c->blocklen = 64;
         c->hashlen  = 16;
-        c->init     = av_md5_init;
-        c->update   = av_md5_update;
-        c->final    = av_md5_final;
+        c->init     = (void*)av_md5_init;
+        c->update   = (void*)av_md5_update;
+        c->final    = (void*)av_md5_final;
         c->hash     = av_md5_alloc();
         break;
     case AV_HMAC_SHA1:
         c->blocklen = 64;
         c->hashlen  = 20;
-        c->init     = sha1_init;
-        c->update   = av_sha_update;
-        c->final    = av_sha_final;
+        c->init     = sha160_init;
+        c->update   = (void*)av_sha_update;
+        c->final    = (void*)av_sha_final;
         c->hash     = av_sha_alloc();
         break;
+    case AV_HMAC_SHA224:
+        c->blocklen = 64;
+        c->hashlen  = 28;
+        c->init     = sha224_init;
+        c->update   = (void*)av_sha_update;
+        c->final    = (void*)av_sha_final;
+        c->hash     = av_sha_alloc();
+        break;
+    case AV_HMAC_SHA256:
+        c->blocklen = 64;
+        c->hashlen  = 32;
+        c->init     = sha256_init;
+        c->update   = (void*)av_sha_update;
+        c->final    = (void*)av_sha_final;
+        c->hash     = av_sha_alloc();
+        break;
+    case AV_HMAC_SHA384:
+        c->blocklen = 128;
+        c->hashlen  = 48;
+        c->init     = sha384_init;
+        c->update   = (void*)av_sha512_update;
+        c->final    = (void*)av_sha512_final;
+        c->hash     = av_sha512_alloc();
+        break;
+    case AV_HMAC_SHA512:
+        c->blocklen = 128;
+        c->hashlen  = 64;
+        c->init     = sha512_init;
+        c->update   = (void*)av_sha512_update;
+        c->final    = (void*)av_sha512_final;
+        c->hash     = av_sha512_alloc();
+        break;
     default:
         av_free(c);
         return NULL;
@@ -159,28 +206,54 @@
 
 int main(void)
 {
-    uint8_t key1[16], key3[16], data3[50], key4[63], key5[64], key6[65];
-    const uint8_t key2[]  = "Jefe";
-    const uint8_t data1[] = "Hi There";
-    const uint8_t data2[] = "what do ya want for nothing?";
+    uint8_t key1[20], key3[131], data3[50];
+    enum AVHMACType i = AV_HMAC_SHA224;
+    static const uint8_t key2[]  = "Jefe";
+    static const uint8_t data1[] = "Hi There";
+    static const uint8_t data2[] = "what do ya want for nothing?";
+    static const uint8_t data4[] = "Test Using Larger Than Block-Size Key - Hash Key First";
+    static const uint8_t data5[] = "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data";
+    static const uint8_t data6[] = "This is a test using a larger than block-size key and a larger "
+                            "than block-size data. The key needs to be hashed before being used"
+                            " by the HMAC algorithm.";
     AVHMAC *hmac = av_hmac_alloc(AV_HMAC_MD5);
     if (!hmac)
         return 1;
     memset(key1, 0x0b, sizeof(key1));
     memset(key3, 0xaa, sizeof(key3));
-    memset(key4, 0x44, sizeof(key4));
-    memset(key5, 0x55, sizeof(key5));
-    memset(key6, 0x66, sizeof(key6));
     memset(data3, 0xdd, sizeof(data3));
-    // RFC 2104 test vectors
+    // RFC 2202 test vectors
+    test(hmac, key1, 16, data1, sizeof(data1));
+    test(hmac, key2, sizeof(key2), data2, sizeof(data2));
+    test(hmac, key3, 16, data3, sizeof(data3));
+    test(hmac, key3, 80, data4, sizeof(data4));
+    test(hmac, key3, 80, data5, sizeof(data5));
+    av_hmac_free(hmac);
+
+    /* SHA-1 */
+    hmac = av_hmac_alloc(AV_HMAC_SHA1);
+    if (!hmac)
+        return 1;
+    // RFC 2202 test vectors
     test(hmac, key1, sizeof(key1), data1, sizeof(data1));
     test(hmac, key2, sizeof(key2), data2, sizeof(data2));
-    test(hmac, key3, sizeof(key3), data3, sizeof(data3));
-    // Additional tests, to test cases where the key is too long
-    test(hmac, key4, sizeof(key4), data1, sizeof(data1));
-    test(hmac, key5, sizeof(key5), data2, sizeof(data2));
-    test(hmac, key6, sizeof(key6), data3, sizeof(data3));
+    test(hmac, key3, 20, data3, sizeof(data3));
+    test(hmac, key3, 80, data4, sizeof(data4));
+    test(hmac, key3, 80, data5, sizeof(data5));
     av_hmac_free(hmac);
+
+    /* SHA-2 */
+    while (i <= AV_HMAC_SHA512) {
+        hmac = av_hmac_alloc(i);
+        // RFC 4231 test vectors
+        test(hmac, key1, sizeof(key1), data1, sizeof(data1));
+        test(hmac, key2, sizeof(key2), data2, sizeof(data2));
+        test(hmac, key3, 20, data3, sizeof(data3));
+        test(hmac, key3, sizeof(key3), data4, sizeof(data4));
+        test(hmac, key3, sizeof(key3), data6, sizeof(data6));
+        av_hmac_free(hmac);
+        i++;
+    }
     return 0;
 }
 #endif /* TEST */
diff --git a/libavutil/hmac.h b/libavutil/hmac.h
index aef84c6..d36d4de 100644
--- a/libavutil/hmac.h
+++ b/libavutil/hmac.h
@@ -32,6 +32,10 @@
 enum AVHMACType {
     AV_HMAC_MD5,
     AV_HMAC_SHA1,
+    AV_HMAC_SHA224 = 10,
+    AV_HMAC_SHA256,
+    AV_HMAC_SHA384,
+    AV_HMAC_SHA512,
 };
 
 typedef struct AVHMAC AVHMAC;
diff --git a/libavutil/imgutils.c b/libavutil/imgutils.c
index 3060b07..d8a579f 100644
--- a/libavutil/imgutils.c
+++ b/libavutil/imgutils.c
@@ -65,7 +65,7 @@
         return AVERROR(EINVAL);
     linesize = max_step * shifted_w;
 
-    if (desc->flags & PIX_FMT_BITSTREAM)
+    if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM)
         linesize = (linesize + 7) >> 3;
     return linesize;
 }
@@ -76,7 +76,7 @@
     int max_step     [4];       /* max pixel step for each plane */
     int max_step_comp[4];       /* the component for each plane which has the max pixel step */
 
-    if ((unsigned)pix_fmt >= AV_PIX_FMT_NB || desc->flags & PIX_FMT_HWACCEL)
+    if ((unsigned)pix_fmt >= AV_PIX_FMT_NB || desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
         return AVERROR(EINVAL);
 
     av_image_fill_max_pixsteps(max_step, max_step_comp, desc);
@@ -92,7 +92,7 @@
 
     memset(linesizes, 0, 4*sizeof(linesizes[0]));
 
-    if (!desc || desc->flags & PIX_FMT_HWACCEL)
+    if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
         return AVERROR(EINVAL);
 
     av_image_fill_max_pixsteps(max_step, max_step_comp, desc);
@@ -113,7 +113,7 @@
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     memset(data     , 0, sizeof(data[0])*4);
 
-    if (!desc || desc->flags & PIX_FMT_HWACCEL)
+    if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
         return AVERROR(EINVAL);
 
     data[0] = ptr;
@@ -121,8 +121,8 @@
         return AVERROR(EINVAL);
     size[0] = linesizes[0] * height;
 
-    if (desc->flags & PIX_FMT_PAL ||
-        desc->flags & PIX_FMT_PSEUDOPAL) {
+    if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
+        desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) {
         size[0] = (size[0] + 3) & ~3;
         data[1] = ptr + size[0]; /* palette is stored here as 256 32 bits words */
         return size[0] + 256 * 4;
@@ -214,7 +214,7 @@
         av_free(buf);
         return ret;
     }
-    if (desc->flags & PIX_FMT_PAL || desc->flags & PIX_FMT_PSEUDOPAL)
+    if (desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)
         avpriv_set_systematic_pal2((uint32_t*)pointers[1], pix_fmt);
 
     return ret;
@@ -260,11 +260,11 @@
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
 
-    if (!desc || desc->flags & PIX_FMT_HWACCEL)
+    if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
         return;
 
-    if (desc->flags & PIX_FMT_PAL ||
-        desc->flags & PIX_FMT_PSEUDOPAL) {
+    if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
+        desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) {
         av_image_copy_plane(dst_data[0], dst_linesizes[0],
                             src_data[0], src_linesizes[0],
                             width, height);
@@ -284,7 +284,7 @@
                 return;
             }
             if (i == 1 || i == 2) {
-                h= -((-height)>>desc->log2_chroma_h);
+                h = FF_CEIL_RSHIFT(height, desc->log2_chroma_h);
             }
             av_image_copy_plane(dst_data[i], dst_linesizes[i],
                                 src_data[i], src_linesizes[i],
@@ -324,7 +324,7 @@
         return AVERROR(EINVAL);
     if (av_image_check_size(width, height, 0, NULL) < 0)
         return AVERROR(EINVAL);
-    if (desc->flags & PIX_FMT_PSEUDOPAL)
+    if (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)
         // do not include palette for these pseudo-paletted formats
         return width * height;
     return av_image_fill_arrays(data, linesize, NULL, pix_fmt, width, height, align);
@@ -358,7 +358,7 @@
         }
     }
 
-    if (desc->flags & PIX_FMT_PAL) {
+    if (desc->flags & AV_PIX_FMT_FLAG_PAL) {
         uint32_t *d32 = (uint32_t *)(((size_t)dst + 3) & ~3);
         for (i = 0; i<256; i++)
             AV_WL32(d32 + i, AV_RN32(src_data[1] + 4*i));
diff --git a/libavutil/internal.h b/libavutil/internal.h
index 6ff14fa..9df2dd1 100644
--- a/libavutil/internal.h
+++ b/libavutil/internal.h
@@ -62,10 +62,24 @@
 #    define av_export
 #endif
 
+#if HAVE_PRAGMA_DEPRECATED
+#    define FF_DISABLE_DEPRECATION_WARNINGS _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
+#    define FF_ENABLE_DEPRECATION_WARNINGS  _Pragma("GCC diagnostic warning \"-Wdeprecated-declarations\"")
+#else
+#    define FF_DISABLE_DEPRECATION_WARNINGS
+#    define FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
 #ifndef INT_BIT
 #    define INT_BIT (CHAR_BIT * sizeof(int))
 #endif
 
+#define FF_MEMORY_POISON 0x2a
+
+#define MAKE_ACCESSORS(str, name, type, field) \
+    type av_##name##_get_##field(const str *s) { return s->field; } \
+    void av_##name##_set_##field(str *s, type v) { s->field = v; }
+
 // Some broken preprocessors need a second expansion
 // to be forced to tokenize __VA_ARGS__
 #define E1(x) x
@@ -112,6 +126,11 @@
 
 #include "libm.h"
 
+#if defined(_MSC_VER)
+#pragma comment(linker, "/include:"EXTERN_PREFIX"avpriv_strtod")
+#pragma comment(linker, "/include:"EXTERN_PREFIX"avpriv_snprintf")
+#endif
+
 /**
  * Return NULL if CONFIG_SMALL is true, otherwise the argument
  * without modification. Used to disable the definition of strings
@@ -183,4 +202,13 @@
 void avpriv_request_sample(void *avc,
                            const char *msg, ...) av_printf_format(2, 3);
 
+#if HAVE_MSVCRT
+#define avpriv_open ff_open
+#endif
+
+/**
+ * A wrapper for open() setting O_CLOEXEC.
+ */
+int avpriv_open(const char *filename, int flags, ...);
+
 #endif /* AVUTIL_INTERNAL_H */
diff --git a/libavutil/lls.c b/libavutil/lls.c
index a27c7ae..abed8ef 100644
--- a/libavutil/lls.c
+++ b/libavutil/lls.c
@@ -28,22 +28,16 @@
 #include <math.h>
 #include <string.h>
 
+#include "attributes.h"
 #include "version.h"
 #include "lls.h"
 
-void avpriv_init_lls(LLSModel *m, int indep_count)
-{
-    memset(m, 0, sizeof(LLSModel));
-    m->indep_count = indep_count;
-}
-
-void avpriv_update_lls(LLSModel *m, double *var, double decay)
+static void update_lls(LLSModel *m, double *var)
 {
     int i, j;
 
     for (i = 0; i <= m->indep_count; i++) {
         for (j = i; j <= m->indep_count; j++) {
-            m->covariance[i][j] *= decay;
             m->covariance[i][j] += var[i] * var[j];
         }
     }
@@ -52,8 +46,8 @@
 void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order)
 {
     int i, j, k;
-    double (*factor)[MAX_VARS + 1] = (void *) &m->covariance[1][0];
-    double (*covar) [MAX_VARS + 1] = (void *) &m->covariance[1][1];
+    double (*factor)[MAX_VARS_ALIGN] = (void *) &m->covariance[1][0];
+    double (*covar) [MAX_VARS_ALIGN] = (void *) &m->covariance[1][1];
     double *covar_y                = m->covariance[0];
     int count                      = m->indep_count;
 
@@ -106,7 +100,7 @@
     }
 }
 
-double avpriv_evaluate_lls(LLSModel *m, double *param, int order)
+static double evaluate_lls(LLSModel *m, double *param, int order)
 {
     int i;
     double out = 0;
@@ -117,14 +111,24 @@
     return out;
 }
 
+av_cold void avpriv_init_lls(LLSModel *m, int indep_count)
+{
+    memset(m, 0, sizeof(LLSModel));
+    m->indep_count = indep_count;
+    m->update_lls = update_lls;
+    m->evaluate_lls = evaluate_lls;
+    if (ARCH_X86)
+        ff_init_lls_x86(m);
+}
+
 #if FF_API_LLS_PRIVATE
-void av_init_lls(LLSModel *m, int indep_count)
+av_cold void av_init_lls(LLSModel *m, int indep_count)
 {
     avpriv_init_lls(m, indep_count);
 }
 void av_update_lls(LLSModel *m, double *param, double decay)
 {
-    avpriv_update_lls(m, param, decay);
+    m->update_lls(m, param);
 }
 void av_solve_lls(LLSModel *m, double threshold, int min_order)
 {
@@ -132,7 +136,7 @@
 }
 double av_evaluate_lls(LLSModel *m, double *param, int order)
 {
-    return avpriv_evaluate_lls(m, param, order);
+    return m->evaluate_lls(m, param, order);
 }
 #endif /* FF_API_LLS_PRIVATE */
 
@@ -152,17 +156,17 @@
     avpriv_init_lls(&m, 3);
 
     for (i = 0; i < 100; i++) {
-        double var[4];
+        LOCAL_ALIGNED(32, double, var, [4]);
         double eval;
 
         var[0] = (av_lfg_get(&lfg) / (double) UINT_MAX - 0.5) * 2;
         var[1] = var[0] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5;
         var[2] = var[1] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5;
         var[3] = var[2] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5;
-        avpriv_update_lls(&m, var, 0.99);
+        m.update_lls(&m, var);
         avpriv_solve_lls(&m, 0.001, 0);
         for (order = 0; order < 3; order++) {
-            eval = avpriv_evaluate_lls(&m, var + 1, order);
+            eval = m.evaluate_lls(&m, var + 1, order);
             printf("real:%9f order:%d pred:%9f var:%f coeffs:%f %9f %9f\n",
                    var[0], order, eval, sqrt(m.variance[order] / (i + 1)),
                    m.coeff[order][0], m.coeff[order][1],
diff --git a/libavutil/lls.h b/libavutil/lls.h
index c785d44..c62d78a 100644
--- a/libavutil/lls.h
+++ b/libavutil/lls.h
@@ -23,9 +23,12 @@
 #ifndef AVUTIL_LLS_H
 #define AVUTIL_LLS_H
 
+#include "common.h"
+#include "mem.h"
 #include "version.h"
 
 #define MAX_VARS 32
+#define MAX_VARS_ALIGN FFALIGN(MAX_VARS+1,4)
 
 //FIXME avoid direct access to LLSModel from outside
 
@@ -33,16 +36,30 @@
  * Linear least squares model.
  */
 typedef struct LLSModel {
-    double covariance[MAX_VARS + 1][MAX_VARS + 1];
-    double coeff[MAX_VARS][MAX_VARS];
+    DECLARE_ALIGNED(32, double, covariance[MAX_VARS_ALIGN][MAX_VARS_ALIGN]);
+    DECLARE_ALIGNED(32, double, coeff[MAX_VARS][MAX_VARS]);
     double variance[MAX_VARS];
     int indep_count;
+    /**
+     * Take the outer-product of var[] with itself, and add to the covariance matrix.
+     * @param m this context
+     * @param var training samples, starting with the value to be predicted
+     *            32-byte aligned, and any padding elements must be initialized
+     *            (i.e not denormal/nan).
+     */
+    void (*update_lls)(struct LLSModel *m, double *var);
+    /**
+     * Inner product of var[] and the LPC coefs.
+     * @param m this context
+     * @param var training samples, excluding the value to be predicted. unaligned.
+     * @param order lpc order
+     */
+    double (*evaluate_lls)(struct LLSModel *m, double *var, int order);
 } LLSModel;
 
 void avpriv_init_lls(LLSModel *m, int indep_count);
-void avpriv_update_lls(LLSModel *m, double *param, double decay);
+void ff_init_lls_x86(LLSModel *m);
 void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order);
-double avpriv_evaluate_lls(LLSModel *m, double *param, int order);
 
 #if FF_API_LLS_PRIVATE
 void av_init_lls(LLSModel *m, int indep_count);
diff --git a/libavutil/log.c b/libavutil/log.c
index 56eeff9..53be3ea 100644
--- a/libavutil/log.c
+++ b/libavutil/log.c
@@ -35,6 +35,7 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include "avutil.h"
+#include "bprint.h"
 #include "common.h"
 #include "internal.h"
 #include "log.h"
@@ -168,37 +169,44 @@
 }
 
 static void format_line(void *ptr, int level, const char *fmt, va_list vl,
-                        char part[3][LINE_SZ], int part_size, int *print_prefix, int type[2])
+                        AVBPrint part[3], int *print_prefix, int type[2])
 {
     AVClass* avc = ptr ? *(AVClass **) ptr : NULL;
-    part[0][0] = part[1][0] = part[2][0] = 0;
+    av_bprint_init(part+0, 0, 1);
+    av_bprint_init(part+1, 0, 1);
+    av_bprint_init(part+2, 0, 65536);
+
     if(type) type[0] = type[1] = AV_CLASS_CATEGORY_NA + 16;
     if (*print_prefix && avc) {
         if (avc->parent_log_context_offset) {
             AVClass** parent = *(AVClass ***) (((uint8_t *) ptr) +
                                    avc->parent_log_context_offset);
             if (parent && *parent) {
-                snprintf(part[0], part_size, "[%s @ %p] ",
+                av_bprintf(part+0, "[%s @ %p] ",
                          (*parent)->item_name(parent), parent);
                 if(type) type[0] = get_category(parent);
             }
         }
-        snprintf(part[1], part_size, "[%s @ %p] ",
+        av_bprintf(part+1, "[%s @ %p] ",
                  avc->item_name(ptr), ptr);
         if(type) type[1] = get_category(ptr);
     }
 
-    vsnprintf(part[2], part_size, fmt, vl);
+    av_vbprintf(part+2, fmt, vl);
 
-    *print_prefix = strlen(part[2]) && part[2][strlen(part[2]) - 1] == '\n';
+    if(*part[0].str || *part[1].str || *part[2].str) {
+        char lastc = part[2].len ? part[2].str[part[2].len - 1] : 0;
+        *print_prefix = lastc == '\n' || lastc == '\r';
+    }
 }
 
 void av_log_format_line(void *ptr, int level, const char *fmt, va_list vl,
                         char *line, int line_size, int *print_prefix)
 {
-    char part[3][LINE_SZ];
-    format_line(ptr, level, fmt, vl, part, sizeof(part[0]), print_prefix, NULL);
-    snprintf(line, line_size, "%s%s%s", part[0], part[1], part[2]);
+    AVBPrint part[3];
+    format_line(ptr, level, fmt, vl, part, print_prefix, NULL);
+    snprintf(line, line_size, "%s%s%s", part[0].str, part[1].str, part[2].str);
+    av_bprint_finalize(part+2, NULL);
 }
 
 void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl)
@@ -206,25 +214,27 @@
     static int print_prefix = 1;
     static int count;
     static char prev[LINE_SZ];
-    char part[3][LINE_SZ];
+    AVBPrint part[3];
     char line[LINE_SZ];
     static int is_atty;
     int type[2];
 
     if (level > av_log_level)
         return;
-    format_line(ptr, level, fmt, vl, part, sizeof(part[0]), &print_prefix, type);
-    snprintf(line, sizeof(line), "%s%s%s", part[0], part[1], part[2]);
+    format_line(ptr, level, fmt, vl, part, &print_prefix, type);
+    snprintf(line, sizeof(line), "%s%s%s", part[0].str, part[1].str, part[2].str);
 
 #if HAVE_ISATTY
     if (!is_atty)
         is_atty = isatty(2) ? 1 : -1;
 #endif
 
-    if (print_prefix && (flags & AV_LOG_SKIP_REPEATED) && !strcmp(line, prev)){
+    if (print_prefix && (flags & AV_LOG_SKIP_REPEATED) && !strcmp(line, prev) &&
+        *line && line[strlen(line) - 1] != '\r'){
         count++;
         if (is_atty == 1)
             fprintf(stderr, "    Last message repeated %d times\r", count);
+        av_bprint_finalize(part+2, NULL);
         return;
     }
     if (count > 0) {
@@ -232,12 +242,13 @@
         count = 0;
     }
     strcpy(prev, line);
-    sanitize(part[0]);
-    colored_fputs(type[0], part[0]);
-    sanitize(part[1]);
-    colored_fputs(type[1], part[1]);
-    sanitize(part[2]);
-    colored_fputs(av_clip(level >> 3, 0, 6), part[2]);
+    sanitize(part[0].str);
+    colored_fputs(type[0], part[0].str);
+    sanitize(part[1].str);
+    colored_fputs(type[1], part[1].str);
+    sanitize(part[2].str);
+    colored_fputs(av_clip(level >> 3, 0, 6), part[2].str);
+    av_bprint_finalize(part+2, NULL);
 }
 
 static void (*av_log_callback)(void*, int, const char*, va_list) =
@@ -281,7 +292,8 @@
     av_log_callback = callback;
 }
 
-static void missing_feature_sample(int sample, void *avc, const char *msg, va_list argument_list)
+static void missing_feature_sample(int sample, void *avc, const char *msg,
+                                   va_list argument_list)
 {
     av_vlog(avc, AV_LOG_WARNING, msg, argument_list);
     av_log(avc, AV_LOG_WARNING, " is not implemented. Update your FFmpeg "
diff --git a/libavutil/md5.c b/libavutil/md5.c
index f8f08f1..63fc37d 100644
--- a/libavutil/md5.c
+++ b/libavutil/md5.c
@@ -83,50 +83,56 @@
         a += T[i];                                                      \
                                                                         \
         if (i < 32) {                                                   \
-            if (i < 16) a += (d ^ (b & (c ^ d))) + X[       i  & 15];   \
-            else        a += (c ^ (d & (c ^ b))) + X[(1 + 5*i) & 15];   \
+            if (i < 16) a += (d ^ (b & (c ^ d)))  + X[       i  & 15];  \
+            else        a += ((d & b) | (~d & c)) + X[(1 + 5*i) & 15];  \
         } else {                                                        \
-            if (i < 48) a += (b ^ c ^ d)         + X[(5 + 3*i) & 15];   \
-            else        a += (c ^ (b | ~d))      + X[(    7*i) & 15];   \
+            if (i < 48) a += (b ^ c ^ d)          + X[(5 + 3*i) & 15];  \
+            else        a += (c ^ (b | ~d))       + X[(    7*i) & 15];  \
         }                                                               \
         a = b + (a << t | a >> (32 - t));                               \
     } while (0)
 
-static void body(uint32_t ABCD[4], uint32_t X[16])
+static void body(uint32_t ABCD[4], uint32_t *src, int nblocks)
 {
     int i av_unused;
-    uint32_t t;
-    uint32_t a = ABCD[3];
-    uint32_t b = ABCD[2];
-    uint32_t c = ABCD[1];
-    uint32_t d = ABCD[0];
+    int n;
+    uint32_t a, b, c, d, t, *X;
+
+    for (n = 0; n < nblocks; n++) {
+        a = ABCD[3];
+        b = ABCD[2];
+        c = ABCD[1];
+        d = ABCD[0];
+
+        X = src + n * 16;
 
 #if HAVE_BIGENDIAN
-    for (i = 0; i < 16; i++)
-        X[i] = av_bswap32(X[i]);
+        for (i = 0; i < 16; i++)
+            X[i] = av_bswap32(X[i]);
 #endif
 
 #if CONFIG_SMALL
-    for (i = 0; i < 64; i++) {
-        CORE(i, a, b, c, d);
-        t = d;
-        d = c;
-        c = b;
-        b = a;
-        a = t;
-    }
+        for (i = 0; i < 64; i++) {
+            CORE(i, a, b, c, d);
+            t = d;
+            d = c;
+            c = b;
+            b = a;
+            a = t;
+        }
 #else
 #define CORE2(i)                                                        \
-    CORE( i,   a,b,c,d); CORE((i+1),d,a,b,c);                           \
-    CORE((i+2),c,d,a,b); CORE((i+3),b,c,d,a)
+        CORE( i,   a,b,c,d); CORE((i+1),d,a,b,c);                       \
+        CORE((i+2),c,d,a,b); CORE((i+3),b,c,d,a)
 #define CORE4(i) CORE2(i); CORE2((i+4)); CORE2((i+8)); CORE2((i+12))
-    CORE4(0); CORE4(16); CORE4(32); CORE4(48);
+        CORE4(0); CORE4(16); CORE4(32); CORE4(48);
 #endif
 
-    ABCD[0] += d;
-    ABCD[1] += c;
-    ABCD[2] += b;
-    ABCD[3] += a;
+        ABCD[0] += d;
+        ABCD[1] += c;
+        ABCD[2] += b;
+        ABCD[3] += a;
+    }
 }
 
 void av_md5_init(AVMD5 *ctx)
@@ -139,20 +145,39 @@
     ctx->ABCD[3] = 0x67452301;
 }
 
-void av_md5_update(AVMD5 *ctx, const uint8_t *src, const int len)
+void av_md5_update(AVMD5 *ctx, const uint8_t *src, int len)
 {
-    int i, j;
+    const uint8_t *end;
+    int j;
 
     j = ctx->len & 63;
     ctx->len += len;
 
-    for (i = 0; i < len; i++) {
-        ctx->block[j++] = src[i];
-        if (j == 64) {
-            body(ctx->ABCD, (uint32_t *) ctx->block);
-            j = 0;
-        }
+    if (j) {
+        int cnt = FFMIN(len, 64 - j);
+        memcpy(ctx->block + j, src, cnt);
+        src += cnt;
+        len -= cnt;
+        if (j + cnt < 64)
+            return;
+        body(ctx->ABCD, (uint32_t *)ctx->block, 1);
     }
+
+    end = src + (len & ~63);
+    if (HAVE_BIGENDIAN || (!HAVE_FAST_UNALIGNED && ((intptr_t)src & 3))) {
+       while (src < end) {
+           memcpy(ctx->block, src, 64);
+           body(ctx->ABCD, (uint32_t *) ctx->block, 1);
+           src += 64;
+        }
+    } else {
+        int nblocks = len / 64;
+        body(ctx->ABCD, (uint32_t *)src, nblocks);
+        src = end;
+    }
+    len &= 63;
+    if (len > 0)
+        memcpy(ctx->block, src, len);
 }
 
 void av_md5_final(AVMD5 *ctx, uint8_t *dst)
diff --git a/libavutil/md5.h b/libavutil/md5.h
index 1d7be9f..79702c8 100644
--- a/libavutil/md5.h
+++ b/libavutil/md5.h
@@ -36,10 +36,42 @@
 
 struct AVMD5;
 
+/**
+ * Allocate an AVMD5 context.
+ */
 struct AVMD5 *av_md5_alloc(void);
+
+/**
+ * Initialize MD5 hashing.
+ *
+ * @param ctx pointer to the function context (of size av_md5_size)
+ */
 void av_md5_init(struct AVMD5 *ctx);
-void av_md5_update(struct AVMD5 *ctx, const uint8_t *src, const int len);
+
+/**
+ * Update hash value.
+ *
+ * @param ctx hash function context
+ * @param src input data to update hash with
+ * @param len input data length
+ */
+void av_md5_update(struct AVMD5 *ctx, const uint8_t *src, int len);
+
+/**
+ * Finish hashing and output digest value.
+ *
+ * @param ctx hash function context
+ * @param dst buffer where output digest value is stored
+ */
 void av_md5_final(struct AVMD5 *ctx, uint8_t *dst);
+
+/**
+ * Hash an array of data.
+ *
+ * @param dst The output buffer to write the digest into
+ * @param src The data to hash
+ * @param len The length of the data, in bytes
+ */
 void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len);
 
 /**
diff --git a/libavutil/mem.c b/libavutil/mem.c
index 860c011..20dfd62 100644
--- a/libavutil/mem.c
+++ b/libavutil/mem.c
@@ -133,7 +133,7 @@
     }
 #if CONFIG_MEMORY_POISONING
     if (ptr)
-        memset(ptr, 0x2a, size);
+        memset(ptr, FF_MEMORY_POISON, size);
 #endif
     return ptr;
 }
@@ -180,6 +180,22 @@
     return r;
 }
 
+void *av_realloc_array(void *ptr, size_t nmemb, size_t size)
+{
+    if (size <= 0 || nmemb >= INT_MAX / size)
+        return NULL;
+    return av_realloc(ptr, nmemb * size);
+}
+
+int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
+{
+    void **ptrptr = ptr;
+    *ptrptr = av_realloc_f(*ptrptr, nmemb, size);
+    if (!*ptrptr && nmemb && size)
+        return AVERROR(ENOMEM);
+    return 0;
+}
+
 void av_free(void *ptr)
 {
 #if CONFIG_MEMALIGN_HACK
@@ -229,7 +245,17 @@
     return ptr;
 }
 
-/* add one element to a dynamic array */
+void *av_memdup(const void *p, size_t size)
+{
+    void *ptr = NULL;
+    if (p) {
+        ptr = av_malloc(size);
+        if (ptr)
+            memcpy(ptr, p, size);
+    }
+    return ptr;
+}
+
 void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem)
 {
     /* see similar ffmpeg.c:grow_array() */
@@ -239,15 +265,58 @@
     nb = *nb_ptr;
     tab = *(intptr_t**)tab_ptr;
     if ((nb & (nb - 1)) == 0) {
-        if (nb == 0)
+        if (nb == 0) {
             nb_alloc = 1;
-        else
+        } else {
+            if (nb > INT_MAX / (2 * sizeof(intptr_t)))
+                goto fail;
             nb_alloc = nb * 2;
+        }
         tab = av_realloc(tab, nb_alloc * sizeof(intptr_t));
+        if (!tab)
+            goto fail;
         *(intptr_t**)tab_ptr = tab;
     }
     tab[nb++] = (intptr_t)elem;
     *nb_ptr = nb;
+    return;
+
+fail:
+    av_freep(tab_ptr);
+    *nb_ptr = 0;
+}
+
+void *av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size,
+                       const uint8_t *elem_data)
+{
+    int nb = *nb_ptr, nb_alloc;
+    uint8_t *tab = *tab_ptr, *tab_elem_data;
+
+    if ((nb & (nb - 1)) == 0) {
+        if (nb == 0) {
+            nb_alloc = 1;
+        } else {
+            if (nb > INT_MAX / (2 * elem_size))
+                goto fail;
+            nb_alloc = nb * 2;
+        }
+        tab = av_realloc(tab, nb_alloc * elem_size);
+        if (!tab)
+            goto fail;
+        *tab_ptr = tab;
+    }
+    *nb_ptr = nb + 1;
+    tab_elem_data = tab + nb*elem_size;
+    if (elem_data)
+        memcpy(tab_elem_data, elem_data, elem_size);
+    else if (CONFIG_MEMORY_POISONING)
+        memset(tab_elem_data, FF_MEMORY_POISON, elem_size);
+    return tab_elem_data;
+
+fail:
+    av_freep(tab_ptr);
+    *nb_ptr = 0;
+    return NULL;
 }
 
 static void fill16(uint8_t *dst, int len)
diff --git a/libavutil/mem.h b/libavutil/mem.h
index ced9453..fb23a69 100644
--- a/libavutil/mem.h
+++ b/libavutil/mem.h
@@ -123,6 +123,32 @@
 void *av_realloc_f(void *ptr, size_t nelem, size_t elsize);
 
 /**
+ * Allocate or reallocate an array.
+ * If ptr is NULL and nmemb > 0, allocate a new block. If
+ * nmemb is zero, free the memory block pointed to by ptr.
+ * @param ptr Pointer to a memory block already allocated with
+ * av_malloc(z)() or av_realloc() or NULL.
+ * @param nmemb Number of elements
+ * @param size Size of the single element
+ * @return Pointer to a newly reallocated block or NULL if the block
+ * cannot be reallocated or the function is used to free the memory block.
+ */
+av_alloc_size(2, 3) void *av_realloc_array(void *ptr, size_t nmemb, size_t size);
+
+/**
+ * Allocate or reallocate an array.
+ * If *ptr is NULL and nmemb > 0, allocate a new block. If
+ * nmemb is zero, free the memory block pointed to by ptr.
+ * @param ptr Pointer to a pointer to a memory block already allocated
+ * with av_malloc(z)() or av_realloc(), or pointer to a pointer to NULL.
+ * The pointer is updated on success, or freed on failure.
+ * @param nmemb Number of elements
+ * @param size Size of the single element
+ * @return Zero on success, an AVERROR error code on failure.
+ */
+av_alloc_size(2, 3) int av_reallocp_array(void *ptr, size_t nmemb, size_t size);
+
+/**
  * Free a memory block which has been allocated with av_malloc(z)() or
  * av_realloc().
  * @param ptr Pointer to the memory block which should be freed.
@@ -180,6 +206,14 @@
 char *av_strdup(const char *s) av_malloc_attrib;
 
 /**
+ * Duplicate the buffer p.
+ * @param p buffer to be duplicated
+ * @return Pointer to a newly allocated buffer containing a
+ * copy of p or NULL if the buffer cannot be allocated.
+ */
+void *av_memdup(const void *p, size_t size);
+
+/**
  * Free a memory block which has been allocated with av_malloc(z)() or
  * av_realloc() and set the pointer pointing to it to NULL.
  * @param ptr Pointer to the pointer to the memory block which should
@@ -191,13 +225,51 @@
 /**
  * Add an element to a dynamic array.
  *
- * @param tab_ptr Pointer to the array.
- * @param nb_ptr  Pointer to the number of elements in the array.
- * @param elem    Element to be added.
+ * The array to grow is supposed to be an array of pointers to
+ * structures, and the element to add must be a pointer to an already
+ * allocated structure.
+ *
+ * The array is reallocated when its size reaches powers of 2.
+ * Therefore, the amortized cost of adding an element is constant.
+ *
+ * In case of success, the pointer to the array is updated in order to
+ * point to the new grown array, and the number pointed to by nb_ptr
+ * is incremented.
+ * In case of failure, the array is freed, *tab_ptr is set to NULL and
+ * *nb_ptr is set to 0.
+ *
+ * @param tab_ptr pointer to the array to grow
+ * @param nb_ptr  pointer to the number of elements in the array
+ * @param elem    element to add
+ * @see av_dynarray2_add()
  */
 void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem);
 
 /**
+ * Add an element of size elem_size to a dynamic array.
+ *
+ * The array is reallocated when its number of elements reaches powers of 2.
+ * Therefore, the amortized cost of adding an element is constant.
+ *
+ * In case of success, the pointer to the array is updated in order to
+ * point to the new grown array, and the number pointed to by nb_ptr
+ * is incremented.
+ * In case of failure, the array is freed, *tab_ptr is set to NULL and
+ * *nb_ptr is set to 0.
+ *
+ * @param tab_ptr   pointer to the array to grow
+ * @param nb_ptr    pointer to the number of elements in the array
+ * @param elem_size size in bytes of the elements in the array
+ * @param elem_data pointer to the data of the element to add. If NULL, the space of
+ *                  the new added element is not filled.
+ * @return          pointer to the data of the element to copy in the new allocated space.
+ *                  If NULL, the new allocated space is left uninitialized."
+ * @see av_dynarray_add()
+ */
+void *av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size,
+                       const uint8_t *elem_data);
+
+/**
  * Multiply two size_t values checking for overflow.
  * @return  0 if success, AVERROR(EINVAL) if overflow.
  */
diff --git a/libavutil/murmur3.c b/libavutil/murmur3.c
new file mode 100644
index 0000000..701fa6a
--- /dev/null
+++ b/libavutil/murmur3.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2013 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
+ *
+ * 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
+ */
+#include <stdint.h>
+#include "mem.h"
+#include "intreadwrite.h"
+#include "murmur3.h"
+
+typedef struct AVMurMur3 {
+    uint64_t h1, h2;
+    uint8_t state[16];
+    int state_pos;
+    uint64_t len;
+} AVMurMur3;
+
+AVMurMur3 *av_murmur3_alloc(void)
+{
+    return av_mallocz(sizeof(AVMurMur3));
+}
+
+void av_murmur3_init_seeded(AVMurMur3 *c, uint64_t seed)
+{
+    memset(c, 0, sizeof(*c));
+    c->h1 = c->h2 = seed;
+}
+
+void av_murmur3_init(AVMurMur3 *c)
+{
+    // arbitrary random number as seed
+    av_murmur3_init_seeded(c, 0x725acc55daddca55);
+}
+
+static const uint64_t c1 = UINT64_C(0x87c37b91114253d5);
+static const uint64_t c2 = UINT64_C(0x4cf5ad432745937f);
+
+#define ROT(a, b) ((a << b) | (a >> (64 - b)))
+
+static uint64_t inline get_k1(const uint8_t *src)
+{
+    uint64_t k = AV_RL64(src);
+    k *= c1;
+    k = ROT(k, 31);
+    k *= c2;
+    return k;
+}
+
+static uint64_t inline get_k2(const uint8_t *src)
+{
+    uint64_t k = AV_RL64(src + 8);
+    k *= c2;
+    k = ROT(k, 33);
+    k *= c1;
+    return k;
+}
+
+static uint64_t inline update_h1(uint64_t k, uint64_t h1, uint64_t h2)
+{
+    k ^= h1;
+    k = ROT(k, 27);
+    k += h2;
+    k *= 5;
+    k += 0x52dce729;
+    return k;
+}
+
+static uint64_t inline update_h2(uint64_t k, uint64_t h1, uint64_t h2)
+{
+    k ^= h2;
+    k = ROT(k, 31);
+    k += h1;
+    k *= 5;
+    k += 0x38495ab5;
+    return k;
+}
+
+void av_murmur3_update(AVMurMur3 *c, const uint8_t *src, int len)
+{
+    const uint8_t *end;
+    uint64_t h1 = c->h1, h2 = c->h2;
+    uint64_t k1, k2;
+    if (len <= 0) return;
+    c->len += len;
+    if (c->state_pos > 0) {
+        while (c->state_pos < 16) {
+            c->state[c->state_pos++] = *src++;
+            if (--len <= 0) return;
+        }
+        c->state_pos = 0;
+        k1 = get_k1(c->state);
+        k2 = get_k2(c->state);
+        h1 = update_h1(k1, h1, h2);
+        h2 = update_h2(k2, h1, h2);
+    }
+
+    end = src + (len & ~15);
+    while (src < end) {
+        // These could be done sequentially instead
+        // of interleaved, but like this is over 10% faster
+        k1 = get_k1(src);
+        k2 = get_k2(src);
+        h1 = update_h1(k1, h1, h2);
+        h2 = update_h2(k2, h1, h2);
+        src += 16;
+    }
+    c->h1 = h1;
+    c->h2 = h2;
+
+    len &= 15;
+    if (len > 0) {
+        memcpy(c->state, src, len);
+        c->state_pos = len;
+    }
+}
+
+static inline uint64_t fmix(uint64_t k)
+{
+    k ^= k >> 33;
+    k *= UINT64_C(0xff51afd7ed558ccd);
+    k ^= k >> 33;
+    k *= UINT64_C(0xc4ceb9fe1a85ec53);
+    k ^= k >> 33;
+    return k;
+}
+
+void av_murmur3_final(AVMurMur3 *c, uint8_t dst[16])
+{
+    uint64_t h1 = c->h1, h2 = c->h2;
+    memset(c->state + c->state_pos, 0, sizeof(c->state) - c->state_pos);
+    h1 ^= get_k1(c->state) ^ c->len;
+    h2 ^= get_k2(c->state) ^ c->len;
+    h1 += h2;
+    h2 += h1;
+    h1 = fmix(h1);
+    h2 = fmix(h2);
+    h1 += h2;
+    h2 += h1;
+    AV_WL64(dst, h1);
+    AV_WL64(dst + 8, h2);
+}
+
+#ifdef TEST
+int main(void)
+{
+    int i;
+    uint8_t hash_result[16] = {0};
+    AVMurMur3 *ctx = av_murmur3_alloc();
+#if 1
+    uint8_t in[256] = {0};
+    uint8_t *hashes = av_mallocz(256 * 16);
+    for (i = 0; i < 256; i++)
+    {
+        in[i] = i;
+        av_murmur3_init_seeded(ctx, 256 - i);
+        // Note: this actually tests hashing 0 bytes
+        av_murmur3_update(ctx, in, i);
+        av_murmur3_final(ctx, hashes + 16 * i);
+    }
+    av_murmur3_init_seeded(ctx, 0);
+    av_murmur3_update(ctx, hashes, 256 * 16);
+    av_murmur3_final(ctx, hash_result);
+    av_free(hashes);
+    av_freep(&ctx);
+    printf("result: 0x%"PRIx64" 0x%"PRIx64"\n", AV_RL64(hash_result), AV_RL64(hash_result + 8));
+    // official reference value is 32 bit
+    return AV_RL32(hash_result) != 0x6384ba69;
+#else
+    uint8_t *in = av_mallocz(512*1024);
+    av_murmur3_init(ctx);
+    for (i = 0; i < 40*1024; i++)
+        av_murmur3_update(ctx, in, 512*1024);
+    av_murmur3_final(ctx, hash_result);
+    av_free(in);
+    return hash_result[0];
+#endif
+}
+#endif
diff --git a/libavutil/murmur3.h b/libavutil/murmur3.h
new file mode 100644
index 0000000..f29ed97
--- /dev/null
+++ b/libavutil/murmur3.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2013 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
+ *
+ * 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
+ */
+
+#ifndef AVUTIL_MURMUR3_H
+#define AVUTIL_MURMUR3_H
+
+#include <stdint.h>
+
+struct AVMurMur3 *av_murmur3_alloc(void);
+void av_murmur3_init_seeded(struct AVMurMur3 *c, uint64_t seed);
+void av_murmur3_init(struct AVMurMur3 *c);
+void av_murmur3_update(struct AVMurMur3 *c, const uint8_t *src, int len);
+void av_murmur3_final(struct AVMurMur3 *c, uint8_t dst[16]);
+
+#endif /* AVUTIL_MURMUR3_H */
diff --git a/libavutil/old_pix_fmts.h b/libavutil/old_pix_fmts.h
index 57b6992..3ee8aec 100644
--- a/libavutil/old_pix_fmts.h
+++ b/libavutil/old_pix_fmts.h
@@ -67,11 +67,13 @@
     PIX_FMT_YUV440P,   ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
     PIX_FMT_YUVJ440P,  ///< planar YUV 4:4:0 full scale (JPEG), deprecated in favor of PIX_FMT_YUV440P and setting color_range
     PIX_FMT_YUVA420P,  ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
+#if FF_API_VDPAU
     PIX_FMT_VDPAU_H264,///< H.264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
     PIX_FMT_VDPAU_MPEG1,///< MPEG-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
     PIX_FMT_VDPAU_MPEG2,///< MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
     PIX_FMT_VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
     PIX_FMT_VDPAU_VC1, ///< VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+#endif
     PIX_FMT_RGB48BE,   ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian
     PIX_FMT_RGB48LE,   ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian
 
@@ -95,7 +97,9 @@
     PIX_FMT_YUV422P16BE,  ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
     PIX_FMT_YUV444P16LE,  ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
     PIX_FMT_YUV444P16BE,  ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+#if FF_API_VDPAU
     PIX_FMT_VDPAU_MPEG4,  ///< MPEG4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+#endif
     PIX_FMT_DXVA2_VLD,    ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer
 
     PIX_FMT_RGB444LE,  ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), little-endian, most significant bits to 0
diff --git a/libavutil/opencl.c b/libavutil/opencl.c
index 1fdb096..5887b50 100644
--- a/libavutil/opencl.c
+++ b/libavutil/opencl.c
@@ -31,8 +31,8 @@
 #include <pthread.h>
 static pthread_mutex_t atomic_opencl_lock = PTHREAD_MUTEX_INITIALIZER;
 
-#define LOCK_OPENCL pthread_mutex_lock(&atomic_opencl_lock);
-#define UNLOCK_OPENCL pthread_mutex_unlock(&atomic_opencl_lock);
+#define LOCK_OPENCL pthread_mutex_lock(&atomic_opencl_lock)
+#define UNLOCK_OPENCL pthread_mutex_unlock(&atomic_opencl_lock)
 
 #elif !HAVE_THREADS
 #define LOCK_OPENCL
@@ -81,6 +81,7 @@
      { "platform_idx",        "set platform index value",  OFFSET(platform_idx),  AV_OPT_TYPE_INT,    {.i64=-1}, -1, INT_MAX},
      { "device_idx",          "set device index value",    OFFSET(device_idx),    AV_OPT_TYPE_INT,    {.i64=-1}, -1, INT_MAX},
      { "build_options",       "build options of opencl",   OFFSET(build_options), AV_OPT_TYPE_STRING, {.str="-I."},  CHAR_MIN, CHAR_MAX},
+     { NULL }
 };
 
 static const AVClass openclutils_class = {
@@ -162,7 +163,7 @@
     {CL_INVALID_DEVICE_PARTITION_COUNT,                 "INVALID DEVICE PARTITION COUNT"},
 };
 
-static const char *opencl_errstr(cl_int status)
+const char *av_opencl_errstr(cl_int status)
 {
     int i;
     for (i = 0; i < sizeof(opencl_err_msg); i++) {
@@ -201,7 +202,7 @@
     status = clGetPlatformIDs(0, NULL, &device_list->platform_num);
     if (status != CL_SUCCESS) {
         av_log(&opencl_ctx, AV_LOG_ERROR,
-               "Could not get OpenCL platform ids: %s\n", opencl_errstr(status));
+               "Could not get OpenCL platform ids: %s\n", av_opencl_errstr(status));
         return AVERROR_EXTERNAL;
     }
     platform_ids = av_mallocz(device_list->platform_num * sizeof(cl_platform_id));
@@ -210,7 +211,7 @@
     status = clGetPlatformIDs(device_list->platform_num, platform_ids, NULL);
     if (status != CL_SUCCESS) {
         av_log(&opencl_ctx, AV_LOG_ERROR,
-                "Could not get OpenCL platform ids: %s\n", opencl_errstr(status));
+                "Could not get OpenCL platform ids: %s\n", av_opencl_errstr(status));
         ret = AVERROR_EXTERNAL;
         goto end;
     }
@@ -256,7 +257,7 @@
                                         devices_num[j], device_ids, NULL);
                 if (status != CL_SUCCESS) {
                     av_log(&opencl_ctx, AV_LOG_WARNING,
-                            "Could not get device ID: %s:\n", opencl_errstr(status));
+                            "Could not get device ID: %s:\n", av_opencl_errstr(status));
                     av_freep(&device_ids);
                     continue;
                 }
@@ -275,7 +276,7 @@
                                              NULL);
                     if (status != CL_SUCCESS) {
                         av_log(&opencl_ctx, AV_LOG_WARNING,
-                                "Could not get device name: %s\n", opencl_errstr(status));
+                                "Could not get device name: %s\n", av_opencl_errstr(status));
                         continue;
                     }
                     device_list->platform_node[i]->device_num++;
@@ -320,31 +321,31 @@
 int av_opencl_set_option(const char *key, const char *val)
 {
     int ret = 0;
-    LOCK_OPENCL
+    LOCK_OPENCL;
     if (!opencl_ctx.opt_init_flag) {
         av_opt_set_defaults(&opencl_ctx);
         opencl_ctx.opt_init_flag = 1;
     }
     ret = av_opt_set(&opencl_ctx, key, val, 0);
-    UNLOCK_OPENCL
+    UNLOCK_OPENCL;
     return ret;
 }
 
 int av_opencl_get_option(const char *key, uint8_t **out_val)
 {
     int ret = 0;
-    LOCK_OPENCL
+    LOCK_OPENCL;
     ret = av_opt_get(&opencl_ctx, key, 0, out_val);
-    UNLOCK_OPENCL
+    UNLOCK_OPENCL;
     return ret;
 }
 
 void av_opencl_free_option(void)
 {
     /*FIXME: free openclutils context*/
-    LOCK_OPENCL
+    LOCK_OPENCL;
     av_opt_free(&opencl_ctx);
-    UNLOCK_OPENCL
+    UNLOCK_OPENCL;
 }
 
 AVOpenCLExternalEnv *av_opencl_alloc_external_env(void)
@@ -416,7 +417,7 @@
                 break;
         }
         if (status != CL_SUCCESS) {
-            av_log(&opencl_ctx, AV_LOG_ERROR, "Could not create OpenCL kernel: %s\n", opencl_errstr(status));
+            av_log(&opencl_ctx, AV_LOG_ERROR, "Could not create OpenCL kernel: %s\n", av_opencl_errstr(status));
             ret = AVERROR_EXTERNAL;
             goto end;
         }
@@ -432,20 +433,20 @@
 void av_opencl_release_kernel(AVOpenCLKernelEnv *env)
 {
     cl_int status;
-    LOCK_OPENCL
+    LOCK_OPENCL;
     if (!env->kernel)
         goto end;
     status = clReleaseKernel(env->kernel);
     if (status != CL_SUCCESS) {
         av_log(&opencl_ctx, AV_LOG_ERROR, "Could not release kernel: %s\n",
-              opencl_errstr(status));
+              av_opencl_errstr(status));
     }
     env->kernel = NULL;
     env->command_queue = NULL;
     env->kernel_name[0] = 0;
     opencl_ctx.kernel_count--;
 end:
-    UNLOCK_OPENCL
+    UNLOCK_OPENCL;
 }
 
 static int init_opencl_env(OpenclContext *opencl_ctx, AVOpenCLExternalEnv *ext_opencl_env)
@@ -526,14 +527,14 @@
                                                        NULL, NULL, &status);
             if (status != CL_SUCCESS) {
                 av_log(opencl_ctx, AV_LOG_ERROR,
-                       "Could not get OpenCL context from device type: %s\n", opencl_errstr(status));
+                       "Could not get OpenCL context from device type: %s\n", av_opencl_errstr(status));
                 return AVERROR_EXTERNAL;
             }
             opencl_ctx->command_queue = clCreateCommandQueue(opencl_ctx->context, opencl_ctx->device_id,
                                                           0, &status);
             if (status != CL_SUCCESS) {
                 av_log(opencl_ctx, AV_LOG_ERROR,
-                       "Could not create OpenCL command queue: %s\n", opencl_errstr(status));
+                       "Could not create OpenCL command queue: %s\n", av_opencl_errstr(status));
                 return AVERROR_EXTERNAL;
             }
         }
@@ -566,7 +567,7 @@
                                                                                 &status);
     if(status != CL_SUCCESS) {
         av_log(opencl_ctx, AV_LOG_ERROR,
-               "Could not create OpenCL program with source code: %s\n", opencl_errstr(status));
+               "Could not create OpenCL program with source code: %s\n", av_opencl_errstr(status));
         return AVERROR_EXTERNAL;
     }
     if (!opencl_ctx->programs[opencl_ctx->program_count]) {
@@ -577,7 +578,7 @@
                             opencl_ctx->build_options, NULL, NULL);
     if (status != CL_SUCCESS) {
         av_log(opencl_ctx, AV_LOG_ERROR,
-               "Could not compile OpenCL kernel: %s\n", opencl_errstr(status));
+               "Could not compile OpenCL kernel: %s\n", av_opencl_errstr(status));
         return AVERROR_EXTERNAL;
     }
     opencl_ctx->program_count++;
@@ -587,7 +588,7 @@
 int av_opencl_init(AVOpenCLExternalEnv *ext_opencl_env)
 {
     int ret = 0;
-    LOCK_OPENCL
+    LOCK_OPENCL;
     if (!opencl_ctx.init_count) {
         if (!opencl_ctx.opt_init_flag) {
             av_opt_set_defaults(&opencl_ctx);
@@ -609,7 +610,7 @@
     opencl_ctx.init_count++;
 
 end:
-    UNLOCK_OPENCL
+    UNLOCK_OPENCL;
     return ret;
 }
 
@@ -617,7 +618,7 @@
 {
     cl_int status;
     int i;
-    LOCK_OPENCL
+    LOCK_OPENCL;
     opencl_ctx.init_count--;
     if (opencl_ctx.is_user_created)
         goto end;
@@ -628,7 +629,7 @@
             status = clReleaseProgram(opencl_ctx.programs[i]);
             if (status != CL_SUCCESS) {
                 av_log(&opencl_ctx, AV_LOG_ERROR,
-                       "Could not release OpenCL program: %s\n", opencl_errstr(status));
+                       "Could not release OpenCL program: %s\n", av_opencl_errstr(status));
             }
             opencl_ctx.programs[i] = NULL;
         }
@@ -637,7 +638,7 @@
         status = clReleaseCommandQueue(opencl_ctx.command_queue);
         if (status != CL_SUCCESS) {
             av_log(&opencl_ctx, AV_LOG_ERROR,
-                   "Could not release OpenCL command queue: %s\n", opencl_errstr(status));
+                   "Could not release OpenCL command queue: %s\n", av_opencl_errstr(status));
         }
         opencl_ctx.command_queue = NULL;
     }
@@ -645,7 +646,7 @@
         status = clReleaseContext(opencl_ctx.context);
         if (status != CL_SUCCESS) {
             av_log(&opencl_ctx, AV_LOG_ERROR,
-                   "Could not release OpenCL context: %s\n", opencl_errstr(status));
+                   "Could not release OpenCL context: %s\n", av_opencl_errstr(status));
         }
         opencl_ctx.context = NULL;
     }
@@ -653,7 +654,7 @@
 end:
     if ((opencl_ctx.init_count <= 0) && (opencl_ctx.kernel_count <= 0))
         av_opt_free(&opencl_ctx); //FIXME: free openclutils context
-    UNLOCK_OPENCL
+    UNLOCK_OPENCL;
 }
 
 int av_opencl_buffer_create(cl_mem *cl_buf, size_t cl_buf_size, int flags, void *host_ptr)
@@ -661,7 +662,7 @@
     cl_int status;
     *cl_buf = clCreateBuffer(opencl_ctx.context, flags, cl_buf_size, host_ptr, &status);
     if (status != CL_SUCCESS) {
-        av_log(&opencl_ctx, AV_LOG_ERROR, "Could not create OpenCL buffer: %s\n", opencl_errstr(status));
+        av_log(&opencl_ctx, AV_LOG_ERROR, "Could not create OpenCL buffer: %s\n", av_opencl_errstr(status));
         return AVERROR_EXTERNAL;
     }
     return 0;
@@ -675,7 +676,7 @@
     status = clReleaseMemObject(*cl_buf);
     if (status != CL_SUCCESS) {
         av_log(&opencl_ctx, AV_LOG_ERROR,
-               "Could not release OpenCL buffer: %s\n", opencl_errstr(status));
+               "Could not release OpenCL buffer: %s\n", av_opencl_errstr(status));
     }
     memset(cl_buf, 0, sizeof(*cl_buf));
 }
@@ -689,7 +690,7 @@
 
     if (status != CL_SUCCESS) {
         av_log(&opencl_ctx, AV_LOG_ERROR,
-               "Could not map OpenCL buffer: %s\n", opencl_errstr(status));
+               "Could not map OpenCL buffer: %s\n", av_opencl_errstr(status));
         return AVERROR_EXTERNAL;
     }
     memcpy(mapped, src_buf, buf_size);
@@ -697,7 +698,7 @@
     status = clEnqueueUnmapMemObject(opencl_ctx.command_queue, dst_cl_buf, mapped, 0, NULL, NULL);
     if (status != CL_SUCCESS) {
         av_log(&opencl_ctx, AV_LOG_ERROR,
-               "Could not unmap OpenCL buffer: %s\n", opencl_errstr(status));
+               "Could not unmap OpenCL buffer: %s\n", av_opencl_errstr(status));
         return AVERROR_EXTERNAL;
     }
     return 0;
@@ -712,7 +713,7 @@
 
     if (status != CL_SUCCESS) {
         av_log(&opencl_ctx, AV_LOG_ERROR,
-               "Could not map OpenCL buffer: %s\n", opencl_errstr(status));
+               "Could not map OpenCL buffer: %s\n", av_opencl_errstr(status));
         return AVERROR_EXTERNAL;
     }
     memcpy(dst_buf, mapped, buf_size);
@@ -720,7 +721,7 @@
     status = clEnqueueUnmapMemObject(opencl_ctx.command_queue, src_cl_buf, mapped, 0, NULL, NULL);
     if (status != CL_SUCCESS) {
         av_log(&opencl_ctx, AV_LOG_ERROR,
-               "Could not unmap OpenCL buffer: %s\n", opencl_errstr(status));
+               "Could not unmap OpenCL buffer: %s\n", av_opencl_errstr(status));
         return AVERROR_EXTERNAL;
     }
     return 0;
@@ -749,7 +750,7 @@
                                 0, NULL, NULL, &status);
     if (status != CL_SUCCESS) {
         av_log(&opencl_ctx, AV_LOG_ERROR,
-               "Could not map OpenCL buffer: %s\n", opencl_errstr(status));
+               "Could not map OpenCL buffer: %s\n", av_opencl_errstr(status));
         return AVERROR_EXTERNAL;
     }
     temp = mapped;
@@ -761,7 +762,7 @@
     status = clEnqueueUnmapMemObject(opencl_ctx.command_queue, dst_cl_buf, mapped, 0, NULL, NULL);
     if (status != CL_SUCCESS) {
         av_log(&opencl_ctx, AV_LOG_ERROR,
-               "Could not unmap OpenCL buffer: %s\n", opencl_errstr(status));
+               "Could not unmap OpenCL buffer: %s\n", av_opencl_errstr(status));
         return AVERROR_EXTERNAL;
     }
     return 0;
@@ -791,7 +792,7 @@
 
     if (status != CL_SUCCESS) {
         av_log(&opencl_ctx, AV_LOG_ERROR,
-               "Could not map OpenCL buffer: %s\n", opencl_errstr(status));
+               "Could not map OpenCL buffer: %s\n", av_opencl_errstr(status));
         return AVERROR_EXTERNAL;
     }
     temp = mapped;
@@ -804,7 +805,7 @@
     status = clEnqueueUnmapMemObject(opencl_ctx.command_queue, src_cl_buf, mapped, 0, NULL, NULL);
     if (status != CL_SUCCESS) {
         av_log(&opencl_ctx, AV_LOG_ERROR,
-               "Could not unmap OpenCL buffer: %s\n", opencl_errstr(status));
+               "Could not unmap OpenCL buffer: %s\n", av_opencl_errstr(status));
         return AVERROR_EXTERNAL;
     }
     return 0;
diff --git a/libavutil/opencl.h b/libavutil/opencl.h
index acafe36..094c108 100644
--- a/libavutil/opencl.h
+++ b/libavutil/opencl.h
@@ -31,8 +31,12 @@
 #ifndef LIBAVUTIL_OPENCL_H
 #define LIBAVUTIL_OPENCL_H
 
-#include <CL/cl.h>
 #include "config.h"
+#if HAVE_CL_CL_H
+#include <CL/cl.h>
+#else
+#include <OpenCL/cl.h>
+#endif
 #include "dict.h"
 
 #define AV_OPENCL_KERNEL( ... )# __VA_ARGS__
@@ -151,6 +155,14 @@
 void av_opencl_free_external_env(AVOpenCLExternalEnv **ext_opencl_env);
 
 /**
+ * Get OpenCL error string.
+ *
+ * @param status    OpenCL error code
+ * @return OpenCL error string
+ */
+const char *av_opencl_errstr(cl_int status);
+
+/**
  * Register kernel code.
  *
  *  The registered kernel code is stored in a global context, and compiled
diff --git a/libavutil/opencl_internal.c b/libavutil/opencl_internal.c
new file mode 100644
index 0000000..3d996ab
--- /dev/null
+++ b/libavutil/opencl_internal.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2012 Peng Gao <peng@multicorewareinc.com>
+ * Copyright (C) 2012 Li   Cao <li@multicorewareinc.com>
+ * Copyright (C) 2012 Wei  Gao <weigao@multicorewareinc.com>
+ *
+ * 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
+ */
+
+#include "opencl_internal.h"
+#include "libavutil/log.h"
+
+int ff_opencl_set_parameter(FFOpenclParam *opencl_param, ...)
+{
+    int ret = 0;
+    va_list arg_ptr;
+    void *param;
+    size_t param_size;
+    cl_int status;
+    if (!opencl_param->kernel) {
+        av_log(opencl_param->ctx, AV_LOG_ERROR, "OpenCL kernel must be set\n");
+        return AVERROR(EINVAL);
+    }
+    va_start(arg_ptr, opencl_param);
+    do {
+        param = va_arg(arg_ptr, void *);
+        if (!param)
+            break;
+        param_size = va_arg(arg_ptr, size_t);
+        if (!param_size) {
+            av_log(opencl_param->ctx, AV_LOG_ERROR, "Parameter size must not be 0\n");
+            ret = AVERROR(EINVAL);
+            goto end;
+        }
+        status = clSetKernelArg(opencl_param->kernel, opencl_param->param_num, param_size, param);
+        if (status != CL_SUCCESS) {
+            av_log(opencl_param->ctx, AV_LOG_ERROR, "Cannot set kernel argument: %s\n", av_opencl_errstr(status));
+            ret = AVERROR_EXTERNAL;
+            goto end;
+        }
+        opencl_param->param_num++;
+    } while (param && param_size);
+end:
+    va_end(arg_ptr);
+    return ret;
+}
diff --git a/libavutil/opencl_internal.h b/libavutil/opencl_internal.h
new file mode 100644
index 0000000..34b39a0
--- /dev/null
+++ b/libavutil/opencl_internal.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2012 Peng Gao <peng@multicorewareinc.com>
+ * Copyright (C) 2012 Li   Cao <li@multicorewareinc.com>
+ * Copyright (C) 2012 Wei  Gao <weigao@multicorewareinc.com>
+ *
+ * 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
+ */
+
+#include "opencl.h"
+
+#define FF_OPENCL_PARAM_INFO(a) ((void*)(&(a))), (sizeof(a))
+
+typedef struct {
+    cl_kernel kernel;
+    int param_num;
+    void *ctx;
+} FFOpenclParam;
+
+int ff_opencl_set_parameter(FFOpenclParam *opencl_param, ...);
diff --git a/libavutil/opt.c b/libavutil/opt.c
index 0e7a3a8..c035307 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -63,7 +63,7 @@
 const AVOption *av_opt_next(void *obj, const AVOption *last)
 {
     AVClass *class = *(AVClass**)obj;
-    if (!last && class->option && class->option[0].name)
+    if (!last && class && class->option && class->option[0].name)
         return class->option;
     if (last && last[1].name)
         return ++last;
@@ -259,7 +259,7 @@
     if (!val && (o->type != AV_OPT_TYPE_STRING &&
                  o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT &&
                  o->type != AV_OPT_TYPE_IMAGE_SIZE && o->type != AV_OPT_TYPE_VIDEO_RATE &&
-                 o->type != AV_OPT_TYPE_DURATION))
+                 o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR))
         return AVERROR(EINVAL);
 
     dst = ((uint8_t*)target_obj) + o->offset;
@@ -331,6 +331,16 @@
                 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as duration\n", val);
             return ret;
         }
+        break;
+    case AV_OPT_TYPE_COLOR:
+        if (!val) {
+            return 0;
+        } else {
+            ret = av_parse_color(dst, val, -1, obj);
+            if (ret < 0)
+                av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as color\n", val);
+            return ret;
+        }
     }
 
     av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
@@ -617,6 +627,9 @@
                        i64 / 3600000000, (int)((i64 / 60000000) % 60),
                        (int)((i64 / 1000000) % 60), (int)(i64 % 1000000));
         break;
+    case AV_OPT_TYPE_COLOR:
+        ret = snprintf(buf, sizeof(buf), "0x%02x%02x%02x%02x", ((int *)dst)[0], ((int *)dst)[1], ((int *)dst)[2], ((int *)dst)[3]);
+        break;
     default:
         return AVERROR(EINVAL);
     }
@@ -886,6 +899,9 @@
             case AV_OPT_TYPE_DURATION:
                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<duration>");
                 break;
+            case AV_OPT_TYPE_COLOR:
+                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<color>");
+                break;
             case AV_OPT_TYPE_CONST:
             default:
                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
@@ -920,6 +936,46 @@
             av_opt_freep_ranges(&r);
         }
 
+        if (opt->type != AV_OPT_TYPE_CONST  &&
+            opt->type != AV_OPT_TYPE_BINARY &&
+                !((opt->type == AV_OPT_TYPE_COLOR      ||
+                   opt->type == AV_OPT_TYPE_IMAGE_SIZE ||
+                   opt->type == AV_OPT_TYPE_STRING     ||
+                   opt->type == AV_OPT_TYPE_VIDEO_RATE) &&
+                  !opt->default_val.str)) {
+            av_log(av_log_obj, AV_LOG_INFO, " (default ");
+            switch (opt->type) {
+            case AV_OPT_TYPE_FLAGS:
+                av_log(av_log_obj, AV_LOG_INFO, "%"PRIX64, opt->default_val.i64);
+                break;
+            case AV_OPT_TYPE_DURATION:
+            case AV_OPT_TYPE_INT:
+            case AV_OPT_TYPE_INT64:
+                log_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64);
+                break;
+            case AV_OPT_TYPE_DOUBLE:
+            case AV_OPT_TYPE_FLOAT:
+                log_value(av_log_obj, AV_LOG_INFO, opt->default_val.dbl);
+                break;
+            case AV_OPT_TYPE_RATIONAL: {
+                AVRational q = av_d2q(opt->default_val.dbl, INT_MAX);
+                av_log(av_log_obj, AV_LOG_INFO, "%d/%d", q.num, q.den); }
+                break;
+            case AV_OPT_TYPE_PIXEL_FMT:
+                av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(opt->default_val.i64), "none"));
+                break;
+            case AV_OPT_TYPE_SAMPLE_FMT:
+                av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(opt->default_val.i64), "none"));
+                break;
+            case AV_OPT_TYPE_COLOR:
+            case AV_OPT_TYPE_IMAGE_SIZE:
+            case AV_OPT_TYPE_STRING:
+            case AV_OPT_TYPE_VIDEO_RATE:
+                av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str);
+            }
+            av_log(av_log_obj, AV_LOG_INFO, ")");
+        }
+
         av_log(av_log_obj, AV_LOG_INFO, "\n");
         if (opt->unit && opt->type != AV_OPT_TYPE_CONST) {
             opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags);
@@ -978,6 +1034,7 @@
                 av_opt_set_q(s, opt->name, val, 0);
             }
             break;
+            case AV_OPT_TYPE_COLOR:
             case AV_OPT_TYPE_STRING:
             case AV_OPT_TYPE_IMAGE_SIZE:
             case AV_OPT_TYPE_VIDEO_RATE:
@@ -1237,6 +1294,9 @@
 
     c= *(AVClass**)obj;
 
+    if (!c)
+        return NULL;
+
     if (search_flags & AV_OPT_SEARCH_CHILDREN) {
         if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) {
             const AVClass *child = NULL;
@@ -1334,6 +1394,7 @@
     case AV_OPT_TYPE_FLOAT:
     case AV_OPT_TYPE_DOUBLE:
     case AV_OPT_TYPE_DURATION:
+    case AV_OPT_TYPE_COLOR:
         break;
     case AV_OPT_TYPE_STRING:
         range->component_min = 0;
@@ -1400,6 +1461,7 @@
     enum AVPixelFormat pix_fmt;
     enum AVSampleFormat sample_fmt;
     int64_t duration;
+    uint8_t color[4];
 } TestContext;
 
 #define OFFSET(x) offsetof(TestContext, x)
@@ -1422,6 +1484,7 @@
 {"sample_fmt", "set samplefmt", OFFSET(sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64 = AV_SAMPLE_FMT_NONE}, -1, AV_SAMPLE_FMT_NB-1},
 {"video_rate", "set videorate", OFFSET(video_rate), AV_OPT_TYPE_VIDEO_RATE,  {.str = "25"}, 0,     0                   },
 {"duration", "set duration",   OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX},
+{"color", "set color",   OFFSET(color), AV_OPT_TYPE_COLOR, {.str = "pink"}, 0, 0},
 {NULL},
 };
 
@@ -1443,7 +1506,7 @@
     printf("\nTesting av_set_options_string()\n");
     {
         TestContext test_ctx = { 0 };
-        const char *options[] = {
+        static const char * const options[] = {
             "",
             ":",
             "=",
@@ -1480,6 +1543,9 @@
             "duration=bogus",
             "duration=123.45",
             "duration=1\\:23\\:45.67",
+            "color=blue",
+            "color=0x223300",
+            "color=0x42FF07AA",
         };
 
         test_ctx.class = &test_class;
@@ -1499,7 +1565,7 @@
     printf("\nTesting av_opt_set_from_string()\n");
     {
         TestContext test_ctx = { 0 };
-        const char *options[] = {
+        static const char * const options[] = {
             "",
             "5",
             "5:hello",
@@ -1510,7 +1576,7 @@
             " 5 : hello : size = pal ",
             "a_very_long_option_name_that_will_need_to_be_ellipsized_around_here=42"
         };
-        const char *shorthand[] = { "num", "string", NULL };
+        static const char * const shorthand[] = { "num", "string", NULL };
 
         test_ctx.class = &test_class;
         av_opt_set_defaults(&test_ctx);
diff --git a/libavutil/opt.h b/libavutil/opt.h
index 7f7b54e..3882751 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -64,7 +64,7 @@
  *     int      bin_len;
  * } test_struct;
  *
- * static const AVOption options[] = {
+ * static const AVOption test_options[] = {
  *   { "test_int", "This is a test option of int type.", offsetof(test_struct, int_opt),
  *     AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX },
  *   { "test_str", "This is a test option of string type.", offsetof(test_struct, str_opt),
@@ -77,7 +77,7 @@
  * static const AVClass test_class = {
  *     .class_name = "test class",
  *     .item_name  = av_default_item_name,
- *     .option     = options,
+ *     .option     = test_options,
  *     .version    = LIBAVUTIL_VERSION_INT,
  * };
  * @endcode
@@ -163,7 +163,7 @@
  *
  * @subsection avoptions_implement_named_constants Named constants
  *      It is possible to create named constants for options. Simply set the unit
- *      field of the option the constants should apply to to a string and
+ *      field of the option the constants should apply to a string and
  *      create the constants themselves as options of type AV_OPT_TYPE_CONST
  *      with their unit field set to the same string.
  *      Their default_val field should contain the value of the named
@@ -232,6 +232,7 @@
     AV_OPT_TYPE_SAMPLE_FMT = MKBETAG('S','F','M','T'),
     AV_OPT_TYPE_VIDEO_RATE = MKBETAG('V','R','A','T'), ///< offset must point to AVRational
     AV_OPT_TYPE_DURATION   = MKBETAG('D','U','R',' '),
+    AV_OPT_TYPE_COLOR      = MKBETAG('C','O','L','R'),
 #if FF_API_OLD_AVOPTIONS
     FF_OPT_TYPE_FLAGS = 0,
     FF_OPT_TYPE_INT,
diff --git a/libavutil/parseutils.c b/libavutil/parseutils.c
index f2f8f18..5797e9e 100644
--- a/libavutil/parseutils.c
+++ b/libavutil/parseutils.c
@@ -824,13 +824,13 @@
         time_t tvi;
         struct tm *tm;
         static char tzstr[] = "TZ=CET-1";
-        const char *time_string[] = {
+        static const char * const time_string[] = {
             "now",
             "12:35:46",
             "2000-12-20 0:02:47.5z",
             "2000-12-20T010247.6",
         };
-        const char *duration_string[] = {
+        static const char * const duration_string[] = {
             "2:34:56.79",
             "-1:23:45.67",
             "42.1729",
diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c
index 9767cc1..e866db2 100644
--- a/libavutil/pixdesc.c
+++ b/libavutil/pixdesc.c
@@ -26,8 +26,9 @@
 #include "common.h"
 #include "pixfmt.h"
 #include "pixdesc.h"
-
+#include "internal.h"
 #include "intreadwrite.h"
+#include "avstring.h"
 
 void av_read_image_line(uint16_t *dst,
                         const uint8_t *data[4], const int linesize[4],
@@ -43,7 +44,7 @@
     int step  = comp.step_minus1 + 1;
     int flags = desc->flags;
 
-    if (flags & PIX_FMT_BITSTREAM) {
+    if (flags & AV_PIX_FMT_FLAG_BITSTREAM) {
         int skip = x * step + comp.offset_plus1 - 1;
         const uint8_t *p = data[plane] + y * linesize[plane] + (skip >> 3);
         int shift = 8 - depth - (skip & 7);
@@ -63,11 +64,11 @@
         int is_8bit = shift + depth <= 8;
 
         if (is_8bit)
-            p += !!(flags & PIX_FMT_BE);
+            p += !!(flags & AV_PIX_FMT_FLAG_BE);
 
         while (w--) {
             int val = is_8bit ? *p :
-                flags & PIX_FMT_BE ? AV_RB16(p) : AV_RL16(p);
+                flags & AV_PIX_FMT_FLAG_BE ? AV_RB16(p) : AV_RL16(p);
             val = (val >> shift) & mask;
             if (read_pal_component)
                 val = data[1][4 * val + c];
@@ -88,7 +89,7 @@
     int step  = comp.step_minus1 + 1;
     int flags = desc->flags;
 
-    if (flags & PIX_FMT_BITSTREAM) {
+    if (flags & AV_PIX_FMT_FLAG_BITSTREAM) {
         int skip = x * step + comp.offset_plus1 - 1;
         uint8_t *p = data[plane] + y * linesize[plane] + (skip >> 3);
         int shift = 8 - depth - (skip & 7);
@@ -105,14 +106,14 @@
                      x * step + comp.offset_plus1 - 1;
 
         if (shift + depth <= 8) {
-            p += !!(flags & PIX_FMT_BE);
+            p += !!(flags & AV_PIX_FMT_FLAG_BE);
             while (w--) {
                 *p |= (*src++ << shift);
                 p += step;
             }
         } else {
             while (w--) {
-                if (flags & PIX_FMT_BE) {
+                if (flags & AV_PIX_FMT_FLAG_BE) {
                     uint16_t val = AV_RB16(p) | (*src++ << shift);
                     AV_WB16(p, val);
                 } else {
@@ -139,7 +140,7 @@
             { 1, 0, 1, 0, 7 },        /* U */
             { 2, 0, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUYV422] = {
         .name = "yuyv422",
@@ -162,7 +163,7 @@
             { 0, 2, 2, 0, 7 },        /* G */
             { 0, 2, 3, 0, 7 },        /* B */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_BGR24] = {
         .name = "bgr24",
@@ -174,7 +175,7 @@
             { 0, 2, 2, 0, 7 },        /* G */
             { 0, 2, 1, 0, 7 },        /* B */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_YUV422P] = {
         .name = "yuv422p",
@@ -186,7 +187,7 @@
             { 1, 0, 1, 0, 7 },        /* U */
             { 2, 0, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV444P] = {
         .name = "yuv444p",
@@ -198,7 +199,7 @@
             { 1, 0, 1, 0, 7 },        /* U */
             { 2, 0, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV410P] = {
         .name = "yuv410p",
@@ -210,7 +211,7 @@
             { 1, 0, 1, 0, 7 },        /* U */
             { 2, 0, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV411P] = {
         .name = "yuv411p",
@@ -222,7 +223,19 @@
             { 1, 0, 1, 0, 7 },        /* U */
             { 2, 0, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
+    },
+    [AV_PIX_FMT_YUVJ411P] = {
+        .name = "yuvj411p",
+        .nb_components = 3,
+        .log2_chroma_w = 2,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 0, 1, 0, 7 },        /* Y */
+            { 1, 0, 1, 0, 7 },        /* U */
+            { 2, 0, 1, 0, 7 },        /* V */
+        },
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_GRAY8] = {
         .name = "gray",
@@ -232,7 +245,7 @@
         .comp = {
             { 0, 0, 1, 0, 7 },        /* Y */
         },
-        .flags = PIX_FMT_PSEUDOPAL,
+        .flags = AV_PIX_FMT_FLAG_PSEUDOPAL,
     },
     [AV_PIX_FMT_MONOWHITE] = {
         .name = "monow",
@@ -242,7 +255,7 @@
         .comp = {
             { 0, 0, 1, 0, 0 },        /* Y */
         },
-        .flags = PIX_FMT_BITSTREAM,
+        .flags = AV_PIX_FMT_FLAG_BITSTREAM,
     },
     [AV_PIX_FMT_MONOBLACK] = {
         .name = "monob",
@@ -252,7 +265,7 @@
         .comp = {
             { 0, 0, 1, 7, 0 },        /* Y */
         },
-        .flags = PIX_FMT_BITSTREAM,
+        .flags = AV_PIX_FMT_FLAG_BITSTREAM,
     },
     [AV_PIX_FMT_PAL8] = {
         .name = "pal8",
@@ -262,7 +275,7 @@
         .comp = {
             { 0, 0, 1, 0, 7 },
         },
-        .flags = PIX_FMT_PAL,
+        .flags = AV_PIX_FMT_FLAG_PAL,
     },
     [AV_PIX_FMT_YUVJ420P] = {
         .name = "yuvj420p",
@@ -274,7 +287,7 @@
             { 1, 0, 1, 0, 7 },        /* U */
             { 2, 0, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUVJ422P] = {
         .name = "yuvj422p",
@@ -286,7 +299,7 @@
             { 1, 0, 1, 0, 7 },        /* U */
             { 2, 0, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUVJ444P] = {
         .name = "yuvj444p",
@@ -298,15 +311,15 @@
             { 1, 0, 1, 0, 7 },        /* U */
             { 2, 0, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_XVMC_MPEG2_MC] = {
         .name = "xvmcmc",
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_XVMC_MPEG2_IDCT] = {
         .name = "xvmcidct",
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_UYVY422] = {
         .name = "uyvy422",
@@ -340,7 +353,7 @@
             { 0, 0, 1, 3, 2 },        /* G */
             { 0, 0, 1, 6, 1 },        /* B */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_PSEUDOPAL,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PSEUDOPAL,
     },
     [AV_PIX_FMT_BGR4] = {
         .name = "bgr4",
@@ -352,7 +365,7 @@
             { 0, 3, 2, 0, 1 },        /* G */
             { 0, 3, 1, 0, 0 },        /* B */
         },
-        .flags = PIX_FMT_BITSTREAM | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_BGR4_BYTE] = {
         .name = "bgr4_byte",
@@ -364,7 +377,7 @@
             { 0, 0, 1, 1, 1 },        /* G */
             { 0, 0, 1, 3, 0 },        /* B */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_PSEUDOPAL,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PSEUDOPAL,
     },
     [AV_PIX_FMT_RGB8] = {
         .name = "rgb8",
@@ -376,7 +389,7 @@
             { 0, 0, 1, 3, 2 },        /* G */
             { 0, 0, 1, 0, 2 },        /* B */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_PSEUDOPAL,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PSEUDOPAL,
     },
     [AV_PIX_FMT_RGB4] = {
         .name = "rgb4",
@@ -388,7 +401,7 @@
             { 0, 3, 2, 0, 1 },        /* G */
             { 0, 3, 4, 0, 0 },        /* B */
         },
-        .flags = PIX_FMT_BITSTREAM | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_RGB4_BYTE] = {
         .name = "rgb4_byte",
@@ -400,7 +413,7 @@
             { 0, 0, 1, 1, 1 },        /* G */
             { 0, 0, 1, 0, 0 },        /* B */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_PSEUDOPAL,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PSEUDOPAL,
     },
     [AV_PIX_FMT_NV12] = {
         .name = "nv12",
@@ -412,7 +425,7 @@
             { 1, 1, 1, 0, 7 },        /* U */
             { 1, 1, 2, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_NV21] = {
         .name = "nv21",
@@ -424,7 +437,7 @@
             { 1, 1, 2, 0, 7 },        /* U */
             { 1, 1, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_ARGB] = {
         .name = "argb",
@@ -437,7 +450,7 @@
             { 0, 3, 4, 0, 7 },        /* B */
             { 0, 3, 1, 0, 7 },        /* A */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_RGBA] = {
         .name = "rgba",
@@ -450,7 +463,7 @@
             { 0, 3, 3, 0, 7 },        /* B */
             { 0, 3, 4, 0, 7 },        /* A */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_ABGR] = {
         .name = "abgr",
@@ -463,7 +476,7 @@
             { 0, 3, 2, 0, 7 },        /* B */
             { 0, 3, 1, 0, 7 },        /* A */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_BGRA] = {
         .name = "bgra",
@@ -476,7 +489,7 @@
             { 0, 3, 1, 0, 7 },        /* B */
             { 0, 3, 4, 0, 7 },        /* A */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_0RGB] = {
         .name = "0rgb",
@@ -488,7 +501,7 @@
             { 0, 3, 3, 0, 7 },        /* G */
             { 0, 3, 4, 0, 7 },        /* B */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_RGB0] = {
         .name = "rgb0",
@@ -500,7 +513,7 @@
             { 0, 3, 2, 0, 7 },        /* G */
             { 0, 3, 3, 0, 7 },        /* B */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_0BGR] = {
         .name = "0bgr",
@@ -512,7 +525,7 @@
             { 0, 3, 3, 0, 7 },        /* G */
             { 0, 3, 2, 0, 7 },        /* B */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_BGR0] = {
         .name = "bgr0",
@@ -524,7 +537,7 @@
             { 0, 3, 2, 0, 7 },        /* G */
             { 0, 3, 1, 0, 7 },        /* B */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_GRAY16BE] = {
         .name = "gray16be",
@@ -534,7 +547,7 @@
         .comp = {
             { 0, 1, 1, 0, 15 },       /* Y */
         },
-        .flags = PIX_FMT_BE,
+        .flags = AV_PIX_FMT_FLAG_BE,
     },
     [AV_PIX_FMT_GRAY16LE] = {
         .name = "gray16le",
@@ -555,7 +568,7 @@
             { 1, 0, 1, 0, 7 },        /* U */
             { 2, 0, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUVJ440P] = {
         .name = "yuvj440p",
@@ -567,7 +580,7 @@
             { 1, 0, 1, 0, 7 },        /* U */
             { 2, 0, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUVA420P] = {
         .name = "yuva420p",
@@ -580,7 +593,7 @@
             { 2, 0, 1, 0, 7 },        /* V */
             { 3, 0, 1, 0, 7 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA422P] = {
         .name = "yuva422p",
@@ -593,7 +606,7 @@
             { 2, 0, 1, 0, 7 },        /* V */
             { 3, 0, 1, 0, 7 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA444P] = {
         .name = "yuva444p",
@@ -606,7 +619,7 @@
             { 2, 0, 1, 0, 7 },        /* V */
             { 3, 0, 1, 0, 7 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA420P9BE] = {
         .name = "yuva420p9be",
@@ -619,7 +632,7 @@
             { 2, 1, 1, 0, 8 },        /* V */
             { 3, 1, 1, 0, 8 },        /* A */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA420P9LE] = {
         .name = "yuva420p9le",
@@ -632,7 +645,7 @@
             { 2, 1, 1, 0, 8 },        /* V */
             { 3, 1, 1, 0, 8 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA422P9BE] = {
         .name = "yuva422p9be",
@@ -645,7 +658,7 @@
             { 2, 1, 1, 0, 8 },        /* V */
             { 3, 1, 1, 0, 8 },        /* A */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA422P9LE] = {
         .name = "yuva422p9le",
@@ -658,7 +671,7 @@
             { 2, 1, 1, 0, 8 },        /* V */
             { 3, 1, 1, 0, 8 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA444P9BE] = {
         .name = "yuva444p9be",
@@ -671,7 +684,7 @@
             { 2, 1, 1, 0, 8 },        /* V */
             { 3, 1, 1, 0, 8 },        /* A */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA444P9LE] = {
         .name = "yuva444p9le",
@@ -684,7 +697,7 @@
             { 2, 1, 1, 0, 8 },        /* V */
             { 3, 1, 1, 0, 8 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA420P10BE] = {
         .name = "yuva420p10be",
@@ -697,7 +710,7 @@
             { 2, 1, 1, 0, 9 },        /* V */
             { 3, 1, 1, 0, 9 },        /* A */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA420P10LE] = {
         .name = "yuva420p10le",
@@ -710,7 +723,7 @@
             { 2, 1, 1, 0, 9 },        /* V */
             { 3, 1, 1, 0, 9 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA422P10BE] = {
         .name = "yuva422p10be",
@@ -723,7 +736,7 @@
             { 2, 1, 1, 0, 9 },        /* V */
             { 3, 1, 1, 0, 9 },        /* A */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA422P10LE] = {
         .name = "yuva422p10le",
@@ -736,7 +749,7 @@
             { 2, 1, 1, 0, 9 },        /* V */
             { 3, 1, 1, 0, 9 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA444P10BE] = {
         .name = "yuva444p10be",
@@ -749,7 +762,7 @@
             { 2, 1, 1, 0, 9 },        /* V */
             { 3, 1, 1, 0, 9 },        /* A */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA444P10LE] = {
         .name = "yuva444p10le",
@@ -762,7 +775,7 @@
             { 2, 1, 1, 0, 9 },        /* V */
             { 3, 1, 1, 0, 9 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA420P16BE] = {
         .name = "yuva420p16be",
@@ -775,7 +788,7 @@
             { 2, 1, 1, 0, 15 },        /* V */
             { 3, 1, 1, 0, 15 },        /* A */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA420P16LE] = {
         .name = "yuva420p16le",
@@ -788,7 +801,7 @@
             { 2, 1, 1, 0, 15 },        /* V */
             { 3, 1, 1, 0, 15 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA422P16BE] = {
         .name = "yuva422p16be",
@@ -801,7 +814,7 @@
             { 2, 1, 1, 0, 15 },        /* V */
             { 3, 1, 1, 0, 15 },        /* A */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA422P16LE] = {
         .name = "yuva422p16le",
@@ -814,7 +827,7 @@
             { 2, 1, 1, 0, 15 },        /* V */
             { 3, 1, 1, 0, 15 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA444P16BE] = {
         .name = "yuva444p16be",
@@ -827,7 +840,7 @@
             { 2, 1, 1, 0, 15 },        /* V */
             { 3, 1, 1, 0, 15 },        /* A */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA444P16LE] = {
         .name = "yuva444p16le",
@@ -840,44 +853,46 @@
             { 2, 1, 1, 0, 15 },        /* V */
             { 3, 1, 1, 0, 15 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
+#if FF_API_VDPAU
     [AV_PIX_FMT_VDPAU_H264] = {
         .name = "vdpau_h264",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_VDPAU_MPEG1] = {
         .name = "vdpau_mpeg1",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_VDPAU_MPEG2] = {
         .name = "vdpau_mpeg2",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_VDPAU_WMV3] = {
         .name = "vdpau_wmv3",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_VDPAU_VC1] = {
         .name = "vdpau_vc1",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_VDPAU_MPEG4] = {
         .name = "vdpau_mpeg4",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
+#endif
     [AV_PIX_FMT_RGB48BE] = {
         .name = "rgb48be",
         .nb_components = 3,
@@ -888,7 +903,7 @@
             { 0, 5, 3, 0, 15 },       /* G */
             { 0, 5, 5, 0, 15 },       /* B */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_BE,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BE,
     },
     [AV_PIX_FMT_RGB48LE] = {
         .name = "rgb48le",
@@ -900,7 +915,7 @@
             { 0, 5, 3, 0, 15 },       /* G */
             { 0, 5, 5, 0, 15 },       /* B */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_RGBA64BE] = {
         .name = "rgba64be",
@@ -913,7 +928,7 @@
             { 0, 7, 5, 0, 15 },       /* B */
             { 0, 7, 7, 0, 15 },       /* A */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_BE | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_RGBA64LE] = {
         .name = "rgba64le",
@@ -926,7 +941,7 @@
             { 0, 7, 5, 0, 15 },       /* B */
             { 0, 7, 7, 0, 15 },       /* A */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_RGB565BE] = {
         .name = "rgb565be",
@@ -938,7 +953,7 @@
             { 0, 1, 1, 5, 5 },        /* G */
             { 0, 1, 1, 0, 4 },        /* B */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_RGB565LE] = {
         .name = "rgb565le",
@@ -950,7 +965,7 @@
             { 0, 1, 1, 5, 5 },        /* G */
             { 0, 1, 1, 0, 4 },        /* B */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_RGB555BE] = {
         .name = "rgb555be",
@@ -962,7 +977,7 @@
             { 0, 1, 1, 5, 4 },        /* G */
             { 0, 1, 1, 0, 4 },        /* B */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_RGB555LE] = {
         .name = "rgb555le",
@@ -974,7 +989,7 @@
             { 0, 1, 1, 5, 4 },        /* G */
             { 0, 1, 1, 0, 4 },        /* B */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_RGB444BE] = {
         .name = "rgb444be",
@@ -986,7 +1001,7 @@
             { 0, 1, 1, 4, 3 },        /* G */
             { 0, 1, 1, 0, 3 },        /* B */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_RGB444LE] = {
         .name = "rgb444le",
@@ -998,7 +1013,7 @@
             { 0, 1, 1, 4, 3 },        /* G */
             { 0, 1, 1, 0, 3 },        /* B */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_BGR48BE] = {
         .name = "bgr48be",
@@ -1010,7 +1025,7 @@
             { 0, 5, 3, 0, 15 },       /* G */
             { 0, 5, 1, 0, 15 },       /* B */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_BGR48LE] = {
         .name = "bgr48le",
@@ -1022,7 +1037,7 @@
             { 0, 5, 3, 0, 15 },       /* G */
             { 0, 5, 1, 0, 15 },       /* B */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_BGRA64BE] = {
         .name = "bgra64be",
@@ -1035,7 +1050,7 @@
             { 0, 7, 1, 0, 15 },       /* B */
             { 0, 7, 7, 0, 15 },       /* A */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_RGB | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_BGRA64LE] = {
         .name = "bgra64le",
@@ -1048,7 +1063,7 @@
             { 0, 7, 1, 0, 15 },       /* B */
             { 0, 7, 7, 0, 15 },       /* A */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_BGR565BE] = {
         .name = "bgr565be",
@@ -1060,7 +1075,7 @@
             { 0, 1, 1, 5, 5 },        /* G */
             { 0, 1, 0, 3, 4 },        /* B */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_BGR565LE] = {
         .name = "bgr565le",
@@ -1072,7 +1087,7 @@
             { 0, 1, 1, 5, 5 },        /* G */
             { 0, 1, 2, 3, 4 },        /* B */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_BGR555BE] = {
         .name = "bgr555be",
@@ -1084,7 +1099,7 @@
             { 0, 1, 1, 5, 4 },       /* G */
             { 0, 1, 0, 2, 4 },       /* B */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB,
      },
     [AV_PIX_FMT_BGR555LE] = {
         .name = "bgr555le",
@@ -1096,7 +1111,7 @@
             { 0, 1, 1, 5, 4 },        /* G */
             { 0, 1, 2, 2, 4 },        /* B */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_BGR444BE] = {
         .name = "bgr444be",
@@ -1108,7 +1123,7 @@
             { 0, 1, 1, 4, 3 },       /* G */
             { 0, 1, 0, 0, 3 },       /* B */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB,
      },
     [AV_PIX_FMT_BGR444LE] = {
         .name = "bgr444le",
@@ -1120,25 +1135,25 @@
             { 0, 1, 1, 4, 3 },        /* G */
             { 0, 1, 2, 0, 3 },        /* B */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_VAAPI_MOCO] = {
         .name = "vaapi_moco",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_VAAPI_IDCT] = {
         .name = "vaapi_idct",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_VAAPI_VLD] = {
         .name = "vaapi_vld",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_YUV420P9LE] = {
         .name = "yuv420p9le",
@@ -1150,7 +1165,7 @@
             { 1, 1, 1, 0, 8 },        /* U */
             { 2, 1, 1, 0, 8 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV420P9BE] = {
         .name = "yuv420p9be",
@@ -1162,7 +1177,7 @@
             { 1, 1, 1, 0, 8 },        /* U */
             { 2, 1, 1, 0, 8 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV420P10LE] = {
         .name = "yuv420p10le",
@@ -1174,7 +1189,7 @@
             { 1, 1, 1, 0, 9 },        /* U */
             { 2, 1, 1, 0, 9 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV420P10BE] = {
         .name = "yuv420p10be",
@@ -1186,7 +1201,7 @@
             { 1, 1, 1, 0, 9 },        /* U */
             { 2, 1, 1, 0, 9 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV420P12LE] = {
         .name = "yuv420p12le",
@@ -1198,7 +1213,7 @@
             { 1, 1, 1, 0, 11 },        /* U */
             { 2, 1, 1, 0, 11 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV420P12BE] = {
         .name = "yuv420p12be",
@@ -1210,7 +1225,7 @@
             { 1, 1, 1, 0, 11 },        /* U */
             { 2, 1, 1, 0, 11 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV420P14LE] = {
         .name = "yuv420p14le",
@@ -1222,7 +1237,7 @@
             { 1, 1, 1, 0, 13 },        /* U */
             { 2, 1, 1, 0, 13 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV420P14BE] = {
         .name = "yuv420p14be",
@@ -1234,7 +1249,7 @@
             { 1, 1, 1, 0, 13 },        /* U */
             { 2, 1, 1, 0, 13 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV420P16LE] = {
         .name = "yuv420p16le",
@@ -1246,7 +1261,7 @@
             { 1, 1, 1, 0, 15 },        /* U */
             { 2, 1, 1, 0, 15 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV420P16BE] = {
         .name = "yuv420p16be",
@@ -1258,7 +1273,7 @@
             { 1, 1, 1, 0, 15 },        /* U */
             { 2, 1, 1, 0, 15 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV422P9LE] = {
         .name = "yuv422p9le",
@@ -1270,7 +1285,7 @@
             { 1, 1, 1, 0, 8 },        /* U */
             { 2, 1, 1, 0, 8 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV422P9BE] = {
         .name = "yuv422p9be",
@@ -1282,7 +1297,7 @@
             { 1, 1, 1, 0, 8 },        /* U */
             { 2, 1, 1, 0, 8 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV422P10LE] = {
         .name = "yuv422p10le",
@@ -1294,7 +1309,7 @@
             { 1, 1, 1, 0, 9 },        /* U */
             { 2, 1, 1, 0, 9 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV422P10BE] = {
         .name = "yuv422p10be",
@@ -1306,7 +1321,7 @@
             { 1, 1, 1, 0, 9 },        /* U */
             { 2, 1, 1, 0, 9 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV422P12LE] = {
         .name = "yuv422p12le",
@@ -1318,7 +1333,7 @@
             { 1, 1, 1, 0, 11 },        /* U */
             { 2, 1, 1, 0, 11 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV422P12BE] = {
         .name = "yuv422p12be",
@@ -1330,7 +1345,7 @@
             { 1, 1, 1, 0, 11 },        /* U */
             { 2, 1, 1, 0, 11 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV422P14LE] = {
         .name = "yuv422p14le",
@@ -1342,7 +1357,7 @@
             { 1, 1, 1, 0, 13 },        /* U */
             { 2, 1, 1, 0, 13 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV422P14BE] = {
         .name = "yuv422p14be",
@@ -1354,7 +1369,7 @@
             { 1, 1, 1, 0, 13 },        /* U */
             { 2, 1, 1, 0, 13 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV422P16LE] = {
         .name = "yuv422p16le",
@@ -1366,7 +1381,7 @@
             { 1, 1, 1, 0, 15 },        /* U */
             { 2, 1, 1, 0, 15 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV422P16BE] = {
         .name = "yuv422p16be",
@@ -1378,7 +1393,7 @@
             { 1, 1, 1, 0, 15 },        /* U */
             { 2, 1, 1, 0, 15 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV444P16LE] = {
         .name = "yuv444p16le",
@@ -1390,7 +1405,7 @@
             { 1, 1, 1, 0, 15 },        /* U */
             { 2, 1, 1, 0, 15 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV444P16BE] = {
         .name = "yuv444p16be",
@@ -1402,7 +1417,7 @@
             { 1, 1, 1, 0, 15 },        /* U */
             { 2, 1, 1, 0, 15 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV444P10LE] = {
         .name = "yuv444p10le",
@@ -1414,7 +1429,7 @@
             { 1, 1, 1, 0, 9 },        /* U */
             { 2, 1, 1, 0, 9 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV444P10BE] = {
         .name = "yuv444p10be",
@@ -1426,7 +1441,7 @@
             { 1, 1, 1, 0, 9 },        /* U */
             { 2, 1, 1, 0, 9 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV444P9LE] = {
         .name = "yuv444p9le",
@@ -1438,7 +1453,7 @@
             { 1, 1, 1, 0, 8 },        /* U */
             { 2, 1, 1, 0, 8 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV444P9BE] = {
         .name = "yuv444p9be",
@@ -1450,7 +1465,7 @@
             { 1, 1, 1, 0, 8 },        /* U */
             { 2, 1, 1, 0, 8 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV444P12LE] = {
         .name = "yuv444p12le",
@@ -1462,7 +1477,7 @@
             { 1, 1, 1, 0, 11 },        /* U */
             { 2, 1, 1, 0, 11 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV444P12BE] = {
         .name = "yuv444p12be",
@@ -1474,7 +1489,7 @@
             { 1, 1, 1, 0, 11 },        /* U */
             { 2, 1, 1, 0, 11 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV444P14LE] = {
         .name = "yuv444p14le",
@@ -1486,7 +1501,7 @@
             { 1, 1, 1, 0, 13 },        /* U */
             { 2, 1, 1, 0, 13 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV444P14BE] = {
         .name = "yuv444p14be",
@@ -1498,19 +1513,19 @@
             { 1, 1, 1, 0, 13 },        /* U */
             { 2, 1, 1, 0, 13 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_DXVA2_VLD] = {
         .name = "dxva2_vld",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_VDA_VLD] = {
         .name = "vda_vld",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_GRAY8A] = {
         .name = "gray8a",
@@ -1519,7 +1534,7 @@
             { 0, 1, 1, 0, 7 },        /* Y */
             { 0, 1, 2, 0, 7 },        /* A */
         },
-        .flags = PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_GBRP] = {
         .name = "gbrp",
@@ -1531,7 +1546,7 @@
             { 0, 0, 1, 0, 7 },        /* G */
             { 1, 0, 1, 0, 7 },        /* B */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_GBRP9LE] = {
         .name = "gbrp9le",
@@ -1543,7 +1558,7 @@
             { 0, 1, 1, 0, 8 },        /* G */
             { 1, 1, 1, 0, 8 },        /* B */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_GBRP9BE] = {
         .name = "gbrp9be",
@@ -1555,7 +1570,7 @@
             { 0, 1, 1, 0, 8 },        /* G */
             { 1, 1, 1, 0, 8 },        /* B */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_GBRP10LE] = {
         .name = "gbrp10le",
@@ -1567,7 +1582,7 @@
             { 0, 1, 1, 0, 9 },        /* G */
             { 1, 1, 1, 0, 9 },        /* B */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_GBRP10BE] = {
         .name = "gbrp10be",
@@ -1579,7 +1594,7 @@
             { 0, 1, 1, 0, 9 },        /* G */
             { 1, 1, 1, 0, 9 },        /* B */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_GBRP12LE] = {
         .name = "gbrp12le",
@@ -1591,7 +1606,7 @@
             { 0, 1, 1, 0, 11 },        /* G */
             { 1, 1, 1, 0, 11 },        /* B */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_GBRP12BE] = {
         .name = "gbrp12be",
@@ -1603,7 +1618,7 @@
             { 0, 1, 1, 0, 11 },        /* G */
             { 1, 1, 1, 0, 11 },        /* B */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_GBRP14LE] = {
         .name = "gbrp14le",
@@ -1615,7 +1630,7 @@
             { 0, 1, 1, 0, 13 },        /* G */
             { 1, 1, 1, 0, 13 },        /* B */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_GBRP14BE] = {
         .name = "gbrp14be",
@@ -1627,7 +1642,7 @@
             { 0, 1, 1, 0, 13 },        /* G */
             { 1, 1, 1, 0, 13 },        /* B */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_GBRP16LE] = {
         .name = "gbrp16le",
@@ -1639,7 +1654,7 @@
             { 0, 1, 1, 0, 15 },       /* G */
             { 1, 1, 1, 0, 15 },       /* B */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_GBRP16BE] = {
         .name = "gbrp16be",
@@ -1651,13 +1666,52 @@
             { 0, 1, 1, 0, 15 },       /* G */
             { 1, 1, 1, 0, 15 },       /* B */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB,
+    },
+    [AV_PIX_FMT_GBRAP] = {
+        .name = "gbrap",
+        .nb_components = 4,
+        .log2_chroma_w = 0,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 2, 0, 1, 0, 7 },        /* R */
+            { 0, 0, 1, 0, 7 },        /* G */
+            { 1, 0, 1, 0, 7 },        /* B */
+            { 3, 0, 1, 0, 7 },        /* A */
+        },
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA,
+    },
+    [AV_PIX_FMT_GBRAP16LE] = {
+        .name = "gbrap16le",
+        .nb_components = 4,
+        .log2_chroma_w = 0,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 2, 1, 1, 0, 15 },       /* R */
+            { 0, 1, 1, 0, 15 },       /* G */
+            { 1, 1, 1, 0, 15 },       /* B */
+            { 3, 1, 1, 0, 15 },       /* A */
+        },
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA,
+    },
+    [AV_PIX_FMT_GBRAP16BE] = {
+        .name = "gbrap16be",
+        .nb_components = 4,
+        .log2_chroma_w = 0,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 2, 1, 1, 0, 15 },       /* R */
+            { 0, 1, 1, 0, 15 },       /* G */
+            { 1, 1, 1, 0, 15 },       /* B */
+            { 3, 1, 1, 0, 15 },       /* A */
+        },
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_VDPAU] = {
         .name = "vdpau",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_XYZ12LE] = {
         .name = "xyz12le",
@@ -1681,10 +1735,11 @@
             { 0, 5, 3, 4, 11 },       /* Y */
             { 0, 5, 5, 4, 11 },       /* Z */
        },
-        .flags = PIX_FMT_BE,
+        .flags = AV_PIX_FMT_FLAG_BE,
     },
 };
 
+FF_DISABLE_DEPRECATION_WARNINGS
 static enum AVPixelFormat get_pix_fmt_internal(const char *name)
 {
     enum AVPixelFormat pix_fmt;
@@ -1755,7 +1810,7 @@
     for (c = 0; c < 4; c++)
         bits += steps[c];
 
-    if(!(pixdesc->flags & PIX_FMT_BITSTREAM))
+    if(!(pixdesc->flags & AV_PIX_FMT_FLAG_BITSTREAM))
         bits *= 8;
 
     return bits >> log2_pixels;
@@ -1802,6 +1857,7 @@
 
     return desc - av_pix_fmt_descriptors;
 }
+FF_ENABLE_DEPRECATION_WARNINGS
 
 int av_pix_fmt_get_chroma_sub_sample(enum AVPixelFormat pix_fmt,
                                      int *h_shift, int *v_shift)
@@ -1847,7 +1903,7 @@
         av_assert0(d->log2_chroma_h <= 3);
         av_assert0(d->nb_components <= 4);
         av_assert0(d->name && d->name[0]);
-        av_assert0((d->nb_components==4 || d->nb_components==2) == !!(d->flags & PIX_FMT_ALPHA));
+        av_assert0((d->nb_components==4 || d->nb_components==2) == !!(d->flags & AV_PIX_FMT_FLAG_ALPHA));
         av_assert2(av_get_pix_fmt(d->name) == i);
 
         for (j=0; j<FF_ARRAY_ELEMS(d->comp); j++) {
@@ -1856,7 +1912,7 @@
                 av_assert0(!c->plane && !c->step_minus1 && !c->offset_plus1 && !c->shift && !c->depth_minus1);
                 continue;
             }
-            if (d->flags & PIX_FMT_BITSTREAM) {
+            if (d->flags & AV_PIX_FMT_FLAG_BITSTREAM) {
                 av_assert0(c->step_minus1 >= c->depth_minus1);
             } else {
                 av_assert0(8*(c->step_minus1+1) >= c->depth_minus1+1);
@@ -1868,3 +1924,22 @@
         }
     }
 }
+
+
+enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt)
+{
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
+    char name[16];
+    int i;
+
+    if (!desc || strlen(desc->name) < 2)
+        return AV_PIX_FMT_NONE;
+    av_strlcpy(name, desc->name, sizeof(name));
+    i = strlen(name) - 2;
+    if (strcmp(name + i, "be") && strcmp(name + i, "le"))
+        return AV_PIX_FMT_NONE;
+
+    name[i] ^= 'b' ^ 'l';
+
+    return get_pix_fmt_internal(name);
+}
diff --git a/libavutil/pixdesc.h b/libavutil/pixdesc.h
index 538e6a5..67b8dbc 100644
--- a/libavutil/pixdesc.h
+++ b/libavutil/pixdesc.h
@@ -23,6 +23,8 @@
 #define AVUTIL_PIXDESC_H
 
 #include <inttypes.h>
+
+#include "attributes.h"
 #include "pixfmt.h"
 
 typedef struct AVComponentDescriptor{
@@ -86,27 +88,60 @@
     AVComponentDescriptor comp[4];
 }AVPixFmtDescriptor;
 
-#define PIX_FMT_BE        1 ///< Pixel format is big-endian.
-#define PIX_FMT_PAL       2 ///< Pixel format has a palette in data[1], values are indexes in this palette.
-#define PIX_FMT_BITSTREAM 4 ///< All values of a component are bit-wise packed end to end.
-#define PIX_FMT_HWACCEL   8 ///< Pixel format is an HW accelerated format.
-#define PIX_FMT_PLANAR   16 ///< At least one pixel component is not in the first data plane
-#define PIX_FMT_RGB      32 ///< The pixel format contains RGB-like data (as opposed to YUV/grayscale)
+/**
+ * Pixel format is big-endian.
+ */
+#define AV_PIX_FMT_FLAG_BE           (1 << 0)
+/**
+ * Pixel format has a palette in data[1], values are indexes in this palette.
+ */
+#define AV_PIX_FMT_FLAG_PAL          (1 << 1)
+/**
+ * All values of a component are bit-wise packed end to end.
+ */
+#define AV_PIX_FMT_FLAG_BITSTREAM    (1 << 2)
+/**
+ * Pixel format is an HW accelerated format.
+ */
+#define AV_PIX_FMT_FLAG_HWACCEL      (1 << 3)
+/**
+ * At least one pixel component is not in the first data plane.
+ */
+#define AV_PIX_FMT_FLAG_PLANAR       (1 << 4)
+/**
+ * The pixel format contains RGB-like data (as opposed to YUV/grayscale).
+ */
+#define AV_PIX_FMT_FLAG_RGB          (1 << 5)
 /**
  * The pixel format is "pseudo-paletted". This means that FFmpeg treats it as
  * paletted internally, but the palette is generated by the decoder and is not
  * stored in the file.
  */
-#define PIX_FMT_PSEUDOPAL 64
+#define AV_PIX_FMT_FLAG_PSEUDOPAL    (1 << 6)
+/**
+ * The pixel format has an alpha channel.
+ */
+#define AV_PIX_FMT_FLAG_ALPHA        (1 << 7)
 
-#define PIX_FMT_ALPHA   128 ///< The pixel format has an alpha channel
-
+#if FF_API_PIX_FMT
+/**
+ * @deprecate use the AV_PIX_FMT_FLAG_* flags
+ */
+#define PIX_FMT_BE        AV_PIX_FMT_FLAG_BE
+#define PIX_FMT_PAL       AV_PIX_FMT_FLAG_PAL
+#define PIX_FMT_BITSTREAM AV_PIX_FMT_FLAG_BITSTREAM
+#define PIX_FMT_HWACCEL   AV_PIX_FMT_FLAG_HWACCEL
+#define PIX_FMT_PLANAR    AV_PIX_FMT_FLAG_PLANAR
+#define PIX_FMT_RGB       AV_PIX_FMT_FLAG_RGB
+#define PIX_FMT_PSEUDOPAL AV_PIX_FMT_FLAG_PSEUDOPAL
+#define PIX_FMT_ALPHA     AV_PIX_FMT_FLAG_ALPHA
+#endif
 
 #if FF_API_PIX_FMT_DESC
 /**
  * The array of all the pixel format descriptors.
  */
-extern const AVPixFmtDescriptor av_pix_fmt_descriptors[];
+extern attribute_deprecated const AVPixFmtDescriptor av_pix_fmt_descriptors[];
 #endif
 
 /**
@@ -168,7 +203,7 @@
 
 /**
  * Print in buf the string corresponding to the pixel format with
- * number pix_fmt, or an header if pix_fmt is negative.
+ * number pix_fmt, or a header if pix_fmt is negative.
  *
  * @param buf the buffer where to write the string
  * @param buf_size the size of buf
@@ -180,7 +215,8 @@
 
 /**
  * Return the number of bits per pixel used by the pixel format
- * described by pixdesc.
+ * described by pixdesc. Note that this is not the same as the number
+ * of bits per sample.
  *
  * The returned number of bits refers to the number of bits actually
  * used for storing the pixel information, that is padding bits are
@@ -241,4 +277,15 @@
 
 void ff_check_pixfmt_descriptors(void);
 
+/**
+ * Utility function to swap the endianness of a pixel format.
+ *
+ * @param[in]  pix_fmt the pixel format
+ *
+ * @return pixel format with swapped endianness if it exists,
+ * otherwise AV_PIX_FMT_NONE
+ */
+enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt);
+
+
 #endif /* AVUTIL_PIXDESC_H */
diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h
index 34be30a..57da2a3 100644
--- a/libavutil/pixfmt.h
+++ b/libavutil/pixfmt.h
@@ -37,17 +37,17 @@
  * Pixel format.
  *
  * @note
- * PIX_FMT_RGB32 is handled in an endian-specific manner. An RGBA
+ * AV_PIX_FMT_RGB32 is handled in an endian-specific manner. An RGBA
  * color is put together as:
  *  (A << 24) | (R << 16) | (G << 8) | B
  * This is stored as BGRA on little-endian CPU architectures and ARGB on
  * big-endian CPUs.
  *
  * @par
- * When the pixel format is palettized RGB (PIX_FMT_PAL8), the palettized
+ * When the pixel format is palettized RGB (AV_PIX_FMT_PAL8), the palettized
  * image data is stored in AVFrame.data[0]. The palette is transported in
  * AVFrame.data[1], is 1024 bytes long (256 4-byte entries) and is
- * formatted the same as in PIX_FMT_RGB32 described above (i.e., it is
+ * formatted the same as in AV_PIX_FMT_RGB32 described above (i.e., it is
  * also endian-specific). Note also that the individual RGB palette
  * components stored in AVFrame.data[1] should be in the range 0..255.
  * This is important as many custom PAL8 video codecs that were designed
@@ -103,11 +103,13 @@
     AV_PIX_FMT_YUV440P,   ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
     AV_PIX_FMT_YUVJ440P,  ///< planar YUV 4:4:0 full scale (JPEG), deprecated in favor of PIX_FMT_YUV440P and setting color_range
     AV_PIX_FMT_YUVA420P,  ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
+#if FF_API_VDPAU
     AV_PIX_FMT_VDPAU_H264,///< H.264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
     AV_PIX_FMT_VDPAU_MPEG1,///< MPEG-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
     AV_PIX_FMT_VDPAU_MPEG2,///< MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
     AV_PIX_FMT_VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
     AV_PIX_FMT_VDPAU_VC1, ///< VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+#endif
     AV_PIX_FMT_RGB48BE,   ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian
     AV_PIX_FMT_RGB48LE,   ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian
 
@@ -131,7 +133,9 @@
     AV_PIX_FMT_YUV422P16BE,  ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
     AV_PIX_FMT_YUV444P16LE,  ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
     AV_PIX_FMT_YUV444P16BE,  ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+#if FF_API_VDPAU
     AV_PIX_FMT_VDPAU_MPEG4,  ///< MPEG4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+#endif
     AV_PIX_FMT_DXVA2_VLD,    ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer
 
     AV_PIX_FMT_RGB444LE,  ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), little-endian, most significant bits to 0
@@ -142,9 +146,11 @@
     AV_PIX_FMT_BGR48BE,   ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as big-endian
     AV_PIX_FMT_BGR48LE,   ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as little-endian
 
-    //the following 10 formats have the disadvantage of needing 1 format for each bit depth, thus
-    //If you want to support multiple bit depths, then using AV_PIX_FMT_YUV420P16* with the bpp stored separately
-    //is better
+    /**
+     * The following 12 formats have the disadvantage of needing 1 format for each bit depth.
+     * Notice that each 9/10 bits sample is stored in 16 bits with extra padding.
+     * If you want to support multiple bit depths, then using AV_PIX_FMT_YUV420P16* with the bpp stored separately is better.
+     */
     AV_PIX_FMT_YUV420P9BE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
     AV_PIX_FMT_YUV420P9LE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
     AV_PIX_FMT_YUV420P10BE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
@@ -234,6 +240,10 @@
     AV_PIX_FMT_GBRP12LE,    ///< planar GBR 4:4:4 36bpp, little-endian
     AV_PIX_FMT_GBRP14BE,    ///< planar GBR 4:4:4 42bpp, big-endian
     AV_PIX_FMT_GBRP14LE,    ///< planar GBR 4:4:4 42bpp, little-endian
+    AV_PIX_FMT_GBRAP,       ///< planar GBRA 4:4:4:4 32bpp
+    AV_PIX_FMT_GBRAP16BE,   ///< planar GBRA 4:4:4:4 64bpp, big-endian
+    AV_PIX_FMT_GBRAP16LE,   ///< planar GBRA 4:4:4:4 64bpp, little-endian
+    AV_PIX_FMT_YUVJ411P,    ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor of PIX_FMT_YUV411P and setting color_range
     AV_PIX_FMT_NB,        ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions
 
 #if FF_API_PIX_FMT
@@ -241,7 +251,7 @@
 #endif
 };
 
-#if AV_HAVE_INCOMPATIBLE_FORK_ABI
+#if AV_HAVE_INCOMPATIBLE_LIBAV_ABI
 #define AV_PIX_FMT_YUVA422P AV_PIX_FMT_YUVA422P_LIBAV
 #define AV_PIX_FMT_YUVA444P AV_PIX_FMT_YUVA444P_LIBAV
 #endif
diff --git a/libavutil/ppc/float_dsp_init.c b/libavutil/ppc/float_dsp_init.c
index d9ca53e..fc6ff39 100644
--- a/libavutil/ppc/float_dsp_init.c
+++ b/libavutil/ppc/float_dsp_init.c
@@ -19,16 +19,15 @@
  */
 
 #include "config.h"
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/float_dsp.h"
 #include "float_dsp_altivec.h"
 
-void ff_float_dsp_init_ppc(AVFloatDSPContext *fdsp, int bit_exact)
+av_cold void ff_float_dsp_init_ppc(AVFloatDSPContext *fdsp, int bit_exact)
 {
 #if HAVE_ALTIVEC
-    int mm_flags = av_get_cpu_flags();
-
-    if (!(mm_flags & AV_CPU_FLAG_ALTIVEC))
+    if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
         return;
 
     fdsp->vector_fmul = ff_vector_fmul_altivec;
diff --git a/libavutil/ppc/timer.h b/libavutil/ppc/timer.h
index 155fc01..b28e624 100644
--- a/libavutil/ppc/timer.h
+++ b/libavutil/ppc/timer.h
@@ -23,6 +23,8 @@
 
 #include <stdint.h>
 
+#include "config.h"
+
 #define AV_READ_TIME read_time
 
 static inline uint64_t read_time(void)
@@ -31,12 +33,11 @@
 
      /* from section 2.2.1 of the 32-bit PowerPC PEM */
      __asm__ volatile(
-         "1:\n"
          "mftbu  %2\n"
          "mftb   %0\n"
          "mftbu  %1\n"
          "cmpw   %2,%1\n"
-         "bne    1b\n"
+         "bne    $-0x10\n"
      : "=r"(tbl), "=r"(tbu), "=r"(temp)
      :
      : "cc");
diff --git a/libavutil/ppc/util_altivec.h b/libavutil/ppc/util_altivec.h
index 7fe3150..fbf6d85 100644
--- a/libavutil/ppc/util_altivec.h
+++ b/libavutil/ppc/util_altivec.h
@@ -34,6 +34,8 @@
 
 #include "types_altivec.h"
 
+#if HAVE_ALTIVEC
+
 // used to build registers permutation vectors (vcprm)
 // the 's' are for words in the _s_econd vector
 #define WORD_0 0x00,0x01,0x02,0x03
@@ -115,4 +117,6 @@
     return vec_perm(a, b, perm_vec);
 }
 
+#endif /* HAVE_ALTIVEC */
+
 #endif /* AVUTIL_PPC_UTIL_ALTIVEC_H */
diff --git a/libavutil/random_seed.c b/libavutil/random_seed.c
index c674704..aa89024 100644
--- a/libavutil/random_seed.c
+++ b/libavutil/random_seed.c
@@ -32,6 +32,7 @@
 #include <time.h>
 #include <string.h>
 #include "avassert.h"
+#include "internal.h"
 #include "timer.h"
 #include "random_seed.h"
 #include "sha.h"
@@ -44,7 +45,7 @@
 static int read_random(uint32_t *dst, const char *file)
 {
 #if HAVE_UNISTD_H
-    int fd = open(file, O_RDONLY);
+    int fd = avpriv_open(file, O_RDONLY);
     int err = -1;
 
     if (fd == -1)
diff --git a/libavutil/rational.c b/libavutil/rational.c
index 768f252..ec2f2e5 100644
--- a/libavutil/rational.c
+++ b/libavutil/rational.c
@@ -26,7 +26,6 @@
  */
 
 #include "avassert.h"
-//#include <math.h>
 #include <limits.h>
 
 #include "common.h"
@@ -111,11 +110,14 @@
     int64_t den;
     if (isnan(d))
         return (AVRational) { 0,0 };
-    if (isinf(d))
+    if (fabs(d) > INT_MAX + 3LL)
         return (AVRational) { d < 0 ? -1 : 1, 0 };
     exponent = FFMAX( (int)(log(fabs(d) + 1e-20)/LOG2), 0);
     den = 1LL << (61 - exponent);
-    av_reduce(&a.num, &a.den, (int64_t)(d * den + 0.5), den, max);
+    // (int64_t)rint() and llrint() do not work with gcc on ia64 and sparc64
+    av_reduce(&a.num, &a.den, floor(d * den + 0.5), den, max);
+    if ((!a.num || !a.den) && d && max>0 && max<INT_MAX)
+        av_reduce(&a.num, &a.den, floor(d * den + 0.5), den, INT_MAX);
 
     return a;
 }
diff --git a/libavutil/ripemd.c b/libavutil/ripemd.c
new file mode 100644
index 0000000..d737c38
--- /dev/null
+++ b/libavutil/ripemd.c
@@ -0,0 +1,435 @@
+/*
+ * Copyright (C) 2007 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (C) 2013 James Almer
+ *
+ * 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
+ */
+
+#include <string.h>
+
+#include "attributes.h"
+#include "avutil.h"
+#include "bswap.h"
+#include "intreadwrite.h"
+#include "ripemd.h"
+#include "mem.h"
+
+/** hash context */
+typedef struct AVRIPEMD {
+    uint8_t  digest_len;  ///< digest length in 32-bit words
+    uint64_t count;       ///< number of bytes in buffer
+    uint8_t  buffer[64];  ///< 512-bit buffer of input values used in hash updating
+    uint32_t state[10];   ///< current hash value
+    uint8_t  ext;         ///< extension (0 for 128 and 160, 1 for 256 and 320)
+    /** function used to update hash for 512-bit input block */
+    void     (*transform)(uint32_t *state, const uint8_t buffer[64], int ext);
+} AVRIPEMD;
+
+const int av_ripemd_size = sizeof(AVRIPEMD);
+
+struct AVRIPEMD *av_ripemd_alloc(void)
+{
+    return av_mallocz(sizeof(struct AVRIPEMD));
+}
+
+static const uint32_t KA[4] = {
+    0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e
+};
+
+static const uint32_t KB[4] = {
+    0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9
+};
+
+static const int ROTA[80] = {
+    11, 14, 15, 12,  5,  8,  7 , 9, 11, 13, 14, 15,  6,  7,  9,  8,
+     7 , 6,  8, 13, 11,  9,  7, 15,  7, 12, 15,  9, 11,  7, 13, 12,
+    11, 13,  6,  7, 14,  9, 13, 15, 14,  8, 13,  6,  5, 12,  7,  5,
+    11, 12, 14, 15, 14, 15,  9,  8,  9, 14,  5,  6,  8,  6,  5, 12,
+     9, 15,  5, 11,  6,  8, 13, 12,  5, 12, 13, 14, 11,  8,  5,  6
+};
+
+static const int ROTB[80] = {
+     8,  9,  9, 11, 13, 15, 15,  5,  7,  7,  8, 11, 14, 14, 12,  6,
+     9, 13, 15,  7, 12,  8,  9, 11,  7,  7, 12,  7,  6, 15, 13, 11,
+     9,  7, 15, 11,  8,  6,  6, 14, 12, 13,  5, 14, 13, 13,  7,  5,
+    15,  5,  8, 11, 14, 14,  6, 14,  6,  9, 12,  9, 12,  5, 15,  8,
+     8,  5, 12,  9, 12,  5, 14,  6,  8, 13,  6,  5, 15, 13, 11, 11
+};
+
+static const int WA[80] = {
+     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+     7,  4, 13,  1, 10,  6, 15,  3, 12,  0,  9,  5,  2, 14, 11,  8,
+     3, 10, 14,  4,  9, 15,  8,  1,  2,  7,  0,  6, 13, 11,  5, 12,
+     1,  9, 11, 10,  0,  8, 12,  4, 13,  3,  7, 15, 14,  5,  6,  2,
+     4,  0,  5,  9,  7, 12,  2, 10, 14,  1,  3,  8, 11,  6, 15, 13
+};
+
+static const int WB[80] = {
+     5, 14,  7,  0,  9,  2, 11,  4, 13,  6, 15,  8,  1, 10,  3, 12,
+     6, 11,  3,  7,  0, 13,  5, 10, 14, 15,  8, 12,  4,  9,  1,  2,
+    15,  5,  1,  3,  7, 14,  6,  9, 11,  8, 12,  2, 10,  0,  4, 13,
+     8,  6,  4,  1,  3, 11, 15,  0,  5, 12,  2, 13,  9,  7, 10, 14,
+    12, 15, 10,  4,  1,  5,  8,  7,  6,  2, 13, 14,  0,  3,  9, 11
+};
+
+#define rol(value, bits) ((value << bits) | (value >> (32 - bits)))
+
+#define SWAP(a,b) if (ext) { int t = a; a = b; b = t; }
+
+#define ROUND128_0_TO_15(a,b,c,d,e,f,g,h)                               \
+    a = rol(a + ((  b ^ c  ^ d)      + block[WA[n]]),         ROTA[n]); \
+    e = rol(e + ((((f ^ g) & h) ^ g) + block[WB[n]] + KB[0]), ROTB[n]); \
+    n++
+
+#define ROUND128_16_TO_31(a,b,c,d,e,f,g,h)                              \
+    a = rol(a + ((((c ^ d) & b) ^ d) + block[WA[n]] + KA[0]), ROTA[n]); \
+    e = rol(e + (((~g | f) ^ h)      + block[WB[n]] + KB[1]), ROTB[n]); \
+    n++
+
+#define ROUND128_32_TO_47(a,b,c,d,e,f,g,h)                              \
+    a = rol(a + (((~c | b) ^ d)      + block[WA[n]] + KA[1]), ROTA[n]); \
+    e = rol(e + ((((g ^ h) & f) ^ h) + block[WB[n]] + KB[2]), ROTB[n]); \
+    n++
+
+#define ROUND128_48_TO_63(a,b,c,d,e,f,g,h)                              \
+    a = rol(a + ((((b ^ c) & d) ^ c) + block[WA[n]] + KA[2]), ROTA[n]); \
+    e = rol(e + ((  f ^ g  ^ h)      + block[WB[n]]),         ROTB[n]); \
+    n++
+
+static void ripemd128_transform(uint32_t *state, const uint8_t buffer[64], int ext)
+{
+    uint32_t a, b, c, d, e, f, g, h;
+    uint32_t block[16];
+    int n;
+
+    if (ext) {
+        a = state[0]; b = state[1]; c = state[2]; d = state[3];
+        e = state[4]; f = state[5]; g = state[6]; h = state[7];
+    } else {
+        a = e = state[0];
+        b = f = state[1];
+        c = g = state[2];
+        d = h = state[3];
+    }
+
+    for (n = 0; n < 16; n++)
+        block[n] = AV_RL32(buffer + 4 * n);
+
+    for (n = 0; n < 16;) {
+        ROUND128_0_TO_15(a,b,c,d,e,f,g,h);
+        ROUND128_0_TO_15(d,a,b,c,h,e,f,g);
+        ROUND128_0_TO_15(c,d,a,b,g,h,e,f);
+        ROUND128_0_TO_15(b,c,d,a,f,g,h,e);
+    }
+    SWAP(a,e)
+
+    for (; n < 32;) {
+        ROUND128_16_TO_31(a,b,c,d,e,f,g,h);
+        ROUND128_16_TO_31(d,a,b,c,h,e,f,g);
+        ROUND128_16_TO_31(c,d,a,b,g,h,e,f);
+        ROUND128_16_TO_31(b,c,d,a,f,g,h,e);
+    }
+    SWAP(b,f)
+
+    for (; n < 48;) {
+        ROUND128_32_TO_47(a,b,c,d,e,f,g,h);
+        ROUND128_32_TO_47(d,a,b,c,h,e,f,g);
+        ROUND128_32_TO_47(c,d,a,b,g,h,e,f);
+        ROUND128_32_TO_47(b,c,d,a,f,g,h,e);
+    }
+    SWAP(c,g)
+
+    for (; n < 64;) {
+        ROUND128_48_TO_63(a,b,c,d,e,f,g,h);
+        ROUND128_48_TO_63(d,a,b,c,h,e,f,g);
+        ROUND128_48_TO_63(c,d,a,b,g,h,e,f);
+        ROUND128_48_TO_63(b,c,d,a,f,g,h,e);
+    }
+    SWAP(d,h)
+
+    if (ext) {
+        state[0] += a; state[1] += b; state[2] += c; state[3] += d;
+        state[4] += e; state[5] += f; state[6] += g; state[7] += h;
+    } else {
+        h += c + state[1];
+        state[1] = state[2] + d + e;
+        state[2] = state[3] + a + f;
+        state[3] = state[0] + b + g;
+        state[0] = h;
+    }
+}
+
+#define ROTATE(x,y) \
+    x = rol(x, 10); \
+    y = rol(y, 10); \
+    n++
+
+#define ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j)                               \
+    a = rol(a + ((  b ^ c  ^ d)      + block[WA[n]]),         ROTA[n]) + e; \
+    f = rol(f + (((~i | h) ^ g)      + block[WB[n]] + KB[0]), ROTB[n]) + j; \
+    ROTATE(c,h)
+
+#define ROUND160_16_TO_31(a,b,c,d,e,f,g,h,i,j)                              \
+    a = rol(a + ((((c ^ d) & b) ^ d) + block[WA[n]] + KA[0]), ROTA[n]) + e; \
+    f = rol(f + ((((g ^ h) & i) ^ h) + block[WB[n]] + KB[1]), ROTB[n]) + j; \
+    ROTATE(c,h)
+
+#define ROUND160_32_TO_47(a,b,c,d,e,f,g,h,i,j)                              \
+    a = rol(a + (((~c | b) ^ d)      + block[WA[n]] + KA[1]), ROTA[n]) + e; \
+    f = rol(f + (((~h | g) ^ i)      + block[WB[n]] + KB[2]), ROTB[n]) + j; \
+    ROTATE(c,h)
+
+#define ROUND160_48_TO_63(a,b,c,d,e,f,g,h,i,j)                              \
+    a = rol(a + ((((b ^ c) & d) ^ c) + block[WA[n]] + KA[2]), ROTA[n]) + e; \
+    f = rol(f + ((((h ^ i) & g) ^ i) + block[WB[n]] + KB[3]), ROTB[n]) + j; \
+    ROTATE(c,h)
+
+#define ROUND160_64_TO_79(a,b,c,d,e,f,g,h,i,j)                              \
+    a = rol(a + (((~d | c) ^ b)      + block[WA[n]] + KA[3]), ROTA[n]) + e; \
+    f = rol(f + ((  g ^ h  ^ i)      + block[WB[n]]),         ROTB[n]) + j; \
+    ROTATE(c,h)
+
+static void ripemd160_transform(uint32_t *state, const uint8_t buffer[64], int ext)
+{
+    uint32_t a, b, c, d, e, f, g, h, i, j;
+    uint32_t block[16];
+    int n;
+
+    if (ext) {
+        a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4];
+        f = state[5]; g = state[6]; h = state[7]; i = state[8]; j = state[9];
+    } else {
+        a = f = state[0];
+        b = g = state[1];
+        c = h = state[2];
+        d = i = state[3];
+        e = j = state[4];
+    }
+
+    for (n = 0; n < 16; n++)
+        block[n] = AV_RL32(buffer + 4 * n);
+
+    for (n = 0; n < 16 - 1;) {
+        ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j);
+        ROUND160_0_TO_15(e,a,b,c,d,j,f,g,h,i);
+        ROUND160_0_TO_15(d,e,a,b,c,i,j,f,g,h);
+        ROUND160_0_TO_15(c,d,e,a,b,h,i,j,f,g);
+        ROUND160_0_TO_15(b,c,d,e,a,g,h,i,j,f);
+    }
+    ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j);
+    SWAP(a,f)
+
+    for (; n < 32 - 1;) {
+        ROUND160_16_TO_31(e,a,b,c,d,j,f,g,h,i);
+        ROUND160_16_TO_31(d,e,a,b,c,i,j,f,g,h);
+        ROUND160_16_TO_31(c,d,e,a,b,h,i,j,f,g);
+        ROUND160_16_TO_31(b,c,d,e,a,g,h,i,j,f);
+        ROUND160_16_TO_31(a,b,c,d,e,f,g,h,i,j);
+    }
+    ROUND160_16_TO_31(e,a,b,c,d,j,f,g,h,i);
+    SWAP(b,g)
+
+    for (; n < 48 - 1;) {
+        ROUND160_32_TO_47(d,e,a,b,c,i,j,f,g,h);
+        ROUND160_32_TO_47(c,d,e,a,b,h,i,j,f,g);
+        ROUND160_32_TO_47(b,c,d,e,a,g,h,i,j,f);
+        ROUND160_32_TO_47(a,b,c,d,e,f,g,h,i,j);
+        ROUND160_32_TO_47(e,a,b,c,d,j,f,g,h,i);
+    }
+    ROUND160_32_TO_47(d,e,a,b,c,i,j,f,g,h);
+    SWAP(c,h)
+
+    for (; n < 64 - 1;) {
+        ROUND160_48_TO_63(c,d,e,a,b,h,i,j,f,g);
+        ROUND160_48_TO_63(b,c,d,e,a,g,h,i,j,f);
+        ROUND160_48_TO_63(a,b,c,d,e,f,g,h,i,j);
+        ROUND160_48_TO_63(e,a,b,c,d,j,f,g,h,i);
+        ROUND160_48_TO_63(d,e,a,b,c,i,j,f,g,h);
+    }
+    ROUND160_48_TO_63(c,d,e,a,b,h,i,j,f,g);
+    SWAP(d,i)
+
+    for (; n < 75;) {
+        ROUND160_64_TO_79(b,c,d,e,a,g,h,i,j,f);
+        ROUND160_64_TO_79(a,b,c,d,e,f,g,h,i,j);
+        ROUND160_64_TO_79(e,a,b,c,d,j,f,g,h,i);
+        ROUND160_64_TO_79(d,e,a,b,c,i,j,f,g,h);
+        ROUND160_64_TO_79(c,d,e,a,b,h,i,j,f,g);
+    }
+    ROUND160_64_TO_79(b,c,d,e,a,g,h,i,j,f);
+    SWAP(e,j)
+
+    if (ext) {
+        state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e;
+        state[5] += f; state[6] += g; state[7] += h; state[8] += i; state[9] += j;
+    } else {
+        i += c + state[1];
+        state[1] = state[2] + d + j;
+        state[2] = state[3] + e + f;
+        state[3] = state[4] + a + g;
+        state[4] = state[0] + b + h;
+        state[0] = i;
+    }
+}
+
+av_cold int av_ripemd_init(AVRIPEMD *ctx, int bits)
+{
+    ctx->digest_len = bits >> 5;
+    switch (bits) {
+    case 128: // RIPEMD-128
+        ctx->state[0] = 0x67452301;
+        ctx->state[1] = 0xEFCDAB89;
+        ctx->state[2] = 0x98BADCFE;
+        ctx->state[3] = 0x10325476;
+        ctx->transform = ripemd128_transform;
+        ctx->ext = 0;
+        break;
+    case 160: // RIPEMD-160
+        ctx->state[0] = 0x67452301;
+        ctx->state[1] = 0xEFCDAB89;
+        ctx->state[2] = 0x98BADCFE;
+        ctx->state[3] = 0x10325476;
+        ctx->state[4] = 0xC3D2E1F0;
+        ctx->transform = ripemd160_transform;
+        ctx->ext = 0;
+        break;
+    case 256: // RIPEMD-256
+        ctx->state[0] = 0x67452301;
+        ctx->state[1] = 0xEFCDAB89;
+        ctx->state[2] = 0x98BADCFE;
+        ctx->state[3] = 0x10325476;
+        ctx->state[4] = 0x76543210;
+        ctx->state[5] = 0xFEDCBA98;
+        ctx->state[6] = 0x89ABCDEF;
+        ctx->state[7] = 0x01234567;
+        ctx->transform = ripemd128_transform;
+        ctx->ext = 1;
+        break;
+    case 320: // RIPEMD-320
+        ctx->state[0] = 0x67452301;
+        ctx->state[1] = 0xEFCDAB89;
+        ctx->state[2] = 0x98BADCFE;
+        ctx->state[3] = 0x10325476;
+        ctx->state[4] = 0xC3D2E1F0;
+        ctx->state[5] = 0x76543210;
+        ctx->state[6] = 0xFEDCBA98;
+        ctx->state[7] = 0x89ABCDEF;
+        ctx->state[8] = 0x01234567;
+        ctx->state[9] = 0x3C2D1E0F;
+        ctx->transform = ripemd160_transform;
+        ctx->ext = 1;
+        break;
+    default:
+        return -1;
+    }
+    ctx->count = 0;
+    return 0;
+}
+
+void av_ripemd_update(AVRIPEMD* ctx, const uint8_t* data, unsigned int len)
+{
+    unsigned int i, j;
+
+    j = ctx->count & 63;
+    ctx->count += len;
+#if CONFIG_SMALL
+    for (i = 0; i < len; i++) {
+        ctx->buffer[j++] = data[i];
+        if (64 == j) {
+            ctx->transform(ctx->state, ctx->buffer, ctx->ext);
+            j = 0;
+        }
+    }
+#else
+    if ((j + len) > 63) {
+        memcpy(&ctx->buffer[j], data, (i = 64 - j));
+        ctx->transform(ctx->state, ctx->buffer, ctx->ext);
+        for (; i + 63 < len; i += 64)
+            ctx->transform(ctx->state, &data[i], ctx->ext);
+        j = 0;
+    } else
+        i = 0;
+    memcpy(&ctx->buffer[j], &data[i], len - i);
+#endif
+}
+
+void av_ripemd_final(AVRIPEMD* ctx, uint8_t *digest)
+{
+    int i;
+    uint64_t finalcount = av_le2ne64(ctx->count << 3);
+
+    av_ripemd_update(ctx, "\200", 1);
+    while ((ctx->count & 63) != 56)
+        av_ripemd_update(ctx, "", 1);
+    av_ripemd_update(ctx, (uint8_t *)&finalcount, 8); /* Should cause a transform() */
+    for (i = 0; i < ctx->digest_len; i++)
+        AV_WL32(digest + i*4, ctx->state[i]);
+}
+
+#ifdef TEST
+#include <stdio.h>
+
+int main(void)
+{
+    int i, j, k;
+    AVRIPEMD ctx;
+    unsigned char digest[40];
+    static const int lengths[4] = { 128, 160, 256, 320 };
+
+    for (j = 0; j < 4; j++) {
+        printf("Testing RIPEMD-%d\n", lengths[j]);
+        for (k = 0; k < 3; k++) {
+            av_ripemd_init(&ctx, lengths[j]);
+            if (k == 0)
+                av_ripemd_update(&ctx, "abc", 3);
+            else if (k == 1)
+                av_ripemd_update(&ctx, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56);
+            else
+                for (i = 0; i < 1000*1000; i++)
+                    av_ripemd_update(&ctx, "a", 1);
+            av_ripemd_final(&ctx, digest);
+            for (i = 0; i < lengths[j] >> 3; i++)
+                printf("%02X", digest[i]);
+            putchar('\n');
+        }
+        switch (j) { //test vectors (from ISO:IEC 10118-3 (2004) and http://homes.esat.kuleuven.be/~bosselae/ripemd160.html)
+        case 0:
+            printf("c14a1219 9c66e4ba 84636b0f 69144c77\n"
+                   "a1aa0689 d0fafa2d dc22e88b 49133a06\n"
+                   "4a7f5723 f954eba1 216c9d8f 6320431f\n");
+            break;
+        case 1:
+            printf("8eb208f7 e05d987a 9b044a8e 98c6b087 f15a0bfc\n"
+                   "12a05338 4a9c0c88 e405a06c 27dcf49a da62eb2b\n"
+                   "52783243 c1697bdb e16d37f9 7f68f083 25dc1528\n");
+            break;
+        case 2:
+            printf("afbd6e22 8b9d8cbb cef5ca2d 03e6dba1 0ac0bc7d cbe4680e 1e42d2e9 75459b65\n"
+                   "38430455 83aac6c8 c8d91285 73e7a980 9afb2a0f 34ccc36e a9e72f16 f6368e3f\n"
+                   "ac953744 e10e3151 4c150d4d 8d7b6773 42e33399 788296e4 3ae4850c e4f97978\n");
+            break;
+        case 3:
+            printf("de4c01b3 054f8930 a79d09ae 738e9230 1e5a1708 5beffdc1 b8d11671 3e74f82f a942d64c dbc4682d\n"
+                   "d034a795 0cf72202 1ba4b84d f769a5de 2060e259 df4c9bb4 a4268c0e 935bbc74 70a969c9 d072a1ac\n"
+                   "bdee37f4 371e2064 6b8b0d86 2dda1629 2ae36f40 965e8c85 09e63d1d bddecc50 3e2b63eb 9245bb66\n");
+            break;
+        }
+    }
+
+    return 0;
+}
+#endif
diff --git a/libavutil/ripemd.h b/libavutil/ripemd.h
new file mode 100644
index 0000000..7b0c8bc
--- /dev/null
+++ b/libavutil/ripemd.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2007 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (C) 2013 James Almer <jamrial@gmail.com>
+ *
+ * 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
+ */
+
+#ifndef AVUTIL_RIPEMD_H
+#define AVUTIL_RIPEMD_H
+
+#include <stdint.h>
+
+#include "attributes.h"
+#include "version.h"
+
+/**
+ * @defgroup lavu_ripemd RIPEMD
+ * @ingroup lavu_crypto
+ * @{
+ */
+
+extern const int av_ripemd_size;
+
+struct AVRIPEMD;
+
+/**
+ * Allocate an AVRIPEMD context.
+ */
+struct AVRIPEMD *av_ripemd_alloc(void);
+
+/**
+ * Initialize RIPEMD hashing.
+ *
+ * @param context pointer to the function context (of size av_ripemd_size)
+ * @param bits    number of bits in digest (128, 160, 256 or 320 bits)
+ * @return        zero if initialization succeeded, -1 otherwise
+ */
+int av_ripemd_init(struct AVRIPEMD* context, int bits);
+
+/**
+ * Update hash value.
+ *
+ * @param context hash function context
+ * @param data    input data to update hash with
+ * @param len     input data length
+ */
+void av_ripemd_update(struct AVRIPEMD* context, const uint8_t* data, unsigned int len);
+
+/**
+ * Finish hashing and output digest value.
+ *
+ * @param context hash function context
+ * @param digest  buffer where output digest value is stored
+ */
+void av_ripemd_final(struct AVRIPEMD* context, uint8_t *digest);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_RIPEMD_H */
diff --git a/libavutil/sha.c b/libavutil/sha.c
index 9f630fc..8c4f8a0 100644
--- a/libavutil/sha.c
+++ b/libavutil/sha.c
@@ -22,6 +22,8 @@
  */
 
 #include <string.h>
+
+#include "attributes.h"
 #include "avutil.h"
 #include "bswap.h"
 #include "sha.h"
@@ -158,7 +160,7 @@
 
 
 #define Ch(x,y,z)   (((x) & ((y) ^ (z))) ^ (z))
-#define Maj(x,y,z)  ((((x) | (y)) & (z)) | ((x) & (y)))
+#define Maj(z,y,x)  ((((x) | (y)) & (z)) | ((x) & (y)))
 
 #define Sigma0_256(x)   (rol((x), 30) ^ rol((x), 19) ^ rol((x), 10))
 #define Sigma1_256(x)   (rol((x), 26) ^ rol((x), 21) ^ rol((x),  7))
@@ -249,7 +251,7 @@
 }
 
 
-int av_sha_init(AVSHA* ctx, int bits)
+av_cold int av_sha_init(AVSHA *ctx, int bits)
 {
     ctx->digest_len = bits >> 5;
     switch (bits) {
@@ -338,7 +340,7 @@
     int i, j, k;
     AVSHA ctx;
     unsigned char digest[32];
-    const int lengths[3] = { 160, 224, 256 };
+    static const int lengths[3] = { 160, 224, 256 };
 
     for (j = 0; j < 3; j++) {
         printf("Testing SHA-%d\n", lengths[j]);
diff --git a/libavutil/sha512.c b/libavutil/sha512.c
new file mode 100644
index 0000000..84136037
--- /dev/null
+++ b/libavutil/sha512.c
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2007 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (C) 2009 Konstantin Shishkov
+ * Copyright (C) 2013 James Almer
+ * based on BSD-licensed SHA-2 code by Aaron D. Gifford
+ *
+ * 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
+ */
+
+#include <string.h>
+
+#include "attributes.h"
+#include "avutil.h"
+#include "bswap.h"
+#include "sha512.h"
+#include "intreadwrite.h"
+#include "mem.h"
+
+/** hash context */
+typedef struct AVSHA512 {
+    uint8_t  digest_len;  ///< digest length in 64-bit words
+    uint64_t count;       ///< number of bytes in buffer
+    uint8_t  buffer[128]; ///< 1024-bit buffer of input values used in hash updating
+    uint64_t state[8];    ///< current hash value
+} AVSHA512;
+
+const int av_sha512_size = sizeof(AVSHA512);
+
+struct AVSHA512 *av_sha512_alloc(void)
+{
+    return av_mallocz(sizeof(struct AVSHA512));
+}
+
+static const uint64_t K512[80] = {
+    UINT64_C(0x428a2f98d728ae22),  UINT64_C(0x7137449123ef65cd),
+    UINT64_C(0xb5c0fbcfec4d3b2f),  UINT64_C(0xe9b5dba58189dbbc),
+    UINT64_C(0x3956c25bf348b538),  UINT64_C(0x59f111f1b605d019),
+    UINT64_C(0x923f82a4af194f9b),  UINT64_C(0xab1c5ed5da6d8118),
+    UINT64_C(0xd807aa98a3030242),  UINT64_C(0x12835b0145706fbe),
+    UINT64_C(0x243185be4ee4b28c),  UINT64_C(0x550c7dc3d5ffb4e2),
+    UINT64_C(0x72be5d74f27b896f),  UINT64_C(0x80deb1fe3b1696b1),
+    UINT64_C(0x9bdc06a725c71235),  UINT64_C(0xc19bf174cf692694),
+    UINT64_C(0xe49b69c19ef14ad2),  UINT64_C(0xefbe4786384f25e3),
+    UINT64_C(0x0fc19dc68b8cd5b5),  UINT64_C(0x240ca1cc77ac9c65),
+    UINT64_C(0x2de92c6f592b0275),  UINT64_C(0x4a7484aa6ea6e483),
+    UINT64_C(0x5cb0a9dcbd41fbd4),  UINT64_C(0x76f988da831153b5),
+    UINT64_C(0x983e5152ee66dfab),  UINT64_C(0xa831c66d2db43210),
+    UINT64_C(0xb00327c898fb213f),  UINT64_C(0xbf597fc7beef0ee4),
+    UINT64_C(0xc6e00bf33da88fc2),  UINT64_C(0xd5a79147930aa725),
+    UINT64_C(0x06ca6351e003826f),  UINT64_C(0x142929670a0e6e70),
+    UINT64_C(0x27b70a8546d22ffc),  UINT64_C(0x2e1b21385c26c926),
+    UINT64_C(0x4d2c6dfc5ac42aed),  UINT64_C(0x53380d139d95b3df),
+    UINT64_C(0x650a73548baf63de),  UINT64_C(0x766a0abb3c77b2a8),
+    UINT64_C(0x81c2c92e47edaee6),  UINT64_C(0x92722c851482353b),
+    UINT64_C(0xa2bfe8a14cf10364),  UINT64_C(0xa81a664bbc423001),
+    UINT64_C(0xc24b8b70d0f89791),  UINT64_C(0xc76c51a30654be30),
+    UINT64_C(0xd192e819d6ef5218),  UINT64_C(0xd69906245565a910),
+    UINT64_C(0xf40e35855771202a),  UINT64_C(0x106aa07032bbd1b8),
+    UINT64_C(0x19a4c116b8d2d0c8),  UINT64_C(0x1e376c085141ab53),
+    UINT64_C(0x2748774cdf8eeb99),  UINT64_C(0x34b0bcb5e19b48a8),
+    UINT64_C(0x391c0cb3c5c95a63),  UINT64_C(0x4ed8aa4ae3418acb),
+    UINT64_C(0x5b9cca4f7763e373),  UINT64_C(0x682e6ff3d6b2b8a3),
+    UINT64_C(0x748f82ee5defb2fc),  UINT64_C(0x78a5636f43172f60),
+    UINT64_C(0x84c87814a1f0ab72),  UINT64_C(0x8cc702081a6439ec),
+    UINT64_C(0x90befffa23631e28),  UINT64_C(0xa4506cebde82bde9),
+    UINT64_C(0xbef9a3f7b2c67915),  UINT64_C(0xc67178f2e372532b),
+    UINT64_C(0xca273eceea26619c),  UINT64_C(0xd186b8c721c0c207),
+    UINT64_C(0xeada7dd6cde0eb1e),  UINT64_C(0xf57d4f7fee6ed178),
+    UINT64_C(0x06f067aa72176fba),  UINT64_C(0x0a637dc5a2c898a6),
+    UINT64_C(0x113f9804bef90dae),  UINT64_C(0x1b710b35131c471b),
+    UINT64_C(0x28db77f523047d84),  UINT64_C(0x32caab7b40c72493),
+    UINT64_C(0x3c9ebe0a15c9bebc),  UINT64_C(0x431d67c49c100d4c),
+    UINT64_C(0x4cc5d4becb3e42b6),  UINT64_C(0x597f299cfc657e2a),
+    UINT64_C(0x5fcb6fab3ad6faec),  UINT64_C(0x6c44198c4a475817),
+};
+
+#define ror(value, bits) (((value) >> (bits)) | ((value) << (64 - (bits))))
+
+#define Ch(x,y,z)   (((x) & ((y) ^ (z))) ^ (z))
+#define Maj(z,y,x)  ((((x) | (y)) & (z)) | ((x) & (y)))
+
+#define Sigma0_512(x)   (ror((x), 28) ^ ror((x), 34) ^ ror((x), 39))
+#define Sigma1_512(x)   (ror((x), 14) ^ ror((x), 18) ^ ror((x), 41))
+#define sigma0_512(x)   (ror((x),  1) ^ ror((x),  8) ^ ((x) >> 7))
+#define sigma1_512(x)   (ror((x), 19) ^ ror((x), 61) ^ ((x) >> 6))
+
+#define blk0(i) (block[i] = AV_RB64(buffer + 8 * (i)))
+#define blk(i)  (block[i] = block[i - 16] + sigma0_512(block[i - 15]) + \
+                            sigma1_512(block[i - 2]) + block[i - 7])
+
+#define ROUND512(a,b,c,d,e,f,g,h)   \
+    T1 += (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[i]; \
+    (d) += T1; \
+    (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
+    i++
+
+#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)   \
+    T1 = blk0(i); \
+    ROUND512(a,b,c,d,e,f,g,h)
+
+#define ROUND512_16_TO_80(a,b,c,d,e,f,g,h)   \
+    T1 = blk(i); \
+    ROUND512(a,b,c,d,e,f,g,h)
+
+static void sha512_transform(uint64_t *state, const uint8_t buffer[128])
+{
+    uint64_t a, b, c, d, e, f, g, h;
+    uint64_t block[80];
+    uint64_t T1;
+    int i;
+
+    a = state[0];
+    b = state[1];
+    c = state[2];
+    d = state[3];
+    e = state[4];
+    f = state[5];
+    g = state[6];
+    h = state[7];
+#if CONFIG_SMALL
+    for (i = 0; i < 80; i++) {
+        uint64_t T2;
+        if (i < 16)
+            T1 = blk0(i);
+        else
+            T1 = blk(i);
+        T1 += h + Sigma1_512(e) + Ch(e, f, g) + K512[i];
+        T2 = Sigma0_512(a) + Maj(a, b, c);
+        h = g;
+        g = f;
+        f = e;
+        e = d + T1;
+        d = c;
+        c = b;
+        b = a;
+        a = T1 + T2;
+    }
+#else
+    for (i = 0; i < 16 - 7;) {
+        ROUND512_0_TO_15(a, b, c, d, e, f, g, h);
+        ROUND512_0_TO_15(h, a, b, c, d, e, f, g);
+        ROUND512_0_TO_15(g, h, a, b, c, d, e, f);
+        ROUND512_0_TO_15(f, g, h, a, b, c, d, e);
+        ROUND512_0_TO_15(e, f, g, h, a, b, c, d);
+        ROUND512_0_TO_15(d, e, f, g, h, a, b, c);
+        ROUND512_0_TO_15(c, d, e, f, g, h, a, b);
+        ROUND512_0_TO_15(b, c, d, e, f, g, h, a);
+    }
+
+    for (; i < 80 - 7;) {
+        ROUND512_16_TO_80(a, b, c, d, e, f, g, h);
+        ROUND512_16_TO_80(h, a, b, c, d, e, f, g);
+        ROUND512_16_TO_80(g, h, a, b, c, d, e, f);
+        ROUND512_16_TO_80(f, g, h, a, b, c, d, e);
+        ROUND512_16_TO_80(e, f, g, h, a, b, c, d);
+        ROUND512_16_TO_80(d, e, f, g, h, a, b, c);
+        ROUND512_16_TO_80(c, d, e, f, g, h, a, b);
+        ROUND512_16_TO_80(b, c, d, e, f, g, h, a);
+    }
+#endif
+    state[0] += a;
+    state[1] += b;
+    state[2] += c;
+    state[3] += d;
+    state[4] += e;
+    state[5] += f;
+    state[6] += g;
+    state[7] += h;
+}
+
+
+av_cold int av_sha512_init(AVSHA512 *ctx, int bits)
+{
+    ctx->digest_len = bits >> 6;
+    switch (bits) {
+    case 224: // SHA-512/224
+        ctx->state[0] = UINT64_C(0x8C3D37C819544DA2);
+        ctx->state[1] = UINT64_C(0x73E1996689DCD4D6);
+        ctx->state[2] = UINT64_C(0x1DFAB7AE32FF9C82);
+        ctx->state[3] = UINT64_C(0x679DD514582F9FCF);
+        ctx->state[4] = UINT64_C(0x0F6D2B697BD44DA8);
+        ctx->state[5] = UINT64_C(0x77E36F7304C48942);
+        ctx->state[6] = UINT64_C(0x3F9D85A86A1D36C8);
+        ctx->state[7] = UINT64_C(0x1112E6AD91D692A1);
+        break;
+    case 256: // SHA-512/256
+        ctx->state[0] = UINT64_C(0x22312194FC2BF72C);
+        ctx->state[1] = UINT64_C(0x9F555FA3C84C64C2);
+        ctx->state[2] = UINT64_C(0x2393B86B6F53B151);
+        ctx->state[3] = UINT64_C(0x963877195940EABD);
+        ctx->state[4] = UINT64_C(0x96283EE2A88EFFE3);
+        ctx->state[5] = UINT64_C(0xBE5E1E2553863992);
+        ctx->state[6] = UINT64_C(0x2B0199FC2C85B8AA);
+        ctx->state[7] = UINT64_C(0x0EB72DDC81C52CA2);
+        break;
+    case 384: // SHA-384
+        ctx->state[0] = UINT64_C(0xCBBB9D5DC1059ED8);
+        ctx->state[1] = UINT64_C(0x629A292A367CD507);
+        ctx->state[2] = UINT64_C(0x9159015A3070DD17);
+        ctx->state[3] = UINT64_C(0x152FECD8F70E5939);
+        ctx->state[4] = UINT64_C(0x67332667FFC00B31);
+        ctx->state[5] = UINT64_C(0x8EB44A8768581511);
+        ctx->state[6] = UINT64_C(0xDB0C2E0D64F98FA7);
+        ctx->state[7] = UINT64_C(0x47B5481DBEFA4FA4);
+        break;
+    case 512: // SHA-512
+        ctx->state[0] = UINT64_C(0x6A09E667F3BCC908);
+        ctx->state[1] = UINT64_C(0xBB67AE8584CAA73B);
+        ctx->state[2] = UINT64_C(0x3C6EF372FE94F82B);
+        ctx->state[3] = UINT64_C(0xA54FF53A5F1D36F1);
+        ctx->state[4] = UINT64_C(0x510E527FADE682D1);
+        ctx->state[5] = UINT64_C(0x9B05688C2B3E6C1F);
+        ctx->state[6] = UINT64_C(0x1F83D9ABFB41BD6B);
+        ctx->state[7] = UINT64_C(0x5BE0CD19137E2179);
+        break;
+    default:
+        return -1;
+    }
+    ctx->count = 0;
+    return 0;
+}
+
+void av_sha512_update(AVSHA512* ctx, const uint8_t* data, unsigned int len)
+{
+    unsigned int i, j;
+
+    j = ctx->count & 127;
+    ctx->count += len;
+#if CONFIG_SMALL
+    for (i = 0; i < len; i++) {
+        ctx->buffer[j++] = data[i];
+        if (128 == j) {
+            sha512_transform(ctx->state, ctx->buffer);
+            j = 0;
+        }
+    }
+#else
+    if ((j + len) > 127) {
+        memcpy(&ctx->buffer[j], data, (i = 128 - j));
+        sha512_transform(ctx->state, ctx->buffer);
+        for (; i + 127 < len; i += 128)
+            sha512_transform(ctx->state, &data[i]);
+        j = 0;
+    } else
+        i = 0;
+    memcpy(&ctx->buffer[j], &data[i], len - i);
+#endif
+}
+
+void av_sha512_final(AVSHA512* ctx, uint8_t *digest)
+{
+    uint64_t i = 0;
+    uint64_t finalcount = av_be2ne64(ctx->count << 3);
+
+    av_sha512_update(ctx, "\200", 1);
+    while ((ctx->count & 127) != 112)
+        av_sha512_update(ctx, "", 1);
+    av_sha512_update(ctx, (uint8_t *)&i, 8);
+    av_sha512_update(ctx, (uint8_t *)&finalcount, 8); /* Should cause a transform() */
+    for (i = 0; i < ctx->digest_len; i++)
+        AV_WB64(digest + i*8, ctx->state[i]);
+    if (ctx->digest_len & 1) /* SHA512/224 is 28 bytes, and is not divisible by 8. */
+        AV_WB32(digest + i*8, ctx->state[i] >> 32);
+}
+
+#ifdef TEST
+#include <stdio.h>
+
+int main(void)
+{
+    int i, j, k;
+    AVSHA512 ctx;
+    unsigned char digest[64];
+    static const int lengths[4] = { 224, 256, 384, 512 };
+
+    for (j = 0; j < 4; j++) {
+        if (j < 2) printf("Testing SHA-512/%d\n", lengths[j]);
+        else       printf("Testing SHA-%d\n", lengths[j]);
+        for (k = 0; k < 3; k++) {
+            av_sha512_init(&ctx, lengths[j]);
+            if (k == 0)
+                av_sha512_update(&ctx, "abc", 3);
+            else if (k == 1)
+                av_sha512_update(&ctx, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+                                       "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112);
+            else
+                for (i = 0; i < 1000*1000; i++)
+                    av_sha512_update(&ctx, "a", 1);
+            av_sha512_final(&ctx, digest);
+            for (i = 0; i < lengths[j] >> 3; i++)
+                printf("%02X", digest[i]);
+            putchar('\n');
+        }
+        switch (j) { //test vectors (from FIPS PUB 180-4 Apendix A)
+        case 0:
+            printf("4634270f 707b6a54 daae7530 460842e2 0e37ed26 5ceee9a4 3e8924aa\n"
+                   "23fec5bb 94d60b23 30819264 0b0c4533 35d66473 4fe40e72 68674af9\n"
+                   "37ab331d 76f0d36d e422bd0e deb22a28 accd487b 7a8453ae 965dd287\n");
+            break;
+        case 1:
+            printf("53048e26 81941ef9 9b2e29b7 6b4c7dab e4c2d0c6 34fc6d46 e0e2f131 07e7af23\n"
+                   "3928e184 fb8690f8 40da3988 121d31be 65cb9d3e f83ee614 6feac861 e19b563a\n"
+                   "9a59a052 930187a9 7038cae6 92f30708 aa649192 3ef51943 94dc68d5 6c74fb21\n");
+            break;
+        case 2:
+            printf("cb00753f 45a35e8b b5a03d69 9ac65007 272c32ab 0eded163 "
+                   "1a8b605a 43ff5bed 8086072b a1e7cc23 58baeca1 34c825a7\n"
+                   "09330c33 f71147e8 3d192fc7 82cd1b47 53111b17 3b3b05d2 "
+                   "2fa08086 e3b0f712 fcc7c71a 557e2db9 66c3e9fa 91746039\n"
+                   "9d0e1809 716474cb 086e834e 310a4a1c ed149e9c 00f24852 "
+                   "7972cec5 704c2a5b 07b8b3dc 38ecc4eb ae97ddd8 7f3d8985\n");
+            break;
+        case 3:
+            printf("ddaf35a1 93617aba cc417349 ae204131 12e6fa4e 89a97ea2 0a9eeee6 4b55d39a "
+                   "2192992a 274fc1a8 36ba3c23 a3feebbd 454d4423 643ce80e 2a9ac94f a54ca49f\n"
+                   "8e959b75 dae313da 8cf4f728 14fc143f 8f7779c6 eb9f7fa1 7299aead b6889018 "
+                   "501d289e 4900f7e4 331b99de c4b5433a c7d329ee b6dd2654 5e96e55b 874be909\n"
+                   "e718483d 0ce76964 4e2e42c7 bc15b463 8e1f98b1 3b204428 5632a803 afa973eb "
+                   "de0ff244 877ea60a 4cb0432c e577c31b eb009c5c 2c49aa2e 4eadb217 ad8cc09b\n");
+            break;
+        }
+    }
+
+    return 0;
+}
+#endif
diff --git a/libavutil/sha512.h b/libavutil/sha512.h
new file mode 100644
index 0000000..7b08701
--- /dev/null
+++ b/libavutil/sha512.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2007 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (C) 2013 James Almer <jamrial@gmail.com>
+ *
+ * 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
+ */
+
+#ifndef AVUTIL_SHA512_H
+#define AVUTIL_SHA512_H
+
+#include <stdint.h>
+
+#include "attributes.h"
+#include "version.h"
+
+/**
+ * @defgroup lavu_sha512 SHA512
+ * @ingroup lavu_crypto
+ * @{
+ */
+
+extern const int av_sha512_size;
+
+struct AVSHA512;
+
+/**
+ * Allocate an AVSHA512 context.
+ */
+struct AVSHA512 *av_sha512_alloc(void);
+
+/**
+ * Initialize SHA-2 512 hashing.
+ *
+ * @param context pointer to the function context (of size av_sha512_size)
+ * @param bits    number of bits in digest (224, 256, 384 or 512 bits)
+ * @return        zero if initialization succeeded, -1 otherwise
+ */
+int av_sha512_init(struct AVSHA512* context, int bits);
+
+/**
+ * Update hash value.
+ *
+ * @param context hash function context
+ * @param data    input data to update hash with
+ * @param len     input data length
+ */
+void av_sha512_update(struct AVSHA512* context, const uint8_t* data, unsigned int len);
+
+/**
+ * Finish hashing and output digest value.
+ *
+ * @param context hash function context
+ * @param digest  buffer where output digest value is stored
+ */
+void av_sha512_final(struct AVSHA512* context, uint8_t *digest);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_SHA512_H */
diff --git a/libavutil/softfloat.c b/libavutil/softfloat.c
index efa0420..bf9cfda 100644
--- a/libavutil/softfloat.c
+++ b/libavutil/softfloat.c
@@ -20,7 +20,6 @@
 
 #include <inttypes.h>
 #include <stdio.h>
-#include <assert.h>
 #include "softfloat.h"
 #include "common.h"
 #include "log.h"
diff --git a/libavutil/timestamp.h b/libavutil/timestamp.h
index c7348d8..f63a08c 100644
--- a/libavutil/timestamp.h
+++ b/libavutil/timestamp.h
@@ -39,7 +39,7 @@
 static inline char *av_ts_make_string(char *buf, int64_t ts)
 {
     if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS");
-    else                      snprintf(buf, AV_TS_MAX_STRING_SIZE, "%"PRId64"", ts);
+    else                      snprintf(buf, AV_TS_MAX_STRING_SIZE, "%"PRId64, ts);
     return buf;
 }
 
diff --git a/libavutil/tree.c b/libavutil/tree.c
index c6ae23d..e1b3197 100644
--- a/libavutil/tree.c
+++ b/libavutil/tree.c
@@ -18,6 +18,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "error.h"
 #include "log.h"
 #include "mem.h"
 #include "tree.h"
@@ -41,7 +42,8 @@
     if (t) {
         unsigned int v = cmp(key, t->elem);
         if (v) {
-            if (next) next[v >> 31] = t->elem;
+            if (next)
+                next[v >> 31] = t->elem;
             return av_tree_find(t->child[(v >> 31) ^ 1], key, cmp, next);
         } else {
             if (next) {
@@ -69,56 +71,60 @@
                 void *next_elem[2];
                 av_tree_find(t->child[i], key, cmp, next_elem);
                 key = t->elem = next_elem[i];
-                v = -i;
+                v   = -i;
             } else {
                 *next = t;
-                *tp = NULL;
+                *tp   = NULL;
                 return NULL;
             }
         }
         ret = av_tree_insert(&t->child[v >> 31], key, cmp, next);
         if (!ret) {
-            int i = (v >> 31) ^ !!*next;
+            int i              = (v >> 31) ^ !!*next;
             AVTreeNode **child = &t->child[i];
             t->state += 2 * i - 1;
 
             if (!(t->state & 1)) {
                 if (t->state) {
                     /* The following code is equivalent to
-                    if((*child)->state*2 == -t->state)
-                        rotate(child, i^1);
-                    rotate(tp, i);
-
-                    with rotate():
-                    static void rotate(AVTreeNode **tp, int i) {
-                        AVTreeNode *t= *tp;
-
-                        *tp= t->child[i];
-                        t->child[i]= t->child[i]->child[i^1];
-                        (*tp)->child[i^1]= t;
-                        i= 4*t->state + 2*(*tp)->state + 12;
-                          t  ->state=                     ((0x614586 >> i) & 3)-1;
-                        (*tp)->state= ((*tp)->state>>1) + ((0x400EEA >> i) & 3)-1;
-                    }
-                    but such a rotate function is both bigger and slower
-                    */
-                    if (( *child )->state * 2 == -t->state) {
+                     * if ((*child)->state * 2 == -t->state)
+                     *     rotate(child, i ^ 1);
+                     * rotate(tp, i);
+                     *
+                     * with rotate():
+                     * static void rotate(AVTreeNode **tp, int i)
+                     * {
+                     *     AVTreeNode *t= *tp;
+                     *
+                     *     *tp = t->child[i];
+                     *     t->child[i] = t->child[i]->child[i ^ 1];
+                     *     (*tp)->child[i ^ 1] = t;
+                     *     i = 4 * t->state + 2 * (*tp)->state + 12;
+                     *     t->state     = ((0x614586 >> i) & 3) - 1;
+                     *     (*tp)->state = ((0x400EEA >> i) & 3) - 1 +
+                     *                    ((*tp)->state >> 1);
+                     * }
+                     * but such a rotate function is both bigger and slower
+                     */
+                    if ((*child)->state * 2 == -t->state) {
                         *tp                    = (*child)->child[i ^ 1];
                         (*child)->child[i ^ 1] = (*tp)->child[i];
                         (*tp)->child[i]        = *child;
-                        *child                 = ( *tp )->child[i ^ 1];
+                        *child                 = (*tp)->child[i ^ 1];
                         (*tp)->child[i ^ 1]    = t;
 
                         (*tp)->child[0]->state = -((*tp)->state > 0);
-                        (*tp)->child[1]->state =   (*tp)->state < 0;
+                        (*tp)->child[1]->state = (*tp)->state < 0;
                         (*tp)->state           = 0;
                     } else {
-                        *tp                    = *child;
-                        *child                 = (*child)->child[i ^ 1];
-                        (*tp)->child[i ^ 1]    = t;
-                        if ((*tp)->state) t->state = 0;
-                        else              t->state >>= 1;
-                        (*tp)->state           = -t->state;
+                        *tp                 = *child;
+                        *child              = (*child)->child[i ^ 1];
+                        (*tp)->child[i ^ 1] = t;
+                        if ((*tp)->state)
+                            t->state = 0;
+                        else
+                            t->state >>= 1;
+                        (*tp)->state = -t->state;
                     }
                 }
             }
@@ -172,11 +178,11 @@
         int left  = check(t->child[0]);
         int right = check(t->child[1]);
 
-        if (left>999 || right>999)
+        if (left > 999 || right > 999)
             return 1000;
         if (right - left != t->state)
             return 1000;
-        if (t->state>1 || t->state<-1)
+        if (t->state > 1 || t->state < -1)
             return 1000;
         return FFMAX(left, right) + 1;
     }
@@ -186,7 +192,8 @@
 static void print(AVTreeNode *t, int depth)
 {
     int i;
-    for (i = 0; i < depth * 4; i++) av_log(NULL, AV_LOG_ERROR, " ");
+    for (i = 0; i < depth * 4; i++)
+        av_log(NULL, AV_LOG_ERROR, " ");
     if (t) {
         av_log(NULL, AV_LOG_ERROR, "Node %p %2d %p\n", t, t->state, t->elem);
         print(t->child[0], depth + 1);
@@ -200,37 +207,51 @@
     return (uint8_t *) a - (const uint8_t *) b;
 }
 
-int main (void)
+int main(int argc, char **argv)
 {
     int i;
     void *k;
     AVTreeNode *root = NULL, *node = NULL;
     AVLFG prng;
+    int log_level = argc <= 1 ? AV_LOG_INFO : atoi(argv[1]);
+
+    av_log_set_level(log_level);
 
     av_lfg_init(&prng, 1);
 
     for (i = 0; i < 10000; i++) {
         intptr_t j = av_lfg_get(&prng) % 86294;
+
         if (check(root) > 999) {
             av_log(NULL, AV_LOG_ERROR, "FATAL error %d\n", i);
-        print(root, 0);
+            print(root, 0);
             return -1;
         }
-        av_log(NULL, AV_LOG_ERROR, "inserting %4d\n", (int)j);
+        av_log(NULL, AV_LOG_DEBUG, "inserting %4d\n", (int)j);
+
         if (!node)
             node = av_tree_node_alloc();
-        av_tree_insert(&root, (void *) (j + 1), cmp, &node);
+        if (!node) {
+            av_log(NULL, AV_LOG_ERROR, "Memory allocation failure.\n");
+            return AVERROR(ENOMEM);
+        }
+        av_tree_insert(&root, (void *)(j + 1), cmp, &node);
 
         j = av_lfg_get(&prng) % 86294;
         {
             AVTreeNode *node2 = NULL;
-            av_log(NULL, AV_LOG_ERROR, "removing %4d\n", (int)j);
-            av_tree_insert(&root, (void *) (j + 1), cmp, &node2);
-            k = av_tree_find(root, (void *) (j + 1), cmp, NULL);
+            av_log(NULL, AV_LOG_DEBUG, "removing %4d\n", (int)j);
+            av_tree_insert(&root, (void *)(j + 1), cmp, &node2);
+            k = av_tree_find(root, (void *)(j + 1), cmp, NULL);
             if (k)
                 av_log(NULL, AV_LOG_ERROR, "removal failure %d\n", i);
+            av_free(node2);
         }
     }
+    av_free(node);
+
+    av_tree_destroy(root);
+
     return 0;
 }
 #endif
diff --git a/libavutil/tree.h b/libavutil/tree.h
index 13fb91b..a14fa91 100644
--- a/libavutil/tree.h
+++ b/libavutil/tree.h
@@ -34,10 +34,10 @@
  * @addtogroup lavu_tree AVTree
  * @ingroup lavu_data
  *
- * Low complexity tree container
+ * Low-complexity tree container
  *
  * Insertion, removal, finding equal, largest which is smaller than and
- * smallest which is larger than, all have O(log n) worst case complexity.
+ * smallest which is larger than, all have O(log n) worst-case complexity.
  * @{
  */
 
@@ -56,10 +56,11 @@
  * @param next If next is not NULL, then next[0] will contain the previous
  *             element and next[1] the next element. If either does not exist,
  *             then the corresponding entry in next is unchanged.
- * @return An element with cmp(key, elem)==0 or NULL if no such element exists in
- *         the tree.
+ * @return An element with cmp(key, elem) == 0 or NULL if no such element
+ *         exists in the tree.
  */
-void *av_tree_find(const struct AVTreeNode *root, void *key, int (*cmp)(void *key, const void *b), void *next[2]);
+void *av_tree_find(const struct AVTreeNode *root, void *key,
+                   int (*cmp)(void *key, const void *b), void *next[2]);
 
 /**
  * Insert or remove an element.
@@ -83,11 +84,17 @@
  *             lower overhead compared to many malloced elements.
  *             You might want to define a function like:
  *             @code
- *             void *tree_insert(struct AVTreeNode **rootp, void *key, int (*cmp)(void *key, const void *b), AVTreeNode **next){
- *                 if(!*next) *next= av_mallocz(av_tree_node_size);
+ *             void *tree_insert(struct AVTreeNode **rootp, void *key,
+ *                               int (*cmp)(void *key, const void *b),
+ *                               AVTreeNode **next)
+ *             {
+ *                 if (!*next)
+ *                     *next = av_mallocz(av_tree_node_size);
  *                 return av_tree_insert(rootp, key, cmp, next);
  *             }
- *             void *tree_remove(struct AVTreeNode **rootp, void *key, int (*cmp)(void *key, const void *b, AVTreeNode **next)){
+ *             void *tree_remove(struct AVTreeNode **rootp, void *key,
+ *                               int (*cmp)(void *key, const void *b, AVTreeNode **next))
+ *             {
  *                 av_freep(next);
  *                 return av_tree_insert(rootp, key, cmp, next);
  *             }
@@ -98,7 +105,10 @@
  *         Which one it is depends on the tree state and the implementation. You
  *         should make no assumptions that it's one or the other in the code.
  */
-void *av_tree_insert(struct AVTreeNode **rootp, void *key, int (*cmp)(void *key, const void *b), struct AVTreeNode **next);
+void *av_tree_insert(struct AVTreeNode **rootp, void *key,
+                     int (*cmp)(void *key, const void *b),
+                     struct AVTreeNode **next);
+
 void av_tree_destroy(struct AVTreeNode *t);
 
 /**
@@ -111,7 +121,9 @@
  * @note The cmp function should use the same ordering used to construct the
  *       tree.
  */
-void av_tree_enumerate(struct AVTreeNode *t, void *opaque, int (*cmp)(void *opaque, void *elem), int (*enu)(void *opaque, void *elem));
+void av_tree_enumerate(struct AVTreeNode *t, void *opaque,
+                       int (*cmp)(void *opaque, void *elem),
+                       int (*enu)(void *opaque, void *elem));
 
 /**
  * @}
diff --git a/libavutil/utils.c b/libavutil/utils.c
index c157aa8..eb87c90 100644
--- a/libavutil/utils.c
+++ b/libavutil/utils.c
@@ -45,6 +45,10 @@
         abort();
     }
 
+    if (llrint(1LL<<60) != 1LL<<60) {
+        av_log(NULL, AV_LOG_ERROR, "Libavutil has been linked to a broken llrint()\n");
+    }
+
     ff_check_pixfmt_descriptors();
     checks_done = 1;
     return LIBAVUTIL_VERSION_INT;
@@ -95,7 +99,7 @@
     if (!list)
         return 0;
 #define LIST_LENGTH(type) \
-    { type t = term, *l = list; for (i = 0; l[i] != t; i++); }
+    { type t = term, *l = (type *)list; for (i = 0; l[i] != t; i++); }
     switch (elsize) {
     case 1: LIST_LENGTH(uint8_t);  break;
     case 2: LIST_LENGTH(uint16_t); break;
diff --git a/libavutil/version.h b/libavutil/version.h
index e46e97c..e522b79 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -75,7 +75,7 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  52
-#define LIBAVUTIL_VERSION_MINOR  27
+#define LIBAVUTIL_VERSION_MINOR  42
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
@@ -135,6 +135,9 @@
 #ifndef FF_API_AVFRAME_LAVC
 #define FF_API_AVFRAME_LAVC             (LIBAVUTIL_VERSION_MAJOR < 53)
 #endif
+#ifndef FF_API_VDPAU
+#define FF_API_VDPAU                    (LIBAVUTIL_VERSION_MAJOR < 53)
+#endif
 
 /**
  * @}
diff --git a/libavutil/x86/Makefile b/libavutil/x86/Makefile
index ae07470..1e19082 100644
--- a/libavutil/x86/Makefile
+++ b/libavutil/x86/Makefile
@@ -1,6 +1,8 @@
 OBJS += x86/cpu.o                                                       \
         x86/float_dsp_init.o                                            \
+        x86/lls_init.o                                                  \
 
 YASM-OBJS += x86/cpuid.o                                                \
              x86/emms.o                                                 \
              x86/float_dsp.o                                            \
+             x86/lls.o                                                  \
diff --git a/libavutil/x86/float_dsp.asm b/libavutil/x86/float_dsp.asm
index 1c28058..49d4876 100644
--- a/libavutil/x86/float_dsp.asm
+++ b/libavutil/x86/float_dsp.asm
@@ -268,21 +268,23 @@
 ;-----------------------------------------------------------------------------
 INIT_XMM sse
 cglobal butterflies_float, 3,3,3, src0, src1, len
-    movsxdifnidn lenq, lend
-    test         lenq, lenq
-    jz           .end
-    shl          lenq, 2
-    add         src0q, lenq
-    add         src1q, lenq
-    neg          lenq
+%if ARCH_X86_64
+    movsxd    lenq, lend
+%endif
+    test      lenq, lenq
+    jz .end
+    shl       lenq, 2
+    add      src0q, lenq
+    add      src1q, lenq
+    neg       lenq
 .loop:
-    mova           m0, [src0q + lenq]
-    mova           m1, [src1q + lenq]
-    subps          m2, m0, m1
-    addps          m0, m0, m1
-    mova      [src1q + lenq], m2
-    mova      [src0q + lenq], m0
-    add          lenq, mmsize
-    jl          .loop
+    mova        m0, [src0q + lenq]
+    mova        m1, [src1q + lenq]
+    subps       m2, m0, m1
+    addps       m0, m0, m1
+    mova        [src1q + lenq], m2
+    mova        [src0q + lenq], m0
+    add       lenq, mmsize
+    jl .loop
 .end:
     REP_RET
diff --git a/libavutil/x86/float_dsp_init.c b/libavutil/x86/float_dsp_init.c
index ee74837..97f7b7c 100644
--- a/libavutil/x86/float_dsp_init.c
+++ b/libavutil/x86/float_dsp_init.c
@@ -18,6 +18,7 @@
 
 #include "config.h"
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/float_dsp.h"
 #include "cpu.h"
@@ -121,19 +122,19 @@
 }
 #endif /* HAVE_6REGS && HAVE_INLINE_ASM */
 
-void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp)
+av_cold void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
 #if HAVE_6REGS && HAVE_INLINE_ASM
-    if (INLINE_AMD3DNOWEXT(mm_flags)) {
+    if (INLINE_AMD3DNOWEXT(cpu_flags)) {
         fdsp->vector_fmul_window  = vector_fmul_window_3dnowext;
     }
-    if (INLINE_SSE(mm_flags)) {
+    if (INLINE_SSE(cpu_flags)) {
         fdsp->vector_fmul_window = vector_fmul_window_sse;
     }
 #endif
-    if (EXTERNAL_SSE(mm_flags)) {
+    if (EXTERNAL_SSE(cpu_flags)) {
         fdsp->vector_fmul = ff_vector_fmul_sse;
         fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_sse;
         fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_sse;
@@ -142,10 +143,10 @@
         fdsp->scalarproduct_float = ff_scalarproduct_float_sse;
         fdsp->butterflies_float   = ff_butterflies_float_sse;
     }
-    if (EXTERNAL_SSE2(mm_flags)) {
+    if (EXTERNAL_SSE2(cpu_flags)) {
         fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_sse2;
     }
-    if (EXTERNAL_AVX(mm_flags)) {
+    if (EXTERNAL_AVX(cpu_flags)) {
         fdsp->vector_fmul = ff_vector_fmul_avx;
         fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_avx;
         fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_avx;
diff --git a/libavutil/x86/lls.asm b/libavutil/x86/lls.asm
new file mode 100644
index 0000000..769befb
--- /dev/null
+++ b/libavutil/x86/lls.asm
@@ -0,0 +1,235 @@
+;******************************************************************************
+;* linear least squares model
+;*
+;* Copyright (c) 2013 Loren Merritt
+;*
+;* 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
+;******************************************************************************
+
+%include "x86util.asm"
+
+SECTION .text
+
+%define MAX_VARS 32
+%define MAX_VARS_ALIGN (MAX_VARS+4)
+%define COVAR_STRIDE MAX_VARS_ALIGN*8
+%define COVAR(x,y) [covarq + (x)*8 + (y)*COVAR_STRIDE]
+
+struc LLSModel
+    .covariance:  resq MAX_VARS_ALIGN*MAX_VARS_ALIGN
+    .coeff:       resq MAX_VARS*MAX_VARS
+    .variance:    resq MAX_VARS
+    .indep_count: resd 1
+endstruc
+
+%macro ADDPD_MEM 2
+%if cpuflag(avx)
+    vaddpd %2, %2, %1
+%else
+    addpd  %2, %1
+%endif
+    mova   %1, %2
+%endmacro
+
+INIT_XMM sse2
+%define movdqa movaps
+cglobal update_lls, 2,5,8, ctx, var, i, j, covar2
+    %define covarq ctxq
+    mov     id, [ctxq + LLSModel.indep_count]
+    lea   varq, [varq + iq*8]
+    neg     iq
+    mov covar2q, covarq
+.loopi:
+    ; Compute all 3 pairwise products of a 2x2 block that lies on the diagonal
+    mova    m1, [varq + iq*8]
+    mova    m3, [varq + iq*8 + 16]
+    pshufd  m4, m1, q1010
+    pshufd  m5, m1, q3232
+    pshufd  m6, m3, q1010
+    pshufd  m7, m3, q3232
+    mulpd   m0, m1, m4
+    mulpd   m1, m1, m5
+    lea covarq, [covar2q + 16]
+    ADDPD_MEM COVAR(-2,0), m0
+    ADDPD_MEM COVAR(-2,1), m1
+    lea     jq, [iq + 2]
+    cmp     jd, -2
+    jg .skip4x4
+.loop4x4:
+    ; Compute all 16 pairwise products of a 4x4 block
+    mulpd   m0, m4, m3
+    mulpd   m1, m5, m3
+    mulpd   m2, m6, m3
+    mulpd   m3, m3, m7
+    ADDPD_MEM COVAR(0,0), m0
+    ADDPD_MEM COVAR(0,1), m1
+    ADDPD_MEM COVAR(0,2), m2
+    ADDPD_MEM COVAR(0,3), m3
+    mova    m3, [varq + jq*8 + 16]
+    mulpd   m0, m4, m3
+    mulpd   m1, m5, m3
+    mulpd   m2, m6, m3
+    mulpd   m3, m3, m7
+    ADDPD_MEM COVAR(2,0), m0
+    ADDPD_MEM COVAR(2,1), m1
+    ADDPD_MEM COVAR(2,2), m2
+    ADDPD_MEM COVAR(2,3), m3
+    mova    m3, [varq + jq*8 + 32]
+    add covarq, 32
+    add     jq, 4
+    cmp     jd, -2
+    jle .loop4x4
+.skip4x4:
+    test    jd, jd
+    jg .skip2x4
+    mulpd   m4, m3
+    mulpd   m5, m3
+    mulpd   m6, m3
+    mulpd   m7, m3
+    ADDPD_MEM COVAR(0,0), m4
+    ADDPD_MEM COVAR(0,1), m5
+    ADDPD_MEM COVAR(0,2), m6
+    ADDPD_MEM COVAR(0,3), m7
+.skip2x4:
+    add     iq, 4
+    add covar2q, 4*COVAR_STRIDE+32
+    cmp     id, -2
+    jle .loopi
+    test    id, id
+    jg .ret
+    mov     jq, iq
+    %define covarq covar2q
+.loop2x1:
+    movsd   m0, [varq + iq*8]
+    movlhps m0, m0
+    mulpd   m0, [varq + jq*8]
+    ADDPD_MEM COVAR(0,0), m0
+    inc     iq
+    add covarq, COVAR_STRIDE
+    test    id, id
+    jle .loop2x1
+.ret:
+    REP_RET
+
+%if HAVE_AVX_EXTERNAL
+INIT_YMM avx
+cglobal update_lls, 3,6,8, ctx, var, count, i, j, count2
+    %define covarq ctxq
+    mov  countd, [ctxq + LLSModel.indep_count]
+    lea count2d, [countq-2]
+    xor     id, id
+.loopi:
+    ; Compute all 10 pairwise products of a 4x4 block that lies on the diagonal
+    mova    ymm1, [varq + iq*8]
+    vbroadcastsd ymm4, [varq + iq*8]
+    vbroadcastsd ymm5, [varq + iq*8 + 8]
+    vbroadcastsd ymm6, [varq + iq*8 + 16]
+    vbroadcastsd ymm7, [varq + iq*8 + 24]
+    vextractf128 xmm3, ymm1, 1
+    vmulpd  ymm0, ymm1, ymm4
+    vmulpd  ymm1, ymm1, ymm5
+    vmulpd  xmm2, xmm3, xmm6
+    vmulpd  xmm3, xmm3, xmm7
+    ADDPD_MEM COVAR(iq  ,0), ymm0
+    ADDPD_MEM COVAR(iq  ,1), ymm1
+    ADDPD_MEM COVAR(iq+2,2), xmm2
+    ADDPD_MEM COVAR(iq+2,3), xmm3
+    lea     jd, [iq + 4]
+    cmp     jd, count2d
+    jg .skip4x4
+.loop4x4:
+    ; Compute all 16 pairwise products of a 4x4 block
+    mova    ymm3, [varq + jq*8]
+    vmulpd  ymm0, ymm3, ymm4
+    vmulpd  ymm1, ymm3, ymm5
+    vmulpd  ymm2, ymm3, ymm6
+    vmulpd  ymm3, ymm3, ymm7
+    ADDPD_MEM COVAR(jq,0), ymm0
+    ADDPD_MEM COVAR(jq,1), ymm1
+    ADDPD_MEM COVAR(jq,2), ymm2
+    ADDPD_MEM COVAR(jq,3), ymm3
+    add     jd, 4
+    cmp     jd, count2d
+    jle .loop4x4
+.skip4x4:
+    cmp     jd, countd
+    jg .skip2x4
+    mova    xmm3, [varq + jq*8]
+    vmulpd  xmm0, xmm3, xmm4
+    vmulpd  xmm1, xmm3, xmm5
+    vmulpd  xmm2, xmm3, xmm6
+    vmulpd  xmm3, xmm3, xmm7
+    ADDPD_MEM COVAR(jq,0), xmm0
+    ADDPD_MEM COVAR(jq,1), xmm1
+    ADDPD_MEM COVAR(jq,2), xmm2
+    ADDPD_MEM COVAR(jq,3), xmm3
+.skip2x4:
+    add     id, 4
+    add covarq, 4*COVAR_STRIDE
+    cmp     id, count2d
+    jle .loopi
+    cmp     id, countd
+    jg .ret
+    mov     jd, id
+.loop2x1:
+    vmovddup xmm0, [varq + iq*8]
+    vmulpd   xmm0, [varq + jq*8]
+    ADDPD_MEM COVAR(jq,0), xmm0
+    inc     id
+    add covarq, COVAR_STRIDE
+    cmp     id, countd
+    jle .loop2x1
+.ret:
+    REP_RET
+%endif
+
+INIT_XMM sse2
+cglobal evaluate_lls, 3,4,2, ctx, var, order, i
+    ; This function is often called on the same buffer as update_lls, but with
+    ; an offset. They can't both be aligned.
+    ; Load halves rather than movu to avoid store-forwarding stalls, since the
+    ; input was initialized immediately prior to this function using scalar math.
+    %define coefsq ctxq
+    mov     id, orderd
+    imul    orderd, MAX_VARS
+    lea     coefsq, [ctxq + LLSModel.coeff + orderq*8]
+    movsd   m0, [varq]
+    movhpd  m0, [varq + 8]
+    mulpd   m0, [coefsq]
+    lea coefsq, [coefsq + iq*8]
+    lea   varq, [varq + iq*8]
+    neg     iq
+    add     iq, 2
+.loop:
+    movsd   m1, [varq + iq*8]
+    movhpd  m1, [varq + iq*8 + 8]
+    mulpd   m1, [coefsq + iq*8]
+    addpd   m0, m1
+    add     iq, 2
+    jl .loop
+    jg .skip1
+    movsd   m1, [varq + iq*8]
+    mulsd   m1, [coefsq + iq*8]
+    addpd   m0, m1
+.skip1:
+    movhlps m1, m0
+    addsd   m0, m1
+%if ARCH_X86_32
+    movsd  r0m, m0
+    fld   qword r0m
+%endif
+    RET
diff --git a/libavutil/x86/lls_init.c b/libavutil/x86/lls_init.c
new file mode 100644
index 0000000..181ca38
--- /dev/null
+++ b/libavutil/x86/lls_init.c
@@ -0,0 +1,41 @@
+/*
+ * linear least squares model
+ *
+ * Copyright (c) 2013 Loren Merritt
+ *
+ * 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
+ */
+
+#include "libavutil/lls.h"
+#include "libavutil/x86/cpu.h"
+
+void ff_update_lls_sse2(LLSModel *m, double *var);
+void ff_update_lls_avx(LLSModel *m, double *var);
+double ff_evaluate_lls_sse2(LLSModel *m, double *var, int order);
+
+av_cold void ff_init_lls_x86(LLSModel *m)
+{
+    int cpu_flags = av_get_cpu_flags();
+    if (EXTERNAL_SSE2(cpu_flags)) {
+        m->update_lls = ff_update_lls_sse2;
+        if (m->indep_count >= 4)
+            m->evaluate_lls = ff_evaluate_lls_sse2;
+    }
+    if (EXTERNAL_AVX(cpu_flags)) {
+        m->update_lls = ff_update_lls_avx;
+    }
+}
diff --git a/libavutil/xtea.c b/libavutil/xtea.c
index e729c91..5fbfd58 100644
--- a/libavutil/xtea.c
+++ b/libavutil/xtea.c
@@ -244,7 +244,7 @@
     AVXTEA ctx;
     uint8_t buf[8], iv[8];
     int i;
-    const uint8_t src[32] = "HelloWorldHelloWorldHelloWorld";
+    static const uint8_t src[32] = "HelloWorldHelloWorldHelloWorld";
     uint8_t ct[32];
     uint8_t pl[32];
 
diff --git a/libpostproc/postprocess_template.c b/libpostproc/postprocess_template.c
index 3db49b6..74b0ab4 100644
--- a/libpostproc/postprocess_template.c
+++ b/libpostproc/postprocess_template.c
@@ -1313,7 +1313,7 @@
 
         "1:                        \n\t"
         : : "r" (src), "r" ((x86_reg)stride), "m" (c->pQPb), "m"(c->pQPb2), "q"(tmp)
-        : "%"REG_a, "%"REG_d
+        : "%"REG_a, "%"REG_d, "%"REG_SP
     );
 #else // HAVE_7REGS && (TEMPLATE_PP_MMXEXT || TEMPLATE_PP_3DNOW)
     int y;
@@ -1875,40 +1875,40 @@
 //      0       1       2       3       4       5       6       7       8       9
 //      %0      eax     eax+%1  eax+2%1 %0+4%1  edx     edx+%1  edx+2%1 %0+8%1  edx+4%1
 
-        "movq (%0), %%mm0                       \n\t" //
-        "movq (%%"REG_a", %1), %%mm2            \n\t" //
-        "movq (%%"REG_a"), %%mm1                \n\t" //
+        "movq (%0), %%mm0                       \n\t"
+        "movq (%%"REG_a", %1), %%mm2            \n\t"
+        "movq (%%"REG_a"), %%mm1                \n\t"
         "movq %%mm0, %%mm3                      \n\t"
-        "pmaxub %%mm1, %%mm0                    \n\t" //
-        "pminub %%mm3, %%mm1                    \n\t" //
-        "pmaxub %%mm2, %%mm1                    \n\t" //
+        "pmaxub %%mm1, %%mm0                    \n\t"
+        "pminub %%mm3, %%mm1                    \n\t"
+        "pmaxub %%mm2, %%mm1                    \n\t"
         "pminub %%mm1, %%mm0                    \n\t"
         "movq %%mm0, (%%"REG_a")                \n\t"
 
-        "movq (%0, %1, 4), %%mm0                \n\t" //
-        "movq (%%"REG_a", %1, 2), %%mm1         \n\t" //
+        "movq (%0, %1, 4), %%mm0                \n\t"
+        "movq (%%"REG_a", %1, 2), %%mm1         \n\t"
         "movq %%mm2, %%mm3                      \n\t"
-        "pmaxub %%mm1, %%mm2                    \n\t" //
-        "pminub %%mm3, %%mm1                    \n\t" //
-        "pmaxub %%mm0, %%mm1                    \n\t" //
+        "pmaxub %%mm1, %%mm2                    \n\t"
+        "pminub %%mm3, %%mm1                    \n\t"
+        "pmaxub %%mm0, %%mm1                    \n\t"
         "pminub %%mm1, %%mm2                    \n\t"
         "movq %%mm2, (%%"REG_a", %1, 2)         \n\t"
 
-        "movq (%%"REG_d"), %%mm2                \n\t" //
-        "movq (%%"REG_d", %1), %%mm1            \n\t" //
+        "movq (%%"REG_d"), %%mm2                \n\t"
+        "movq (%%"REG_d", %1), %%mm1            \n\t"
         "movq %%mm2, %%mm3                      \n\t"
-        "pmaxub %%mm0, %%mm2                    \n\t" //
-        "pminub %%mm3, %%mm0                    \n\t" //
-        "pmaxub %%mm1, %%mm0                    \n\t" //
+        "pmaxub %%mm0, %%mm2                    \n\t"
+        "pminub %%mm3, %%mm0                    \n\t"
+        "pmaxub %%mm1, %%mm0                    \n\t"
         "pminub %%mm0, %%mm2                    \n\t"
         "movq %%mm2, (%%"REG_d")                \n\t"
 
-        "movq (%%"REG_d", %1, 2), %%mm2         \n\t" //
-        "movq (%0, %1, 8), %%mm0                \n\t" //
+        "movq (%%"REG_d", %1, 2), %%mm2         \n\t"
+        "movq (%0, %1, 8), %%mm0                \n\t"
         "movq %%mm2, %%mm3                      \n\t"
-        "pmaxub %%mm0, %%mm2                    \n\t" //
-        "pminub %%mm3, %%mm0                    \n\t" //
-        "pmaxub %%mm1, %%mm0                    \n\t" //
+        "pmaxub %%mm0, %%mm2                    \n\t"
+        "pminub %%mm3, %%mm0                    \n\t"
+        "pmaxub %%mm1, %%mm0                    \n\t"
         "pminub %%mm0, %%mm2                    \n\t"
         "movq %%mm2, (%%"REG_d", %1, 2)         \n\t"
 
diff --git a/libswresample/dither.c b/libswresample/dither.c
index d0193dd..7cbe410 100644
--- a/libswresample/dither.c
+++ b/libswresample/dither.c
@@ -88,6 +88,7 @@
         if(out_fmt == AV_SAMPLE_FMT_S16) scale = 1.0/(1L<<15);
         if(out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1.0/(1L<< 7);
     }
+    if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_S32 && (s->dither.output_sample_bits&31)) scale = 1;
     if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_S16) scale = 1L<<16;
     if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1L<<24;
     if(in_fmt == AV_SAMPLE_FMT_S16 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1L<<8;
diff --git a/libswresample/rematrix.c b/libswresample/rematrix.c
index 84c55ee..5c98e68 100644
--- a/libswresample/rematrix.c
+++ b/libswresample/rematrix.c
@@ -34,6 +34,10 @@
 #include "rematrix_template.c"
 #undef TEMPLATE_REMATRIX_S16
 
+#define TEMPLATE_REMATRIX_S32
+#include "rematrix_template.c"
+#undef TEMPLATE_REMATRIX_S32
+
 #define FRONT_LEFT             0
 #define FRONT_RIGHT            1
 #define FRONT_CENTER           2
@@ -78,9 +82,6 @@
 }
 
 static int clean_layout(SwrContext *s, int64_t layout){
-    if((layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == AV_CH_LAYOUT_STEREO_DOWNMIX)
-        return AV_CH_LAYOUT_STEREO;
-
     if(layout && layout != AV_CH_FRONT_CENTER && !(layout&(layout-1))) {
         char buf[128];
         av_get_channel_layout_string(buf, sizeof(buf), -1, layout);
@@ -116,15 +117,22 @@
     double maxcoef=0;
     char buf[128];
     const int matrix_encoding = s->matrix_encoding;
+    float maxval;
 
     in_ch_layout = clean_layout(s, s->in_ch_layout);
+    out_ch_layout = clean_layout(s, s->out_ch_layout);
+
+    if(   out_ch_layout == AV_CH_LAYOUT_STEREO_DOWNMIX
+       && (in_ch_layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == 0
+    )
+        out_ch_layout = AV_CH_LAYOUT_STEREO;
+
     if(!sane_layout(in_ch_layout)){
         av_get_channel_layout_string(buf, sizeof(buf), -1, s->in_ch_layout);
         av_log(s, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf);
         return AVERROR(EINVAL);
     }
 
-    out_ch_layout = clean_layout(s, s->out_ch_layout);
     if(!sane_layout(out_ch_layout)){
         av_get_channel_layout_string(buf, sizeof(buf), -1, s->out_ch_layout);
         av_log(s, AV_LOG_ERROR, "Output channel layout '%s' is not supported\n", buf);
@@ -300,8 +308,16 @@
     if(s->rematrix_volume  < 0)
         maxcoef = -s->rematrix_volume;
 
-    if((   av_get_packed_sample_fmt(s->out_sample_fmt) < AV_SAMPLE_FMT_FLT
-        || av_get_packed_sample_fmt(s->int_sample_fmt) < AV_SAMPLE_FMT_FLT) && maxcoef > 1.0){
+    if (s->rematrix_maxval > 0) {
+        maxval = s->rematrix_maxval;
+    } else if (   av_get_packed_sample_fmt(s->out_sample_fmt) < AV_SAMPLE_FMT_FLT
+               || av_get_packed_sample_fmt(s->int_sample_fmt) < AV_SAMPLE_FMT_FLT) {
+        maxval = 1.0;
+    } else
+        maxval = INT_MAX;
+
+    if(maxcoef > maxval || s->rematrix_volume  < 0){
+        maxcoef /= maxval;
         for(i=0; i<SWR_CH_MAX; i++)
             for(j=0; j<SWR_CH_MAX; j++){
                 s->matrix[i][j] /= maxcoef;
@@ -366,6 +382,17 @@
         s->mix_1_1_f = (mix_1_1_func_type*)copy_double;
         s->mix_2_1_f = (mix_2_1_func_type*)sum2_double;
         s->mix_any_f = (mix_any_func_type*)get_mix_any_func_double(s);
+    }else if(s->midbuf.fmt == AV_SAMPLE_FMT_S32P){
+        // Only for dithering currently
+//         s->native_matrix = av_calloc(nb_in * nb_out, sizeof(double));
+        s->native_one    = av_mallocz(sizeof(int));
+//         for (i = 0; i < nb_out; i++)
+//             for (j = 0; j < nb_in; j++)
+//                 ((double*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
+        *((int*)s->native_one) = 32768;
+        s->mix_1_1_f = (mix_1_1_func_type*)copy_s32;
+        s->mix_2_1_f = (mix_2_1_func_type*)sum2_s32;
+        s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s32(s);
     }else
         av_assert0(0);
     //FIXME quantize for integeres
@@ -388,6 +415,7 @@
     av_freep(&s->native_matrix);
     av_freep(&s->native_one);
     av_freep(&s->native_simd_matrix);
+    av_freep(&s->native_simd_one);
 }
 
 int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy){
diff --git a/libswresample/rematrix_template.c b/libswresample/rematrix_template.c
index b8ca901..95a3b9a 100644
--- a/libswresample/rematrix_template.c
+++ b/libswresample/rematrix_template.c
@@ -36,14 +36,20 @@
 #    define COEFF int
 #    define INTER int
 #    define RENAME(x) x ## _s16
+#elif defined(TEMPLATE_REMATRIX_S32)
+#    define R(x) (((x) + 16384)>>15)
+#    define SAMPLE int32_t
+#    define COEFF int
+#    define INTER int64_t
+#    define RENAME(x) x ## _s32
 #endif
 
 typedef void (RENAME(mix_any_func_type))(SAMPLE **out, const SAMPLE **in1, COEFF *coeffp, integer len);
 
 static void RENAME(sum2)(SAMPLE *out, const SAMPLE *in1, const SAMPLE *in2, COEFF *coeffp, integer index1, integer index2, integer len){
     int i;
-    COEFF coeff1 = coeffp[index1];
-    COEFF coeff2 = coeffp[index2];
+    INTER coeff1 = coeffp[index1];
+    INTER coeff2 = coeffp[index2];
 
     for(i=0; i<len; i++)
         out[i] = R(coeff1*in1[i] + coeff2*in2[i]);
@@ -51,7 +57,7 @@
 
 static void RENAME(copy)(SAMPLE *out, const SAMPLE *in, COEFF *coeffp, integer index, integer len){
     int i;
-    COEFF coeff = coeffp[index];
+    INTER coeff = coeffp[index];
     for(i=0; i<len; i++)
         out[i] = R(coeff*in[i]);
 }
@@ -60,9 +66,9 @@
     int i;
 
     for(i=0; i<len; i++) {
-        INTER t = in[2][i]*coeffp[0*6+2] + in[3][i]*coeffp[0*6+3];
-        out[0][i] = R(t + in[0][i]*coeffp[0*6+0] + in[4][i]*coeffp[0*6+4]);
-        out[1][i] = R(t + in[1][i]*coeffp[1*6+1] + in[5][i]*coeffp[1*6+5]);
+        INTER t = in[2][i]*(INTER)coeffp[0*6+2] + in[3][i]*(INTER)coeffp[0*6+3];
+        out[0][i] = R(t + in[0][i]*(INTER)coeffp[0*6+0] + in[4][i]*(INTER)coeffp[0*6+4]);
+        out[1][i] = R(t + in[1][i]*(INTER)coeffp[1*6+1] + in[5][i]*(INTER)coeffp[1*6+5]);
     }
 }
 
@@ -70,9 +76,9 @@
     int i;
 
     for(i=0; i<len; i++) {
-        INTER t = in[2][i]*coeffp[0*8+2] + in[3][i]*coeffp[0*8+3];
-        out[0][i] = R(t + in[0][i]*coeffp[0*8+0] + in[4][i]*coeffp[0*8+4] + in[6][i]*coeffp[0*8+6]);
-        out[1][i] = R(t + in[1][i]*coeffp[1*8+1] + in[5][i]*coeffp[1*8+5] + in[7][i]*coeffp[1*8+7]);
+        INTER t = in[2][i]*(INTER)coeffp[0*8+2] + in[3][i]*(INTER)coeffp[0*8+3];
+        out[0][i] = R(t + in[0][i]*(INTER)coeffp[0*8+0] + in[4][i]*(INTER)coeffp[0*8+4] + in[6][i]*(INTER)coeffp[0*8+6]);
+        out[1][i] = R(t + in[1][i]*(INTER)coeffp[1*8+1] + in[5][i]*(INTER)coeffp[1*8+5] + in[7][i]*(INTER)coeffp[1*8+7]);
     }
 }
 
diff --git a/libswresample/swresample.c b/libswresample/swresample.c
index 9b71b2e..cdfe5bf 100644
--- a/libswresample/swresample.c
+++ b/libswresample/swresample.c
@@ -68,6 +68,7 @@
 {"lfe_mix_level"        , "set LFE mix level"           , OFFSET(lfe_mix_level  ), AV_OPT_TYPE_FLOAT, {.dbl=0                     }, -32    , 32        , PARAM},
 {"rmvol"                , "set rematrix volume"         , OFFSET(rematrix_volume), AV_OPT_TYPE_FLOAT, {.dbl=1.0                   }, -1000  , 1000      , PARAM},
 {"rematrix_volume"      , "set rematrix volume"         , OFFSET(rematrix_volume), AV_OPT_TYPE_FLOAT, {.dbl=1.0                   }, -1000  , 1000      , PARAM},
+{"rematrix_maxval"      , "set rematrix maxval"         , OFFSET(rematrix_maxval), AV_OPT_TYPE_FLOAT, {.dbl=0.0                   }, 0      , 1000      , PARAM},
 
 {"flags"                , "set flags"                   , OFFSET(flags          ), AV_OPT_TYPE_FLAGS, {.i64=0                     }, 0      , UINT_MAX  , PARAM, "flags"},
 {"swr_flags"            , "set flags"                   , OFFSET(flags          ), AV_OPT_TYPE_FLAGS, {.i64=0                     }, 0      , UINT_MAX  , PARAM, "flags"},
@@ -127,7 +128,7 @@
 
 { "kaiser_beta"         , "set swr Kaiser Window Beta"  , OFFSET(kaiser_beta)    , AV_OPT_TYPE_INT  , {.i64=9                     }, 2      , 16        , PARAM },
 
-{ "output_sample_bits"   , ""  , OFFSET(dither.output_sample_bits)               , AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , 64        , 0 },
+{ "output_sample_bits"  , "set swr number of output sample bits", OFFSET(dither.output_sample_bits), AV_OPT_TYPE_INT  , {.i64=0   }, 0      , 64        , PARAM },
 {0}
 };
 
@@ -651,7 +652,8 @@
     if(s->resample_first ? !s->rematrix : !s->resample)
         preout= midbuf;
 
-    if(s->int_sample_fmt == s->out_sample_fmt && s->out.planar){
+    if(s->int_sample_fmt == s->out_sample_fmt && s->out.planar
+       && !(s->out_sample_fmt==AV_SAMPLE_FMT_S32P && (s->dither.output_sample_bits&31))){
         if(preout==in){
             out_count= FFMIN(out_count, in_count); //TODO check at the end if this is needed or redundant
             av_assert0(s->in.planar); //we only support planar internally so it has to be, we support copying non planar though
@@ -708,7 +710,7 @@
 
                     if(len1)
                         for(ch=0; ch<preout->ch_count; ch++)
-                            s->mix_2_1_simd(conv_src->ch[ch], preout->ch[ch], s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos, s->native_one, 0, 0, len1);
+                            s->mix_2_1_simd(conv_src->ch[ch], preout->ch[ch], s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos, s->native_simd_one, 0, 0, len1);
                     if(out_count != len1)
                         for(ch=0; ch<preout->ch_count; ch++)
                             s->mix_2_1_f(conv_src->ch[ch] + off, preout->ch[ch] + off, s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos + off + len1, s->native_one, 0, 0, out_count - len1);
@@ -726,7 +728,7 @@
             }
             s->dither.noise_pos += out_count;
         }
-//FIXME packed doesnt need more than 1 chan here!
+//FIXME packed doesn't need more than 1 chan here!
         swri_audio_convert(s->out_convert, out, conv_src, out_count);
     }
     return out_count;
@@ -746,7 +748,7 @@
 
         reversefill_audiodata(&s->drop_temp, tmp_arg);
         s->drop_output *= -1; //FIXME find a less hackish solution
-        ret = swr_convert(s, tmp_arg, FFMIN(-s->drop_output, MAX_DROP_STEP), in_arg, in_count); //FIXME optimize but this is as good as never called so maybe it doesnt matter
+        ret = swr_convert(s, tmp_arg, FFMIN(-s->drop_output, MAX_DROP_STEP), in_arg, in_count); //FIXME optimize but this is as good as never called so maybe it doesn't matter
         s->drop_output *= -1;
         in_count = 0;
         if(ret>0) {
diff --git a/libswresample/swresample_internal.h b/libswresample/swresample_internal.h
index 17b85d5..ab19f21 100644
--- a/libswresample/swresample_internal.h
+++ b/libswresample/swresample_internal.h
@@ -82,6 +82,7 @@
     float clev;                                     ///< center mixing level
     float lfe_mix_level;                            ///< LFE mixing level
     float rematrix_volume;                          ///< rematrixing volume coefficient
+    float rematrix_maxval;                          ///< maximum value for rematrixing output
     enum AVMatrixEncoding matrix_encoding;          /**< matrixed stereo encoding */
     const int *channel_map;                         ///< channel index (or -1 if muted channel) map
     int used_ch_count;                              ///< number of used input channels (mapped channel count if channel_map, otherwise in.ch_count)
@@ -134,6 +135,7 @@
     float matrix[SWR_CH_MAX][SWR_CH_MAX];           ///< floating point rematrixing coefficients
     uint8_t *native_matrix;
     uint8_t *native_one;
+    uint8_t *native_simd_one;
     uint8_t *native_simd_matrix;
     int32_t matrix32[SWR_CH_MAX][SWR_CH_MAX];       ///< 17.15 fixed point rematrixing coefficients
     uint8_t matrix_ch[SWR_CH_MAX][SWR_CH_MAX+1];    ///< Lists of input channels per output channel that have non zero rematrixing coefficients
diff --git a/libswresample/version.h b/libswresample/version.h
index df9df48..8272b76 100644
--- a/libswresample/version.h
+++ b/libswresample/version.h
@@ -30,7 +30,7 @@
 
 #define LIBSWRESAMPLE_VERSION_MAJOR 0
 #define LIBSWRESAMPLE_VERSION_MINOR 17
-#define LIBSWRESAMPLE_VERSION_MICRO 102
+#define LIBSWRESAMPLE_VERSION_MICRO 103
 
 #define LIBSWRESAMPLE_VERSION_INT  AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \
                                                   LIBSWRESAMPLE_VERSION_MINOR, \
diff --git a/libswresample/x86/audio_convert.asm b/libswresample/x86/audio_convert.asm
index ad46977..4963959 100644
--- a/libswresample/x86/audio_convert.asm
+++ b/libswresample/x86/audio_convert.asm
@@ -195,7 +195,12 @@
     add lenq, 2*mmsize/(1<<%4)
 %endif
         jl .next
+%if mmsize == 8
+    emms
+    RET
+%else
     REP_RET
+%endif
 %endmacro
 
 %macro PACK_6CH 5-7
diff --git a/libswresample/x86/swresample_x86.c b/libswresample/x86/swresample_x86.c
index e18f0c5..581dc17 100644
--- a/libswresample/x86/swresample_x86.c
+++ b/libswresample/x86/swresample_x86.c
@@ -169,6 +169,7 @@
             s->mix_2_1_simd = ff_mix_2_1_a_int16_sse2;
         }
         s->native_simd_matrix = av_mallocz(2 * num * sizeof(int16_t));
+        s->native_simd_one    = av_mallocz(2 * sizeof(int16_t));
         for(i=0; i<nb_out; i++){
             int sh = 0;
             for(j=0; j<nb_in; j++)
@@ -180,6 +181,8 @@
                     ((((int*)s->native_matrix)[i * nb_in + j]) + (1<<sh>>1)) >> sh;
             }
         }
+        ((int16_t*)s->native_simd_one)[1] = 14;
+        ((int16_t*)s->native_simd_one)[0] = 16384;
     } else if(s->midbuf.fmt == AV_SAMPLE_FMT_FLTP){
         if(mm_flags & AV_CPU_FLAG_SSE) {
             s->mix_1_1_simd = ff_mix_1_1_a_float_sse;
@@ -191,5 +194,7 @@
         }
         s->native_simd_matrix = av_mallocz(num * sizeof(float));
         memcpy(s->native_simd_matrix, s->native_matrix, num * sizeof(float));
+        s->native_simd_one = av_mallocz(sizeof(float));
+        memcpy(s->native_simd_one, s->native_one, sizeof(float));
     }
 }
diff --git a/libswscale/input.c b/libswscale/input.c
index 5259603..919b232 100644
--- a/libswscale/input.c
+++ b/libswscale/input.c
@@ -18,7 +18,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <assert.h>
 #include <math.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -720,6 +719,14 @@
     }
 }
 
+static void planar_rgb_to_a(uint8_t *_dst, const uint8_t *src[4], int width, int32_t *unused)
+{
+    uint16_t *dst = (uint16_t *)_dst;
+    int i;
+    for (i = 0; i < width; i++)
+        dst[i] = src[3][i] << 6;
+}
+
 static void planar_rgb_to_uv(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *src[4], int width, int32_t *rgb2yuv)
 {
     uint16_t *dstU = (uint16_t *)_dstU;
@@ -746,65 +753,16 @@
     const uint16_t **src = (const uint16_t **)_src;
     uint16_t *dst        = (uint16_t *)_dst;
     int32_t ry = rgb2yuv[RY_IDX], gy = rgb2yuv[GY_IDX], by = rgb2yuv[BY_IDX];
+    int shift = bpc < 16 ? bpc : 14;
     for (i = 0; i < width; i++) {
         int g = rdpx(src[0] + i);
         int b = rdpx(src[1] + i);
         int r = rdpx(src[2] + i);
 
-        dst[i] = ((ry*r + gy*g + by*b + (33 << (RGB2YUV_SHIFT + bpc - 9))) >> (RGB2YUV_SHIFT + bpc - 14));
+        dst[i] = ((ry*r + gy*g + by*b + (33 << (RGB2YUV_SHIFT + bpc - 9))) >> (RGB2YUV_SHIFT + shift - 14));
     }
 }
 
-static void planar_rgb9le_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_y(dst, src, w, 9, 0, rgb2yuv);
-}
-
-static void planar_rgb9be_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_y(dst, src, w, 9, 1, rgb2yuv);
-}
-
-static void planar_rgb10le_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_y(dst, src, w, 10, 0, rgb2yuv);
-}
-
-static void planar_rgb10be_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_y(dst, src, w, 10, 1, rgb2yuv);
-}
-
-static void planar_rgb12le_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_y(dst, src, w, 12, 0, rgb2yuv);
-}
-
-static void planar_rgb12be_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_y(dst, src, w, 12, 1, rgb2yuv);
-}
-
-static void planar_rgb14le_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_y(dst, src, w, 14, 0, rgb2yuv);
-}
-
-static void planar_rgb14be_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_y(dst, src, w, 14, 1, rgb2yuv);
-}
-
-static void planar_rgb16le_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_y(dst, src, w, 16, 0, rgb2yuv);
-}
-
-static void planar_rgb16be_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_y(dst, src, w, 16, 1, rgb2yuv);
-}
-
 static av_always_inline void planar_rgb16_to_uv(uint8_t *_dstU, uint8_t *_dstV,
                                                 const uint8_t *_src[4], int width,
                                                 int bpc, int is_be, int32_t *rgb2yuv)
@@ -815,76 +773,39 @@
     uint16_t *dstV       = (uint16_t *)_dstV;
     int32_t ru = rgb2yuv[RU_IDX], gu = rgb2yuv[GU_IDX], bu = rgb2yuv[BU_IDX];
     int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX];
+    int shift = bpc < 16 ? bpc : 14;
     for (i = 0; i < width; i++) {
         int g = rdpx(src[0] + i);
         int b = rdpx(src[1] + i);
         int r = rdpx(src[2] + i);
 
-        dstU[i] = (ru*r + gu*g + bu*b + (257 << (RGB2YUV_SHIFT + bpc - 9))) >> (RGB2YUV_SHIFT + bpc - 14);
-        dstV[i] = (rv*r + gv*g + bv*b + (257 << (RGB2YUV_SHIFT + bpc - 9))) >> (RGB2YUV_SHIFT + bpc - 14);
+        dstU[i] = (ru*r + gu*g + bu*b + (257 << (RGB2YUV_SHIFT + bpc - 9))) >> (RGB2YUV_SHIFT + shift - 14);
+        dstV[i] = (rv*r + gv*g + bv*b + (257 << (RGB2YUV_SHIFT + bpc - 9))) >> (RGB2YUV_SHIFT + shift - 14);
     }
 }
 #undef rdpx
 
-static void planar_rgb9le_to_uv(uint8_t *dstU, uint8_t *dstV,
-                                const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_uv(dstU, dstV, src, w, 9, 0, rgb2yuv);
-}
+#define rgb9plus_planar_funcs_endian(nbits, endian_name, endian)                                    \
+static void planar_rgb##nbits##endian_name##_to_y(uint8_t *dst, const uint8_t *src[4],              \
+                                                  int w, int32_t *rgb2yuv)                          \
+{                                                                                                   \
+    planar_rgb16_to_y(dst, src, w, nbits, endian, rgb2yuv);                                         \
+}                                                                                                   \
+static void planar_rgb##nbits##endian_name##_to_uv(uint8_t *dstU, uint8_t *dstV,                    \
+                                                   const uint8_t *src[4], int w, int32_t *rgb2yuv)  \
+{                                                                                                   \
+    planar_rgb16_to_uv(dstU, dstV, src, w, nbits, endian, rgb2yuv);                                 \
+}                                                                                                   \
 
-static void planar_rgb9be_to_uv(uint8_t *dstU, uint8_t *dstV,
-                                const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_uv(dstU, dstV, src, w, 9, 1, rgb2yuv);
-}
+#define rgb9plus_planar_funcs(nbits)            \
+    rgb9plus_planar_funcs_endian(nbits, le, 0)  \
+    rgb9plus_planar_funcs_endian(nbits, be, 1)
 
-static void planar_rgb10le_to_uv(uint8_t *dstU, uint8_t *dstV,
-                                 const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_uv(dstU, dstV, src, w, 10, 0, rgb2yuv);
-}
-
-static void planar_rgb10be_to_uv(uint8_t *dstU, uint8_t *dstV,
-                                 const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_uv(dstU, dstV, src, w, 10, 1, rgb2yuv);
-}
-
-static void planar_rgb12le_to_uv(uint8_t *dstU, uint8_t *dstV,
-                                 const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_uv(dstU, dstV, src, w, 12, 0, rgb2yuv);
-}
-
-static void planar_rgb12be_to_uv(uint8_t *dstU, uint8_t *dstV,
-                                 const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_uv(dstU, dstV, src, w, 12, 1, rgb2yuv);
-}
-
-static void planar_rgb14le_to_uv(uint8_t *dstU, uint8_t *dstV,
-                                 const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_uv(dstU, dstV, src, w, 14, 0, rgb2yuv);
-}
-
-static void planar_rgb14be_to_uv(uint8_t *dstU, uint8_t *dstV,
-                                 const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_uv(dstU, dstV, src, w, 14, 1, rgb2yuv);
-}
-
-static void planar_rgb16le_to_uv(uint8_t *dstU, uint8_t *dstV,
-                                 const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_uv(dstU, dstV, src, w, 16, 0, rgb2yuv);
-}
-
-static void planar_rgb16be_to_uv(uint8_t *dstU, uint8_t *dstV,
-                                 const uint8_t *src[4], int w, int32_t *rgb2yuv)
-{
-    planar_rgb16_to_uv(dstU, dstV, src, w, 16, 1, rgb2yuv);
-}
+rgb9plus_planar_funcs(9)
+rgb9plus_planar_funcs(10)
+rgb9plus_planar_funcs(12)
+rgb9plus_planar_funcs(14)
+rgb9plus_planar_funcs(16)
 
 av_cold void ff_sws_init_input_funcs(SwsContext *c)
 {
@@ -923,6 +844,7 @@
     case AV_PIX_FMT_GBRP14LE:
         c->readChrPlanar = planar_rgb14le_to_uv;
         break;
+    case AV_PIX_FMT_GBRAP16LE:
     case AV_PIX_FMT_GBRP16LE:
         c->readChrPlanar = planar_rgb16le_to_uv;
         break;
@@ -938,9 +860,11 @@
     case AV_PIX_FMT_GBRP14BE:
         c->readChrPlanar = planar_rgb14be_to_uv;
         break;
+    case AV_PIX_FMT_GBRAP16BE:
     case AV_PIX_FMT_GBRP16BE:
         c->readChrPlanar = planar_rgb16be_to_uv;
         break;
+    case AV_PIX_FMT_GBRAP:
     case AV_PIX_FMT_GBRP:
         c->readChrPlanar = planar_rgb_to_uv;
         break;
@@ -1043,7 +967,8 @@
         case AV_PIX_FMT_BGR555BE:
             c->chrToYV12 = bgr15beToUV_half_c;
             break;
-        case AV_PIX_FMT_GBR24P  :
+        case AV_PIX_FMT_GBRAP:
+        case AV_PIX_FMT_GBRP:
             c->chrToYV12 = gbr24pToUV_half_c;
             break;
         case AV_PIX_FMT_BGR444LE:
@@ -1172,6 +1097,7 @@
     case AV_PIX_FMT_GBRP14LE:
         c->readLumPlanar = planar_rgb14le_to_y;
         break;
+    case AV_PIX_FMT_GBRAP16LE:
     case AV_PIX_FMT_GBRP16LE:
         c->readLumPlanar = planar_rgb16le_to_y;
         break;
@@ -1187,9 +1113,12 @@
     case AV_PIX_FMT_GBRP14BE:
         c->readLumPlanar = planar_rgb14be_to_y;
         break;
+    case AV_PIX_FMT_GBRAP16BE:
     case AV_PIX_FMT_GBRP16BE:
         c->readLumPlanar = planar_rgb16be_to_y;
         break;
+    case AV_PIX_FMT_GBRAP:
+        c->readAlpPlanar = planar_rgb_to_a;
     case AV_PIX_FMT_GBRP:
         c->readLumPlanar = planar_rgb_to_y;
         break;
diff --git a/libswscale/options.c b/libswscale/options.c
index fc571ac..8985e6b 100644
--- a/libswscale/options.c
+++ b/libswscale/options.c
@@ -33,7 +33,7 @@
 #define DEFAULT 0
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 
-static const AVOption options[] = {
+static const AVOption swscale_options[] = {
     { "sws_flags",       "scaler flags",                  OFFSET(flags),     AV_OPT_TYPE_FLAGS,  { .i64 = DEFAULT            }, 0,       UINT_MAX,       VE, "sws_flags" },
     { "fast_bilinear",   "fast bilinear",                 0,                 AV_OPT_TYPE_CONST,  { .i64  = SWS_FAST_BILINEAR  }, INT_MIN, INT_MAX,        VE, "sws_flags" },
     { "bilinear",        "bilinear",                      0,                 AV_OPT_TYPE_CONST,  { .i64  = SWS_BILINEAR       }, INT_MIN, INT_MAX,        VE, "sws_flags" },
@@ -64,13 +64,23 @@
     { "param0",          "scaler param 0",                OFFSET(param[0]),  AV_OPT_TYPE_DOUBLE, { .dbl = SWS_PARAM_DEFAULT  }, INT_MIN, INT_MAX,        VE },
     { "param1",          "scaler param 1",                OFFSET(param[1]),  AV_OPT_TYPE_DOUBLE, { .dbl = SWS_PARAM_DEFAULT  }, INT_MIN, INT_MAX,        VE },
 
+    { "src_v_chr_pos",   "source vertical chroma position in luma grid/256"  , OFFSET(src_v_chr_pos), AV_OPT_TYPE_INT, { .i64 = -1            }, -1,      512,             VE },
+    { "src_h_chr_pos",   "source horizontal chroma position in luma grid/256", OFFSET(src_h_chr_pos), AV_OPT_TYPE_INT, { .i64 = -1            }, -1,      512,             VE },
+    { "dst_v_chr_pos",   "destination vertical chroma position in luma grid/256"  , OFFSET(dst_v_chr_pos), AV_OPT_TYPE_INT, { .i64 = -1            }, -1,      512,             VE },
+    { "dst_h_chr_pos",   "destination horizontal chroma position in luma grid/256", OFFSET(dst_h_chr_pos), AV_OPT_TYPE_INT, { .i64 = -1            }, -1,      512,             VE },
+
+    { "sws_dither",      "set dithering algorithm",       OFFSET(dither),    AV_OPT_TYPE_INT,    { .i64  = SWS_DITHER_AUTO   }, 0,       NB_SWS_DITHER,  VE, "sws_dither" },
+    { "auto",            "leave choice to sws",           0,                 AV_OPT_TYPE_CONST,  { .i64  = SWS_DITHER_AUTO   }, INT_MIN, INT_MAX,        VE, "sws_dither" },
+    { "bayer",           "bayer dither",                  0,                 AV_OPT_TYPE_CONST,  { .i64  = SWS_DITHER_BAYER  }, INT_MIN, INT_MAX,        VE, "sws_dither" },
+    { "ed",              "error diffusion",               0,                 AV_OPT_TYPE_CONST,  { .i64  = SWS_DITHER_ED     }, INT_MIN, INT_MAX,        VE, "sws_dither" },
+
     { NULL }
 };
 
 const AVClass sws_context_class = {
     .class_name = "SWScaler",
     .item_name  = sws_context_to_name,
-    .option     = options,
+    .option     = swscale_options,
     .category   = AV_CLASS_CATEGORY_SWSCALER,
     .version    = LIBAVUTIL_VERSION_INT,
 };
diff --git a/libswscale/output.c b/libswscale/output.c
index da760d2..ddb0d0c 100644
--- a/libswscale/output.c
+++ b/libswscale/output.c
@@ -18,7 +18,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <assert.h>
 #include <math.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -37,19 +36,19 @@
 #include "swscale.h"
 #include "swscale_internal.h"
 
-DECLARE_ALIGNED(8, const uint8_t, dither_2x2_4)[][8]={
+DECLARE_ALIGNED(8, const uint8_t, ff_dither_2x2_4)[][8] = {
 {  1,   3,   1,   3,   1,   3,   1,   3, },
 {  2,   0,   2,   0,   2,   0,   2,   0, },
 {  1,   3,   1,   3,   1,   3,   1,   3, },
 };
 
-DECLARE_ALIGNED(8, const uint8_t, dither_2x2_8)[][8]={
+DECLARE_ALIGNED(8, const uint8_t, ff_dither_2x2_8)[][8] = {
 {  6,   2,   6,   2,   6,   2,   6,   2, },
 {  0,   4,   0,   4,   0,   4,   0,   4, },
 {  6,   2,   6,   2,   6,   2,   6,   2, },
 };
 
-DECLARE_ALIGNED(8, const uint8_t, dither_4x4_16)[][8]={
+DECLARE_ALIGNED(8, const uint8_t, ff_dither_4x4_16)[][8] = {
 {  8,   4,  11,   7,   8,   4,  11,   7, },
 {  2,  14,   1,  13,   2,  14,   1,  13, },
 { 10,   6,   9,   5,  10,   6,   9,   5, },
@@ -57,7 +56,7 @@
 {  8,   4,  11,   7,   8,   4,  11,   7, },
 };
 
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_32)[][8]={
+DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_32)[][8] = {
 { 17,   9,  23,  15,  16,   8,  22,  14, },
 {  5,  29,   3,  27,   4,  28,   2,  26, },
 { 21,  13,  19,  11,  20,  12,  18,  10, },
@@ -69,7 +68,7 @@
 { 17,   9,  23,  15,  16,   8,  22,  14, },
 };
 
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_73)[][8]={
+DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_73)[][8] = {
 {  0,  55,  14,  68,   3,  58,  17,  72, },
 { 37,  18,  50,  32,  40,  22,  54,  35, },
 {  9,  64,   5,  59,  13,  67,   8,  63, },
@@ -82,7 +81,7 @@
 };
 
 #if 1
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[][8]={
+DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_220)[][8] = {
 {117,  62, 158, 103, 113,  58, 155, 100, },
 { 34, 199,  21, 186,  31, 196,  17, 182, },
 {144,  89, 131,  76, 141,  86, 127,  72, },
@@ -95,7 +94,7 @@
 };
 #elif 1
 // tries to correct a gamma of 1.5
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[][8]={
+DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_220)[][8] = {
 {  0, 143,  18, 200,   2, 156,  25, 215, },
 { 78,  28, 125,  64,  89,  36, 138,  74, },
 { 10, 180,   3, 161,  16, 195,   8, 175, },
@@ -108,7 +107,7 @@
 };
 #elif 1
 // tries to correct a gamma of 2.0
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[][8]={
+DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_220)[][8] = {
 {  0, 124,   8, 193,   0, 140,  12, 213, },
 { 55,  14, 104,  42,  66,  19, 119,  52, },
 {  3, 168,   1, 145,   6, 187,   3, 162, },
@@ -121,7 +120,7 @@
 };
 #else
 // tries to correct a gamma of 2.5
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[][8]={
+DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_220)[][8] = {
 {  0, 107,   3, 187,   0, 125,   6, 212, },
 { 39,   7,  86,  28,  49,  11, 102,  36, },
 {  1, 158,   0, 131,   3, 180,   1, 151, },
@@ -330,7 +329,7 @@
                       const int16_t **alpSrc, uint8_t *dest, int dstW,
                       int y, enum AVPixelFormat target)
 {
-    const uint8_t * const d128=dither_8x8_220[y&7];
+    const uint8_t * const d128 = ff_dither_8x8_220[y&7];
     int i;
     unsigned acc = 0;
     int err = 0;
@@ -350,7 +349,7 @@
             Y1 = av_clip_uint8(Y1);
             Y2 = av_clip_uint8(Y2);
         }
-        if (c->flags & SWS_ERROR_DIFFUSION) {
+        if (c->dither == SWS_DITHER_ED) {
             Y1 += (7*err + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2] + 8 - 256)>>4;
             c->dither_error[0][i] = err;
             acc = 2*acc + (Y1 >= 128);
@@ -383,11 +382,11 @@
                       enum AVPixelFormat target)
 {
     const int16_t *buf0  = buf[0],  *buf1  = buf[1];
-    const uint8_t * const d128 = dither_8x8_220[y & 7];
+    const uint8_t * const d128 = ff_dither_8x8_220[y & 7];
     int  yalpha1 = 4096 - yalpha;
     int i;
 
-    if (c->flags & SWS_ERROR_DIFFUSION) {
+    if (c->dither == SWS_DITHER_ED) {
         int err = 0;
         int acc = 0;
         for (i = 0; i < dstW; i +=2) {
@@ -441,10 +440,10 @@
                       const int16_t *abuf0, uint8_t *dest, int dstW,
                       int uvalpha, int y, enum AVPixelFormat target)
 {
-    const uint8_t * const d128 = dither_8x8_220[y & 7];
+    const uint8_t * const d128 = ff_dither_8x8_220[y & 7];
     int i;
 
-    if (c->flags & SWS_ERROR_DIFFUSION) {
+    if (c->dither == SWS_DITHER_ED) {
         int err = 0;
         int acc = 0;
         for (i = 0; i < dstW; i +=2) {
@@ -674,12 +673,231 @@
     }
 
 static av_always_inline void
+yuv2rgba64_X_c_template(SwsContext *c, const int16_t *lumFilter,
+                       const int32_t **lumSrc, int lumFilterSize,
+                       const int16_t *chrFilter, const int32_t **chrUSrc,
+                       const int32_t **chrVSrc, int chrFilterSize,
+                       const int32_t **alpSrc, uint16_t *dest, int dstW,
+                       int y, enum AVPixelFormat target, int hasAlpha)
+{
+    int i;
+    int A1 = 0xffff<<14, A2 = 0xffff<<14;
+
+    for (i = 0; i < ((dstW + 1) >> 1); i++) {
+        int j;
+        int Y1 = -0x40000000;
+        int Y2 = -0x40000000;
+        int U  = -128 << 23; // 19
+        int V  = -128 << 23;
+        int R, G, B;
+
+        for (j = 0; j < lumFilterSize; j++) {
+            Y1 += lumSrc[j][i * 2]     * (unsigned)lumFilter[j];
+            Y2 += lumSrc[j][i * 2 + 1] * (unsigned)lumFilter[j];
+        }
+        for (j = 0; j < chrFilterSize; j++) {;
+            U += chrUSrc[j][i] * (unsigned)chrFilter[j];
+            V += chrVSrc[j][i] * (unsigned)chrFilter[j];
+        }
+
+        if (hasAlpha) {
+            A1 = -0x40000000;
+            A2 = -0x40000000;
+            for (j = 0; j < lumFilterSize; j++) {
+                A1 += alpSrc[j][i * 2]     * (unsigned)lumFilter[j];
+                A2 += alpSrc[j][i * 2 + 1] * (unsigned)lumFilter[j];
+            }
+            A1 >>= 1;
+            A1 += 0x20002000;
+            A2 >>= 1;
+            A2 += 0x20002000;
+        }
+
+        // 8bit: 12+15=27; 16-bit: 12+19=31
+        Y1 >>= 14; // 10
+        Y1 += 0x10000;
+        Y2 >>= 14;
+        Y2 += 0x10000;
+        U  >>= 14;
+        V  >>= 14;
+
+        // 8bit: 27 -> 17bit, 16bit: 31 - 14 = 17bit
+        Y1 -= c->yuv2rgb_y_offset;
+        Y2 -= c->yuv2rgb_y_offset;
+        Y1 *= c->yuv2rgb_y_coeff;
+        Y2 *= c->yuv2rgb_y_coeff;
+        Y1 += 1 << 13; // 21
+        Y2 += 1 << 13;
+        // 8bit: 17 + 13bit = 30bit, 16bit: 17 + 13bit = 30bit
+
+        R = V * c->yuv2rgb_v2r_coeff;
+        G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
+        B =                            U * c->yuv2rgb_u2b_coeff;
+
+        // 8bit: 30 - 22 = 8bit, 16bit: 30bit - 14 = 16bit
+        output_pixel(&dest[0], av_clip_uintp2(B_R + Y1, 30) >> 14);
+        output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
+        output_pixel(&dest[2], av_clip_uintp2(R_B + Y1, 30) >> 14);
+        output_pixel(&dest[3], av_clip_uintp2(A1      , 30) >> 14);
+        output_pixel(&dest[4], av_clip_uintp2(B_R + Y2, 30) >> 14);
+        output_pixel(&dest[5], av_clip_uintp2(  G + Y2, 30) >> 14);
+        output_pixel(&dest[6], av_clip_uintp2(R_B + Y2, 30) >> 14);
+        output_pixel(&dest[7], av_clip_uintp2(A2      , 30) >> 14);
+        dest += 8;
+    }
+}
+
+static av_always_inline void
+yuv2rgba64_2_c_template(SwsContext *c, const int32_t *buf[2],
+                       const int32_t *ubuf[2], const int32_t *vbuf[2],
+                       const int32_t *abuf[2], uint16_t *dest, int dstW,
+                       int yalpha, int uvalpha, int y,
+                       enum AVPixelFormat target, int hasAlpha)
+{
+    const int32_t *buf0  = buf[0],  *buf1  = buf[1],
+                  *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
+                  *vbuf0 = vbuf[0], *vbuf1 = vbuf[1],
+                  *abuf0 = hasAlpha ? abuf[0] : NULL,
+                  *abuf1 = hasAlpha ? abuf[1] : NULL;
+    int  yalpha1 = 4096 - yalpha;
+    int uvalpha1 = 4096 - uvalpha;
+    int i;
+    int A1 = 0xffff<<14, A2 = 0xffff<<14;
+
+    for (i = 0; i < ((dstW + 1) >> 1); i++) {
+        int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha) >> 14;
+        int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha) >> 14;
+        int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha + (-128 << 23)) >> 14;
+        int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha + (-128 << 23)) >> 14;
+        int R, G, B;
+
+        Y1 -= c->yuv2rgb_y_offset;
+        Y2 -= c->yuv2rgb_y_offset;
+        Y1 *= c->yuv2rgb_y_coeff;
+        Y2 *= c->yuv2rgb_y_coeff;
+        Y1 += 1 << 13;
+        Y2 += 1 << 13;
+
+        R = V * c->yuv2rgb_v2r_coeff;
+        G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
+        B =                            U * c->yuv2rgb_u2b_coeff;
+
+        if (hasAlpha) {
+            A1 = (abuf0[i * 2    ] * yalpha1 + abuf1[i * 2    ] * yalpha) >> 1;
+            A2 = (abuf0[i * 2 + 1] * yalpha1 + abuf1[i * 2 + 1] * yalpha) >> 1;
+
+            A1 += 1 << 13;
+            A2 += 1 << 13;
+        }
+
+        output_pixel(&dest[0], av_clip_uintp2(B_R + Y1, 30) >> 14);
+        output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
+        output_pixel(&dest[2], av_clip_uintp2(R_B + Y1, 30) >> 14);
+        output_pixel(&dest[3], av_clip_uintp2(A1      , 30) >> 14);
+        output_pixel(&dest[4], av_clip_uintp2(B_R + Y2, 30) >> 14);
+        output_pixel(&dest[5], av_clip_uintp2(  G + Y2, 30) >> 14);
+        output_pixel(&dest[6], av_clip_uintp2(R_B + Y2, 30) >> 14);
+        output_pixel(&dest[7], av_clip_uintp2(A2      , 30) >> 14);
+        dest += 8;
+    }
+}
+
+static av_always_inline void
+yuv2rgba64_1_c_template(SwsContext *c, const int32_t *buf0,
+                       const int32_t *ubuf[2], const int32_t *vbuf[2],
+                       const int32_t *abuf0, uint16_t *dest, int dstW,
+                       int uvalpha, int y, enum AVPixelFormat target, int hasAlpha)
+{
+    const int32_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
+    int i;
+    int A1 = 0xffff<<14, A2= 0xffff<<14;
+
+    if (uvalpha < 2048) {
+        for (i = 0; i < ((dstW + 1) >> 1); i++) {
+            int Y1 = (buf0[i * 2]    ) >> 2;
+            int Y2 = (buf0[i * 2 + 1]) >> 2;
+            int U  = (ubuf0[i] + (-128 << 11)) >> 2;
+            int V  = (vbuf0[i] + (-128 << 11)) >> 2;
+            int R, G, B;
+
+            Y1 -= c->yuv2rgb_y_offset;
+            Y2 -= c->yuv2rgb_y_offset;
+            Y1 *= c->yuv2rgb_y_coeff;
+            Y2 *= c->yuv2rgb_y_coeff;
+            Y1 += 1 << 13;
+            Y2 += 1 << 13;
+
+            if (hasAlpha) {
+                A1 = abuf0[i * 2    ] << 11;
+                A2 = abuf0[i * 2 + 1] << 11;
+
+                A1 += 1 << 13;
+                A2 += 1 << 13;
+            }
+
+            R = V * c->yuv2rgb_v2r_coeff;
+            G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
+            B =                            U * c->yuv2rgb_u2b_coeff;
+
+            output_pixel(&dest[0], av_clip_uintp2(B_R + Y1, 30) >> 14);
+            output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
+            output_pixel(&dest[2], av_clip_uintp2(R_B + Y1, 30) >> 14);
+            output_pixel(&dest[3], av_clip_uintp2(A1      , 30) >> 14);
+            output_pixel(&dest[4], av_clip_uintp2(B_R + Y2, 30) >> 14);
+            output_pixel(&dest[5], av_clip_uintp2(  G + Y2, 30) >> 14);
+            output_pixel(&dest[6], av_clip_uintp2(R_B + Y2, 30) >> 14);
+            output_pixel(&dest[7], av_clip_uintp2(A2      , 30) >> 14);
+            dest += 8;
+        }
+    } else {
+        const int32_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
+        int A1 = 0xffff<<14, A2 = 0xffff<<14;
+        for (i = 0; i < ((dstW + 1) >> 1); i++) {
+            int Y1 = (buf0[i * 2]    ) >> 2;
+            int Y2 = (buf0[i * 2 + 1]) >> 2;
+            int U  = (ubuf0[i] + ubuf1[i] + (-128 << 12)) >> 3;
+            int V  = (vbuf0[i] + vbuf1[i] + (-128 << 12)) >> 3;
+            int R, G, B;
+
+            Y1 -= c->yuv2rgb_y_offset;
+            Y2 -= c->yuv2rgb_y_offset;
+            Y1 *= c->yuv2rgb_y_coeff;
+            Y2 *= c->yuv2rgb_y_coeff;
+            Y1 += 1 << 13;
+            Y2 += 1 << 13;
+
+            if (hasAlpha) {
+                A1 = abuf0[i * 2    ] << 11;
+                A2 = abuf0[i * 2 + 1] << 11;
+
+                A1 += 1 << 13;
+                A2 += 1 << 13;
+            }
+
+            R = V * c->yuv2rgb_v2r_coeff;
+            G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
+            B =                            U * c->yuv2rgb_u2b_coeff;
+
+            output_pixel(&dest[0], av_clip_uintp2(B_R + Y1, 30) >> 14);
+            output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
+            output_pixel(&dest[2], av_clip_uintp2(R_B + Y1, 30) >> 14);
+            output_pixel(&dest[3], av_clip_uintp2(A1      , 30) >> 14);
+            output_pixel(&dest[4], av_clip_uintp2(B_R + Y2, 30) >> 14);
+            output_pixel(&dest[5], av_clip_uintp2(  G + Y2, 30) >> 14);
+            output_pixel(&dest[6], av_clip_uintp2(R_B + Y2, 30) >> 14);
+            output_pixel(&dest[7], av_clip_uintp2(A2      , 30) >> 14);
+            dest += 8;
+        }
+    }
+}
+
+static av_always_inline void
 yuv2rgb48_X_c_template(SwsContext *c, const int16_t *lumFilter,
                        const int32_t **lumSrc, int lumFilterSize,
                        const int16_t *chrFilter, const int32_t **chrUSrc,
                        const int32_t **chrVSrc, int chrFilterSize,
                        const int32_t **alpSrc, uint16_t *dest, int dstW,
-                       int y, enum AVPixelFormat target)
+                       int y, enum AVPixelFormat target, int hasAlpha)
 {
     int i;
 
@@ -737,7 +955,7 @@
                        const int32_t *ubuf[2], const int32_t *vbuf[2],
                        const int32_t *abuf[2], uint16_t *dest, int dstW,
                        int yalpha, int uvalpha, int y,
-                       enum AVPixelFormat target)
+                       enum AVPixelFormat target, int hasAlpha)
 {
     const int32_t *buf0  = buf[0],  *buf1  = buf[1],
                   *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
@@ -778,7 +996,7 @@
 yuv2rgb48_1_c_template(SwsContext *c, const int32_t *buf0,
                        const int32_t *ubuf[2], const int32_t *vbuf[2],
                        const int32_t *abuf0, uint16_t *dest, int dstW,
-                       int uvalpha, int y, enum AVPixelFormat target)
+                       int uvalpha, int y, enum AVPixelFormat target, int hasAlpha)
 {
     const int32_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
     int i;
@@ -845,7 +1063,7 @@
 #undef r_b
 #undef b_r
 
-#define YUV2PACKED16WRAPPER(name, base, ext, fmt) \
+#define YUV2PACKED16WRAPPER(name, base, ext, fmt, hasAlpha) \
 static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
                         const int16_t **_lumSrc, int lumFilterSize, \
                         const int16_t *chrFilter, const int16_t **_chrUSrc, \
@@ -860,7 +1078,7 @@
     uint16_t *dest = (uint16_t *) _dest; \
     name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
                           chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
-                          alpSrc, dest, dstW, y, fmt); \
+                          alpSrc, dest, dstW, y, fmt, hasAlpha); \
 } \
  \
 static void name ## ext ## _2_c(SwsContext *c, const int16_t *_buf[2], \
@@ -874,7 +1092,7 @@
                   **abuf = (const int32_t **) _abuf; \
     uint16_t *dest = (uint16_t *) _dest; \
     name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
-                          dest, dstW, yalpha, uvalpha, y, fmt); \
+                          dest, dstW, yalpha, uvalpha, y, fmt, hasAlpha); \
 } \
  \
 static void name ## ext ## _1_c(SwsContext *c, const int16_t *_buf0, \
@@ -888,13 +1106,17 @@
                   *abuf0 = (const int32_t *)  _abuf0; \
     uint16_t *dest = (uint16_t *) _dest; \
     name ## base ## _1_c_template(c, buf0, ubuf, vbuf, abuf0, dest, \
-                                  dstW, uvalpha, y, fmt); \
+                                  dstW, uvalpha, y, fmt, hasAlpha); \
 }
 
-YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48be, AV_PIX_FMT_RGB48BE)
-YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48le, AV_PIX_FMT_RGB48LE)
-YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48be, AV_PIX_FMT_BGR48BE)
-YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48le, AV_PIX_FMT_BGR48LE)
+YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48be, AV_PIX_FMT_RGB48BE, 0)
+YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48le, AV_PIX_FMT_RGB48LE, 0)
+YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48be, AV_PIX_FMT_BGR48BE, 0)
+YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48le, AV_PIX_FMT_BGR48LE, 0)
+YUV2PACKED16WRAPPER(yuv2, rgba64, rgba64be, AV_PIX_FMT_RGBA64BE, 1)
+YUV2PACKED16WRAPPER(yuv2, rgba64, rgba64le, AV_PIX_FMT_RGBA64LE, 1)
+YUV2PACKED16WRAPPER(yuv2, rgba64, rgbx64be, AV_PIX_FMT_RGBA64BE, 0)
+YUV2PACKED16WRAPPER(yuv2, rgba64, rgbx64le, AV_PIX_FMT_RGBA64LE, 0)
 
 /*
  * Write out 2 RGB pixels in the target pixel format. This function takes a
@@ -926,9 +1148,15 @@
         if (hasAlpha) {
             int sh = (target == AV_PIX_FMT_RGB32_1 || target == AV_PIX_FMT_BGR32_1) ? 0 : 24;
 
+            av_assert2((((r[Y1] + g[Y1] + b[Y1]) >> sh) & 0xFF) == 0);
             dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1] + (A1 << sh);
             dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2] + (A2 << sh);
         } else {
+#if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1
+            int sh = (target == AV_PIX_FMT_RGB32_1 || target == AV_PIX_FMT_BGR32_1) ? 0 : 24;
+
+            av_assert2((((r[Y1] + g[Y1] + b[Y1]) >> sh) & 0xFF) == 0xFF);
+#endif
             dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1];
             dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2];
         }
@@ -960,26 +1188,26 @@
         int dr1, dg1, db1, dr2, dg2, db2;
 
         if (target == AV_PIX_FMT_RGB565 || target == AV_PIX_FMT_BGR565) {
-            dr1 = dither_2x2_8[ y & 1     ][0];
-            dg1 = dither_2x2_4[ y & 1     ][0];
-            db1 = dither_2x2_8[(y & 1) ^ 1][0];
-            dr2 = dither_2x2_8[ y & 1     ][1];
-            dg2 = dither_2x2_4[ y & 1     ][1];
-            db2 = dither_2x2_8[(y & 1) ^ 1][1];
+            dr1 = ff_dither_2x2_8[ y & 1     ][0];
+            dg1 = ff_dither_2x2_4[ y & 1     ][0];
+            db1 = ff_dither_2x2_8[(y & 1) ^ 1][0];
+            dr2 = ff_dither_2x2_8[ y & 1     ][1];
+            dg2 = ff_dither_2x2_4[ y & 1     ][1];
+            db2 = ff_dither_2x2_8[(y & 1) ^ 1][1];
         } else if (target == AV_PIX_FMT_RGB555 || target == AV_PIX_FMT_BGR555) {
-            dr1 = dither_2x2_8[ y & 1     ][0];
-            dg1 = dither_2x2_8[ y & 1     ][1];
-            db1 = dither_2x2_8[(y & 1) ^ 1][0];
-            dr2 = dither_2x2_8[ y & 1     ][1];
-            dg2 = dither_2x2_8[ y & 1     ][0];
-            db2 = dither_2x2_8[(y & 1) ^ 1][1];
+            dr1 = ff_dither_2x2_8[ y & 1     ][0];
+            dg1 = ff_dither_2x2_8[ y & 1     ][1];
+            db1 = ff_dither_2x2_8[(y & 1) ^ 1][0];
+            dr2 = ff_dither_2x2_8[ y & 1     ][1];
+            dg2 = ff_dither_2x2_8[ y & 1     ][0];
+            db2 = ff_dither_2x2_8[(y & 1) ^ 1][1];
         } else {
-            dr1 = dither_4x4_16[ y & 3     ][0];
-            dg1 = dither_4x4_16[ y & 3     ][1];
-            db1 = dither_4x4_16[(y & 3) ^ 3][0];
-            dr2 = dither_4x4_16[ y & 3     ][1];
-            dg2 = dither_4x4_16[ y & 3     ][0];
-            db2 = dither_4x4_16[(y & 3) ^ 3][1];
+            dr1 = ff_dither_4x4_16[ y & 3     ][0];
+            dg1 = ff_dither_4x4_16[ y & 3     ][1];
+            db1 = ff_dither_4x4_16[(y & 3) ^ 3][0];
+            dr2 = ff_dither_4x4_16[ y & 3     ][1];
+            dg2 = ff_dither_4x4_16[ y & 3     ][0];
+            db2 = ff_dither_4x4_16[(y & 3) ^ 3][1];
         }
 
         dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1];
@@ -992,15 +1220,15 @@
         int dr1, dg1, db1, dr2, dg2, db2;
 
         if (target == AV_PIX_FMT_RGB8 || target == AV_PIX_FMT_BGR8) {
-            const uint8_t * const d64 = dither_8x8_73[y & 7];
-            const uint8_t * const d32 = dither_8x8_32[y & 7];
+            const uint8_t * const d64 = ff_dither_8x8_73[y & 7];
+            const uint8_t * const d32 = ff_dither_8x8_32[y & 7];
             dr1 = dg1 = d32[(i * 2 + 0) & 7];
             db1 =       d64[(i * 2 + 0) & 7];
             dr2 = dg2 = d32[(i * 2 + 1) & 7];
             db2 =       d64[(i * 2 + 1) & 7];
         } else {
-            const uint8_t * const d64  = dither_8x8_73 [y & 7];
-            const uint8_t * const d128 = dither_8x8_220[y & 7];
+            const uint8_t * const d64  = ff_dither_8x8_73 [y & 7];
+            const uint8_t * const d128 = ff_dither_8x8_220[y & 7];
             dr1 = db1 = d128[(i * 2 + 0) & 7];
             dg1 =        d64[(i * 2 + 0) & 7];
             dr2 = db2 = d128[(i * 2 + 1) & 7];
@@ -1323,6 +1551,7 @@
     int i;
     int step = (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) ? 3 : 4;
     int err[4] = {0};
+    int A = 0; //init to silence warning
 
     if(   target == AV_PIX_FMT_BGR4_BYTE || target == AV_PIX_FMT_RGB4_BYTE
        || target == AV_PIX_FMT_BGR8      || target == AV_PIX_FMT_RGB8)
@@ -1333,7 +1562,6 @@
         int Y = 1<<9;
         int U = (1<<9)-(128 << 19);
         int V = (1<<9)-(128 << 19);
-        int A;
 
         for (j = 0; j < lumFilterSize; j++) {
             Y += lumSrc[j][i] * lumFilter[j];
@@ -1379,6 +1607,7 @@
     int i;
     int step = (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) ? 3 : 4;
     int err[4] = {0};
+    int A = 0; // init to silcene warning
 
     if(   target == AV_PIX_FMT_BGR4_BYTE || target == AV_PIX_FMT_RGB4_BYTE
        || target == AV_PIX_FMT_BGR8      || target == AV_PIX_FMT_RGB8)
@@ -1388,7 +1617,6 @@
         int Y = ( buf0[i] * yalpha1  +  buf1[i] * yalpha             ) >> 10; //FIXME rounding
         int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha-(128 << 19)) >> 10;
         int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha-(128 << 19)) >> 10;
-        int A;
 
         if (hasAlpha) {
             A = (abuf0[i] * yalpha1 + abuf1[i] * yalpha + (1<<18)) >> 19;
@@ -1421,11 +1649,11 @@
         step = 1;
 
     if (uvalpha < 2048) {
+        int A = 0; //init to silence warning
         for (i = 0; i < dstW; i++) {
             int Y = buf0[i] << 2;
             int U = (ubuf0[i] - (128<<7)) << 2;
             int V = (vbuf0[i] - (128<<7)) << 2;
-            int A;
 
             if (hasAlpha) {
                 A = (abuf0[i] + 64) >> 7;
@@ -1438,11 +1666,11 @@
         }
     } else {
         const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
+        int A = 0; //init to silence warning
         for (i = 0; i < dstW; i++) {
             int Y = buf0[i] << 2;
             int U = (ubuf0[i] + ubuf1[i] - (128<<8)) << 1;
             int V = (vbuf0[i] + vbuf1[i] - (128<<8)) << 1;
-            int A;
 
             if (hasAlpha) {
                 A = (abuf0[i] + 64) >> 7;
@@ -1495,16 +1723,17 @@
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->dstFormat);
     int i;
-    int hasAlpha = 0;
+    int hasAlpha = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) && alpSrc;
     uint16_t **dest16 = (uint16_t**)dest;
     int SH = 22 + 7 - desc->comp[0].depth_minus1;
+    int A = 0; // init to silence warning
 
     for (i = 0; i < dstW; i++) {
         int j;
         int Y = 1 << 9;
         int U = (1 << 9) - (128 << 19);
         int V = (1 << 9) - (128 << 19);
-        int R, G, B, A;
+        int R, G, B;
 
         for (j = 0; j < lumFilterSize; j++)
             Y += lumSrc[j][i] * lumFilter[j];
@@ -1547,10 +1776,14 @@
             dest16[0][i] = G >> SH;
             dest16[1][i] = B >> SH;
             dest16[2][i] = R >> SH;
+            if (hasAlpha)
+                dest16[3][i] = A;
         } else {
             dest[0][i] = G >> 22;
             dest[1][i] = B >> 22;
             dest[2][i] = R >> 22;
+            if (hasAlpha)
+                dest[3][i] = A;
         }
     }
     if (SH != 22 && (!isBE(c->dstFormat)) != (!HAVE_BIGENDIAN)) {
@@ -1558,6 +1791,8 @@
             dest16[0][i] = av_bswap16(dest16[0][i]);
             dest16[1][i] = av_bswap16(dest16[1][i]);
             dest16[2][i] = av_bswap16(dest16[2][i]);
+            if (hasAlpha)
+                dest16[3][i] = av_bswap16(dest16[3][i]);
         }
     }
 }
@@ -1722,6 +1957,7 @@
         case AV_PIX_FMT_GBRP14LE:
         case AV_PIX_FMT_GBRP16BE:
         case AV_PIX_FMT_GBRP16LE:
+        case AV_PIX_FMT_GBRAP:
             *yuv2anyX = yuv2gbrp_full_X_c;
             break;
         }
@@ -1730,6 +1966,34 @@
     } else {
         YUV_PACKED:
         switch (dstFormat) {
+        case AV_PIX_FMT_RGBA64LE:
+#if CONFIG_SWSCALE_ALPHA
+            if (c->alpPixBuf) {
+                *yuv2packed1 = yuv2rgba64le_1_c;
+                *yuv2packed2 = yuv2rgba64le_2_c;
+                *yuv2packedX = yuv2rgba64le_X_c;
+            } else
+#endif /* CONFIG_SWSCALE_ALPHA */
+            {
+                *yuv2packed1 = yuv2rgbx64le_1_c;
+                *yuv2packed2 = yuv2rgbx64le_2_c;
+                *yuv2packedX = yuv2rgbx64le_X_c;
+            }
+            break;
+        case AV_PIX_FMT_RGBA64BE:
+#if CONFIG_SWSCALE_ALPHA
+            if (c->alpPixBuf) {
+                *yuv2packed1 = yuv2rgba64be_1_c;
+                *yuv2packed2 = yuv2rgba64be_2_c;
+                *yuv2packedX = yuv2rgba64be_X_c;
+            } else
+#endif /* CONFIG_SWSCALE_ALPHA */
+            {
+                *yuv2packed1 = yuv2rgbx64be_1_c;
+                *yuv2packed2 = yuv2rgbx64be_2_c;
+                *yuv2packedX = yuv2rgbx64be_X_c;
+            }
+            break;
         case AV_PIX_FMT_RGB48LE:
             *yuv2packed1 = yuv2rgb48le_1_c;
             *yuv2packed2 = yuv2rgb48le_2_c;
diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c
index a8501d9..b0661f8 100644
--- a/libswscale/ppc/yuv2rgb_altivec.c
+++ b/libswscale/ppc/yuv2rgb_altivec.c
@@ -246,8 +246,6 @@
                   (vector unsigned short)                               \
                       vec_max(y, ((vector signed short) { 0 })))
 
-//#define out_pixels(a, b, c, ptr) vec_mstrgb32(__typeof__(a), ((__typeof__(a)) { 255 }), a, a, a, ptr)
-
 static inline void cvtyuvtoRGB(SwsContext *c, vector signed short Y,
                                vector signed short U, vector signed short V,
                                vector signed short *R, vector signed short *G,
@@ -620,18 +618,18 @@
     return;
 }
 
-static av_always_inline void ff_yuv2packedX_altivec(SwsContext *c,
-                                                    const int16_t *lumFilter,
-                                                    const int16_t **lumSrc,
-                                                    int lumFilterSize,
-                                                    const int16_t *chrFilter,
-                                                    const int16_t **chrUSrc,
-                                                    const int16_t **chrVSrc,
-                                                    int chrFilterSize,
-                                                    const int16_t **alpSrc,
-                                                    uint8_t *dest,
-                                                    int dstW, int dstY,
-                                                    enum AVPixelFormat target)
+static av_always_inline void yuv2packedX_altivec(SwsContext *c,
+                                                 const int16_t *lumFilter,
+                                                 const int16_t **lumSrc,
+                                                 int lumFilterSize,
+                                                 const int16_t *chrFilter,
+                                                 const int16_t **chrUSrc,
+                                                 const int16_t **chrVSrc,
+                                                 int chrFilterSize,
+                                                 const int16_t **alpSrc,
+                                                 uint8_t *dest,
+                                                 int dstW, int dstY,
+                                                 enum AVPixelFormat target)
 {
     int i, j;
     vector signed short X, X0, X1, Y0, U0, V0, Y1, U1, V1, U, V;
@@ -840,10 +838,10 @@
                                      const int16_t **alpSrc,            \
                                      uint8_t *dest, int dstW, int dstY) \
 {                                                                       \
-    ff_yuv2packedX_altivec(c, lumFilter, lumSrc, lumFilterSize,         \
-                           chrFilter, chrUSrc, chrVSrc,                 \
-                           chrFilterSize, alpSrc,                       \
-                           dest, dstW, dstY, pixfmt);                   \
+    yuv2packedX_altivec(c, lumFilter, lumSrc, lumFilterSize,            \
+                        chrFilter, chrUSrc, chrVSrc,                    \
+                        chrFilterSize, alpSrc,                          \
+                        dest, dstW, dstY, pixfmt);                      \
 }
 
 YUV2PACKEDX_WRAPPER(abgr,  AV_PIX_FMT_ABGR);
diff --git a/libswscale/rgb2rgb_template.c b/libswscale/rgb2rgb_template.c
index 76229d8..98e3a14 100644
--- a/libswscale/rgb2rgb_template.c
+++ b/libswscale/rgb2rgb_template.c
@@ -26,6 +26,8 @@
 
 #include <stddef.h>
 
+#include "libavutil/attributes.h"
+
 static inline void rgb24tobgr32_c(const uint8_t *src, uint8_t *dst,
                                   int src_size)
 {
@@ -821,7 +823,7 @@
                            int lumStride, int chromStride, int srcStride)
 {
     int y;
-    const int chromWidth = -((-width) >> 1);
+    const int chromWidth = FF_CEIL_RSHIFT(width, 1);
 
     for (y = 0; y < height; y++) {
         extract_even_c(src, ydst, width);
@@ -841,7 +843,7 @@
                            int lumStride, int chromStride, int srcStride)
 {
     int y;
-    const int chromWidth = -((-width) >> 1);
+    const int chromWidth = FF_CEIL_RSHIFT(width, 1);
 
     for (y = 0; y < height; y++) {
         extract_even_c(src, ydst, width);
@@ -859,7 +861,7 @@
                            int lumStride, int chromStride, int srcStride)
 {
     int y;
-    const int chromWidth = -((-width) >> 1);
+    const int chromWidth = FF_CEIL_RSHIFT(width, 1);
 
     for (y = 0; y < height; y++) {
         extract_even_c(src + 1, ydst, width);
@@ -879,7 +881,7 @@
                            int lumStride, int chromStride, int srcStride)
 {
     int y;
-    const int chromWidth = -((-width) >> 1);
+    const int chromWidth = FF_CEIL_RSHIFT(width, 1);
 
     for (y = 0; y < height; y++) {
         extract_even_c(src + 1, ydst, width);
@@ -892,7 +894,7 @@
     }
 }
 
-static inline void rgb2rgb_init_c(void)
+static av_cold void rgb2rgb_init_c(void)
 {
     rgb15to16          = rgb15to16_c;
     rgb15tobgr24       = rgb15tobgr24_c;
diff --git a/libswscale/swscale.c b/libswscale/swscale.c
index 0c20a71..c61989f 100644
--- a/libswscale/swscale.c
+++ b/libswscale/swscale.c
@@ -18,7 +18,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <assert.h>
 #include <inttypes.h>
 #include <math.h>
 #include <stdio.h>
@@ -36,7 +35,7 @@
 #include "swscale_internal.h"
 #include "swscale.h"
 
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_128)[8][8] = {
+DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_128)[9][8] = {
     {  36, 68,  60, 92,  34, 66,  58, 90, },
     { 100,  4, 124, 28,  98,  2, 122, 26, },
     {  52, 84,  44, 76,  50, 82,  42, 74, },
@@ -45,9 +44,10 @@
     {  96,  0, 120, 24, 102,  6, 126, 30, },
     {  48, 80,  40, 72,  54, 86,  46, 78, },
     { 112, 16, 104,  8, 118, 22, 110, 14, },
+    {  36, 68,  60, 92,  34, 66,  58, 90, },
 };
 
-DECLARE_ALIGNED(8, const uint8_t, ff_sws_pb_64)[8] = {
+DECLARE_ALIGNED(8, static const uint8_t, sws_pb_64)[8] = {
     64, 64, 64, 64, 64, 64, 64, 64
 };
 
@@ -256,6 +256,9 @@
     } else if (c->readLumPlanar && !isAlpha) {
         c->readLumPlanar(formatConvBuffer, src_in, srcW, c->input_rgb2yuv_table);
         src = formatConvBuffer;
+    } else if (c->readAlpPlanar && isAlpha) {
+        c->readAlpPlanar(formatConvBuffer, src_in, srcW, NULL);
+        src = formatConvBuffer;
     }
 
     if (!c->hyscale_fast) {
@@ -370,8 +373,8 @@
     yuv2packed2_fn yuv2packed2       = c->yuv2packed2;
     yuv2packedX_fn yuv2packedX       = c->yuv2packedX;
     yuv2anyX_fn yuv2anyX             = c->yuv2anyX;
-    const int chrSrcSliceY           =     srcSliceY  >> c->chrSrcVSubSample;
-    const int chrSrcSliceH           = -((-srcSliceH) >> c->chrSrcVSubSample);
+    const int chrSrcSliceY           =                srcSliceY >> c->chrSrcVSubSample;
+    const int chrSrcSliceH           = FF_CEIL_RSHIFT(srcSliceH,   c->chrSrcVSubSample);
     int should_dither                = is9_OR_10BPS(c->srcFormat) ||
                                        is16BPS(c->srcFormat);
     int lastDstY;
@@ -446,7 +449,7 @@
     }
 
     if (!should_dither) {
-        c->chrDither8 = c->lumDither8 = ff_sws_pb_64;
+        c->chrDither8 = c->lumDither8 = sws_pb_64;
     }
     lastDstY = dstY;
 
@@ -488,7 +491,7 @@
 
         // Do we have enough lines in this slice to output the dstY line
         enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH &&
-                       lastChrSrcY < -((-srcSliceY - srcSliceH) >> c->chrSrcVSubSample);
+                       lastChrSrcY < FF_CEIL_RSHIFT(srcSliceY + srcSliceH, c->chrSrcVSubSample);
 
         if (!enough_lines) {
             lastLumSrcY = srcSliceY + srcSliceH - 1;
@@ -555,8 +558,8 @@
                               lastInLumBuf, lastInChrBuf);
 #endif
         if (should_dither) {
-            c->chrDither8 = dither_8x8_128[chrDstY & 7];
-            c->lumDither8 = dither_8x8_128[dstY    & 7];
+            c->chrDither8 = ff_dither_8x8_128[chrDstY & 7];
+            c->lumDither8 = ff_dither_8x8_128[dstY    & 7];
         }
         if (dstY >= dstH - 2) {
             /* hmm looks like we can't use MMX here without overwriting
@@ -791,6 +794,118 @@
     return 1;
 }
 
+static void xyz12Torgb48(struct SwsContext *c, uint16_t *dst,
+                         const uint16_t *src, int stride, int h)
+{
+    int xp,yp;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
+
+    for (yp=0; yp<h; yp++) {
+        for (xp=0; xp+2<stride; xp+=3) {
+            int x, y, z, r, g, b;
+
+            if (desc->flags & AV_PIX_FMT_FLAG_BE) {
+                x = AV_RB16(src + xp + 0);
+                y = AV_RB16(src + xp + 1);
+                z = AV_RB16(src + xp + 2);
+            } else {
+                x = AV_RL16(src + xp + 0);
+                y = AV_RL16(src + xp + 1);
+                z = AV_RL16(src + xp + 2);
+            }
+
+            x = c->xyzgamma[x>>4];
+            y = c->xyzgamma[y>>4];
+            z = c->xyzgamma[z>>4];
+
+            // convert from XYZlinear to sRGBlinear
+            r = c->xyz2rgb_matrix[0][0] * x +
+                c->xyz2rgb_matrix[0][1] * y +
+                c->xyz2rgb_matrix[0][2] * z >> 12;
+            g = c->xyz2rgb_matrix[1][0] * x +
+                c->xyz2rgb_matrix[1][1] * y +
+                c->xyz2rgb_matrix[1][2] * z >> 12;
+            b = c->xyz2rgb_matrix[2][0] * x +
+                c->xyz2rgb_matrix[2][1] * y +
+                c->xyz2rgb_matrix[2][2] * z >> 12;
+
+            // limit values to 12-bit depth
+            r = av_clip_c(r,0,4095);
+            g = av_clip_c(g,0,4095);
+            b = av_clip_c(b,0,4095);
+
+            // convert from sRGBlinear to RGB and scale from 12bit to 16bit
+            if (desc->flags & AV_PIX_FMT_FLAG_BE) {
+                AV_WB16(dst + xp + 0, c->rgbgamma[r] << 4);
+                AV_WB16(dst + xp + 1, c->rgbgamma[g] << 4);
+                AV_WB16(dst + xp + 2, c->rgbgamma[b] << 4);
+            } else {
+                AV_WL16(dst + xp + 0, c->rgbgamma[r] << 4);
+                AV_WL16(dst + xp + 1, c->rgbgamma[g] << 4);
+                AV_WL16(dst + xp + 2, c->rgbgamma[b] << 4);
+            }
+        }
+        src += stride;
+        dst += stride;
+    }
+}
+
+static void rgb48Toxyz12(struct SwsContext *c, uint16_t *dst,
+                         const uint16_t *src, int stride, int h)
+{
+    int xp,yp;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
+
+    for (yp=0; yp<h; yp++) {
+        for (xp=0; xp+2<stride; xp+=3) {
+            int x, y, z, r, g, b;
+
+            if (desc->flags & AV_PIX_FMT_FLAG_BE) {
+                r = AV_RB16(src + xp + 0);
+                g = AV_RB16(src + xp + 1);
+                b = AV_RB16(src + xp + 2);
+            } else {
+                r = AV_RL16(src + xp + 0);
+                g = AV_RL16(src + xp + 1);
+                b = AV_RL16(src + xp + 2);
+            }
+
+            r = c->rgbgammainv[r>>4];
+            g = c->rgbgammainv[g>>4];
+            b = c->rgbgammainv[b>>4];
+
+            // convert from sRGBlinear to XYZlinear
+            x = c->rgb2xyz_matrix[0][0] * r +
+                c->rgb2xyz_matrix[0][1] * g +
+                c->rgb2xyz_matrix[0][2] * b >> 12;
+            y = c->rgb2xyz_matrix[1][0] * r +
+                c->rgb2xyz_matrix[1][1] * g +
+                c->rgb2xyz_matrix[1][2] * b >> 12;
+            z = c->rgb2xyz_matrix[2][0] * r +
+                c->rgb2xyz_matrix[2][1] * g +
+                c->rgb2xyz_matrix[2][2] * b >> 12;
+
+            // limit values to 12-bit depth
+            x = av_clip_c(x,0,4095);
+            y = av_clip_c(y,0,4095);
+            z = av_clip_c(z,0,4095);
+
+            // convert from XYZlinear to X'Y'Z' and scale from 12bit to 16bit
+            if (desc->flags & AV_PIX_FMT_FLAG_BE) {
+                AV_WB16(dst + xp + 0, c->xyzgammainv[x] << 4);
+                AV_WB16(dst + xp + 1, c->xyzgammainv[y] << 4);
+                AV_WB16(dst + xp + 2, c->xyzgammainv[z] << 4);
+            } else {
+                AV_WL16(dst + xp + 0, c->xyzgammainv[x] << 4);
+                AV_WL16(dst + xp + 1, c->xyzgammainv[y] << 4);
+                AV_WL16(dst + xp + 2, c->xyzgammainv[z] << 4);
+            }
+        }
+        src += stride;
+        dst += stride;
+    }
+}
+
 /**
  * swscale wrapper, so we don't need to export the SwsContext.
  * Assumes planar YUV to be in YUV order instead of YVU.
@@ -912,6 +1027,9 @@
         uint8_t *base;
         int x,y;
         rgb0_tmp = av_malloc(FFABS(srcStride[0]) * srcSliceH + 32);
+        if (!rgb0_tmp)
+            return AVERROR(ENOMEM);
+
         base = srcStride[0] < 0 ? rgb0_tmp - srcStride[0] * (srcSliceH-1) : rgb0_tmp;
         for (y=0; y<srcSliceH; y++){
             memcpy(base + srcStride[0]*y, src2[0] + srcStride[0]*y, 4*c->srcW);
@@ -922,7 +1040,19 @@
         src2[0] = base;
     }
 
-    if (!srcSliceY && (c->flags & SWS_BITEXACT) && (c->flags & SWS_ERROR_DIFFUSION) && c->dither_error[0])
+    if (c->srcXYZ && !(c->dstXYZ && c->srcW==c->dstW && c->srcH==c->dstH)) {
+        uint8_t *base;
+        rgb0_tmp = av_malloc(FFABS(srcStride[0]) * srcSliceH + 32);
+        if (!rgb0_tmp)
+            return AVERROR(ENOMEM);
+
+        base = srcStride[0] < 0 ? rgb0_tmp - srcStride[0] * (srcSliceH-1) : rgb0_tmp;
+
+        xyz12Torgb48(c, (uint16_t*)base, (const uint16_t*)src2[0], srcStride[0]/2, srcSliceH);
+        src2[0] = base;
+    }
+
+    if (!srcSliceY && (c->flags & SWS_BITEXACT) && c->dither == SWS_DITHER_ED && c->dither_error[0])
         for (i = 0; i < 4; i++)
             memset(c->dither_error[i], 0, sizeof(c->dither_error[0][0]) * (c->dstW+2));
 
@@ -972,6 +1102,12 @@
                           srcSliceH, dst2, dstStride2);
     }
 
+
+    if (c->dstXYZ && !(c->srcXYZ && c->srcW==c->dstW && c->srcH==c->dstH)) {
+        /* replace on the same data */
+        rgb48Toxyz12(c, (uint16_t*)dst2[0], (const uint16_t*)dst2[0], dstStride[0]/2, ret);
+    }
+
     av_free(rgb0_tmp);
     return ret;
 }
diff --git a/libswscale/swscale.h b/libswscale/swscale.h
index 5f6ae0f..42702b7 100644
--- a/libswscale/swscale.h
+++ b/libswscale/swscale.h
@@ -147,6 +147,13 @@
 int sws_isSupportedOutput(enum AVPixelFormat pix_fmt);
 
 /**
+ * @param[in]  pix_fmt the pixel format
+ * @return a positive value if an endianness conversion for pix_fmt is
+ * supported, 0 otherwise.
+ */
+int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt);
+
+/**
  * Allocate an empty SwsContext. This must be filled and passed to
  * sws_init_context(). For filling see AVOptions, options.c and
  * sws_setColorspaceDetails().
diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h
index be5a80e..eaaed0e 100644
--- a/libswscale/swscale_internal.h
+++ b/libswscale/swscale_internal.h
@@ -61,6 +61,14 @@
 
 struct SwsContext;
 
+typedef enum SwsDither {
+    SWS_DITHER_NONE = 0,
+    SWS_DITHER_AUTO,
+    SWS_DITHER_BAYER,
+    SWS_DITHER_ED,
+    NB_SWS_DITHER,
+} SwsDither;
+
 typedef int (*SwsFunc)(struct SwsContext *context, const uint8_t *src[],
                        int srcStride[], int srcSliceY, int srcSliceH,
                        uint8_t *dst[], int dstStride[]);
@@ -380,6 +388,12 @@
     int dstRange;                 ///< 0 = MPG YUV range, 1 = JPG YUV range (destination image).
     int src0Alpha;
     int dst0Alpha;
+    int srcXYZ;
+    int dstXYZ;
+    int src_h_chr_pos;
+    int dst_h_chr_pos;
+    int src_v_chr_pos;
+    int dst_v_chr_pos;
     int yuv2rgb_y_offset;
     int yuv2rgb_y_coeff;
     int yuv2rgb_v2r_coeff;
@@ -473,6 +487,16 @@
 #endif
     int use_mmx_vfilter;
 
+/* pre defined color-spaces gamma */
+#define XYZ_GAMMA (2.6f)
+#define RGB_GAMMA (2.2f)
+    int16_t *xyzgamma;
+    int16_t *rgbgamma;
+    int16_t *xyzgammainv;
+    int16_t *rgbgammainv;
+    int16_t xyz2rgb_matrix[3][4];
+    int16_t rgb2xyz_matrix[3][4];
+
     /* function pointers for swScale() */
     yuv2planar1_fn yuv2plane1;
     yuv2planarX_fn yuv2planeX;
@@ -495,12 +519,13 @@
 
     /**
      * Functions to read planar input, such as planar RGB, and convert
-     * internally to Y/UV.
+     * internally to Y/UV/A.
      */
     /** @{ */
     void (*readLumPlanar)(uint8_t *dst, const uint8_t *src[4], int width, int32_t *rgb2yuv);
     void (*readChrPlanar)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src[4],
                           int width, int32_t *rgb2yuv);
+    void (*readAlpPlanar)(uint8_t *dst, const uint8_t *src[4], int width, int32_t *rgb2yuv);
     /** @} */
 
     /**
@@ -576,6 +601,8 @@
     void (*chrConvertRange)(int16_t *dst1, int16_t *dst2, int width);
 
     int needs_hcscale; ///< Set if there are chroma planes to be converted.
+
+    SwsDither dither;
 } SwsContext;
 //FIXME check init (where 0)
 
@@ -623,33 +650,33 @@
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return desc->flags & PIX_FMT_BE;
+    return desc->flags & AV_PIX_FMT_FLAG_BE;
 }
 
 static av_always_inline int isYUV(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return !(desc->flags & PIX_FMT_RGB) && desc->nb_components >= 2;
+    return !(desc->flags & AV_PIX_FMT_FLAG_RGB) && desc->nb_components >= 2;
 }
 
 static av_always_inline int isPlanarYUV(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return ((desc->flags & PIX_FMT_PLANAR) && isYUV(pix_fmt));
+    return ((desc->flags & AV_PIX_FMT_FLAG_PLANAR) && isYUV(pix_fmt));
 }
 
 static av_always_inline int isRGB(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return (desc->flags & PIX_FMT_RGB);
+    return (desc->flags & AV_PIX_FMT_FLAG_RGB);
 }
 
 #if 0 // FIXME
 #define isGray(x) \
-    (!(av_pix_fmt_desc_get(x)->flags & PIX_FMT_PAL) && \
+    (!(av_pix_fmt_desc_get(x)->flags & AV_PIX_FMT_FLAG_PAL) && \
      av_pix_fmt_desc_get(x)->nb_components <= 2)
 #else
 #define isGray(x)                      \
@@ -725,23 +752,16 @@
     (           \
           isRGBinInt(x)       ||    \
           isBGRinInt(x)       ||    \
-          isRGB(x)            ||    \
-          (x)==AV_PIX_FMT_GBRP9LE  || \
-          (x)==AV_PIX_FMT_GBRP9BE  || \
-          (x)==AV_PIX_FMT_GBRP10LE || \
-          (x)==AV_PIX_FMT_GBRP10BE || \
-          (x)==AV_PIX_FMT_GBRP12LE || \
-          (x)==AV_PIX_FMT_GBRP12BE || \
-          (x)==AV_PIX_FMT_GBRP14LE || \
-          (x)==AV_PIX_FMT_GBRP14BE || \
-          (x)==AV_PIX_FMT_GBR24P     \
+          isRGB(x)      \
     )
 
 static av_always_inline int isALPHA(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return desc->flags & PIX_FMT_ALPHA;
+    if (pix_fmt == AV_PIX_FMT_PAL8)
+        return 1;
+    return desc->flags & AV_PIX_FMT_FLAG_ALPHA;
 }
 
 #if 1
@@ -758,7 +778,7 @@
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return ((desc->nb_components >= 2 && !(desc->flags & PIX_FMT_PLANAR)) ||
+    return ((desc->nb_components >= 2 && !(desc->flags & AV_PIX_FMT_FLAG_PLANAR)) ||
             pix_fmt == AV_PIX_FMT_PAL8);
 }
 
@@ -767,36 +787,43 @@
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return (desc->nb_components >= 2 && (desc->flags & PIX_FMT_PLANAR));
+    return (desc->nb_components >= 2 && (desc->flags & AV_PIX_FMT_FLAG_PLANAR));
 }
 
 static av_always_inline int isPackedRGB(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return ((desc->flags & (PIX_FMT_PLANAR | PIX_FMT_RGB)) == PIX_FMT_RGB);
+    return ((desc->flags & (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB)) == AV_PIX_FMT_FLAG_RGB);
 }
 
 static av_always_inline int isPlanarRGB(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return ((desc->flags & (PIX_FMT_PLANAR | PIX_FMT_RGB)) ==
-            (PIX_FMT_PLANAR | PIX_FMT_RGB));
+    return ((desc->flags & (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB)) ==
+            (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB));
 }
 
 static av_always_inline int usePal(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return (desc->flags & PIX_FMT_PAL) || (desc->flags & PIX_FMT_PSEUDOPAL);
+    return (desc->flags & AV_PIX_FMT_FLAG_PAL) || (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL);
 }
 
 extern const uint64_t ff_dither4[2];
 extern const uint64_t ff_dither8[2];
-extern const uint8_t dithers[8][8][8];
-extern const uint16_t dither_scale[15][16];
 
+extern const uint8_t ff_dither_2x2_4[3][8];
+extern const uint8_t ff_dither_2x2_8[3][8];
+extern const uint8_t ff_dither_4x4_16[5][8];
+extern const uint8_t ff_dither_8x8_32[9][8];
+extern const uint8_t ff_dither_8x8_73[9][8];
+extern const uint8_t ff_dither_8x8_128[9][8];
+extern const uint8_t ff_dither_8x8_220[9][8];
+
+extern const int32_t ff_yuv2rgb_coeffs[8][4];
 
 extern const AVClass sws_context_class;
 
diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
index 863d9ee..b2b792f 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -34,7 +34,7 @@
 #include "libavutil/pixdesc.h"
 #include "libavutil/avassert.h"
 
-DECLARE_ALIGNED(8, const uint8_t, dithers)[8][8][8]={
+DECLARE_ALIGNED(8, static const uint8_t, dithers)[8][8][8]={
 {
   {   0,  1,  0,  1,  0,  1,  0,  1,},
   {   1,  0,  1,  0,  1,  0,  1,  0,},
@@ -109,7 +109,7 @@
   { 112, 16,104,  8,118, 22,110, 14,},
 }};
 
-const uint16_t dither_scale[15][16]={
+static const uint16_t dither_scale[15][16]={
 {    2,    3,    3,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,},
 {    2,    3,    7,    7,   13,   13,   25,   25,   25,   25,   25,   25,   25,   25,   25,   25,},
 {    3,    3,    4,   15,   15,   29,   57,   57,   57,  113,  113,  113,  113,  113,  113,  113,},
@@ -321,19 +321,23 @@
                               int srcStride[], int srcSliceY, int srcSliceH,
                               uint8_t *dst[], int dstStride[])
 {
-    int i, j;
-    int srcstr = srcStride[0] >> 1;
-    int dststr = dstStride[0] >> 1;
-    uint16_t       *dstPtr =       (uint16_t *) dst[0];
-    const uint16_t *srcPtr = (const uint16_t *) src[0];
-    int min_stride         = FFMIN(srcstr, dststr);
+    int i, j, p;
 
-    for (i = 0; i < srcSliceH; i++) {
-        for (j = 0; j < min_stride; j++) {
-            dstPtr[j] = av_bswap16(srcPtr[j]);
+    for (p = 0; p < 4; p++) {
+        int srcstr = srcStride[p] / 2;
+        int dststr = dstStride[p] / 2;
+        uint16_t       *dstPtr =       (uint16_t *) dst[p];
+        const uint16_t *srcPtr = (const uint16_t *) src[p];
+        int min_stride         = FFMIN(FFABS(srcstr), FFABS(dststr));
+        if(!dstPtr || !srcPtr)
+            continue;
+        for (i = 0; i < (srcSliceH >> c->chrDstVSubSample); i++) {
+            for (j = 0; j < min_stride; j++) {
+                dstPtr[j] = av_bswap16(srcPtr[j]);
+            }
+            srcPtr += srcstr;
+            dstPtr += dststr;
         }
-        srcPtr += srcstr;
-        dstPtr += dststr;
     }
 
     return srcSliceH;
@@ -385,6 +389,152 @@
     return srcSliceH;
 }
 
+static void gbr16ptopacked16(const uint16_t *src[], int srcStride[],
+                             uint8_t *dst, int dstStride, int srcSliceH,
+                             int alpha, int swap, int bpp, int width)
+{
+    int x, h, i;
+    int scale_high = 16 - bpp, scale_low = (bpp - 8) * 2;
+    for (h = 0; h < srcSliceH; h++) {
+        uint16_t *dest = (uint16_t *)(dst + dstStride * h);
+        uint16_t component;
+
+        switch(swap) {
+        case 3:
+            if (alpha) {
+                for (x = 0; x < width; x++) {
+                    component = av_bswap16(src[0][x]);
+                    *dest++ = av_bswap16(component << scale_high | component >> scale_low);
+                    component = av_bswap16(src[1][x]);
+                    *dest++ = av_bswap16(component << scale_high | component >> scale_low);
+                    component = av_bswap16(src[2][x]);
+                    *dest++ = av_bswap16(component << scale_high | component >> scale_low);
+                    *dest++ = 0xffff;
+                }
+            } else {
+                for (x = 0; x < width; x++) {
+                    component = av_bswap16(src[0][x]);
+                    *dest++ = av_bswap16(component << scale_high | component >> scale_low);
+                    component = av_bswap16(src[1][x]);
+                    *dest++ = av_bswap16(component << scale_high | component >> scale_low);
+                    component = av_bswap16(src[2][x]);
+                    *dest++ = av_bswap16(component << scale_high | component >> scale_low);
+                }
+            }
+            break;
+        case 2:
+            if (alpha) {
+                for (x = 0; x < width; x++) {
+                    *dest++ = av_bswap16(src[0][x] << scale_high | src[0][x] >> scale_low);
+                    *dest++ = av_bswap16(src[1][x] << scale_high | src[1][x] >> scale_low);
+                    *dest++ = av_bswap16(src[2][x] << scale_high | src[2][x] >> scale_low);
+                    *dest++ = 0xffff;
+                }
+            } else {
+                for (x = 0; x < width; x++) {
+                    *dest++ = av_bswap16(src[0][x] << scale_high | src[0][x] >> scale_low);
+                    *dest++ = av_bswap16(src[1][x] << scale_high | src[1][x] >> scale_low);
+                    *dest++ = av_bswap16(src[2][x] << scale_high | src[2][x] >> scale_low);
+                }
+            }
+            break;
+        case 1:
+            if (alpha) {
+                for (x = 0; x < width; x++) {
+                    *dest++ = av_bswap16(src[0][x]) << scale_high | av_bswap16(src[0][x]) >> scale_low;
+                    *dest++ = av_bswap16(src[1][x]) << scale_high | av_bswap16(src[1][x]) >> scale_low;
+                    *dest++ = av_bswap16(src[2][x]) << scale_high | av_bswap16(src[2][x]) >> scale_low;
+                    *dest++ = 0xffff;
+                }
+            } else {
+                for (x = 0; x < width; x++) {
+                    *dest++ = av_bswap16(src[0][x]) << scale_high | av_bswap16(src[0][x]) >> scale_low;
+                    *dest++ = av_bswap16(src[1][x]) << scale_high | av_bswap16(src[1][x]) >> scale_low;
+                    *dest++ = av_bswap16(src[2][x]) << scale_high | av_bswap16(src[2][x]) >> scale_low;
+                }
+            }
+            break;
+        default:
+            if (alpha) {
+                for (x = 0; x < width; x++) {
+                    *dest++ = src[0][x] << scale_high | src[0][x] >> scale_low;
+                    *dest++ = src[1][x] << scale_high | src[1][x] >> scale_low;
+                    *dest++ = src[2][x] << scale_high | src[2][x] >> scale_low;
+                    *dest++ = 0xffff;
+                }
+            } else {
+                for (x = 0; x < width; x++) {
+                    *dest++ = src[0][x] << scale_high | src[0][x] >> scale_low;
+                    *dest++ = src[1][x] << scale_high | src[1][x] >> scale_low;
+                    *dest++ = src[2][x] << scale_high | src[2][x] >> scale_low;
+                }
+            }
+        }
+        for (i = 0; i < 3; i++)
+            src[i] += srcStride[i] >> 1;
+    }
+}
+
+static int planarRgb16ToRgb16Wrapper(SwsContext *c, const uint8_t *src[],
+                                     int srcStride[], int srcSliceY, int srcSliceH,
+                                     uint8_t *dst[], int dstStride[])
+{
+    const uint16_t *src102[] = { (uint16_t *)src[1], (uint16_t *)src[0], (uint16_t *)src[2] };
+    const uint16_t *src201[] = { (uint16_t *)src[2], (uint16_t *)src[0], (uint16_t *)src[1] };
+    int stride102[] = { srcStride[1], srcStride[0], srcStride[2] };
+    int stride201[] = { srcStride[2], srcStride[0], srcStride[1] };
+    const AVPixFmtDescriptor *src_format = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *dst_format = av_pix_fmt_desc_get(c->dstFormat);
+    int bits_per_sample = src_format->comp[0].depth_minus1 + 1;
+    int swap = 0;
+    if ( HAVE_BIGENDIAN && !(src_format->flags & AV_PIX_FMT_FLAG_BE) ||
+        !HAVE_BIGENDIAN &&   src_format->flags & AV_PIX_FMT_FLAG_BE)
+        swap++;
+    if ( HAVE_BIGENDIAN && !(dst_format->flags & AV_PIX_FMT_FLAG_BE) ||
+        !HAVE_BIGENDIAN &&   dst_format->flags & AV_PIX_FMT_FLAG_BE)
+        swap += 2;
+
+    if ((src_format->flags & (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB)) !=
+        (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB) ||
+        bits_per_sample <= 8) {
+        av_log(c, AV_LOG_ERROR, "unsupported planar RGB conversion %s -> %s\n",
+               src_format->name, dst_format->name);
+        return srcSliceH;
+    }
+    switch (c->dstFormat) {
+    case AV_PIX_FMT_BGR48LE:
+    case AV_PIX_FMT_BGR48BE:
+        gbr16ptopacked16(src102, stride102,
+                         dst[0] + srcSliceY * dstStride[0], dstStride[0],
+                         srcSliceH, 0, swap, bits_per_sample, c->srcW);
+        break;
+    case AV_PIX_FMT_RGB48LE:
+    case AV_PIX_FMT_RGB48BE:
+        gbr16ptopacked16(src201, stride201,
+                         dst[0] + srcSliceY * dstStride[0], dstStride[0],
+                         srcSliceH, 0, swap, bits_per_sample, c->srcW);
+        break;
+    case AV_PIX_FMT_RGBA64LE:
+    case AV_PIX_FMT_RGBA64BE:
+         gbr16ptopacked16(src201, stride201,
+                          dst[0] + srcSliceY * dstStride[0], dstStride[0],
+                          srcSliceH, 1, swap, bits_per_sample, c->srcW);
+        break;
+    case AV_PIX_FMT_BGRA64LE:
+    case AV_PIX_FMT_BGRA64BE:
+        gbr16ptopacked16(src102, stride102,
+                         dst[0] + srcSliceY * dstStride[0], dstStride[0],
+                         srcSliceH, 1, swap, bits_per_sample, c->srcW);
+        break;
+    default:
+        av_log(c, AV_LOG_ERROR,
+               "unsupported planar RGB conversion %s -> %s\n",
+               src_format->name, dst_format->name);
+    }
+
+    return srcSliceH;
+}
+
 static void gbr24ptopacked24(const uint8_t *src[], int srcStride[],
                              uint8_t *dst, int dstStride, int srcSliceH,
                              int width)
@@ -488,6 +638,22 @@
     return srcSliceH;
 }
 
+static int planarRgbToplanarRgbWrapper(SwsContext *c, const uint8_t *src[],
+                                       int srcStride[], int srcSliceY, int srcSliceH,
+                                       uint8_t *dst[], int dstStride[])
+{
+    copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
+              dst[0], dstStride[0]);
+    copyPlane(src[1], srcStride[1], srcSliceY, srcSliceH, c->srcW,
+              dst[1], dstStride[1]);
+    copyPlane(src[2], srcStride[2], srcSliceY, srcSliceH, c->srcW,
+              dst[2], dstStride[2]);
+    if (dst[3])
+        fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
+
+    return srcSliceH;
+}
+
 static void packedtogbr24p(const uint8_t *src, int srcStride,
                            uint8_t *dst[], int dstStride[], int srcSliceH,
                            int alpha_first, int inc_size, int width)
@@ -595,7 +761,7 @@
 
 #define IS_NOT_NE(bpp, desc) \
     (((bpp + 7) >> 3) == 2 && \
-     (!(desc->flags & PIX_FMT_BE) != !HAVE_BIGENDIAN))
+     (!(desc->flags & AV_PIX_FMT_FLAG_BE) != !HAVE_BIGENDIAN))
 
 #define CONV_IS(src, dst) (srcFormat == AV_PIX_FMT_##src && dstFormat == AV_PIX_FMT_##dst)
 
@@ -832,9 +998,9 @@
     const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->dstFormat);
     int plane, i, j;
     for (plane = 0; plane < 4; plane++) {
-        int length = (plane == 0 || plane == 3) ? c->srcW  : -((-c->srcW  ) >> c->chrDstHSubSample);
-        int y =      (plane == 0 || plane == 3) ? srcSliceY: -((-srcSliceY) >> c->chrDstVSubSample);
-        int height = (plane == 0 || plane == 3) ? srcSliceH: -((-srcSliceH) >> c->chrDstVSubSample);
+        int length = (plane == 0 || plane == 3) ? c->srcW  : FF_CEIL_RSHIFT(c->srcW,   c->chrDstHSubSample);
+        int y =      (plane == 0 || plane == 3) ? srcSliceY: FF_CEIL_RSHIFT(srcSliceY, c->chrDstVSubSample);
+        int height = (plane == 0 || plane == 3) ? srcSliceH: FF_CEIL_RSHIFT(srcSliceH, c->chrDstVSubSample);
         const uint8_t *srcPtr = src[plane];
         uint8_t *dstPtr = dst[plane] + dstStride[plane] * y;
         int shiftonly= plane==1 || plane==2 || (!c->srcRange && plane==0);
@@ -1014,7 +1180,7 @@
     /* yuv2bgr */
     if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUV422P ||
          srcFormat == AV_PIX_FMT_YUVA420P) && isAnyRGB(dstFormat) &&
-        !(flags & (SWS_ACCURATE_RND|SWS_ERROR_DIFFUSION)) && !(dstH & 1)) {
+        !(flags & SWS_ACCURATE_RND) && (c->dither == SWS_DITHER_BAYER || c->dither == SWS_DITHER_AUTO) && !(dstH & 1)) {
         c->swScale = ff_yuv2rgb_get_func_ptr(c);
     }
 
@@ -1035,6 +1201,10 @@
         && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
         c->swScale= rgbToRgbWrapper;
 
+    if ((srcFormat == AV_PIX_FMT_GBRP && dstFormat == AV_PIX_FMT_GBRAP) ||
+        (srcFormat == AV_PIX_FMT_GBRAP && dstFormat == AV_PIX_FMT_GBRP))
+        c->swScale = planarRgbToplanarRgbWrapper;
+
 #define isByteRGB(f) (             \
         f == AV_PIX_FMT_RGB32   || \
         f == AV_PIX_FMT_RGB32_1 || \
@@ -1046,6 +1216,17 @@
     if (srcFormat == AV_PIX_FMT_GBRP && isPlanar(srcFormat) && isByteRGB(dstFormat))
         c->swScale = planarRgbToRgbWrapper;
 
+    if ((srcFormat == AV_PIX_FMT_GBRP9LE  || srcFormat == AV_PIX_FMT_GBRP9BE  ||
+         srcFormat == AV_PIX_FMT_GBRP16LE || srcFormat == AV_PIX_FMT_GBRP16BE ||
+         srcFormat == AV_PIX_FMT_GBRP10LE || srcFormat == AV_PIX_FMT_GBRP10BE ||
+         srcFormat == AV_PIX_FMT_GBRP12LE || srcFormat == AV_PIX_FMT_GBRP12BE ||
+         srcFormat == AV_PIX_FMT_GBRP14LE || srcFormat == AV_PIX_FMT_GBRP14BE) &&
+        (dstFormat == AV_PIX_FMT_RGB48LE  || dstFormat == AV_PIX_FMT_RGB48BE  ||
+         dstFormat == AV_PIX_FMT_BGR48LE  || dstFormat == AV_PIX_FMT_BGR48BE  ||
+         dstFormat == AV_PIX_FMT_RGBA64LE || dstFormat == AV_PIX_FMT_RGBA64BE ||
+         dstFormat == AV_PIX_FMT_BGRA64LE || dstFormat == AV_PIX_FMT_BGRA64BE))
+        c->swScale = planarRgb16ToRgb16Wrapper;
+
     if (av_pix_fmt_desc_get(srcFormat)->comp[0].depth_minus1 == 7 &&
         isPackedRGB(srcFormat) && dstFormat == AV_PIX_FMT_GBRP)
         c->swScale = rgbToPlanarRgbWrapper;
@@ -1057,11 +1238,33 @@
         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR555) ||
         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR565) ||
         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GRAY16) ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP9)  ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP10) ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP12) ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP14) ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP16) ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRAP16) ||
         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB444) ||
         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB48)  ||
         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGBA64) ||
         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB555) ||
-        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB565))
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB565) ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_XYZ12)  ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P9)  ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P10) ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P12) ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P14) ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P16) ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P9)  ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P10) ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P12) ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P14) ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P16) ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P9)  ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P10) ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P12) ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P14) ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P16))
         c->swScale = packed_16bpc_bswap;
 
     if (usePal(srcFormat) && isByteRGB(dstFormat))
diff --git a/libswscale/utils.c b/libswscale/utils.c
index ca7c2c4..e34188a 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -52,6 +52,8 @@
 #include "swscale.h"
 #include "swscale_internal.h"
 
+static void handle_formats(SwsContext *c);
+
 unsigned swscale_version(void)
 {
     av_assert0(LIBSWSCALE_VERSION_MICRO >= 100);
@@ -72,7 +74,9 @@
 #define RET 0xC3 // near return opcode for x86
 
 typedef struct FormatEntry {
-    int is_supported_in, is_supported_out;
+    uint8_t is_supported_in         :1;
+    uint8_t is_supported_out        :1;
+    uint8_t is_supported_endianness :1;
 } FormatEntry;
 
 static const FormatEntry format_entries[AV_PIX_FMT_NB] = {
@@ -89,6 +93,7 @@
     [AV_PIX_FMT_MONOBLACK]   = { 1, 1 },
     [AV_PIX_FMT_PAL8]        = { 1, 0 },
     [AV_PIX_FMT_YUVJ420P]    = { 1, 1 },
+    [AV_PIX_FMT_YUVJ411P]    = { 1, 1 },
     [AV_PIX_FMT_YUVJ422P]    = { 1, 1 },
     [AV_PIX_FMT_YUVJ444P]    = { 1, 1 },
     [AV_PIX_FMT_UYVY422]     = { 1, 1 },
@@ -136,8 +141,8 @@
     [AV_PIX_FMT_YUVA444P16LE]= { 1, 1 },
     [AV_PIX_FMT_RGB48BE]     = { 1, 1 },
     [AV_PIX_FMT_RGB48LE]     = { 1, 1 },
-    [AV_PIX_FMT_RGBA64BE]    = { 1, 0 },
-    [AV_PIX_FMT_RGBA64LE]    = { 1, 0 },
+    [AV_PIX_FMT_RGBA64BE]    = { 1, 1 },
+    [AV_PIX_FMT_RGBA64LE]    = { 1, 1 },
     [AV_PIX_FMT_RGB565BE]    = { 1, 1 },
     [AV_PIX_FMT_RGB565LE]    = { 1, 1 },
     [AV_PIX_FMT_RGB555BE]    = { 1, 1 },
@@ -196,6 +201,11 @@
     [AV_PIX_FMT_GBRP14BE]    = { 1, 1 },
     [AV_PIX_FMT_GBRP16LE]    = { 1, 0 },
     [AV_PIX_FMT_GBRP16BE]    = { 1, 0 },
+    [AV_PIX_FMT_XYZ12BE]     = { 1, 1, 1 },
+    [AV_PIX_FMT_XYZ12LE]     = { 1, 1, 1 },
+    [AV_PIX_FMT_GBRAP]       = { 1, 1 },
+    [AV_PIX_FMT_GBRAP16LE]   = { 1, 0 },
+    [AV_PIX_FMT_GBRAP16BE]   = { 1, 0 },
 };
 
 int sws_isSupportedInput(enum AVPixelFormat pix_fmt)
@@ -210,7 +220,11 @@
            format_entries[pix_fmt].is_supported_out : 0;
 }
 
-extern const int32_t ff_yuv2rgb_coeffs[8][4];
+int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt)
+{
+    return (unsigned)pix_fmt < AV_PIX_FMT_NB ?
+           format_entries[pix_fmt].is_supported_endianness : 0;
+}
 
 #if FF_API_SWS_FORMAT_NAME
 const char *sws_format_name(enum AVPixelFormat format)
@@ -236,11 +250,21 @@
                               dist - 1.0);
 }
 
-static int initFilter(int16_t **outFilter, int32_t **filterPos,
-                      int *outFilterSize, int xInc, int srcW, int dstW,
-                      int filterAlign, int one, int flags, int cpu_flags,
-                      SwsVector *srcFilter, SwsVector *dstFilter,
-                      double param[2])
+static av_cold int get_local_pos(SwsContext *s, int chr_subsample, int pos, int dir)
+{
+    if (pos < 0) {
+        pos = (128 << chr_subsample) - 128;
+    }
+    pos += 128; // relative to ideal left edge
+    return pos >> chr_subsample;
+}
+
+static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos,
+                              int *outFilterSize, int xInc, int srcW,
+                              int dstW, int filterAlign, int one,
+                              int flags, int cpu_flags,
+                              SwsVector *srcFilter, SwsVector *dstFilter,
+                              double param[2], int srcPos, int dstPos)
 {
     int i;
     int filterSize;
@@ -256,7 +280,7 @@
     // NOTE: the +3 is for the MMX(+1) / SSE(+3) scaler which reads over the end
     FF_ALLOC_OR_GOTO(NULL, *filterPos, (dstW + 3) * sizeof(**filterPos), fail);
 
-    if (FFABS(xInc - 0x10000) < 10) { // unscaled
+    if (FFABS(xInc - 0x10000) < 10 && srcPos == dstPos) { // unscaled
         int i;
         filterSize = 1;
         FF_ALLOCZ_OR_GOTO(NULL, filter,
@@ -273,7 +297,7 @@
         FF_ALLOC_OR_GOTO(NULL, filter,
                          dstW * sizeof(*filter) * filterSize, fail);
 
-        xDstInSrc = xInc / 2 - 0x8000;
+        xDstInSrc = ((dstPos*(int64_t)xInc)>>8) - ((srcPos*0x8000LL)>>7);
         for (i = 0; i < dstW; i++) {
             int xx = (xDstInSrc - ((filterSize - 1) << 15) + (1 << 15)) >> 16;
 
@@ -289,7 +313,7 @@
         FF_ALLOC_OR_GOTO(NULL, filter,
                          dstW * sizeof(*filter) * filterSize, fail);
 
-        xDstInSrc = xInc / 2 - 0x8000;
+        xDstInSrc = ((dstPos*(int64_t)xInc)>>8) - ((srcPos*0x8000LL)>>7);
         for (i = 0; i < dstW; i++) {
             int xx = (xDstInSrc - ((filterSize - 1) << 15) + (1 << 15)) >> 16;
             int j;
@@ -340,7 +364,7 @@
         FF_ALLOC_OR_GOTO(NULL, filter,
                          dstW * sizeof(*filter) * filterSize, fail);
 
-        xDstInSrc = xInc - 0x10000;
+        xDstInSrc = ((dstPos*(int64_t)xInc)>>7) - ((srcPos*0x10000LL)>>7);
         for (i = 0; i < dstW; i++) {
             int xx = (xDstInSrc - ((filterSize - 2) << 16)) / (1 << 17);
             int j;
@@ -520,7 +544,7 @@
             filterAlign = 1;
     }
 
-    if (INLINE_MMX(cpu_flags)) {
+    if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) {
         // special case for unscaled vertical filtering
         if (minFilterSize == 1 && filterAlign == 2)
             filterAlign = 1;
@@ -627,9 +651,9 @@
 }
 
 #if HAVE_MMXEXT_INLINE
-static int init_hscaler_mmxext(int dstW, int xInc, uint8_t *filterCode,
-                               int16_t *filter, int32_t *filterPos,
-                               int numSplits)
+static av_cold int init_hscaler_mmxext(int dstW, int xInc, uint8_t *filterCode,
+                                       int16_t *filter, int32_t *filterPos,
+                                       int numSplits)
 {
     uint8_t *fragmentA;
     x86_reg imm8OfPShufW1A;
@@ -878,7 +902,7 @@
     c->input_rgb2yuv_table[GV_IDX] = -ROUNDED_DIV((1 << RGB2YUV_SHIFT)*ONE*ONE  , Cv);
     c->input_rgb2yuv_table[BV_IDX] =  ROUNDED_DIV((1 << RGB2YUV_SHIFT)*W        , Cv);
 
-    if(/*!dstRange && */table == ff_yuv2rgb_coeffs[SWS_CS_DEFAULT]) {
+    if(/*!dstRange && */!memcmp(table, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT], sizeof(ff_yuv2rgb_coeffs[SWS_CS_DEFAULT]))) {
         c->input_rgb2yuv_table[BY_IDX] =  ((int)(0.114 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
         c->input_rgb2yuv_table[BV_IDX] = (-(int)(0.081 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
         c->input_rgb2yuv_table[BU_IDX] =  ((int)(0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
@@ -893,15 +917,55 @@
         AV_WL16(p + 16*4 + 2*i, map[i] >= 0 ? c->input_rgb2yuv_table[map[i]] : 0);
 }
 
+static void fill_xyztables(struct SwsContext *c)
+{
+    int i;
+    double xyzgamma = XYZ_GAMMA;
+    double rgbgamma = 1.0 / RGB_GAMMA;
+    double xyzgammainv = 1.0 / XYZ_GAMMA;
+    double rgbgammainv = RGB_GAMMA;
+    static const int16_t xyz2rgb_matrix[3][4] = {
+        {13270, -6295, -2041},
+        {-3969,  7682,   170},
+        {  228,  -835,  4329} };
+    static const int16_t rgb2xyz_matrix[3][4] = {
+        {1689, 1464,  739},
+        { 871, 2929,  296},
+        {  79,  488, 3891} };
+    static int16_t xyzgamma_tab[4096], rgbgamma_tab[4096], xyzgammainv_tab[4096], rgbgammainv_tab[4096];
+
+    memcpy(c->xyz2rgb_matrix, xyz2rgb_matrix, sizeof(c->xyz2rgb_matrix));
+    memcpy(c->rgb2xyz_matrix, rgb2xyz_matrix, sizeof(c->rgb2xyz_matrix));
+    c->xyzgamma = xyzgamma_tab;
+    c->rgbgamma = rgbgamma_tab;
+    c->xyzgammainv = xyzgammainv_tab;
+    c->rgbgammainv = rgbgammainv_tab;
+
+    if (rgbgamma_tab[4095])
+        return;
+
+    /* set gamma vectors */
+    for (i = 0; i < 4096; i++) {
+        xyzgamma_tab[i] = lrint(pow(i / 4095.0, xyzgamma) * 4095.0);
+        rgbgamma_tab[i] = lrint(pow(i / 4095.0, rgbgamma) * 4095.0);
+        xyzgammainv_tab[i] = lrint(pow(i / 4095.0, xyzgammainv) * 4095.0);
+        rgbgammainv_tab[i] = lrint(pow(i / 4095.0, rgbgammainv) * 4095.0);
+    }
+}
+
 int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4],
                              int srcRange, const int table[4], int dstRange,
                              int brightness, int contrast, int saturation)
 {
-    const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->dstFormat);
-    const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *desc_dst;
+    const AVPixFmtDescriptor *desc_src;
     memcpy(c->srcColorspaceTable, inv_table, sizeof(int) * 4);
     memcpy(c->dstColorspaceTable, table, sizeof(int) * 4);
 
+    handle_formats(c);
+    desc_dst = av_pix_fmt_desc_get(c->dstFormat);
+    desc_src = av_pix_fmt_desc_get(c->srcFormat);
+
     if(!isYUV(c->dstFormat) && !isGray(c->dstFormat))
         dstRange = 0;
     if(!isYUV(c->srcFormat) && !isGray(c->srcFormat))
@@ -913,6 +977,8 @@
     c->srcRange   = srcRange;
     c->dstRange   = dstRange;
 
+    fill_xyztables(c);
+
     if ((isYUV(c->dstFormat) || isGray(c->dstFormat)) && (isYUV(c->srcFormat) || isGray(c->srcFormat)))
         return -1;
 
@@ -938,7 +1004,7 @@
                              int *srcRange, int **table, int *dstRange,
                              int *brightness, int *contrast, int *saturation)
 {
-    if (!c || isYUV(c->dstFormat) || isGray(c->dstFormat))
+    if (!c )
         return -1;
 
     *inv_table  = c->srcColorspaceTable;
@@ -958,6 +1024,9 @@
     case AV_PIX_FMT_YUVJ420P:
         *format = AV_PIX_FMT_YUV420P;
         return 1;
+    case AV_PIX_FMT_YUVJ411P:
+        *format = AV_PIX_FMT_YUV411P;
+        return 1;
     case AV_PIX_FMT_YUVJ422P:
         *format = AV_PIX_FMT_YUV422P;
         return 1;
@@ -967,6 +1036,8 @@
     case AV_PIX_FMT_YUVJ440P:
         *format = AV_PIX_FMT_YUV440P;
         return 1;
+    case AV_PIX_FMT_GRAY8:
+        return 1;
     default:
         return 0;
     }
@@ -983,6 +1054,23 @@
     }
 }
 
+static int handle_xyz(enum AVPixelFormat *format)
+{
+    switch (*format) {
+    case AV_PIX_FMT_XYZ12BE : *format = AV_PIX_FMT_RGB48BE; return 1;
+    case AV_PIX_FMT_XYZ12LE : *format = AV_PIX_FMT_RGB48LE; return 1;
+    default:                                                return 0;
+    }
+}
+
+static void handle_formats(SwsContext *c)
+{
+    c->src0Alpha |= handle_0alpha(&c->srcFormat);
+    c->dst0Alpha |= handle_0alpha(&c->dstFormat);
+    c->srcXYZ    |= handle_xyz(&c->srcFormat);
+    c->dstXYZ    |= handle_xyz(&c->dstFormat);
+}
+
 SwsContext *sws_alloc_context(void)
 {
     SwsContext *c = av_mallocz(sizeof(SwsContext));
@@ -1010,8 +1098,8 @@
     int flags, cpu_flags;
     enum AVPixelFormat srcFormat = c->srcFormat;
     enum AVPixelFormat dstFormat = c->dstFormat;
-    const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(srcFormat);
-    const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(dstFormat);
+    const AVPixFmtDescriptor *desc_src;
+    const AVPixFmtDescriptor *desc_dst;
 
     cpu_flags = av_get_cpu_flags();
     flags     = c->flags;
@@ -1021,17 +1109,24 @@
 
     unscaled = (srcW == dstW && srcH == dstH);
 
-    handle_jpeg(&srcFormat);
-    handle_jpeg(&dstFormat);
-    handle_0alpha(&srcFormat);
-    handle_0alpha(&dstFormat);
+    c->srcRange |= handle_jpeg(&c->srcFormat);
+    c->dstRange |= handle_jpeg(&c->dstFormat);
 
-    if(srcFormat!=c->srcFormat || dstFormat!=c->dstFormat){
+    if (!c->contrast && !c->saturation && !c->dstFormatBpp)
+        sws_setColorspaceDetails(c, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT], c->srcRange,
+                                 ff_yuv2rgb_coeffs[SWS_CS_DEFAULT],
+                                 c->dstRange, 0, 1 << 16, 1 << 16);
+
+    if(srcFormat!=c->srcFormat || dstFormat!=c->dstFormat)
         av_log(c, AV_LOG_WARNING, "deprecated pixel format used, make sure you did set range correctly\n");
-        c->srcFormat= srcFormat;
-        c->dstFormat= dstFormat;
-    }
+    handle_formats(c);
+    srcFormat = c->srcFormat;
+    dstFormat = c->dstFormat;
+    desc_src = av_pix_fmt_desc_get(srcFormat);
+    desc_dst = av_pix_fmt_desc_get(dstFormat);
 
+    if (!(unscaled && sws_isSupportedEndiannessConversion(srcFormat) &&
+          av_pix_fmt_swap_endianness(srcFormat) == dstFormat)) {
     if (!sws_isSupportedInput(srcFormat)) {
         av_log(c, AV_LOG_ERROR, "%s is not supported as input pixel format\n",
                av_get_pix_fmt_name(srcFormat));
@@ -1042,6 +1137,7 @@
                av_get_pix_fmt_name(dstFormat));
         return AVERROR(EINVAL);
     }
+    }
 
     i = flags & (SWS_POINT         |
                  SWS_AREA          |
@@ -1098,23 +1194,33 @@
         }
     }
 
+    if (c->dither == SWS_DITHER_AUTO) {
+        if (flags & SWS_ERROR_DIFFUSION)
+            c->dither = SWS_DITHER_ED;
+    }
+
     if(dstFormat == AV_PIX_FMT_BGR4_BYTE ||
        dstFormat == AV_PIX_FMT_RGB4_BYTE ||
        dstFormat == AV_PIX_FMT_BGR8 ||
        dstFormat == AV_PIX_FMT_RGB8) {
-        if (flags & SWS_ERROR_DIFFUSION && !(flags & SWS_FULL_CHR_H_INT)) {
-            av_log(c, AV_LOG_DEBUG,
-                "Error diffusion dither is only supported in full chroma interpolation for destination format '%s'\n",
-                av_get_pix_fmt_name(dstFormat));
-            flags   |= SWS_FULL_CHR_H_INT;
-            c->flags = flags;
+        if (c->dither == SWS_DITHER_AUTO)
+            c->dither = (flags & SWS_FULL_CHR_H_INT) ? SWS_DITHER_ED : SWS_DITHER_BAYER;
+        if (!(flags & SWS_FULL_CHR_H_INT)) {
+            if (c->dither == SWS_DITHER_ED) {
+                av_log(c, AV_LOG_DEBUG,
+                    "Desired dithering only supported in full chroma interpolation for destination format '%s'\n",
+                    av_get_pix_fmt_name(dstFormat));
+                flags   |= SWS_FULL_CHR_H_INT;
+                c->flags = flags;
+            }
         }
-        if (!(flags & SWS_ERROR_DIFFUSION) && (flags & SWS_FULL_CHR_H_INT)) {
-            av_log(c, AV_LOG_DEBUG,
-                "Ordered dither is not supported in full chroma interpolation for destination format '%s'\n",
-                av_get_pix_fmt_name(dstFormat));
-            flags   |= SWS_ERROR_DIFFUSION;
-            c->flags = flags;
+        if (flags & SWS_FULL_CHR_H_INT) {
+            if (c->dither == SWS_DITHER_BAYER) {
+                av_log(c, AV_LOG_DEBUG,
+                    "Ordered dither is not supported in full chroma interpolation for destination format '%s'\n",
+                    av_get_pix_fmt_name(dstFormat));
+                c->dither = SWS_DITHER_ED;
+            }
         }
     }
     if (isPlanarRGB(dstFormat)) {
@@ -1172,11 +1278,11 @@
          (flags & SWS_FAST_BILINEAR)))
         c->chrSrcHSubSample = 1;
 
-    // Note the -((-x)>>y) is so that we always round toward +inf.
-    c->chrSrcW = -((-srcW) >> c->chrSrcHSubSample);
-    c->chrSrcH = -((-srcH) >> c->chrSrcVSubSample);
-    c->chrDstW = -((-dstW) >> c->chrDstHSubSample);
-    c->chrDstH = -((-dstH) >> c->chrDstVSubSample);
+    // Note the FF_CEIL_RSHIFT is so that we always round toward +inf.
+    c->chrSrcW = FF_CEIL_RSHIFT(srcW, c->chrSrcHSubSample);
+    c->chrSrcH = FF_CEIL_RSHIFT(srcH, c->chrSrcVSubSample);
+    c->chrDstW = FF_CEIL_RSHIFT(dstW, c->chrDstHSubSample);
+    c->chrDstH = FF_CEIL_RSHIFT(dstH, c->chrDstVSubSample);
 
     FF_ALLOC_OR_GOTO(c, c->formatConvBuffer, FFALIGN(srcW*2+78, 16) * 2, fail);
 
@@ -1314,14 +1420,18 @@
                            srcW, dstW, filterAlign, 1 << 14,
                            (flags & SWS_BICUBLIN) ? (flags | SWS_BICUBIC) : flags,
                            cpu_flags, srcFilter->lumH, dstFilter->lumH,
-                           c->param) < 0)
+                           c->param,
+                           get_local_pos(c, 0, 0, 0),
+                           get_local_pos(c, 0, 0, 0)) < 0)
                 goto fail;
             if (initFilter(&c->hChrFilter, &c->hChrFilterPos,
                            &c->hChrFilterSize, c->chrXInc,
                            c->chrSrcW, c->chrDstW, filterAlign, 1 << 14,
                            (flags & SWS_BICUBLIN) ? (flags | SWS_BILINEAR) : flags,
                            cpu_flags, srcFilter->chrH, dstFilter->chrH,
-                           c->param) < 0)
+                           c->param,
+                           get_local_pos(c, c->chrSrcHSubSample, c->src_h_chr_pos, 0),
+                           get_local_pos(c, c->chrDstHSubSample, c->dst_h_chr_pos, 0)) < 0)
                 goto fail;
         }
     } // initialize horizontal stuff
@@ -1337,14 +1447,19 @@
                        c->lumYInc, srcH, dstH, filterAlign, (1 << 12),
                        (flags & SWS_BICUBLIN) ? (flags | SWS_BICUBIC) : flags,
                        cpu_flags, srcFilter->lumV, dstFilter->lumV,
-                       c->param) < 0)
+                       c->param,
+                       get_local_pos(c, 0, 0, 1),
+                       get_local_pos(c, 0, 0, 1)) < 0)
             goto fail;
         if (initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize,
                        c->chrYInc, c->chrSrcH, c->chrDstH,
                        filterAlign, (1 << 12),
                        (flags & SWS_BICUBLIN) ? (flags | SWS_BILINEAR) : flags,
                        cpu_flags, srcFilter->chrV, dstFilter->chrV,
-                       c->param) < 0)
+                       c->param,
+                       get_local_pos(c, c->chrSrcVSubSample, c->src_v_chr_pos, 1),
+                       get_local_pos(c, c->chrDstVSubSample, c->dst_v_chr_pos, 1)) < 0)
+
             goto fail;
 
 #if HAVE_ALTIVEC
@@ -1514,10 +1629,6 @@
     c->srcH      = srcH;
     c->dstW      = dstW;
     c->dstH      = dstH;
-    c->srcRange  = handle_jpeg(&srcFormat);
-    c->dstRange  = handle_jpeg(&dstFormat);
-    c->src0Alpha = handle_0alpha(&srcFormat);
-    c->dst0Alpha = handle_0alpha(&dstFormat);
     c->srcFormat = srcFormat;
     c->dstFormat = dstFormat;
 
@@ -1525,9 +1636,6 @@
         c->param[0] = param[0];
         c->param[1] = param[1];
     }
-    sws_setColorspaceDetails(c, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT], c->srcRange,
-                             ff_yuv2rgb_coeffs[SWS_CS_DEFAULT] /* FIXME*/,
-                             c->dstRange, 0, 1 << 16, 1 << 16);
 
     if (sws_init_context(c, srcFilter, dstFilter) < 0) {
         sws_freeContext(c);
@@ -1957,21 +2065,13 @@
             return NULL;
         context->srcW      = srcW;
         context->srcH      = srcH;
-        context->srcRange  = handle_jpeg(&srcFormat);
-        context->src0Alpha = handle_0alpha(&srcFormat);
         context->srcFormat = srcFormat;
         context->dstW      = dstW;
         context->dstH      = dstH;
-        context->dstRange  = handle_jpeg(&dstFormat);
-        context->dst0Alpha = handle_0alpha(&dstFormat);
         context->dstFormat = dstFormat;
         context->flags     = flags;
         context->param[0]  = param[0];
         context->param[1]  = param[1];
-        sws_setColorspaceDetails(context, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT],
-                                 context->srcRange,
-                                 ff_yuv2rgb_coeffs[SWS_CS_DEFAULT] /* FIXME*/,
-                                 context->dstRange, 0, 1 << 16, 1 << 16);
         if (sws_init_context(context, srcFilter, dstFilter) < 0) {
             sws_freeContext(context);
             return NULL;
diff --git a/libswscale/version.h b/libswscale/version.h
index c430f2d..06f119a 100644
--- a/libswscale/version.h
+++ b/libswscale/version.h
@@ -27,7 +27,7 @@
 #include "libavutil/avutil.h"
 
 #define LIBSWSCALE_VERSION_MAJOR 2
-#define LIBSWSCALE_VERSION_MINOR 2
+#define LIBSWSCALE_VERSION_MINOR 5
 #define LIBSWSCALE_VERSION_MICRO 100
 
 #define LIBSWSCALE_VERSION_INT  AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \
diff --git a/libswscale/x86/rgb2rgb_template.c b/libswscale/x86/rgb2rgb_template.c
index fd5b4b9..d684b70 100644
--- a/libswscale/x86/rgb2rgb_template.c
+++ b/libswscale/x86/rgb2rgb_template.c
@@ -26,6 +26,8 @@
 
 #include <stddef.h>
 
+#include "libavutil/attributes.h"
+
 #undef PREFETCH
 #undef MOVNTQ
 #undef EMMS
@@ -2352,7 +2354,7 @@
                                  int lumStride, int chromStride, int srcStride)
 {
     int y;
-    const int chromWidth= -((-width)>>1);
+    const int chromWidth = FF_CEIL_RSHIFT(width, 1);
 
     for (y=0; y<height; y++) {
         RENAME(extract_even)(src, ydst, width);
@@ -2378,7 +2380,7 @@
                                  int lumStride, int chromStride, int srcStride)
 {
     int y;
-    const int chromWidth= -((-width)>>1);
+    const int chromWidth = FF_CEIL_RSHIFT(width, 1);
 
     for (y=0; y<height; y++) {
         RENAME(extract_even)(src, ydst, width);
@@ -2402,7 +2404,7 @@
                                  int lumStride, int chromStride, int srcStride)
 {
     int y;
-    const int chromWidth= -((-width)>>1);
+    const int chromWidth = FF_CEIL_RSHIFT(width, 1);
 
     for (y=0; y<height; y++) {
         RENAME(extract_even)(src+1, ydst, width);
@@ -2428,7 +2430,7 @@
                                  int lumStride, int chromStride, int srcStride)
 {
     int y;
-    const int chromWidth= -((-width)>>1);
+    const int chromWidth = FF_CEIL_RSHIFT(width, 1);
 
     for (y=0; y<height; y++) {
         RENAME(extract_even)(src+1, ydst, width);
@@ -2448,7 +2450,7 @@
 #endif /* !COMPILE_TEMPLATE_AMD3DNOW */
 #endif /* !COMPILE_TEMPLATE_SSE2 */
 
-static inline void RENAME(rgb2rgb_init)(void)
+static av_cold void RENAME(rgb2rgb_init)(void)
 {
 #if !COMPILE_TEMPLATE_SSE2
 #if !COMPILE_TEMPLATE_AMD3DNOW
diff --git a/libswscale/x86/yuv2rgb.c b/libswscale/x86/yuv2rgb.c
index 3938e6b..cceca49 100644
--- a/libswscale/x86/yuv2rgb.c
+++ b/libswscale/x86/yuv2rgb.c
@@ -27,7 +27,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
-#include <assert.h>
 
 #include "config.h"
 #include "libswscale/rgb2rgb.h"
diff --git a/libswscale/yuv2rgb.c b/libswscale/yuv2rgb.c
index d12abda..e447056 100644
--- a/libswscale/yuv2rgb.c
+++ b/libswscale/yuv2rgb.c
@@ -35,13 +35,6 @@
 #include "swscale_internal.h"
 #include "libavutil/pixdesc.h"
 
-extern const uint8_t dither_2x2_4[3][8];
-extern const uint8_t dither_2x2_8[3][8];
-extern const uint8_t dither_4x4_16[5][8];
-extern const uint8_t dither_8x8_32[9][8];
-extern const uint8_t dither_8x8_73[9][8];
-extern const uint8_t dither_8x8_220[9][8];
-
 const int32_t ff_yuv2rgb_coeffs[8][4] = {
     { 117504, 138453, 13954, 34903 }, /* no sequence_display_extension */
     { 117504, 138453, 13954, 34903 }, /* ITU-R Rec. 709 (1990) */
@@ -266,28 +259,28 @@
     PUTRGBA(dst_2, py_2, pa_2, 0, 24);
 
     LOADCHROMA(1);
-    PUTRGBA(dst_2, py_2, pa_1, 1, 24);
-    PUTRGBA(dst_1, py_1, pa_2, 1, 24);
+    PUTRGBA(dst_2, py_2, pa_2, 1, 24);
+    PUTRGBA(dst_1, py_1, pa_1, 1, 24);
 
     LOADCHROMA(2);
     PUTRGBA(dst_1, py_1, pa_1, 2, 24);
     PUTRGBA(dst_2, py_2, pa_2, 2, 24);
 
     LOADCHROMA(3);
-    PUTRGBA(dst_2, py_2, pa_1, 3, 24);
-    PUTRGBA(dst_1, py_1, pa_2, 3, 24);
-    pa_1 += 8; \
-    pa_2 += 8; \
+    PUTRGBA(dst_2, py_2, pa_2, 3, 24);
+    PUTRGBA(dst_1, py_1, pa_1, 3, 24);
+    pa_1 += 8;
+    pa_2 += 8;
 ENDYUV2RGBLINE(8, 0)
     LOADCHROMA(0);
     PUTRGBA(dst_1, py_1, pa_1, 0, 24);
     PUTRGBA(dst_2, py_2, pa_2, 0, 24);
 
     LOADCHROMA(1);
-    PUTRGBA(dst_2, py_2, pa_1, 1, 24);
-    PUTRGBA(dst_1, py_1, pa_2, 1, 24);
-    pa_1 += 4; \
-    pa_2 += 4; \
+    PUTRGBA(dst_2, py_2, pa_2, 1, 24);
+    PUTRGBA(dst_1, py_1, pa_1, 1, 24);
+    pa_1 += 4;
+    pa_2 += 4;
 ENDYUV2RGBLINE(8, 1)
     LOADCHROMA(0);
     PUTRGBA(dst_1, py_1, pa_1, 0, 24);
@@ -310,8 +303,8 @@
     LOADCHROMA(3);
     PUTRGBA(dst_2, py_2, pa_2, 3, 0);
     PUTRGBA(dst_1, py_1, pa_1, 3, 0);
-    pa_1 += 8; \
-    pa_2 += 8; \
+    pa_1 += 8;
+    pa_2 += 8;
 ENDYUV2RGBLINE(8, 0)
     LOADCHROMA(0);
     PUTRGBA(dst_1, py_1, pa_1, 0, 0);
@@ -320,8 +313,8 @@
     LOADCHROMA(1);
     PUTRGBA(dst_2, py_2, pa_2, 1, 0);
     PUTRGBA(dst_1, py_1, pa_1, 1, 0);
-    pa_1 += 4; \
-    pa_2 += 4; \
+    pa_1 += 4;
+    pa_2 += 4;
 ENDYUV2RGBLINE(8, 1)
     LOADCHROMA(0);
     PUTRGBA(dst_1, py_1, pa_1, 0, 0);
@@ -390,9 +383,9 @@
 ENDYUV2RGBFUNC()
 
 YUV2RGBFUNC(yuv2rgb_c_16_ordered_dither, uint16_t, 0)
-    const uint8_t *d16 = dither_2x2_8[y & 1];
-    const uint8_t *e16 = dither_2x2_4[y & 1];
-    const uint8_t *f16 = dither_2x2_8[(y & 1)^1];
+    const uint8_t *d16 = ff_dither_2x2_8[y & 1];
+    const uint8_t *e16 = ff_dither_2x2_4[y & 1];
+    const uint8_t *f16 = ff_dither_2x2_8[(y & 1)^1];
 
 #define PUTRGB16(dst, src, i, o)                    \
     Y              = src[2 * i];                    \
@@ -421,8 +414,8 @@
 CLOSEYUV2RGBFUNC(8)
 
 YUV2RGBFUNC(yuv2rgb_c_15_ordered_dither, uint16_t, 0)
-    const uint8_t *d16 = dither_2x2_8[y & 1];
-    const uint8_t *e16 = dither_2x2_8[(y & 1)^1];
+    const uint8_t *d16 = ff_dither_2x2_8[y & 1];
+    const uint8_t *e16 = ff_dither_2x2_8[(y & 1)^1];
 
 #define PUTRGB15(dst, src, i, o)                    \
     Y              = src[2 * i];                    \
@@ -452,7 +445,7 @@
 
 // r, g, b, dst_1, dst_2
 YUV2RGBFUNC(yuv2rgb_c_12_ordered_dither, uint16_t, 0)
-    const uint8_t *d16 = dither_4x4_16[y & 3];
+    const uint8_t *d16 = ff_dither_4x4_16[y & 3];
 
 #define PUTRGB12(dst, src, i, o)                    \
     Y              = src[2 * i];                    \
@@ -483,8 +476,8 @@
 
 // r, g, b, dst_1, dst_2
 YUV2RGBFUNC(yuv2rgb_c_8_ordered_dither, uint8_t, 0)
-    const uint8_t *d32 = dither_8x8_32[y & 7];
-    const uint8_t *d64 = dither_8x8_73[y & 7];
+    const uint8_t *d32 = ff_dither_8x8_32[y & 7];
+    const uint8_t *d64 = ff_dither_8x8_73[y & 7];
 
 #define PUTRGB8(dst, src, i, o)                     \
     Y              = src[2 * i];                    \
@@ -514,8 +507,8 @@
 CLOSEYUV2RGBFUNC(8)
 
 YUV2RGBFUNC(yuv2rgb_c_4_ordered_dither, uint8_t, 0)
-    const uint8_t * d64 = dither_8x8_73[y & 7];
-    const uint8_t *d128 = dither_8x8_220[y & 7];
+    const uint8_t * d64 = ff_dither_8x8_73[y & 7];
+    const uint8_t *d128 = ff_dither_8x8_220[y & 7];
     int acc;
 
 #define PUTRGB4D(dst, src, i, o)                    \
@@ -547,8 +540,8 @@
 CLOSEYUV2RGBFUNC(4)
 
 YUV2RGBFUNC(yuv2rgb_c_4b_ordered_dither, uint8_t, 0)
-    const uint8_t *d64  = dither_8x8_73[y & 7];
-    const uint8_t *d128 = dither_8x8_220[y & 7];
+    const uint8_t *d64  = ff_dither_8x8_73[y & 7];
+    const uint8_t *d128 = ff_dither_8x8_220[y & 7];
 
 #define PUTRGB4DB(dst, src, i, o)                   \
     Y              = src[2 * i];                    \
@@ -578,7 +571,7 @@
 CLOSEYUV2RGBFUNC(8)
 
 YUV2RGBFUNC(yuv2rgb_c_1_ordered_dither, uint8_t, 0)
-    const uint8_t *d128 = dither_8x8_220[y & 7];
+    const uint8_t *d128 = ff_dither_8x8_220[y & 7];
     char out_1 = 0, out_2 = 0;
     g = c->table_gU[128 + YUVRGB_TABLE_HEADROOM] + c->table_gV[128 + YUVRGB_TABLE_HEADROOM];
 
@@ -893,6 +886,7 @@
         fill_gv_table(c->table_gV, 1, cgv);
         break;
     case 32:
+    case 64:
         base      = (c->dstFormat == AV_PIX_FMT_RGB32_1 ||
                      c->dstFormat == AV_PIX_FMT_BGR32_1) ? 8 : 0;
         rbase     = base + (isRgb ? 16 : 0);
diff --git a/tests/Makefile b/tests/Makefile
index b267293..61423f4 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -13,7 +13,7 @@
 	@echo
 	$(SRC_PATH)/tests/ffserver-regression.sh $(FFSERVER_REFFILE) $(SRC_PATH)/tests/ffserver.conf
 
-OBJDIRS += tests/data tests/vsynth1
+OBJDIRS += tests/data tests/vsynth1 tests/data/filtergraphs
 
 $(VREF): tests/videogen$(HOSTEXESUF) | tests/vsynth1
 	$(M)./$< 'tests/vsynth1/'
@@ -41,7 +41,14 @@
 
 tests/data/%.sw tests/data/asynth% tests/data/vsynth%.yuv tests/vsynth%/00.pgm tests/data/%.nut: TAG = GEN
 
+tests/data/filtergraphs/%: TAG = COPY
+tests/data/filtergraphs/%: $(SRC_PATH)/tests/filtergraphs/% | tests/data/filtergraphs
+	$(M)cp $< $@
+
+# Check sanity of dependencies when running FATE tests.
+ifneq (,$(filter check fate%,$(filter-out fate-rsync,$(MAKECMDGOALS))))
 CHKCFG  = $(if $($(1))$(!$(1)),$($(1)), $(error No such config: $(1)))
+endif
 
 ALLYES  = $(strip $(call XYES, $(1)))
 XYES    = $(if $(strip $(1)),                                           \
@@ -59,6 +66,8 @@
 DEMDEC  = $(call ALLYES, $(1)_DEMUXER $(2:%=%_DECODER))
 ENCMUX  = $(call ALLYES, $(1:%=%_ENCODER) $(2)_MUXER)
 
+DEMMUX  = $(call ALLYES, $(1)_DEMUXER $(2)_MUXER)
+
 FILTERDEMDEC       = $(call ALLYES, $(1)_FILTER $(2)_DEMUXER $(3)_DECODER)
 FILTERDEMDECMUX    = $(call ALLYES, $(1)_FILTER $(2)_DEMUXER $(3)_DECODER $(4)_MUXER)
 FILTERDEMDECENCMUX = $(call ALLYES, $(1)_FILTER $(2)_DEMUXER $(3)_DECODER $(4)_ENCODER $(5)_MUXER)
@@ -66,7 +75,6 @@
 include $(SRC_PATH)/tests/fate/acodec.mak
 include $(SRC_PATH)/tests/fate/vcodec.mak
 include $(SRC_PATH)/tests/fate/avformat.mak
-include $(SRC_PATH)/tests/fate/avfilter.mak
 include $(SRC_PATH)/tests/fate/seek.mak
 
 include $(SRC_PATH)/tests/fate/aac.mak
@@ -85,6 +93,7 @@
 include $(SRC_PATH)/tests/fate/dfa.mak
 include $(SRC_PATH)/tests/fate/dpcm.mak
 include $(SRC_PATH)/tests/fate/ea.mak
+include $(SRC_PATH)/tests/fate/exif.mak
 include $(SRC_PATH)/tests/fate/ffmpeg.mak
 include $(SRC_PATH)/tests/fate/ffprobe.mak
 include $(SRC_PATH)/tests/fate/filter-audio.mak
@@ -96,11 +105,13 @@
 include $(SRC_PATH)/tests/fate/image.mak
 include $(SRC_PATH)/tests/fate/indeo.mak
 include $(SRC_PATH)/tests/fate/libavcodec.mak
+include $(SRC_PATH)/tests/fate/libavdevice.mak
 include $(SRC_PATH)/tests/fate/libavformat.mak
 include $(SRC_PATH)/tests/fate/libavutil.mak
 include $(SRC_PATH)/tests/fate/lossless-audio.mak
 include $(SRC_PATH)/tests/fate/lossless-video.mak
 include $(SRC_PATH)/tests/fate/microsoft.mak
+include $(SRC_PATH)/tests/fate/monkeysaudio.mak
 include $(SRC_PATH)/tests/fate/mp3.mak
 include $(SRC_PATH)/tests/fate/mpc.mak
 include $(SRC_PATH)/tests/fate/pcm.mak
@@ -167,12 +178,13 @@
 
 coverage.info: TAG = LCOV
 coverage.info:
-	$(M)lcov -d $(CURDIR) -b $(SRC_PATH) --capture | sed -e 's#/./#/#g' > $@
-	$(M)lcov --remove $@ "/usr*" -o $@
+	$(M)lcov -q -d $(CURDIR) -b $(SRC_PATH) --capture | \
+	    sed "s,$(CURDIR)/\./,$(CURDIR)/," > $@
+	$(M)lcov -q --remove $@ "/usr*" -o $@
 
 lcov:  TAG = GENHTML
 lcov: coverage.info
-	$(M)genhtml -o $(CURDIR)/lcov $<
+	$(M)genhtml -q -o $(CURDIR)/lcov $<
 
 lcov-reset: TAG = LCOV
 lcov-reset:
diff --git a/tests/audiogen.c b/tests/audiogen.c
index 09cf429..e705061 100644
--- a/tests/audiogen.c
+++ b/tests/audiogen.c
@@ -48,7 +48,7 @@
 
 #define COS_TABLE_BITS 7
 
-/* integer cosinus */
+/* integer cosine */
 static const unsigned short cos_table[(1 << COS_TABLE_BITS) + 2] = {
     0x8000, 0x7ffe, 0x7ff6, 0x7fea, 0x7fd9, 0x7fc2, 0x7fa7, 0x7f87,
     0x7f62, 0x7f38, 0x7f0a, 0x7ed6, 0x7e9d, 0x7e60, 0x7e1e, 0x7dd6,
@@ -180,7 +180,7 @@
     if ((ext = strrchr(argv[1], '.')) != NULL && !strcmp(ext, ".wav"))
         put_wav_header(sample_rate, nb_channels, 6 * sample_rate);
 
-    /* 1 second of single freq sinus at 1000 Hz */
+    /* 1 second of single freq sine at 1000 Hz */
     a = 0;
     for (i = 0; i < 1 * sample_rate; i++) {
         v = (int_cos(a) * 10000) >> FRAC_BITS;
diff --git a/tests/fate-run.sh b/tests/fate-run.sh
index ed99387..52ddc22 100755
--- a/tests/fate-run.sh
+++ b/tests/fate-run.sh
@@ -75,6 +75,10 @@
     run ffprobe -show_entries format=format_name -print_format default=nw=1:nk=1 -v 0 "$@"
 }
 
+probeframes(){
+    run ffprobe -show_frames -v 0 "$@"
+}
+
 ffmpeg(){
     dec_opts="-threads $threads -thread_type $thread_type"
     ffmpeg_args="-nostats -cpuflags $cpuflags"
@@ -146,23 +150,62 @@
     tests/tiny_psnr $srcfile $decfile $cmp_unit $cmp_shift
 }
 
-regtest(){
-    t="${test#$2-}"
-    ref=${base}/ref/$2/$t
-    ${base}/${1}-regression.sh $t $2 $3 "$target_exec" "$target_path" "$threads" "$thread_type" "$cpuflags" "$samples"
-}
-
 lavffatetest(){
-    regtest lavf lavf-fate tests/vsynth1
+    t="${test#lavf-fate-}"
+    ref=${base}/ref/lavf-fate/$t
+    ${base}/lavf-regression.sh $t lavf-fate tests/vsynth1 "$target_exec" "$target_path" "$threads" "$thread_type" "$cpuflags" "$samples"
 }
 
 lavftest(){
-    regtest lavf lavf tests/vsynth1
+    t="${test#lavf-}"
+    ref=${base}/ref/lavf/$t
+    ${base}/lavf-regression.sh $t lavf tests/vsynth1 "$target_exec" "$target_path" "$threads" "$thread_type" "$cpuflags" "$samples"
 }
 
-lavfitest(){
-    cleanfiles="tests/data/lavfi/${test#lavfi-}.nut"
-    regtest lavfi lavfi tests/vsynth1
+video_filter(){
+    filters=$1
+    shift
+    label=${test#filter-}
+    raw_src="${target_path}/tests/vsynth1/%02d.pgm"
+    printf '%-20s' $label
+    ffmpeg $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src \
+        $FLAGS $ENC_OPTS -vf "$filters" -vcodec rawvideo $* -f nut md5:
+}
+
+pixdesc(){
+    pix_fmts="$(ffmpeg -pix_fmts list 2>/dev/null | awk 'NR > 8 && /^IO/ { print $2 }' | sort)"
+    for pix_fmt in $pix_fmts; do
+        test=$pix_fmt
+        video_filter "format=$pix_fmt,pixdesctest" -pix_fmt $pix_fmt
+    done
+}
+
+pixfmts(){
+    filter=${test#filter-pixfmts-}
+    filter=${filter%_*}
+    filter_args=$1
+    prefilter_chain=$2
+
+    showfiltfmts="$target_exec $target_path/libavfilter/filtfmts-test"
+    scale_exclude_fmts=${outfile}_scale_exclude_fmts
+    scale_in_fmts=${outfile}_scale_in_fmts
+    scale_out_fmts=${outfile}_scale_out_fmts
+    in_fmts=${outfile}_in_fmts
+
+    # exclude pixel formats which are not supported as input
+    $showfiltfmts scale | awk -F '[ \r]' '/^INPUT/{ fmt=substr($3, 5); print fmt }' | sort >$scale_in_fmts
+    $showfiltfmts scale | awk -F '[ \r]' '/^OUTPUT/{ fmt=substr($3, 5); print fmt }' | sort >$scale_out_fmts
+    comm -12 $scale_in_fmts $scale_out_fmts >$scale_exclude_fmts
+
+    $showfiltfmts $filter | awk -F '[ \r]' '/^INPUT/{ fmt=substr($3, 5); print fmt }' | sort >$in_fmts
+    pix_fmts=$(comm -12 $scale_exclude_fmts $in_fmts)
+
+    for pix_fmt in $pix_fmts; do
+        test=$pix_fmt
+        video_filter "${prefilter_chain}format=$pix_fmt,$filter=$filter_args" -pix_fmt $pix_fmt
+    done
+
+    rm $in_fmts $scale_in_fmts $scale_out_fmts $scale_exclude_fmts
 }
 
 mkdir -p "$outdir"
diff --git a/tests/fate.sh b/tests/fate.sh
index 1f70e79..1757714 100755
--- a/tests/fate.sh
+++ b/tests/fate.sh
@@ -46,15 +46,18 @@
         --samples="${samples}"                                          \
         --enable-gpl                                                    \
         --enable-memory-poisoning                                       \
+        --enable-avresample                                             \
         ${arch:+--arch=$arch}                                           \
         ${cpu:+--cpu="$cpu"}                                            \
         ${cross_prefix:+--cross-prefix="$cross_prefix"}                 \
+        ${as:+--as="$as"}                                               \
         ${cc:+--cc="$cc"}                                               \
         ${ld:+--ld="$ld"}                                               \
         ${target_os:+--target-os="$target_os"}                          \
         ${sysroot:+--sysroot="$sysroot"}                                \
         ${target_exec:+--target-exec="$target_exec"}                    \
         ${target_path:+--target-path="$target_path"}                    \
+        ${target_samples:+--target-samples="$target_samples"}           \
         ${extra_cflags:+--extra-cflags="$extra_cflags"}                 \
         ${extra_ldflags:+--extra-ldflags="$extra_ldflags"}              \
         ${extra_libs:+--extra-libs="$extra_libs"}                       \
@@ -67,6 +70,7 @@
 )
 
 fate()(
+    test "$build_only" = "yes" && return
     cd ${build} || return
     ${make} ${makeopts} -k fate
 )
diff --git a/tests/fate/aac.mak b/tests/fate/aac.mak
index 0b3999d..304661b 100644
--- a/tests/fate/aac.mak
+++ b/tests/fate/aac.mak
@@ -1,56 +1,56 @@
 FATE_AAC += fate-aac-al04_44
-fate-aac-al04_44: CMD = pcm -i $(SAMPLES)/aac/al04_44.mp4
+fate-aac-al04_44: CMD = pcm -i $(TARGET_SAMPLES)/aac/al04_44.mp4
 fate-aac-al04_44: REF = $(SAMPLES)/aac/al04_44.s16
 
 FATE_AAC += fate-aac-al05_44
-fate-aac-al05_44: CMD = pcm -i $(SAMPLES)/aac/al05_44.mp4
+fate-aac-al05_44: CMD = pcm -i $(TARGET_SAMPLES)/aac/al05_44.mp4
 fate-aac-al05_44: REF = $(SAMPLES)/aac/al05_44.s16
 
 FATE_AAC += fate-aac-al06_44
-fate-aac-al06_44: CMD = pcm -i $(SAMPLES)/aac/al06_44.mp4
+fate-aac-al06_44: CMD = pcm -i $(TARGET_SAMPLES)/aac/al06_44.mp4
 fate-aac-al06_44: REF = $(SAMPLES)/aac/al06_44_reorder.s16
 
 FATE_AAC += fate-aac-al07_96
-fate-aac-al07_96: CMD = pcm -i $(SAMPLES)/aac/al07_96.mp4
+fate-aac-al07_96: CMD = pcm -i $(TARGET_SAMPLES)/aac/al07_96.mp4
 fate-aac-al07_96: REF = $(SAMPLES)/aac/al07_96_reorder.s16
 
 FATE_AAC += fate-aac-al15_44
-fate-aac-al15_44: CMD = pcm -i $(SAMPLES)/aac/al15_44.mp4
+fate-aac-al15_44: CMD = pcm -i $(TARGET_SAMPLES)/aac/al15_44.mp4
 fate-aac-al15_44: REF = $(SAMPLES)/aac/al15_44_reorder.s16
 
 FATE_AAC += fate-aac-al17_44
-fate-aac-al17_44: CMD = pcm -i $(SAMPLES)/aac/al17_44.mp4
+fate-aac-al17_44: CMD = pcm -i $(TARGET_SAMPLES)/aac/al17_44.mp4
 fate-aac-al17_44: REF = $(SAMPLES)/aac/al17_44.s16
 
 FATE_AAC += fate-aac-al18_44
-fate-aac-al18_44: CMD = pcm -i $(SAMPLES)/aac/al18_44.mp4
+fate-aac-al18_44: CMD = pcm -i $(TARGET_SAMPLES)/aac/al18_44.mp4
 fate-aac-al18_44: REF = $(SAMPLES)/aac/al18_44.s16
 
 FATE_AAC += fate-aac-am00_88
-fate-aac-am00_88: CMD = pcm -i $(SAMPLES)/aac/am00_88.mp4
+fate-aac-am00_88: CMD = pcm -i $(TARGET_SAMPLES)/aac/am00_88.mp4
 fate-aac-am00_88: REF = $(SAMPLES)/aac/am00_88.s16
 
 FATE_AAC += fate-aac-am05_44
-fate-aac-am05_44: CMD = pcm -i $(SAMPLES)/aac/am05_44.mp4
+fate-aac-am05_44: CMD = pcm -i $(TARGET_SAMPLES)/aac/am05_44.mp4
 fate-aac-am05_44: REF = $(SAMPLES)/aac/am05_44_reorder.s16
 
 FATE_AAC += fate-aac-al_sbr_hq_cm_48_2
-fate-aac-al_sbr_hq_cm_48_2: CMD = pcm -i $(SAMPLES)/aac/al_sbr_cm_48_2.mp4
+fate-aac-al_sbr_hq_cm_48_2: CMD = pcm -i $(TARGET_SAMPLES)/aac/al_sbr_cm_48_2.mp4
 fate-aac-al_sbr_hq_cm_48_2: REF = $(SAMPLES)/aac/al_sbr_hq_cm_48_2.s16
 
 FATE_AAC += fate-aac-al_sbr_hq_cm_48_5.1
-fate-aac-al_sbr_hq_cm_48_5.1: CMD = pcm -i $(SAMPLES)/aac/al_sbr_cm_48_5.1.mp4
+fate-aac-al_sbr_hq_cm_48_5.1: CMD = pcm -i $(TARGET_SAMPLES)/aac/al_sbr_cm_48_5.1.mp4
 fate-aac-al_sbr_hq_cm_48_5.1: REF = $(SAMPLES)/aac/al_sbr_hq_cm_48_5.1_reorder.s16
 
 FATE_AAC += fate-aac-al_sbr_ps_06_ur
-fate-aac-al_sbr_ps_06_ur: CMD = pcm -i $(SAMPLES)/aac/al_sbr_ps_06_new.mp4
+fate-aac-al_sbr_ps_06_ur: CMD = pcm -i $(TARGET_SAMPLES)/aac/al_sbr_ps_06_new.mp4
 fate-aac-al_sbr_ps_06_ur: REF = $(SAMPLES)/aac/al_sbr_ps_06_ur.s16
 
 FATE_AAC += fate-aac-ap05_48
-fate-aac-ap05_48: CMD = pcm -i $(SAMPLES)/aac/ap05_48.mp4
+fate-aac-ap05_48: CMD = pcm -i $(TARGET_SAMPLES)/aac/ap05_48.mp4
 fate-aac-ap05_48: REF = $(SAMPLES)/aac/ap05_48.s16
 
-fate-aac-ct%: CMD = pcm -i $(SAMPLES)/aac/CT_DecoderCheck/$(@:fate-aac-ct-%=%)
+fate-aac-ct%: CMD = pcm -i $(TARGET_SAMPLES)/aac/CT_DecoderCheck/$(@:fate-aac-ct-%=%)
 fate-aac-ct%: REF = $(SAMPLES)/aac/CT_DecoderCheck/aacPlusv2.wav
 
 FATE_AAC_CT_RAW = fate-aac-ct-sbr_i-ps_i.aac
@@ -82,11 +82,11 @@
 fate-aac-ln-encode: SIZE_TOLERANCE = 3560
 
 FATE_AAC_LATM += fate-aac-latm_000000001180bc60
-fate-aac-latm_000000001180bc60: CMD = pcm -i $(SAMPLES)/aac/latm_000000001180bc60.mpg
+fate-aac-latm_000000001180bc60: CMD = pcm -i $(TARGET_SAMPLES)/aac/latm_000000001180bc60.mpg
 fate-aac-latm_000000001180bc60: REF = $(SAMPLES)/aac/latm_000000001180bc60.s16
 
 FATE_AAC_LATM += fate-aac-latm_stereo_to_51
-fate-aac-latm_stereo_to_51: CMD = pcm -i $(SAMPLES)/aac/latm_stereo_to_51.ts -channel_layout 5.1
+fate-aac-latm_stereo_to_51: CMD = pcm -i $(TARGET_SAMPLES)/aac/latm_stereo_to_51.ts -channel_layout 5.1
 fate-aac-latm_stereo_to_51: REF = $(SAMPLES)/aac/latm_stereo_to_51_ref.s16
 
 FATE_AAC-$(call      DEMDEC, AAC,    AAC)      += $(FATE_AAC_CT_RAW)
diff --git a/tests/fate/ac3.mak b/tests/fate/ac3.mak
index 90dfc41..f386499 100644
--- a/tests/fate/ac3.mak
+++ b/tests/fate/ac3.mak
@@ -1,45 +1,45 @@
 FATE_AC3 += fate-ac3-2.0
-fate-ac3-2.0: CMD = pcm -i $(SAMPLES)/ac3/monsters_inc_2.0_192_small.ac3
+fate-ac3-2.0: CMD = pcm -i $(TARGET_SAMPLES)/ac3/monsters_inc_2.0_192_small.ac3
 fate-ac3-2.0: REF = $(SAMPLES)/ac3/monsters_inc_2.0_192_small_v2.pcm
 
 FATE_AC3 += fate-ac3-4.0
-fate-ac3-4.0: CMD = pcm -i $(SAMPLES)/ac3/millers_crossing_4.0.ac3
+fate-ac3-4.0: CMD = pcm -i $(TARGET_SAMPLES)/ac3/millers_crossing_4.0.ac3
 fate-ac3-4.0: REF = $(SAMPLES)/ac3/millers_crossing_4.0_v2.pcm
 
 FATE_AC3 += fate-ac3-4.0-downmix-mono
-fate-ac3-4.0-downmix-mono: CMD = pcm -request_channels 1 -i $(SAMPLES)/ac3/millers_crossing_4.0.ac3
+fate-ac3-4.0-downmix-mono: CMD = pcm -request_channels 1 -i $(TARGET_SAMPLES)/ac3/millers_crossing_4.0.ac3
 fate-ac3-4.0-downmix-mono: REF = $(SAMPLES)/ac3/millers_crossing_4.0_mono_v2.pcm
 
 FATE_AC3 += fate-ac3-4.0-downmix-stereo
-fate-ac3-4.0-downmix-stereo: CMD = pcm -request_channels 2 -i $(SAMPLES)/ac3/millers_crossing_4.0.ac3
+fate-ac3-4.0-downmix-stereo: CMD = pcm -request_channels 2 -i $(TARGET_SAMPLES)/ac3/millers_crossing_4.0.ac3
 fate-ac3-4.0-downmix-stereo: REF = $(SAMPLES)/ac3/millers_crossing_4.0_stereo_v2.pcm
 
 FATE_AC3 += fate-ac3-5.1
-fate-ac3-5.1: CMD = pcm -i $(SAMPLES)/ac3/monsters_inc_5.1_448_small.ac3
+fate-ac3-5.1: CMD = pcm -i $(TARGET_SAMPLES)/ac3/monsters_inc_5.1_448_small.ac3
 fate-ac3-5.1: REF = $(SAMPLES)/ac3/monsters_inc_5.1_448_small_v2.pcm
 
 FATE_AC3 += fate-ac3-5.1-downmix-mono
-fate-ac3-5.1-downmix-mono: CMD = pcm -request_channels 1 -i $(SAMPLES)/ac3/monsters_inc_5.1_448_small.ac3
+fate-ac3-5.1-downmix-mono: CMD = pcm -request_channels 1 -i $(TARGET_SAMPLES)/ac3/monsters_inc_5.1_448_small.ac3
 fate-ac3-5.1-downmix-mono: REF = $(SAMPLES)/ac3/monsters_inc_5.1_448_small_mono_v2.pcm
 
 FATE_AC3 += fate-ac3-5.1-downmix-stereo
-fate-ac3-5.1-downmix-stereo: CMD = pcm -request_channels 2 -i $(SAMPLES)/ac3/monsters_inc_5.1_448_small.ac3
+fate-ac3-5.1-downmix-stereo: CMD = pcm -request_channels 2 -i $(TARGET_SAMPLES)/ac3/monsters_inc_5.1_448_small.ac3
 fate-ac3-5.1-downmix-stereo: REF = $(SAMPLES)/ac3/monsters_inc_5.1_448_small_stereo_v2.pcm
 
 FATE_EAC3 += fate-eac3-1
-fate-eac3-1: CMD = pcm -i $(SAMPLES)/eac3/csi_miami_5.1_256_spx_small.eac3
+fate-eac3-1: CMD = pcm -i $(TARGET_SAMPLES)/eac3/csi_miami_5.1_256_spx_small.eac3
 fate-eac3-1: REF = $(SAMPLES)/eac3/csi_miami_5.1_256_spx_small_v2.pcm
 
 FATE_EAC3 += fate-eac3-2
-fate-eac3-2: CMD = pcm -i $(SAMPLES)/eac3/csi_miami_stereo_128_spx_small.eac3
+fate-eac3-2: CMD = pcm -i $(TARGET_SAMPLES)/eac3/csi_miami_stereo_128_spx_small.eac3
 fate-eac3-2: REF = $(SAMPLES)/eac3/csi_miami_stereo_128_spx_small_v2.pcm
 
 FATE_EAC3 += fate-eac3-3
-fate-eac3-3: CMD = pcm -i $(SAMPLES)/eac3/matrix2_commentary1_stereo_192_small.eac3
+fate-eac3-3: CMD = pcm -i $(TARGET_SAMPLES)/eac3/matrix2_commentary1_stereo_192_small.eac3
 fate-eac3-3: REF = $(SAMPLES)/eac3/matrix2_commentary1_stereo_192_small_v2.pcm
 
 FATE_EAC3 += fate-eac3-4
-fate-eac3-4: CMD = pcm -i $(SAMPLES)/eac3/serenity_english_5.1_1536_small.eac3
+fate-eac3-4: CMD = pcm -i $(TARGET_SAMPLES)/eac3/serenity_english_5.1_1536_small.eac3
 fate-eac3-4: REF = $(SAMPLES)/eac3/serenity_english_5.1_1536_small_v2.pcm
 
 $(FATE_AC3) $(FATE_EAC3): CMP = oneoff
@@ -48,18 +48,17 @@
 FATE_EAC3-$(call DEMDEC, EAC3, EAC3) += $(FATE_EAC3)
 
 FATE_AC3-$(call ENCDEC, AC3, AC3) += fate-ac3-encode
-fate-ac3-encode: CMD = enc_dec_pcm ac3 wav s16le $(REF) -c:a ac3 -b:a 128k
+fate-ac3-encode: CMD = enc_dec_pcm ac3 wav s16le $(subst $(SAMPLES),$(TARGET_SAMPLES),$(REF)) -c:a ac3 -b:a 128k
 fate-ac3-encode: CMP_SHIFT = -1024
 fate-ac3-encode: CMP_TARGET = 404.53
 fate-ac3-encode: SIZE_TOLERANCE = 488
-fate-ac3-encode: FUZZ = 4
+
 
 FATE_EAC3-$(call ENCDEC, EAC3, EAC3) += fate-eac3-encode
-fate-eac3-encode: CMD = enc_dec_pcm eac3 wav s16le $(REF) -c:a eac3 -b:a 128k
+fate-eac3-encode: CMD = enc_dec_pcm eac3 wav s16le $(subst $(SAMPLES),$(TARGET_SAMPLES),$(REF)) -c:a eac3 -b:a 128k
 fate-eac3-encode: CMP_SHIFT = -1024
 fate-eac3-encode: CMP_TARGET = 516.94
 fate-eac3-encode: SIZE_TOLERANCE = 488
-fate-eac3-encode: FUZZ = 3
 
 fate-ac3-encode fate-eac3-encode: CMP = stddev
 fate-ac3-encode fate-eac3-encode: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav
diff --git a/tests/fate/acodec.mak b/tests/fate/acodec.mak
index 0206486..78508bc 100644
--- a/tests/fate/acodec.mak
+++ b/tests/fate/acodec.mak
@@ -77,15 +77,15 @@
 fate-acodec-dca: SRC = tests/data/asynth-44100-2.wav
 fate-acodec-dca: CMD = md5 -i $(TARGET_PATH)/$(SRC) -c:a dca -strict -2 -f dts -flags +bitexact
 fate-acodec-dca: CMP = oneline
-fate-acodec-dca: REF = 66bd0e602be7fb97dc19151554c0ee29
+fate-acodec-dca: REF = fe28cef432ed88de4ee01b87537fd2bd
 
 FATE_ACODEC-$(call ENCDEC, DCA, WAV) += fate-acodec-dca2
 fate-acodec-dca2: CMD = enc_dec_pcm dts wav s16le $(SRC) -c:a dca -strict -2 -flags +bitexact
 fate-acodec-dca2: REF = $(SRC)
 fate-acodec-dca2: CMP = stddev
-fate-acodec-dca2: CMP_SHIFT = -1920
-fate-acodec-dca2: CMP_TARGET = 2424
-fate-acodec-dca2: SIZE_TOLERANCE = 544
+fate-acodec-dca2: CMP_SHIFT = -2048
+fate-acodec-dca2: CMP_TARGET = 527
+fate-acodec-dca2: SIZE_TOLERANCE = 1632
 
 FATE_ACODEC-$(call ENCDEC, FLAC, FLAC) += fate-acodec-flac
 fate-acodec-flac: FMT = flac
diff --git a/tests/fate/adpcm.mak b/tests/fate/adpcm.mak
index 71764cc..6b1dd3c 100644
--- a/tests/fate/adpcm.mak
+++ b/tests/fate/adpcm.mak
@@ -1,83 +1,89 @@
 FATE_ADPCM-$(call DEMDEC, FOURXM, ADPCM_4XM) += fate-adpcm-4xm
-fate-adpcm-4xm: CMD = framecrc -i $(SAMPLES)/4xm/dracula.4xm -vn -map 0:6
+fate-adpcm-4xm: CMD = framecrc -i $(TARGET_SAMPLES)/4xm/dracula.4xm -vn -map 0:6
 
 FATE_ADPCM-$(call DEMDEC, AST, ADPCM_AFC) += fate-adpcm-afc
-fate-adpcm-afc: CMD = framecrc -i $(SAMPLES)/ast/demo11_02_partial.ast
+fate-adpcm-afc: CMD = framecrc -i $(TARGET_SAMPLES)/ast/demo11_02_partial.ast
 
 FATE_ADPCM-$(call DEMDEC, WAV, ADPCM_CT) += fate-adpcm-creative
-fate-adpcm-creative: CMD = md5 -i $(SAMPLES)/creative/intro-partial.wav -f s16le
+fate-adpcm-creative: CMD = md5 -i $(TARGET_SAMPLES)/creative/intro-partial.wav -f s16le
 
 FATE_ADPCM-$(call DEMDEC, VOC, ADPCM_SBPRO_2) += fate-adpcm-creative-8-2bit
-fate-adpcm-creative-8-2bit: CMD = md5 -i $(SAMPLES)/creative/BBC_2BIT.VOC -f s16le
+fate-adpcm-creative-8-2bit: CMD = md5 -i $(TARGET_SAMPLES)/creative/BBC_2BIT.VOC -f s16le
 
 FATE_ADPCM-$(call DEMDEC, VOC, ADPCM_SBPRO_3) += fate-adpcm-creative-8-2.6bit
-fate-adpcm-creative-8-2.6bit: CMD = md5 -i $(SAMPLES)/creative/BBC_3BIT.VOC -f s16le
+fate-adpcm-creative-8-2.6bit: CMD = md5 -i $(TARGET_SAMPLES)/creative/BBC_3BIT.VOC -f s16le
 
 FATE_ADPCM-$(call DEMDEC, VOC, ADPCM_SBPRO_4) += fate-adpcm-creative-8-4bit
-fate-adpcm-creative-8-4bit: CMD = md5 -i $(SAMPLES)/creative/BBC_4BIT.VOC -f s16le
+fate-adpcm-creative-8-4bit: CMD = md5 -i $(TARGET_SAMPLES)/creative/BBC_4BIT.VOC -f s16le
+
+FATE_ADPCM-$(call DEMDEC, ADP, ADPCM_DTK) += fate-adpcm-dtk
+fate-adpcm-dtk: CMD = framecrc -i $(TARGET_SAMPLES)/adp/shakespr_partial.adp -f s16le
 
 FATE_ADPCM-$(call DEMDEC, EA, ADPCM_EA) += fate-adpcm-ea-1
-fate-adpcm-ea-1: CMD = framecrc -i $(SAMPLES)/ea-wve/networkBackbone-partial.wve -frames:a 26 -vn
+fate-adpcm-ea-1: CMD = framecrc -i $(TARGET_SAMPLES)/ea-wve/networkBackbone-partial.wve -frames:a 26 -vn
 
 FATE_ADPCM-$(call DEMDEC, EA, ADPCM_EA) += fate-adpcm-ea-2
-fate-adpcm-ea-2: CMD = framecrc -i $(SAMPLES)/ea-dct/NFS2Esprit-partial.dct -vn
+fate-adpcm-ea-2: CMD = framecrc -i $(TARGET_SAMPLES)/ea-dct/NFS2Esprit-partial.dct -vn
 
 FATE_ADPCM-$(call DEMDEC, XA, ADPCM_EA_MAXIS_XA) += fate-adpcm-ea-maxis-xa
-fate-adpcm-ea-maxis-xa: CMD = framecrc -i $(SAMPLES)/maxis-xa/SC2KBUG.XA -frames:a 30
+fate-adpcm-ea-maxis-xa: CMD = framecrc -i $(TARGET_SAMPLES)/maxis-xa/SC2KBUG.XA -frames:a 30
 
 FATE_ADPCM-$(call DEMDEC, EA, ADPCM_EA_R1) += fate-adpcm-ea-r1
-fate-adpcm-ea-r1: CMD = framecrc -i $(SAMPLES)/ea-mad/NFS6LogoE.mad -vn
+fate-adpcm-ea-r1: CMD = framecrc -i $(TARGET_SAMPLES)/ea-mad/NFS6LogoE.mad -vn
 
 FATE_ADPCM-$(call DEMDEC, EA, ADPCM_EA_R2) += fate-adpcm-ea-r2
-fate-adpcm-ea-r2: CMD = crc -i $(SAMPLES)/ea-mpc/THX_logo.mpc -vn
+fate-adpcm-ea-r2: CMD = crc -i $(TARGET_SAMPLES)/ea-mpc/THX_logo.mpc -vn
 
 FATE_ADPCM-$(call DEMDEC, EA, ADPCM_EA_R3) += fate-adpcm-ea-r3
-fate-adpcm-ea-r3: CMD = crc -i $(SAMPLES)/ea-vp6/THX_logo.vp6 -vn
+fate-adpcm-ea-r3: CMD = crc -i $(TARGET_SAMPLES)/ea-vp6/THX_logo.vp6 -vn
 
 FATE_ADPCM-$(call DEMDEC, AVI, ADPCM_IMA_AMV) += fate-adpcm-ima-amv
-fate-adpcm-ima-amv: CMD = framecrc -i $(SAMPLES)/amv/MTV_high_res_320x240_sample_Penguin_Joke_MTV_from_WMV.amv -t 10 -vn
+fate-adpcm-ima-amv: CMD = framecrc -i $(TARGET_SAMPLES)/amv/MTV_high_res_320x240_sample_Penguin_Joke_MTV_from_WMV.amv -t 10 -vn
 
 FATE_ADPCM-$(call DEMDEC, APC, ADPCM_IMA_APC) += fate-adpcm-ima-apc
-fate-adpcm-ima-apc: CMD = md5 -i $(SAMPLES)/cryo-apc/cine007.APC -f s16le
+fate-adpcm-ima-apc: CMD = md5 -i $(TARGET_SAMPLES)/cryo-apc/cine007.APC -f s16le
 
 FATE_ADPCM-$(call DEMDEC, AVI, ADPCM_IMA_DK3) += fate-adpcm-ima-dk3
-fate-adpcm-ima-dk3: CMD = md5 -i $(SAMPLES)/duck/sop-audio-only.avi -f s16le
+fate-adpcm-ima-dk3: CMD = md5 -i $(TARGET_SAMPLES)/duck/sop-audio-only.avi -f s16le
 
 FATE_ADPCM-$(call DEMDEC, AVI, ADPCM_IMA_DK4) += fate-adpcm-ima-dk4
-fate-adpcm-ima-dk4: CMD = md5 -i $(SAMPLES)/duck/salsa-audio-only.avi -f s16le
+fate-adpcm-ima-dk4: CMD = md5 -i $(TARGET_SAMPLES)/duck/salsa-audio-only.avi -f s16le
 
 FATE_ADPCM-$(call DEMDEC, EA, ADPCM_IMA_EA_EACS) += fate-adpcm-ima-ea-eacs
-fate-adpcm-ima-ea-eacs: CMD = framecrc -i $(SAMPLES)/ea-tgv/INTRO8K-partial.TGV -vn
+fate-adpcm-ima-ea-eacs: CMD = framecrc -i $(TARGET_SAMPLES)/ea-tgv/INTRO8K-partial.TGV -vn
 
 FATE_ADPCM-$(call DEMDEC, EA, ADPCM_IMA_EA_SEAD) += fate-adpcm-ima-ea-sead
-fate-adpcm-ima-ea-sead: CMD = framecrc -i $(SAMPLES)/ea-tgv/INTEL_S.TGV -vn
+fate-adpcm-ima-ea-sead: CMD = framecrc -i $(TARGET_SAMPLES)/ea-tgv/INTEL_S.TGV -vn
 
 FATE_ADPCM-$(call DEMDEC, ISS, ADPCM_IMA_ISS) += fate-adpcm-ima-iss
-fate-adpcm-ima-iss: CMD = md5 -i $(SAMPLES)/funcom-iss/0004010100.iss -f s16le
+fate-adpcm-ima-iss: CMD = md5 -i $(TARGET_SAMPLES)/funcom-iss/0004010100.iss -f s16le
 
 FATE_ADPCM-$(call DEMDEC, WAV, ADPCM_IMA_OKI) += fate-adpcm-ima-oki
-fate-adpcm-ima-oki: CMD = md5 -i $(SAMPLES)/oki/test.wav -f s16le
+fate-adpcm-ima-oki: CMD = md5 -i $(TARGET_SAMPLES)/oki/test.wav -f s16le
+
+FATE_ADPCM-$(call DEMDEC, RSD, ADPCM_IMA_RAD) += fate-adpcm-ima-rad
+fate-adpcm-ima-rad: CMD = md5 -i $(TARGET_SAMPLES)/rsd/hit_run_partial.rsd -f s16le
 
 FATE_ADPCM-$(call DEMDEC, SMJPEG, ADPCM_IMA_SMJPEG) += fate-adpcm-ima-smjpeg
-fate-adpcm-ima-smjpeg: CMD = framecrc -i $(SAMPLES)/smjpeg/scenwin.mjpg -vn
+fate-adpcm-ima-smjpeg: CMD = framecrc -i $(TARGET_SAMPLES)/smjpeg/scenwin.mjpg -vn
 
 FATE_ADPCM-$(call DEMDEC, MOV, ADPCM_IMA_WAV) += fate-adpcm-ima_wav-stereo
-fate-adpcm-ima_wav-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-L-ms11.mov -f s16le
+fate-adpcm-ima_wav-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-L-ms11.mov -f s16le
 
 FATE_ADPCM-$(call DEMDEC, WSVQA, ADPCM_IMA_WS) += fate-adpcm-ima-ws
-fate-adpcm-ima-ws: CMD = framecrc -i $(SAMPLES)/vqa/cc-demo1-partial.vqa -vn
+fate-adpcm-ima-ws: CMD = framecrc -i $(TARGET_SAMPLES)/vqa/cc-demo1-partial.vqa -vn
 
 FATE_ADPCM-$(call DEMDEC, DXA, ADPCM_MS) += fate-adpcm-ms-mono
-fate-adpcm-ms-mono: CMD = framecrc -i $(SAMPLES)/dxa/meetsquid.dxa -t 2 -vn
+fate-adpcm-ms-mono: CMD = framecrc -i $(TARGET_SAMPLES)/dxa/meetsquid.dxa -t 2 -vn
 
 FATE_ADPCM-$(call DEMDEC, MOV, ADPCM_MS) += fate-adpcm_ms-stereo
-fate-adpcm_ms-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-L-ms02.mov -f s16le
+fate-adpcm_ms-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-L-ms02.mov -f s16le
 
 FATE_ADPCM-$(call DEMDEC, THP, ADPCM_THP) += fate-adpcm-thp
-fate-adpcm-thp: CMD = framecrc -i $(SAMPLES)/thp/pikmin2-opening1-partial.thp -vn
+fate-adpcm-thp: CMD = framecrc -i $(TARGET_SAMPLES)/thp/pikmin2-opening1-partial.thp -vn
 
 FATE_ADPCM-$(call DEMDEC, STR, ADPCM_XA) += fate-adpcm-xa
-fate-adpcm-xa: CMD = framecrc -i $(SAMPLES)/psx-str/abc000_cut.str -vn
+fate-adpcm-xa: CMD = framecrc -i $(TARGET_SAMPLES)/psx-str/abc000_cut.str -vn
 
 FATE_SAMPLES_AVCONV += $(FATE_ADPCM-yes)
 fate-adpcm: $(FATE_ADPCM-yes)
diff --git a/tests/fate/alac.mak b/tests/fate/alac.mak
index d724837..5e29e90 100644
--- a/tests/fate/alac.mak
+++ b/tests/fate/alac.mak
@@ -12,10 +12,10 @@
 fate-alac-%-lpc-orders:  OPTS = -min_prediction_order 1 -max_prediction_order 30
 
 fate-alac-16-%: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav
-fate-alac-16-%: CMD = enc_dec_pcm mov wav s16le $(REF) -c alac $(OPTS)
+fate-alac-16-%: CMD = enc_dec_pcm mov wav s16le $(subst $(SAMPLES),$(TARGET_SAMPLES),$(REF)) -c alac $(OPTS)
 
 fate-alac-24-%: REF = $(SAMPLES)/audio-reference/divertimenti_2ch_96kHz_s24.wav
-fate-alac-24-%: CMD = enc_dec_pcm mov wav s24le $(REF) -c alac $(OPTS)
+fate-alac-24-%: CMD = enc_dec_pcm mov wav s24le $(subst $(SAMPLES),$(TARGET_SAMPLES),$(REF)) -c alac $(OPTS)
 
 fate-alac-%: CMP = oneoff
 fate-alac-%: FUZZ = 0
diff --git a/tests/fate/als.mak b/tests/fate/als.mak
index 5ec1189..ff2badf 100644
--- a/tests/fate/als.mak
+++ b/tests/fate/als.mak
@@ -2,7 +2,7 @@
 
 define FATE_ALS_SUITE
 FATE_ALS += fate-mpeg4-als-conformance-$(1)
-fate-mpeg4-als-conformance-$(1): CMD = crc -i $(SAMPLES)/lossless-audio/als_$(1)_2ch48k16b.mp4
+fate-mpeg4-als-conformance-$(1): CMD = crc -i $(TARGET_SAMPLES)/lossless-audio/als_$(1)_2ch48k16b.mp4
 endef
 
 $(foreach N,$(ALS_SUITE),$(eval $(call FATE_ALS_SUITE,$(N))))
diff --git a/tests/fate/amrnb.mak b/tests/fate/amrnb.mak
index 6dbba58..c0feec2 100644
--- a/tests/fate/amrnb.mak
+++ b/tests/fate/amrnb.mak
@@ -1,33 +1,33 @@
 FATE_AMRNB += fate-amrnb-4k75
-fate-amrnb-4k75: CMD = pcm -i $(SAMPLES)/amrnb/4.75k.amr
+fate-amrnb-4k75: CMD = pcm -i $(TARGET_SAMPLES)/amrnb/4.75k.amr
 fate-amrnb-4k75: REF = $(SAMPLES)/amrnb/4.75k.pcm
 
 FATE_AMRNB += fate-amrnb-5k15
-fate-amrnb-5k15: CMD = pcm -i $(SAMPLES)/amrnb/5.15k.amr
+fate-amrnb-5k15: CMD = pcm -i $(TARGET_SAMPLES)/amrnb/5.15k.amr
 fate-amrnb-5k15: REF = $(SAMPLES)/amrnb/5.15k.pcm
 
 FATE_AMRNB += fate-amrnb-5k9
-fate-amrnb-5k9: CMD = pcm -i $(SAMPLES)/amrnb/5.9k.amr
+fate-amrnb-5k9: CMD = pcm -i $(TARGET_SAMPLES)/amrnb/5.9k.amr
 fate-amrnb-5k9: REF = $(SAMPLES)/amrnb/5.9k.pcm
 
 FATE_AMRNB += fate-amrnb-6k7
-fate-amrnb-6k7: CMD = pcm -i $(SAMPLES)/amrnb/6.7k.amr
+fate-amrnb-6k7: CMD = pcm -i $(TARGET_SAMPLES)/amrnb/6.7k.amr
 fate-amrnb-6k7: REF = $(SAMPLES)/amrnb/6.7k.pcm
 
 FATE_AMRNB += fate-amrnb-7k4
-fate-amrnb-7k4: CMD = pcm -i $(SAMPLES)/amrnb/7.4k.amr
+fate-amrnb-7k4: CMD = pcm -i $(TARGET_SAMPLES)/amrnb/7.4k.amr
 fate-amrnb-7k4: REF = $(SAMPLES)/amrnb/7.4k.pcm
 
 FATE_AMRNB += fate-amrnb-7k95
-fate-amrnb-7k95: CMD = pcm -i $(SAMPLES)/amrnb/7.95k.amr
+fate-amrnb-7k95: CMD = pcm -i $(TARGET_SAMPLES)/amrnb/7.95k.amr
 fate-amrnb-7k95: REF = $(SAMPLES)/amrnb/7.95k.pcm
 
 FATE_AMRNB += fate-amrnb-10k2
-fate-amrnb-10k2: CMD = pcm -i $(SAMPLES)/amrnb/10.2k.amr
+fate-amrnb-10k2: CMD = pcm -i $(TARGET_SAMPLES)/amrnb/10.2k.amr
 fate-amrnb-10k2: REF = $(SAMPLES)/amrnb/10.2k.pcm
 
 FATE_AMRNB += fate-amrnb-12k2
-fate-amrnb-12k2: CMD = pcm -i $(SAMPLES)/amrnb/12.2k.amr
+fate-amrnb-12k2: CMD = pcm -i $(TARGET_SAMPLES)/amrnb/12.2k.amr
 fate-amrnb-12k2: REF = $(SAMPLES)/amrnb/12.2k.pcm
 
 $(FATE_AMRNB): CMP = stddev
diff --git a/tests/fate/amrwb.mak b/tests/fate/amrwb.mak
index 99c2737..b93835d 100644
--- a/tests/fate/amrwb.mak
+++ b/tests/fate/amrwb.mak
@@ -1,44 +1,44 @@
 FATE_AMRWB += fate-amrwb-6k60
-fate-amrwb-6k60: CMD = pcm -i $(SAMPLES)/amrwb/seed-6k60.awb
+fate-amrwb-6k60: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/seed-6k60.awb
 fate-amrwb-6k60: REF = $(SAMPLES)/amrwb/seed-6k60.pcm
 
 FATE_AMRWB += fate-amrwb-8k85
-fate-amrwb-8k85: CMD = pcm -i $(SAMPLES)/amrwb/seed-8k85.awb
+fate-amrwb-8k85: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/seed-8k85.awb
 fate-amrwb-8k85: REF = $(SAMPLES)/amrwb/seed-8k85.pcm
 
 FATE_AMRWB += fate-amrwb-12k65
-fate-amrwb-12k65: CMD = pcm -i $(SAMPLES)/amrwb/seed-12k65.awb
+fate-amrwb-12k65: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/seed-12k65.awb
 fate-amrwb-12k65: REF = $(SAMPLES)/amrwb/seed-12k65.pcm
 
 FATE_AMRWB += fate-amrwb-14k25
-fate-amrwb-14k25: CMD = pcm -i $(SAMPLES)/amrwb/seed-14k25.awb
+fate-amrwb-14k25: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/seed-14k25.awb
 fate-amrwb-14k25: REF = $(SAMPLES)/amrwb/seed-14k25.pcm
 fate-amrwb-14k25: FUZZ = 2.6
 
 FATE_AMRWB += fate-amrwb-15k85
-fate-amrwb-15k85: CMD = pcm -i $(SAMPLES)/amrwb/seed-15k85.awb
+fate-amrwb-15k85: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/seed-15k85.awb
 fate-amrwb-15k85: REF = $(SAMPLES)/amrwb/seed-15k85.pcm
 
 FATE_AMRWB += fate-amrwb-18k25
-fate-amrwb-18k25: CMD = pcm -i $(SAMPLES)/amrwb/seed-18k25.awb
+fate-amrwb-18k25: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/seed-18k25.awb
 fate-amrwb-18k25: REF = $(SAMPLES)/amrwb/seed-18k25.pcm
 
 FATE_AMRWB += fate-amrwb-19k85
-fate-amrwb-19k85: CMD = pcm -i $(SAMPLES)/amrwb/seed-19k85.awb
+fate-amrwb-19k85: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/seed-19k85.awb
 fate-amrwb-19k85: REF = $(SAMPLES)/amrwb/seed-19k85.pcm
 
 FATE_AMRWB += fate-amrwb-23k05
-fate-amrwb-23k05: CMD = pcm -i $(SAMPLES)/amrwb/seed-23k05.awb
+fate-amrwb-23k05: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/seed-23k05.awb
 fate-amrwb-23k05: REF = $(SAMPLES)/amrwb/seed-23k05.pcm
 fate-amrwb-23k05: FUZZ = 2
 
 FATE_AMRWB += fate-amrwb-23k85
-fate-amrwb-23k85: CMD = pcm -i $(SAMPLES)/amrwb/seed-23k85.awb
+fate-amrwb-23k85: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/seed-23k85.awb
 fate-amrwb-23k85: REF = $(SAMPLES)/amrwb/seed-23k85.pcm
 fate-amrwb-23k85: FUZZ = 2
 
 FATE_AMRWB += fate-amrwb-23k85-2
-fate-amrwb-23k85-2: CMD = pcm -i $(SAMPLES)/amrwb/deus-23k85.awb
+fate-amrwb-23k85-2: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/deus-23k85.awb
 fate-amrwb-23k85-2: REF = $(SAMPLES)/amrwb/deus-23k85.pcm
 
 $(FATE_AMRWB): CMP = stddev
diff --git a/tests/fate/atrac.mak b/tests/fate/atrac.mak
index 3ac5553..94dbe38 100644
--- a/tests/fate/atrac.mak
+++ b/tests/fate/atrac.mak
@@ -1,17 +1,17 @@
 FATE_ATRAC1-$(call DEMDEC, AEA, ATRAC1) += fate-atrac1
-fate-atrac1: CMD = pcm -i $(SAMPLES)/atrac1/test_tones_small.aea
+fate-atrac1: CMD = pcm -i $(TARGET_SAMPLES)/atrac1/test_tones_small.aea
 fate-atrac1: REF = $(SAMPLES)/atrac1/test_tones_small.pcm
 
 FATE_ATRAC3 += fate-atrac3-1
-fate-atrac3-1: CMD = pcm -i $(SAMPLES)/atrac3/mc_sich_at3_066_small.wav
+fate-atrac3-1: CMD = pcm -i $(TARGET_SAMPLES)/atrac3/mc_sich_at3_066_small.wav
 fate-atrac3-1: REF = $(SAMPLES)/atrac3/mc_sich_at3_066_small.pcm
 
 FATE_ATRAC3 += fate-atrac3-2
-fate-atrac3-2: CMD = pcm -i $(SAMPLES)/atrac3/mc_sich_at3_105_small.wav
+fate-atrac3-2: CMD = pcm -i $(TARGET_SAMPLES)/atrac3/mc_sich_at3_105_small.wav
 fate-atrac3-2: REF = $(SAMPLES)/atrac3/mc_sich_at3_105_small.pcm
 
 FATE_ATRAC3 += fate-atrac3-3
-fate-atrac3-3: CMD = pcm -i $(SAMPLES)/atrac3/mc_sich_at3_132_small.wav
+fate-atrac3-3: CMD = pcm -i $(TARGET_SAMPLES)/atrac3/mc_sich_at3_132_small.wav
 fate-atrac3-3: REF = $(SAMPLES)/atrac3/mc_sich_at3_132_small.pcm
 
 FATE_ATRAC3-$(call DEMDEC, WAV, ATRAC3) += $(FATE_ATRAC3)
diff --git a/tests/fate/audio.mak b/tests/fate/audio.mak
index 65bb146..6b5d1a9 100644
--- a/tests/fate/audio.mak
+++ b/tests/fate/audio.mak
@@ -1,10 +1,10 @@
 FATE_BINKAUDIO-$(call DEMDEC, BINK, BINKAUDIO_DCT) += fate-binkaudio-dct
-fate-binkaudio-dct: CMD = pcm -i $(SAMPLES)/bink/binkaudio_dct.bik
+fate-binkaudio-dct: CMD = pcm -i $(TARGET_SAMPLES)/bink/binkaudio_dct.bik
 fate-binkaudio-dct: REF = $(SAMPLES)/bink/binkaudio_dct.pcm
 fate-binkaudio-dct: FUZZ = 2
 
 FATE_BINKAUDIO-$(call DEMDEC, BINK, BINKAUDIO_RDFT) += fate-binkaudio-rdft
-fate-binkaudio-rdft: CMD = pcm -i $(SAMPLES)/bink/binkaudio_rdft.bik
+fate-binkaudio-rdft: CMD = pcm -i $(TARGET_SAMPLES)/bink/binkaudio_rdft.bik
 fate-binkaudio-rdft: REF = $(SAMPLES)/bink/binkaudio_rdft.pcm
 fate-binkaudio-rdft: FUZZ = 2
 
@@ -14,23 +14,23 @@
 fate-binkaudio: $(FATE_BINKAUDIO-yes)
 
 FATE_SAMPLES_AUDIO-$(call DEMDEC, BMV, BMV_AUDIO) += fate-bmv-audio
-fate-bmv-audio: CMD = framecrc -i $(SAMPLES)/bmv/SURFING-partial.BMV -vn
+fate-bmv-audio: CMD = framecrc -i $(TARGET_SAMPLES)/bmv/SURFING-partial.BMV -vn
 
 FATE_SAMPLES_AUDIO-$(call DEMDEC, DSICIN, DSICINAUDIO) += fate-delphine-cin-audio
-fate-delphine-cin-audio: CMD = framecrc -i $(SAMPLES)/delphine-cin/LOGO-partial.CIN -vn
+fate-delphine-cin-audio: CMD = framecrc -i $(TARGET_SAMPLES)/delphine-cin/LOGO-partial.CIN -vn
 
 FATE_SAMPLES_AUDIO-$(call DEMDEC, MPEGTS, DCA) += fate-dts
-fate-dts: CMD = pcm -i $(SAMPLES)/dts/dts.ts
+fate-dts: CMD = pcm -i $(TARGET_SAMPLES)/dts/dts.ts
 fate-dts: CMP = oneoff
 fate-dts: REF = $(SAMPLES)/dts/dts.pcm
 
 FATE_SAMPLES_AUDIO-$(call DEMDEC, AVI, IMC) += fate-imc
-fate-imc: CMD = pcm -i $(SAMPLES)/imc/imc.avi
+fate-imc: CMD = pcm -i $(TARGET_SAMPLES)/imc/imc.avi
 fate-imc: CMP = oneoff
 fate-imc: REF = $(SAMPLES)/imc/imc.pcm
 
 FATE_SAMPLES_AUDIO-$(call DEMDEC, FLV, NELLYMOSER) += fate-nellymoser
-fate-nellymoser: CMD = pcm -i $(SAMPLES)/nellymoser/nellymoser.flv
+fate-nellymoser: CMD = pcm -i $(TARGET_SAMPLES)/nellymoser/nellymoser.flv
 fate-nellymoser: CMP = oneoff
 fate-nellymoser: REF = $(SAMPLES)/nellymoser/nellymoser.pcm
 
@@ -44,19 +44,19 @@
 fate-nellymoser-aref-encode: SIZE_TOLERANCE = 268
 
 FATE_SAMPLES_AUDIO-$(call DEMDEC, PAF, PAF_AUDIO) += fate-paf-audio
-fate-paf-audio: CMD = framecrc -i $(SAMPLES)/paf/hod1-partial.paf -vn
+fate-paf-audio: CMD = framecrc -i $(TARGET_SAMPLES)/paf/hod1-partial.paf -vn
 
 FATE_SAMPLES_AUDIO-$(call DEMDEC, VMD, VMDAUDIO) += fate-sierra-vmd-audio
-fate-sierra-vmd-audio: CMD = framecrc -i $(SAMPLES)/vmd/12.vmd -vn
+fate-sierra-vmd-audio: CMD = framecrc -i $(TARGET_SAMPLES)/vmd/12.vmd -vn
 
 FATE_SAMPLES_AUDIO-$(call DEMDEC, SMACKER, SMACKAUD) += fate-smacker-audio
-fate-smacker-audio: CMD = framecrc -i $(SAMPLES)/smacker/wetlogo.smk -vn
+fate-smacker-audio: CMD = framecrc -i $(TARGET_SAMPLES)/smacker/wetlogo.smk -vn
 
 FATE_SAMPLES_AUDIO-$(call DEMDEC, SMUSH, VIMA) += fate-vima
-fate-vima: CMD = framecrc -i $(SAMPLES)/smush/ronin_part.znm -vn
+fate-vima: CMD = framecrc -i $(TARGET_SAMPLES)/smush/ronin_part.znm -vn
 
 FATE_SAMPLES_AUDIO-$(call DEMDEC, WSVQA, WS_SND1) += fate-ws_snd
-fate-ws_snd: CMD = md5 -i $(SAMPLES)/vqa/ws_snd.vqa -f s16le
+fate-ws_snd: CMD = md5 -i $(TARGET_SAMPLES)/vqa/ws_snd.vqa -f s16le
 
 FATE_SAMPLES_AUDIO += $(FATE_SAMPLES_AUDIO-yes)
 
diff --git a/tests/fate/avfilter.mak b/tests/fate/avfilter.mak
deleted file mode 100644
index d68757d..0000000
--- a/tests/fate/avfilter.mak
+++ /dev/null
@@ -1,66 +0,0 @@
-FATE_LAVFI = fate-lavfi-alphaextract_rgb                                \
-             fate-lavfi-alphaextract_yuv                                \
-             fate-lavfi-alphamerge_rgb                                  \
-             fate-lavfi-alphamerge_yuv                                  \
-             fate-lavfi-crop                                            \
-             fate-lavfi-crop_scale                                      \
-             fate-lavfi-crop_scale_vflip                                \
-             fate-lavfi-crop_vflip                                      \
-             fate-lavfi-drawbox                                         \
-             fate-lavfi-edgedetect                                      \
-             fate-lavfi-fade                                            \
-             fate-lavfi-field                                           \
-             fate-lavfi-idet                                            \
-             fate-lavfi-il                                              \
-             fate-lavfi-null                                            \
-             fate-lavfi-overlay_rgb                                     \
-             fate-lavfi-overlay_yuv420                                  \
-             fate-lavfi-overlay_yuv444                                  \
-             fate-lavfi-pad                                             \
-             fate-lavfi-pixfmts_copy                                    \
-             fate-lavfi-pixfmts_crop                                    \
-             fate-lavfi-pixfmts_hflip                                   \
-             fate-lavfi-pixfmts_null                                    \
-             fate-lavfi-pixfmts_pad                                     \
-             fate-lavfi-pixfmts_pixdesctest                             \
-             fate-lavfi-pixfmts_scale                                   \
-             fate-lavfi-pixfmts_vflip                                   \
-             fate-lavfi-scale200                                        \
-             fate-lavfi-scale500                                        \
-             fate-lavfi-select                                          \
-             fate-lavfi-setdar                                          \
-             fate-lavfi-setsar                                          \
-             fate-lavfi-thumbnail                                       \
-             fate-lavfi-tile                                            \
-             fate-lavfi-transpose                                       \
-             fate-lavfi-unsharp                                         \
-             fate-lavfi-vflip                                           \
-             fate-lavfi-vflip_crop                                      \
-             fate-lavfi-vflip_vflip                                     \
-
-FATE_LAVFI-$(CONFIG_AVDEVICE) += fate-lavfi-life                        \
-                                 fate-lavfi-scalenorm                   \
-                                 fate-lavfi-testsrc                     \
-
-FATE_LAVFI-$(CONFIG_GPL) += fate-lavfi-colormatrix1                     \
-                            fate-lavfi-colormatrix2                     \
-                            fate-lavfi-hue                              \
-                            fate-lavfi-kerndeint                        \
-                            fate-lavfi-pixfmts_super2xsai               \
-                            fate-lavfi-pp                               \
-                            fate-lavfi-pp2                              \
-                            fate-lavfi-pp3                              \
-                            fate-lavfi-pp4                              \
-                            fate-lavfi-pp5                              \
-                            fate-lavfi-pp6                              \
-                            fate-lavfi-tinterlace_merge                 \
-                            fate-lavfi-tinterlace_pad                   \
-
-FATE_LAVFI += $(FATE_LAVFI-yes)
-
-$(FATE_LAVFI): $(VREF) libavfilter/filtfmts-test$(EXESUF)
-$(FATE_LAVFI): CMD = lavfitest
-
-FATE_AVCONV += $(FATE_LAVFI)
-fate-lavfi:    $(FATE_LAVFI)
-
diff --git a/tests/fate/bmp.mak b/tests/fate/bmp.mak
index 9e52ac0..923c70d 100644
--- a/tests/fate/bmp.mak
+++ b/tests/fate/bmp.mak
@@ -1,41 +1,41 @@
 FATE_BMP += fate-bmp-1bit
-fate-bmp-1bit: CMD = framecrc -i $(SAMPLES)/bmp/test1.bmp -pix_fmt rgb24
+fate-bmp-1bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test1.bmp -pix_fmt rgb24
 
 FATE_BMP += fate-bmp-4bit
-fate-bmp-4bit: CMD = framecrc -i $(SAMPLES)/bmp/test4.bmp -pix_fmt rgb24
+fate-bmp-4bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test4.bmp -pix_fmt rgb24
 
 FATE_BMP += fate-bmp-4bit-os2
-fate-bmp-4bit-os2: CMD = framecrc -i $(SAMPLES)/bmp/test4os2v2.bmp -pix_fmt rgb24
+fate-bmp-4bit-os2: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test4os2v2.bmp -pix_fmt rgb24
 
 FATE_BMP += fate-bmp-8bit
-fate-bmp-8bit: CMD = framecrc -i $(SAMPLES)/bmp/test8.bmp -pix_fmt rgb24
+fate-bmp-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test8.bmp -pix_fmt rgb24
 
 FATE_BMP += fate-bmp-8bit-os2
-fate-bmp-8bit-os2: CMD = framecrc -i $(SAMPLES)/bmp/test8os2.bmp -pix_fmt rgb24
+fate-bmp-8bit-os2: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test8os2.bmp -pix_fmt rgb24
 
 FATE_BMP += fate-bmp-15bit
-fate-bmp-15bit: CMD = framecrc -i $(SAMPLES)/bmp/test16.bmp -pix_fmt rgb555le
+fate-bmp-15bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test16.bmp -pix_fmt rgb555le
 
 FATE_BMP += fate-bmp-15bit-mask
-fate-bmp-15bit-mask: CMD = framecrc -i $(SAMPLES)/bmp/test16bf555.bmp -pix_fmt rgb555le
+fate-bmp-15bit-mask: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test16bf555.bmp -pix_fmt rgb555le
 
 FATE_BMP += fate-bmp-16bit-mask
-fate-bmp-16bit-mask: CMD = framecrc -i $(SAMPLES)/bmp/test16bf565.bmp -pix_fmt rgb565le
+fate-bmp-16bit-mask: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test16bf565.bmp -pix_fmt rgb565le
 
 FATE_BMP += fate-bmp-24bit
-fate-bmp-24bit: CMD = framecrc -i $(SAMPLES)/bmp/test24.bmp
+fate-bmp-24bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test24.bmp
 
 FATE_BMP += fate-bmp-32bit
-fate-bmp-32bit: CMD = framecrc -i $(SAMPLES)/bmp/test32.bmp -pix_fmt bgr24
+fate-bmp-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test32.bmp -pix_fmt bgr24
 
 FATE_BMP += fate-bmp-32bit-mask
-fate-bmp-32bit-mask: CMD = framecrc -i $(SAMPLES)/bmp/test32bf.bmp -pix_fmt bgr24
+fate-bmp-32bit-mask: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test32bf.bmp -pix_fmt bgr24
 
 FATE_BMP += fate-bmp-rle4
-fate-bmp-rle4: CMD = framecrc -i $(SAMPLES)/bmp/testcompress4.bmp -pix_fmt rgb24
+fate-bmp-rle4: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/testcompress4.bmp -pix_fmt rgb24
 
 FATE_BMP += fate-bmp-rle8
-fate-bmp-rle8: CMD = framecrc -i $(SAMPLES)/bmp/testcompress8.bmp -pix_fmt rgb24
+fate-bmp-rle8: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/testcompress8.bmp -pix_fmt rgb24
 
 FATE_BMP-$(call DEMDEC, IMAGE2, BMP) += $(FATE_BMP)
 
diff --git a/tests/fate/cdxl.mak b/tests/fate/cdxl.mak
index 11ff902..8144f96 100644
--- a/tests/fate/cdxl.mak
+++ b/tests/fate/cdxl.mak
@@ -1,17 +1,17 @@
 FATE_CDXL += fate-cdxl-bitline-ham6
-fate-cdxl-bitline-ham6: CMD = framecrc -i $(SAMPLES)/cdxl/bitline.cdxl -frames:v 10
+fate-cdxl-bitline-ham6: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/bitline.cdxl -frames:v 10
 
 FATE_CDXL += fate-cdxl-ham6
-fate-cdxl-ham6: CMD = framecrc -i $(SAMPLES)/cdxl/cat.cdxl -an -frames:v 16
+fate-cdxl-ham6: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/cat.cdxl -an -frames:v 16
 
 FATE_CDXL += fate-cdxl-ham8
-fate-cdxl-ham8: CMD = framecrc -i $(SAMPLES)/cdxl/mirage.cdxl -an -frames:v 1
+fate-cdxl-ham8: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/mirage.cdxl -an -frames:v 1
 
 FATE_CDXL += fate-cdxl-pal8
-fate-cdxl-pal8: CMD = framecrc -i $(SAMPLES)/cdxl/maku.cdxl -pix_fmt rgb24 -frames:v 11
+fate-cdxl-pal8: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/maku.cdxl -pix_fmt rgb24 -frames:v 11
 
 FATE_CDXL += fate-cdxl-pal8-small
-fate-cdxl-pal8-small: CMD = framecrc -i $(SAMPLES)/cdxl/fruit.cdxl -an -pix_fmt rgb24 -frames:v 46
+fate-cdxl-pal8-small: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/fruit.cdxl -an -pix_fmt rgb24 -frames:v 46
 
 FATE_CDXL-$(call DEMDEC, CDXL, CDXL) += $(FATE_CDXL)
 
diff --git a/tests/fate/cover-art.mak b/tests/fate/cover-art.mak
index b175c3e..9d748ee 100644
--- a/tests/fate/cover-art.mak
+++ b/tests/fate/cover-art.mak
@@ -1,31 +1,35 @@
 FATE_COVER_ART-$(CONFIG_APE_DEMUXER) += fate-cover-art-ape
-fate-cover-art-ape: CMD = md5 -i $(SAMPLES)/cover_art/luckynight_cover.ape -an -c:v copy -f rawvideo
+fate-cover-art-ape: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/luckynight_cover.ape -an -c:v copy -f rawvideo
 fate-cover-art-ape: REF = 45333c983c45af54449dff10af144317
 
 FATE_COVER_ART-$(CONFIG_FLAC_DEMUXER) += fate-cover-art-flac
-fate-cover-art-flac: CMD = md5 -i $(SAMPLES)/cover_art/cover_art.flac -an -c:v copy -f rawvideo
+fate-cover-art-flac: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/cover_art.flac -an -c:v copy -f rawvideo
 fate-cover-art-flac: REF = 0de1fc6200596fa32b8f7300a14c0261
 
 FATE_COVER_ART-$(CONFIG_MOV_DEMUXER) += fate-cover-art-m4a
-fate-cover-art-m4a: CMD = md5 -i $(SAMPLES)/cover_art/Owner-iTunes_9.0.3.15.m4a -an -c:v copy -f rawvideo
+fate-cover-art-m4a: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/Owner-iTunes_9.0.3.15.m4a -an -c:v copy -f rawvideo
 fate-cover-art-m4a: REF = 08ba70a3b594ff6345a93965e96a9d3e
 
 FATE_COVER_ART-$(CONFIG_ASF_DEMUXER) += fate-cover-art-wma
-fate-cover-art-wma: CMD = md5 -i $(SAMPLES)/cover_art/Californication_cover.wma -an -c:v copy -f rawvideo
+fate-cover-art-wma: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/Californication_cover.wma -an -c:v copy -f rawvideo
 fate-cover-art-wma: REF = 0808bd0e1b61542a16e1906812dd924b
 
 FATE_COVER_ART-$(CONFIG_ASF_DEMUXER) += fate-cover-art-wma-id3
-fate-cover-art-wma-id3: CMD = md5 -i $(SAMPLES)/cover_art/wma_with_ID3_APIC_trimmed.wma -an -c:v copy -f rawvideo
+fate-cover-art-wma-id3: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/wma_with_ID3_APIC_trimmed.wma -an -c:v copy -f rawvideo
 fate-cover-art-wma-id3: REF = e6a8dd03687d5178bc13fc7d3316696e
 
 FATE_COVER_ART-$(CONFIG_ASF_DEMUXER) += fate-cover-art-wma-metadatalib
-fate-cover-art-wma-metadatalib: CMD = md5 -i $(SAMPLES)/cover_art/wma_with_metadata_library_object_tag_trimmed.wma -map 0:v -c:v copy -f rawvideo
+fate-cover-art-wma-metadatalib: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/wma_with_metadata_library_object_tag_trimmed.wma -map 0:v -c:v copy -f rawvideo
 fate-cover-art-wma-metadatalib: REF = 32e8bd4fad546f63d881a0256f083aea
 
 FATE_COVER_ART-$(CONFIG_WV_DEMUXER) += fate-cover-art-wv
-fate-cover-art-wv: CMD = md5 -i $(SAMPLES)/cover_art/luckynight_cover.wv -an -c:v copy -f rawvideo
+fate-cover-art-wv: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/luckynight_cover.wv -an -c:v copy -f rawvideo
 fate-cover-art-wv: REF = 45333c983c45af54449dff10af144317
 
+FATE_COVER_ART-$(CONFIG_OGG_DEMUXER) += fate-cover-art-ogg
+fate-cover-art-ogg: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/ogg_vorbiscomment_cover.opus -map 0:v -c:v copy -f rawvideo
+fate-cover-art-ogg: REF = 7f117e073620eabb4ed02680cf70af41
+
 FATE_COVER_ART = $(FATE_COVER_ART-yes)
 
 $(FATE_COVER_ART): CMP = oneline
diff --git a/tests/fate/demux.mak b/tests/fate/demux.mak
index 3b5f954..743274d 100644
--- a/tests/fate/demux.mak
+++ b/tests/fate/demux.mak
@@ -1,98 +1,107 @@
 FATE_SAMPLES_DEMUX-$(call DEMDEC, AVI, FRAPS) += fate-avio-direct
-fate-avio-direct: CMD = framecrc -avioflags direct -i $(SAMPLES)/fraps/fraps-v5-bouncing-balls-partial.avi -avioflags direct
+fate-avio-direct: CMD = framecrc -avioflags direct -i $(TARGET_SAMPLES)/fraps/fraps-v5-bouncing-balls-partial.avi -avioflags direct
 
 FATE_SAMPLES_DEMUX-$(CONFIG_AAC_DEMUXER) += fate-adts-demux
-fate-adts-demux: CMD = crc -i $(SAMPLES)/aac/ct_faac-adts.aac -acodec copy
+fate-adts-demux: CMD = crc -i $(TARGET_SAMPLES)/aac/ct_faac-adts.aac -acodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_AEA_DEMUXER) += fate-aea-demux
-fate-aea-demux: CMD = crc -i $(SAMPLES)/aea/chirp.aea -acodec copy
+fate-aea-demux: CMD = crc -i $(TARGET_SAMPLES)/aea/chirp.aea -acodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_AST_DEMUXER) += fate-ast
-fate-ast: CMD = crc -i $(SAMPLES)/ast/demo11_02_partial.ast -c copy
+fate-ast: CMD = crc -i $(TARGET_SAMPLES)/ast/demo11_02_partial.ast -c copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_BINK_DEMUXER) += fate-bink-demux
-fate-bink-demux: CMD = crc -i $(SAMPLES)/bink/Snd0a7d9b58.dee -vn -acodec copy
+fate-bink-demux: CMD = crc -i $(TARGET_SAMPLES)/bink/Snd0a7d9b58.dee -vn -acodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_BRSTM_DEMUXER) += fate-brstm
-fate-brstm: CMD = crc -i $(SAMPLES)/brstm/lozswd_partial.brstm -acodec copy
+fate-brstm: CMD = crc -i $(TARGET_SAMPLES)/brstm/lozswd_partial.brstm -acodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_CAF_DEMUXER) += fate-caf
-fate-caf: CMD = crc -i $(SAMPLES)/caf/caf-pcm16.caf -c copy
+fate-caf: CMD = crc -i $(TARGET_SAMPLES)/caf/caf-pcm16.caf -c copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_CDXL_DEMUXER) += fate-cdxl-demux
-fate-cdxl-demux: CMD = framecrc -i $(SAMPLES)/cdxl/mirage.cdxl -vcodec copy -acodec copy
+fate-cdxl-demux: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/mirage.cdxl -vcodec copy -acodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_DAUD_DEMUXER) += fate-d-cinema-demux
-fate-d-cinema-demux: CMD = framecrc -i $(SAMPLES)/d-cinema/THX_Science_FLT_1920-partial.302 -acodec copy
+fate-d-cinema-demux: CMD = framecrc -i $(TARGET_SAMPLES)/d-cinema/THX_Science_FLT_1920-partial.302 -acodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_GIF_DEMUXER) += fate-gif-demux
-fate-gif-demux: CMD = framecrc -i $(SAMPLES)/gif/Newtons_cradle_animation_book_2.gif -vcodec copy
+fate-gif-demux: CMD = framecrc -i $(TARGET_SAMPLES)/gif/Newtons_cradle_animation_book_2.gif -vcodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_IV8_DEMUXER) += fate-iv8-demux
-fate-iv8-demux: CMD = framecrc -i $(SAMPLES)/iv8/zzz-partial.mpg -vcodec copy
+fate-iv8-demux: CMD = framecrc -i $(TARGET_SAMPLES)/iv8/zzz-partial.mpg -vcodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_JV_DEMUXER) += fate-jv-demux
-fate-jv-demux: CMD = framecrc -i $(SAMPLES)/jv/intro.jv -vcodec copy -acodec copy
+fate-jv-demux: CMD = framecrc -i $(TARGET_SAMPLES)/jv/intro.jv -vcodec copy -acodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_LMLM4_DEMUXER) += fate-lmlm4-demux
-fate-lmlm4-demux: CMD = framecrc -i $(SAMPLES)/lmlm4/LMLM4_CIFat30fps.divx -t 3 -acodec copy -vcodec copy
+fate-lmlm4-demux: CMD = framecrc -i $(TARGET_SAMPLES)/lmlm4/LMLM4_CIFat30fps.divx -t 3 -acodec copy -vcodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_XA_DEMUXER) += fate-maxis-xa
-fate-maxis-xa: CMD = framecrc -i $(SAMPLES)/maxis-xa/SC2KBUG.XA -frames:a 30 -c:a copy
+fate-maxis-xa: CMD = framecrc -i $(TARGET_SAMPLES)/maxis-xa/SC2KBUG.XA -frames:a 30 -c:a copy
+
+FATE_SAMPLES_DEMUX-$(CONFIG_MATROSKA_DEMUXER) += fate-mkv
+fate-mkv: CMD = framecrc -i $(TARGET_SAMPLES)/mkv/test7_cut.mkv -c copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_MTV_DEMUXER) += fate-mtv
-fate-mtv: CMD = framecrc -i $(SAMPLES)/mtv/comedian_auto-partial.mtv -c copy
+fate-mtv: CMD = framecrc -i $(TARGET_SAMPLES)/mtv/comedian_auto-partial.mtv -c copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_MXF_DEMUXER) += fate-mxf-demux
-fate-mxf-demux: CMD = framecrc -i $(SAMPLES)/mxf/C0023S01.mxf -acodec copy -vcodec copy
+fate-mxf-demux: CMD = framecrc -i $(TARGET_SAMPLES)/mxf/C0023S01.mxf -acodec copy -vcodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_NC_DEMUXER) += fate-nc-demux
-fate-nc-demux: CMD = framecrc -i $(SAMPLES)/nc-camera/nc-sample-partial -vcodec copy
+fate-nc-demux: CMD = framecrc -i $(TARGET_SAMPLES)/nc-camera/nc-sample-partial -vcodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_NISTSPHERE_DEMUXER) += fate-nistsphere-demux
-fate-nistsphere-demux: CMD = crc -i $(SAMPLES)/nistsphere/nist-ulaw.nist -acodec copy
+fate-nistsphere-demux: CMD = crc -i $(TARGET_SAMPLES)/nistsphere/nist-ulaw.nist -acodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_NSV_DEMUXER) += fate-nsv-demux
-fate-nsv-demux: CMD = framecrc -i $(SAMPLES)/nsv/witchblade-51kbps.nsv -t 6 -vcodec copy -acodec copy
+fate-nsv-demux: CMD = framecrc -i $(TARGET_SAMPLES)/nsv/witchblade-51kbps.nsv -t 6 -vcodec copy -acodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_OMA_DEMUXER) += fate-oma-demux
-fate-oma-demux: CMD = crc -i $(SAMPLES)/oma/01-Untitled-partial.oma -acodec copy
+fate-oma-demux: CMD = crc -i $(TARGET_SAMPLES)/oma/01-Untitled-partial.oma -acodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_PAF_DEMUXER) += fate-paf-demux
-fate-paf-demux: CMD = framecrc -i $(SAMPLES)/paf/hod1-partial.paf -vcodec copy -acodec copy
+fate-paf-demux: CMD = framecrc -i $(TARGET_SAMPLES)/paf/hod1-partial.paf -vcodec copy -acodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_PMP_DEMUXER) += fate-pmp-demux
-fate-pmp-demux: CMD = framecrc -i $(SAMPLES)/pmp/demo.pmp -vn -c:a copy
+fate-pmp-demux: CMD = framecrc -i $(TARGET_SAMPLES)/pmp/demo.pmp -vn -c:a copy
+
+FATE_SAMPLES_DEMUX-$(CONFIG_RSD_DEMUXER) += fate-rsd-demux
+fate-rsd-demux: CMD = crc -i $(TARGET_SAMPLES)/rsd/hum01_partial.rsd -c:a copy
+
+FATE_SAMPLES_DEMUX-$(CONFIG_REDSPARK_DEMUXER) += fate-redspark-demux
+fate-redspark-demux: CMD = crc -i $(TARGET_SAMPLES)/redspark/jingle04_partial.rsd -c:a copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_STR_DEMUXER) += fate-psx-str-demux
-fate-psx-str-demux: CMD = framecrc -i $(SAMPLES)/psx-str/descent-partial.str -c copy
+fate-psx-str-demux: CMD = framecrc -i $(TARGET_SAMPLES)/psx-str/descent-partial.str -c copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_PVA_DEMUXER) += fate-pva-demux
-fate-pva-demux: CMD = framecrc -idct simple -i $(SAMPLES)/pva/PVA_test-partial.pva -t 0.6 -acodec copy
+fate-pva-demux: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/pva/PVA_test-partial.pva -t 0.6 -acodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_QCP_DEMUXER) += fate-qcp-demux
-fate-qcp-demux: CMD = crc -i $(SAMPLES)/qcp/0036580847.QCP -acodec copy
+fate-qcp-demux: CMD = crc -i $(TARGET_SAMPLES)/qcp/0036580847.QCP -acodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_R3D_DEMUXER) += fate-redcode-demux
-fate-redcode-demux: CMD = framecrc -i $(SAMPLES)/r3d/4MB-sample.r3d -vcodec copy -acodec copy
+fate-redcode-demux: CMD = framecrc -i $(TARGET_SAMPLES)/r3d/4MB-sample.r3d -vcodec copy -acodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_SIFF_DEMUXER) += fate-siff-demux
-fate-siff-demux: CMD = framecrc -i $(SAMPLES)/SIFF/INTRO_B.VB -c copy
+fate-siff-demux: CMD = framecrc -i $(TARGET_SAMPLES)/SIFF/INTRO_B.VB -c copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_SMJPEG_DEMUXER) += fate-smjpeg-demux
-fate-smjpeg-demux: CMD = framecrc -i $(SAMPLES)/smjpeg/scenwin.mjpg -c copy
+fate-smjpeg-demux: CMD = framecrc -i $(TARGET_SAMPLES)/smjpeg/scenwin.mjpg -c copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_WSAUD_DEMUXER) += fate-westwood-aud
-fate-westwood-aud: CMD = framecrc -i $(SAMPLES)/westwood-aud/excellent.aud -c copy
+fate-westwood-aud: CMD = framecrc -i $(TARGET_SAMPLES)/westwood-aud/excellent.aud -c copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_WTV_DEMUXER) += fate-wtv-demux
-fate-wtv-demux: CMD = framecrc -i $(SAMPLES)/wtv/law-and-order-partial.wtv -vcodec copy -acodec copy
+fate-wtv-demux: CMD = framecrc -i $(TARGET_SAMPLES)/wtv/law-and-order-partial.wtv -vcodec copy -acodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_XMV_DEMUXER) += fate-xmv-demux
-fate-xmv-demux: CMD = framecrc -i $(SAMPLES)/xmv/logos1p.fmv -vcodec copy -acodec copy
+fate-xmv-demux: CMD = framecrc -i $(TARGET_SAMPLES)/xmv/logos1p.fmv -vcodec copy -acodec copy
 
 FATE_SAMPLES_DEMUX-$(CONFIG_XWMA_DEMUXER) += fate-xwma-demux
-fate-xwma-demux: CMD = crc -i $(SAMPLES)/xwma/ergon.xwma -acodec copy
+fate-xwma-demux: CMD = crc -i $(TARGET_SAMPLES)/xwma/ergon.xwma -acodec copy
 
 FATE_SAMPLES_DEMUX += $(FATE_SAMPLES_DEMUX-yes)
 FATE_SAMPLES_FFMPEG += $(FATE_SAMPLES_DEMUX)
diff --git a/tests/fate/dfa.mak b/tests/fate/dfa.mak
index 4800d8a..f4b6057 100644
--- a/tests/fate/dfa.mak
+++ b/tests/fate/dfa.mak
@@ -1,35 +1,35 @@
 FATE_DFA += fate-dfa1
-fate-dfa1: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0000.dfa -pix_fmt rgb24
+fate-dfa1: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0000.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa2
-fate-dfa2: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0001.dfa -pix_fmt rgb24
+fate-dfa2: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0001.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa3
-fate-dfa3: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0002.dfa -pix_fmt rgb24
+fate-dfa3: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0002.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa4
-fate-dfa4: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0003.dfa -pix_fmt rgb24
+fate-dfa4: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0003.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa5
-fate-dfa5: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0004.dfa -pix_fmt rgb24
+fate-dfa5: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0004.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa6
-fate-dfa6: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0005.dfa -pix_fmt rgb24
+fate-dfa6: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0005.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa7
-fate-dfa7: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0006.dfa -pix_fmt rgb24
+fate-dfa7: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0006.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa8
-fate-dfa8: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0007.dfa -pix_fmt rgb24
+fate-dfa8: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0007.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa9
-fate-dfa9: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0008.dfa -pix_fmt rgb24
+fate-dfa9: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0008.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa10
-fate-dfa10: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0009.dfa -pix_fmt rgb24
+fate-dfa10: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0009.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa11
-fate-dfa11: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0010.dfa -pix_fmt rgb24
+fate-dfa11: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0010.dfa -pix_fmt rgb24
 
 FATE_DFA-$(call DEMDEC, DFA, DFA) += $(FATE_DFA)
 
diff --git a/tests/fate/dpcm.mak b/tests/fate/dpcm.mak
index abc25ed..dd27246 100644
--- a/tests/fate/dpcm.mak
+++ b/tests/fate/dpcm.mak
@@ -1,14 +1,14 @@
 FATE_DPCM-$(call DEMDEC, ROQ, ROQ_DPCM) += fate-dpcm-idroq
-fate-dpcm-idroq: CMD = framecrc -i $(SAMPLES)/idroq/idlogo.roq -vn
+fate-dpcm-idroq: CMD = framecrc -i $(TARGET_SAMPLES)/idroq/idlogo.roq -vn
 
 FATE_DPCM-$(call DEMDEC, IPMOVIE, INTERPLAY_DPCM) += fate-dpcm-interplay
-fate-dpcm-interplay: CMD = framecrc -i $(SAMPLES)/interplay-mve/interplay-logo-2MB.mve -vn
+fate-dpcm-interplay: CMD = framecrc -i $(TARGET_SAMPLES)/interplay-mve/interplay-logo-2MB.mve -vn
 
 FATE_DPCM-$(call DEMDEC, SOL, SOL_DPCM) += fate-dpcm-sierra
-fate-dpcm-sierra: CMD = md5 -i $(SAMPLES)/sol/lsl7sample.sol -f s16le
+fate-dpcm-sierra: CMD = md5 -i $(TARGET_SAMPLES)/sol/lsl7sample.sol -f s16le
 
 FATE_DPCM-$(call DEMDEC, AVI, XAN_DPCM) += fate-dpcm-xan
-fate-dpcm-xan: CMD = md5 -i $(SAMPLES)/wc4-xan/wc4_2.avi -vn -f s16le
+fate-dpcm-xan: CMD = md5 -i $(TARGET_SAMPLES)/wc4-xan/wc4_2.avi -vn -f s16le
 
 FATE_SAMPLES_AVCONV += $(FATE_DPCM-yes)
 fate-dpcm: $(FATE_DPCM-yes)
diff --git a/tests/fate/ea.mak b/tests/fate/ea.mak
index 81e14b8..9de671c 100644
--- a/tests/fate/ea.mak
+++ b/tests/fate/ea.mak
@@ -1,26 +1,26 @@
 FATE_SAMPLES_EA-$(call DEMDEC, EA_CDATA, ADPCM_EA_XAS) += fate-ea-cdata
-fate-ea-cdata: CMD = md5 -i $(SAMPLES)/ea-cdata/166b084d.46410f77.0009b440.24be960c.cdata -f s16le
+fate-ea-cdata: CMD = md5 -i $(TARGET_SAMPLES)/ea-cdata/166b084d.46410f77.0009b440.24be960c.cdata -f s16le
 
 FATE_SAMPLES_EA-$(call DEMDEC, EA, EACMV) += fate-ea-cmv
-fate-ea-cmv: CMD = framecrc -i $(SAMPLES)/ea-cmv/TITLE.CMV -pix_fmt rgb24
+fate-ea-cmv: CMD = framecrc -i $(TARGET_SAMPLES)/ea-cmv/TITLE.CMV -pix_fmt rgb24
 
 FATE_SAMPLES_EA-$(call DEMDEC, EA, EAMAD) += fate-ea-mad
-fate-ea-mad: CMD = framecrc -i $(SAMPLES)/ea-mad/NFS6LogoE.mad -an
+fate-ea-mad: CMD = framecrc -i $(TARGET_SAMPLES)/ea-mad/NFS6LogoE.mad -an
 
 FATE_SAMPLES_EA-$(call DEMDEC, EA, EATGQ) += fate-ea-tgq
-fate-ea-tgq: CMD = framecrc -i $(SAMPLES)/ea-tgq/v27.tgq -an
+fate-ea-tgq: CMD = framecrc -i $(TARGET_SAMPLES)/ea-tgq/v27.tgq -an
 
 FATE_EA_TGV += fate-ea-tgv-1
-fate-ea-tgv-1: CMD = framecrc -i $(SAMPLES)/ea-tgv/INTRO8K-partial.TGV -pix_fmt rgb24 -an
+fate-ea-tgv-1: CMD = framecrc -i $(TARGET_SAMPLES)/ea-tgv/INTRO8K-partial.TGV -pix_fmt rgb24 -an
 
 FATE_EA_TGV += fate-ea-tgv-2
-fate-ea-tgv-2: CMD = framecrc -i $(SAMPLES)/ea-tgv/INTEL_S.TGV -pix_fmt rgb24 -an
+fate-ea-tgv-2: CMD = framecrc -i $(TARGET_SAMPLES)/ea-tgv/INTEL_S.TGV -pix_fmt rgb24 -an
 
 FATE_SAMPLES_EA-$(call DEMDEC, EA, EATGV) += $(FATE_EA_TGV)
 fate-ea-tgv: $(FATE_EA_TGV)
 
 FATE_SAMPLES_EA-$(call DEMDEC, EA, EATQI) += fate-ea-tqi
-fate-ea-tqi: CMD = framecrc -i $(SAMPLES)/ea-wve/networkBackbone-partial.wve -frames:v 26 -an
+fate-ea-tqi: CMD = framecrc -i $(TARGET_SAMPLES)/ea-wve/networkBackbone-partial.wve -frames:v 26 -an
 
 FATE_SAMPLES_FFMPEG += $(FATE_SAMPLES_EA-yes)
 fate-ea: $(FATE_SAMPLES_EA-yes)
diff --git a/tests/fate/exif.mak b/tests/fate/exif.mak
new file mode 100644
index 0000000..3953b62
--- /dev/null
+++ b/tests/fate/exif.mak
@@ -0,0 +1,14 @@
+# test exif metadata in TIFF images
+FATE_SAMPLES_EXIF-$(call DEMDEC, IMAGE2, TIFF) += fate-exif-image-tiff
+fate-exif-image-tiff: CMD = probeframes $(TARGET_SAMPLES)/exif/image_small.tiff
+
+# test exif metadata in JPG images
+FATE_SAMPLES_EXIF-$(call DEMDEC, IMAGE2, MJPEG) += fate-exif-image-jpg
+fate-exif-image-jpg: CMD = probeframes $(TARGET_SAMPLES)/exif/image_small.jpg
+
+# test exif metadata in MP3 with embedded JPEG images
+FATE_SAMPLES_EXIF-$(call ALLYES, MP3_DEMUXER IMAGE2_DEMUXER MJPEG_DECODER) += fate-exif-image-embedded
+fate-exif-image-embedded: CMD = probeframes $(TARGET_SAMPLES)/exif/embedded_small.mp3
+
+# add all -yes targets to the tested targets
+FATE_SAMPLES_FFMPEG += $(FATE_SAMPLES_EXIF-yes)
diff --git a/tests/fate/fft.mak b/tests/fate/fft.mak
index 20d5638..2413415 100644
--- a/tests/fate/fft.mak
+++ b/tests/fate/fft.mak
@@ -38,5 +38,22 @@
 $(FATE_FFT_FIXED): CMD = run libavcodec/fft-fixed-test $(CPUFLAGS:%=-c%) $(ARGS)
 $(FATE_FFT_FIXED): REF = /dev/null
 
-FATE-$(call ALLYES, AVCODEC FFT) += $(FATE_FFT) $(FATE_FFT_FIXED)
-fate-fft: $(FATE_FFT) $(FATE_FFT_FIXED)
+define DEF_FFT_FIXED32
+FATE_FFT_FIXED32 += fate-fft-fixed32-$(1)   fate-ifft-fixed32-$(1)  \
+                  fate-mdct-fixed32-$(1) fate-imdct-fixed32-$(1)
+
+fate-fft-fixed32-$(1):   ARGS = -n$(1)
+fate-ifft-fixed32-$(1):  ARGS = -n$(1) -i
+#fate-mdct-fixed32-$(1):  ARGS = -n$(1) -m
+fate-imdct-fixed32-$(1): ARGS = -n$(1) -m -i
+endef
+
+$(foreach N, 4 5 6 7 8 9 10 11 12, $(eval $(call DEF_FFT_FIXED32,$(N))))
+
+fate-fft-fixed32-test: $(FATE_FFT_FIXED32)
+$(FATE_FFT_FIXED32): libavcodec/fft-fixed32-test$(EXESUF)
+$(FATE_FFT_FIXED32): CMD = run libavcodec/fft-fixed32-test $(CPUFLAGS:%=-c%) $(ARGS)
+$(FATE_FFT_FIXED32): REF = /dev/null
+
+FATE-$(call ALLYES, AVCODEC FFT) += $(FATE_FFT) $(FATE_FFT_FIXED) $(FATE_FFT_FIXED32)
+fate-fft: $(FATE_FFT) $(FATE_FFT_FIXED) $(FATE_FFT_FIXED32)
diff --git a/tests/fate/filter-audio.mak b/tests/fate/filter-audio.mak
index 6eaa4bf..a76d3a4 100644
--- a/tests/fate/filter-audio.mak
+++ b/tests/fate/filter-audio.mak
@@ -20,21 +20,38 @@
 $(FATE_AMIX): CMP_UNIT = f32
 
 FATE_AFILTER-$(call FILTERDEMDECMUX, ASYNCTS, FLV, NELLYMOSER, PCM_S16LE) += fate-filter-asyncts
-fate-filter-asyncts: SRC = $(SAMPLES)/nellymoser/nellymoser-discont.flv
+fate-filter-asyncts: SRC = $(TARGET_SAMPLES)/nellymoser/nellymoser-discont.flv
 fate-filter-asyncts: CMD = pcm -analyzeduration 10000000 -i $(SRC) -af asyncts
 fate-filter-asyncts: CMP = oneoff
-fate-filter-asyncts: REF = $(SAMPLES)/nellymoser/nellymoser-discont-async-v2.pcm
+fate-filter-asyncts: REF = $(SAMPLES)/nellymoser/nellymoser-discont-async-v3.pcm
 
 FATE_FILTER-$(CONFIG_ARESAMPLE_FILTER) += fate-filter-aresample
 fate-filter-aresample: SRC = $(SAMPLES)/nellymoser/nellymoser-discont.flv
-fate-filter-aresample: CMD = pcm -i $(SRC) -af aresample=min_comp=0.001:min_hard_comp=0.1:first_pts=0
+fate-filter-aresample: CMD = pcm -analyzeduration 10000000 -i $(SRC) -af aresample=min_comp=0.001:min_hard_comp=0.1:first_pts=0
 fate-filter-aresample: CMP = oneoff
 fate-filter-aresample: REF = $(SAMPLES)/nellymoser/nellymoser-discont.pcm
 
+FATE_ATRIM += fate-filter-atrim-duration
+fate-filter-atrim-duration: CMD = framecrc -i $(SRC) -af atrim=start=0.1:duration=0.01
+FATE_ATRIM += fate-filter-atrim-mixed
+fate-filter-atrim-mixed: CMD = framecrc -i $(SRC) -af atrim=start=0.05:start_sample=1025:end=0.1:end_sample=4411
+
+FATE_ATRIM += fate-filter-atrim-samples
+fate-filter-atrim-samples: CMD = framecrc -i $(SRC) -af atrim=start_sample=26:end_sample=80
+
+FATE_ATRIM += fate-filter-atrim-time
+fate-filter-atrim-time: CMD = framecrc -i $(SRC) -af atrim=0.1:0.2
+
+$(FATE_ATRIM): tests/data/asynth-44100-2.wav
+$(FATE_ATRIM): SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav
+
+FATE_FILTER-$(call FILTERDEMDECENCMUX, ATRIM, WAV, PCM_S16LE, PCM_S16LE, WAV) += $(FATE_ATRIM)
+
 FATE_AFILTER-$(call FILTERDEMDECENCMUX, CHANNELMAP, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-channelmap
+fate-filter-channelmap: tests/data/filtergraphs/channelmap
 fate-filter-channelmap: SRC = $(TARGET_PATH)/tests/data/asynth-44100-6.wav
 fate-filter-channelmap: tests/data/asynth-44100-6.wav
-fate-filter-channelmap: CMD = md5 -i $(SRC) -filter_complex_script $(SRC_PATH)/tests/filtergraphs/channelmap -f wav -flags +bitexact
+fate-filter-channelmap: CMD = md5 -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/channelmap -f wav -flags +bitexact
 fate-filter-channelmap: CMP = oneline
 fate-filter-channelmap: REF = 06168d06085e2c0603e4e118ba4cade2
 
diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak
index cc83d8b..e882553 100644
--- a/tests/fate/filter-video.mak
+++ b/tests/fate/filter-video.mak
@@ -1,25 +1,45 @@
 FATE_FILTER-$(call ALLYES, PERMS_FILTER DELOGO_FILTER RM_DEMUXER RV30_DECODER) += fate-filter-delogo
-fate-filter-delogo: CMD = framecrc -i $(SAMPLES)/real/rv30.rm -vf perms=random,delogo=show=0:x=290:y=25:w=26:h=16 -an
+fate-filter-delogo: CMD = framecrc -i $(TARGET_SAMPLES)/real/rv30.rm -vf perms=random,delogo=show=0:x=290:y=25:w=26:h=16 -an
 
 FATE_YADIF += fate-filter-yadif-mode0
-fate-filter-yadif-mode0: CMD = framecrc -flags bitexact -idct simple -i $(SAMPLES)/mpeg2/mpeg2_field_encoding.ts -vframes 30 -vf yadif=0
+fate-filter-yadif-mode0: CMD = framecrc -flags bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg2/mpeg2_field_encoding.ts -vframes 30 -vf yadif=0
 
 FATE_YADIF += fate-filter-yadif-mode1
-fate-filter-yadif-mode1: CMD = framecrc -flags bitexact -idct simple -i $(SAMPLES)/mpeg2/mpeg2_field_encoding.ts -vframes 59 -vf yadif=1
+fate-filter-yadif-mode1: CMD = framecrc -flags bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg2/mpeg2_field_encoding.ts -vframes 59 -vf yadif=1
 
 FATE_FILTER-$(call FILTERDEMDEC, YADIF, MPEGTS, MPEG2VIDEO) += $(FATE_YADIF)
 
+FATE_MCDEINT += fate-filter-mcdeint-fast
+fate-filter-mcdeint-fast: CMD = framecrc -flags bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg2/mpeg2_field_encoding.ts -vframes 30 -vf mcdeint=fast
+
+FATE_MCDEINT += fate-filter-mcdeint-medium
+fate-filter-mcdeint-medium: CMD = framecrc -flags bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg2/mpeg2_field_encoding.ts -vframes 30 -vf mcdeint=mode=medium
+
+FATE_FILTER-$(call ALLYES, MCDEINT_FILTER, MPEGTS_DEMUXER, MPEG2VIDEO_DECODER SNOW_ENCODER) += $(FATE_MCDEINT)
+
 FATE_SAMPLES_AVCONV += $(FATE_FILTER-yes)
 
+FATE_FILTER-$(call ALLYES, AVDEVICE LIFE_FILTER) += fate-filter-lavd-life
+fate-filter-lavd-life: CMD = framecrc -f lavfi -i life=s=40x40:r=5:seed=42:mold=64:ratio=0.1:death_color=red:life_color=green -t 2
+
+FATE_FILTER-$(call ALLYES, AVDEVICE TESTSRC_FILTER) += fate-filter-lavd-testsrc
+fate-filter-lavd-testsrc: CMD = framecrc -f lavfi -i testsrc=r=7:n=2:d=10
+
+FATE_FILTER-$(call ALLYES, AVDEVICE TESTSRC_FILTER FORMAT_FILTER CONCAT_FILTER SCALE_FILTER) += fate-filter-lavd-scalenorm
+fate-filter-lavd-scalenorm: CMD = framecrc -f lavfi -graph_file $(SRC_PATH)/tests/filtergraphs/scalenorm -i dummy
+
 
 FATE_FILTER_VSYNTH-$(CONFIG_BOXBLUR_FILTER) += fate-filter-boxblur
 fate-filter-boxblur: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf boxblur=2:1
 
+FATE_FILTER_VSYNTH-$(call ALLYES, COLORCHANNELMIXER_FILTER FORMAT_FILTER PERMS_FILTER) += fate-filter-colorchannelmixer
+fate-filter-colorchannelmixer: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf format=rgb24,perms=random,colorchannelmixer=.31415927:.4:.31415927:0:.27182818:.8:.27182818:0:.2:.6:.2:0 -flags +bitexact -sws_flags +accurate_rnd+bitexact
+
 FATE_FILTER_VSYNTH-$(CONFIG_DRAWBOX_FILTER) += fate-filter-drawbox
-fate-filter-drawbox: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf drawbox=10:20:200:60:red@0.5
+fate-filter-drawbox: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf drawbox=224:24:88:72:red@0.5
 
 FATE_FILTER_VSYNTH-$(CONFIG_FADE_FILTER) += fate-filter-fade
-fate-filter-fade: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf fade=in:0:25,fade=out:25:25
+fate-filter-fade: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf fade=in:5:15,fade=out:30:15
 
 FATE_FILTER_VSYNTH-$(CONFIG_GRADFUN_FILTER) += fate-filter-gradfun
 fate-filter-gradfun: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf gradfun
@@ -40,29 +60,234 @@
 fate-filter-histogram-waveform: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf histogram=mode=waveform -flags +bitexact -sws_flags +accurate_rnd+bitexact
 
 FATE_FILTER_VSYNTH-$(CONFIG_OVERLAY_FILTER) += fate-filter-overlay
-fate-filter-overlay: CMD = framecrc -c:v pgmyuv -i $(SRC) -c:v pgmyuv -i $(SRC) -filter_complex_script $(SRC_PATH)/tests/filtergraphs/overlay
+fate-filter-overlay: tests/data/filtergraphs/overlay
+fate-filter-overlay: CMD = framecrc -c:v pgmyuv -i $(SRC) -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay
+
+FATE_FILTER_VSYNTH-$(call ALLYES, SPLIT_FILTER SCALE_FILTER PAD_FILTER OVERLAY_FILTER) += fate-filter-overlay_rgb
+fate-filter-overlay_rgb: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(SRC_PATH)/tests/filtergraphs/overlay_rgb
+
+FATE_FILTER_VSYNTH-$(call ALLYES, SPLIT_FILTER SCALE_FILTER PAD_FILTER OVERLAY_FILTER) += fate-filter-overlay_yuv420
+fate-filter-overlay_yuv420: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(SRC_PATH)/tests/filtergraphs/overlay_yuv420
+
+FATE_FILTER_VSYNTH-$(call ALLYES, SPLIT_FILTER SCALE_FILTER PAD_FILTER OVERLAY_FILTER) += fate-filter-overlay_yuv444
+fate-filter-overlay_yuv444: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(SRC_PATH)/tests/filtergraphs/overlay_yuv444
+
+FATE_FILTER_VSYNTH-$(CONFIG_SEPARATEFIELDS_FILTER) += fate-filter-separatefields
+fate-filter-separatefields: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf separatefields
 
 FATE_FILTER_VSYNTH-$(call ALLYES, SETPTS_FILTER  SETTB_FILTER) += fate-filter-setpts
-fate-filter-setpts: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_script $(SRC_PATH)/tests/filtergraphs/setpts
+fate-filter-setpts: tests/data/filtergraphs/setpts
+fate-filter-setpts: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_script $(TARGET_PATH)/tests/data/filtergraphs/setpts
+
+FATE_FILTER_VSYNTH-$(CONFIG_TELECINE_FILTER) += fate-filter-telecine
+fate-filter-telecine: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf telecine
 
 FATE_FILTER_VSYNTH-$(CONFIG_TRANSPOSE_FILTER) += fate-filter-transpose
 fate-filter-transpose: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf transpose
 
+FATE_TRIM += fate-filter-trim-duration
+fate-filter-trim-duration: CMD = framecrc -i $(SRC) -vf trim=start=0.4:duration=0.05
+
+FATE_TRIM += fate-filter-trim-frame
+fate-filter-trim-frame: CMD = framecrc -i $(SRC) -vf trim=start_frame=3:end_frame=10
+
+FATE_TRIM += fate-filter-trim-mixed
+fate-filter-trim-mixed: CMD = framecrc -i $(SRC) -vf trim=start=0.2:end=0.4:start_frame=1:end_frame=3
+
+FATE_TRIM += fate-filter-trim-time
+fate-filter-trim-time: CMD = framecrc -i $(SRC) -vf trim=0:0.09
+
+FATE_FILTER_VSYNTH-$(CONFIG_TRIM_FILTER) += $(FATE_TRIM)
+
 FATE_FILTER_VSYNTH-$(CONFIG_UNSHARP_FILTER) += fate-filter-unsharp
-fate-filter-unsharp: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf unsharp
+fate-filter-unsharp: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf unsharp=11:11:-1.5:11:11:-1.5
 
 FATE_FILTER-$(call ALLYES, SMJPEG_DEMUXER MJPEG_DECODER PERMS_FILTER HQDN3D_FILTER) += fate-filter-hqdn3d-sample
-fate-filter-hqdn3d-sample: CMD = framecrc -idct simple -i $(SAMPLES)/smjpeg/scenwin.mjpg -vf perms=random,hqdn3d -an
+fate-filter-hqdn3d-sample: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/smjpeg/scenwin.mjpg -filter_complex_script $(SRC_PATH)/tests/filtergraphs/hqdn3d -an
 
 FATE_FILTER-$(call ALLYES, UTVIDEO_DECODER AVI_DEMUXER PERMS_FILTER CURVES_FILTER) += fate-filter-curves
-fate-filter-curves: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgb_median.avi -vf perms=random,curves=vintage
+fate-filter-curves: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_rgb_median.avi -vf perms=random,curves=vintage
 
 FATE_FILTER-$(call ALLYES, VMD_DEMUXER VMDVIDEO_DECODER FORMAT_FILTER PERMS_FILTER GRADFUN_FILTER) += fate-filter-gradfun-sample
-fate-filter-gradfun-sample: CMD = framecrc -i $(SAMPLES)/vmd/12.vmd -filter_script $(SRC_PATH)/tests/filtergraphs/gradfun -an -frames:v 20
+fate-filter-gradfun-sample: CMD = framecrc -i $(TARGET_SAMPLES)/vmd/12.vmd -filter_script $(SRC_PATH)/tests/filtergraphs/gradfun -an -frames:v 20
 
 FATE_FILTER-$(call ALLYES, TESTSRC_FILTER SINE_FILTER CONCAT_FILTER) += fate-filter-concat
 fate-filter-concat: CMD = framecrc -filter_complex_script $(SRC_PATH)/tests/filtergraphs/concat
 
+FATE_FILTER_VSYNTH-$(call ALLYES, FORMAT_FILTER SPLIT_FILTER ALPHAEXTRACT_FILTER ALPHAMERGE_FILTER) += fate-filter-alphaextract_alphamerge_rgb
+fate-filter-alphaextract_alphamerge_rgb: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(SRC_PATH)/tests/filtergraphs/alphamerge_alphaextract_rgb
+
+FATE_FILTER_VSYNTH-$(call ALLYES, FORMAT_FILTER SPLIT_FILTER ALPHAEXTRACT_FILTER ALPHAMERGE_FILTER) += fate-filter-alphaextract_alphamerge_yuv
+fate-filter-alphaextract_alphamerge_yuv: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(SRC_PATH)/tests/filtergraphs/alphamerge_alphaextract_yuv
+
+FATE_FILTER_VSYNTH-$(CONFIG_CROP_FILTER) += fate-filter-crop
+fate-filter-crop: CMD = video_filter "crop=iw-100:ih-100:100:100"
+
+FATE_FILTER_VSYNTH-$(call ALLYES, CROP_FILTER SCALE_FILTER) += fate-filter-crop_scale
+fate-filter-crop_scale: CMD = video_filter "crop=iw-100:ih-100:100:100,scale=w=400:h=-1"
+
+FATE_FILTER_VSYNTH-$(call ALLYES, CROP_FILTER SCALE_FILTER VFLIP_FILTER) += fate-filter-crop_scale_vflip
+fate-filter-crop_scale_vflip: CMD = video_filter "null,null,crop=iw-200:ih-200:200:200,crop=iw-20:ih-20:20:20,scale=w=200:h=200,scale=w=250:h=250,vflip,vflip,null,scale=w=200:h=200,crop=iw-100:ih-100:100:100,vflip,scale=w=200:h=200,null,vflip,crop=iw-100:ih-100:100:100,null"
+
+FATE_FILTER_VSYNTH-$(call ALLYES, CROP_FILTER VFLIP_FILTER) += fate-filter-crop_vflip
+fate-filter-crop_vflip: CMD = video_filter "crop=iw-100:ih-100:100:100,vflip"
+
+FATE_FILTER_VSYNTH-$(CONFIG_NULL_FILTER) += fate-filter-null
+fate-filter-null: CMD = video_filter "null"
+
+FATE_FILTER_VSYNTH-$(CONFIG_SCALE_FILTER) += fate-filter-scale200
+fate-filter-scale200: CMD = video_filter "scale=w=200:h=200"
+
+FATE_FILTER_VSYNTH-$(CONFIG_SCALE_FILTER) += fate-filter-scale500
+fate-filter-scale500: CMD = video_filter "scale=w=500:h=500"
+
+FATE_FILTER_VSYNTH-$(CONFIG_VFLIP_FILTER) += fate-filter-vflip
+fate-filter-vflip: CMD = video_filter "vflip"
+
+FATE_FILTER_VSYNTH-$(CONFIG_COLORMATRIX_FILTER) += fate-filter-colormatrix1
+fate-filter-colormatrix1: CMD = video_filter "colormatrix=bt601:smpte240m,colormatrix=smpte240m:fcc,colormatrix=fcc:bt601,colormatrix=bt601:fcc,colormatrix=fcc:smpte240m,colormatrix=smpte240m:bt709"
+
+FATE_FILTER_VSYNTH-$(CONFIG_COLORMATRIX_FILTER) += fate-filter-colormatrix2
+fate-filter-colormatrix2: CMD = video_filter "colormatrix=bt709:fcc,colormatrix=fcc:bt709,colormatrix=bt709:bt601,colormatrix=bt601:bt709,colormatrix=bt709:smpte240m,colormatrix=smpte240m:bt601"
+
+FATE_FILTER_VSYNTH-$(call ALLYES, CROP_FILTER VFLIP_FILTER) += fate-filter-vflip_crop
+fate-filter-vflip_crop: CMD = video_filter "vflip,crop=iw-100:ih-100:100:100"
+
+FATE_FILTER_VSYNTH-$(CONFIG_VFLIP_FILTER) += fate-filter-vflip_vflip
+fate-filter-vflip_vflip: CMD = video_filter "vflip,vflip"
+
+FATE_FILTER_VSYNTH-$(call ALLYES, FORMAT_FILTER PERMS_FILTER EDGEDETECT_FILTER) += fate-filter-edgedetect
+fate-filter-edgedetect: CMD = video_filter "format=gray,perms=random,edgedetect"
+
+FATE_FILTER_VSYNTH-$(call ALLYES, PERMS_FILTER HUE_FILTER) += fate-filter-hue
+fate-filter-hue: CMD = video_filter "perms=random,hue=s=sin(2*PI*t)+1"
+
+FATE_FILTER_VSYNTH-$(CONFIG_IDET_FILTER) += fate-filter-idet
+fate-filter-idet: CMD = video_filter "idet"
+
+FATE_FILTER_VSYNTH-$(CONFIG_PAD_FILTER) += fate-filter-pad
+fate-filter-pad: CMD = video_filter "pad=iw*1.5:ih*1.5:iw*0.3:ih*0.2"
+
+FATE_FILTER_VSYNTH-$(CONFIG_PP_FILTER) += fate-filter-pp
+fate-filter-pp: CMD = video_filter "pp=be/hb/vb/tn/l5/al"
+
+FATE_FILTER_VSYNTH-$(CONFIG_PP_FILTER) += fate-filter-pp2
+fate-filter-pp2: CMD = video_filter "pp=be/fq|16/h1/v1/lb"
+
+FATE_FILTER_VSYNTH-$(CONFIG_PP_FILTER) += fate-filter-pp3
+fate-filter-pp3: CMD = video_filter "pp=be/fq|8/ha|128|7/va/li"
+
+FATE_FILTER_VSYNTH-$(CONFIG_PP_FILTER) += fate-filter-pp4
+fate-filter-pp4: CMD = video_filter "pp=be/ci"
+
+FATE_FILTER_VSYNTH-$(CONFIG_PP_FILTER) += fate-filter-pp5
+fate-filter-pp5: CMD = video_filter "pp=md"
+
+FATE_FILTER_VSYNTH-$(CONFIG_PP_FILTER) += fate-filter-pp6
+fate-filter-pp6: CMD = video_filter "pp=be/fd"
+
+FATE_FILTER_VSYNTH-$(CONFIG_SELECT_FILTER) += fate-filter-select
+fate-filter-select: CMD = video_filter "select=not(eq(mod(n\,2)\,0)+eq(mod(n\,3)\,0))"
+
+FATE_FILTER_VSYNTH-$(CONFIG_SETDAR_FILTER) += fate-filter-setdar
+fate-filter-setdar: CMD = video_filter "setdar=dar=16/9"
+
+FATE_FILTER_VSYNTH-$(CONFIG_SETSAR_FILTER) += fate-filter-setsar
+fate-filter-setsar: CMD = video_filter "setsar=sar=16/11"
+
+FATE_STEREO3D += fate-filter-stereo3d-al-sbsl
+fate-filter-stereo3d-al-sbsl: CMD = framecrc -c:v pgmyuv -i $(SRC) -vframes 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=al:sbsl
+
+FATE_STEREO3D += fate-filter-stereo3d-ar-abl
+fate-filter-stereo3d-ar-abl: CMD = framecrc -c:v pgmyuv -i $(SRC) -vframes 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=ar:abl
+
+FATE_STEREO3D += fate-filter-stereo3d-abr-mr
+fate-filter-stereo3d-abr-mr: CMD = framecrc -c:v pgmyuv -i $(SRC) -vframes 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=abr:mr
+
+FATE_STEREO3D += fate-filter-stereo3d-abr-ml
+fate-filter-stereo3d-abr-ml: CMD = framecrc -c:v pgmyuv -i $(SRC) -vframes 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=abr:ml
+
+FATE_STEREO3D  += fate-filter-stereo3d-sbsl-abl
+fate-filter-stereo3d-sbsl-abl: CMD = framecrc -c:v pgmyuv -i $(SRC) -vframes 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:abl
+
+FATE_STEREO3D += fate-filter-stereo3d-sbsl-abr
+fate-filter-stereo3d-sbsl-abr: CMD = framecrc -c:v pgmyuv -i $(SRC) -vframes 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:abr
+
+FATE_STEREO3D += fate-filter-stereo3d-sbsl-al
+fate-filter-stereo3d-sbsl-al: CMD = framecrc -c:v pgmyuv -i $(SRC) -vframes 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:al
+
+FATE_STEREO3D += fate-filter-stereo3d-sbsl-sbsr
+fate-filter-stereo3d-sbsl-sbsr: CMD = framecrc -c:v pgmyuv -i $(SRC) -vframes 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:sbsr
+
+FATE_FILTER_VSYNTH-$(CONFIG_STEREO3D_FILTER) += $(FATE_STEREO3D)
+
+FATE_FILTER_VSYNTH-$(CONFIG_THUMBNAIL_FILTER) += fate-filter-thumbnail
+fate-filter-thumbnail: CMD = video_filter "thumbnail=10"
+
+FATE_FILTER_VSYNTH-$(CONFIG_TILE_FILTER) += fate-filter-tile
+fate-filter-tile: CMD = video_filter "tile=3x3:nb_frames=5:padding=7:margin=2"
+
+
+FATE_FILTER_VSYNTH-$(CONFIG_FORMAT_FILTER) += fate-filter-pixdesc
+fate-filter-pixdesc: CMD = pixdesc
+
+
+FATE_FILTER_PIXFMTS-$(CONFIG_COPY_FILTER) += fate-filter-pixfmts-copy
+fate-filter-pixfmts-copy:  CMD = pixfmts
+
+FATE_FILTER_PIXFMTS-$(CONFIG_CROP_FILTER) += fate-filter-pixfmts-crop
+fate-filter-pixfmts-crop:  CMD = pixfmts "100:100:100:100"
+
+FATE_FILTER_PIXFMTS-$(CONFIG_FIELD_FILTER) += fate-filter-pixfmts-field
+fate-filter-pixfmts-field: CMD = pixfmts "bottom"
+
+FATE_FILTER_PIXFMTS-$(CONFIG_HFLIP_FILTER) += fate-filter-pixfmts-hflip
+fate-filter-pixfmts-hflip: CMD = pixfmts
+
+#FATE_FILTER_PIXFMTS-$(CONFIG_HISTEQ_FILTER) += fate-filter-pixfmts-histeq
+#fate-filter-pixfmts-histeq: CMD = pixfmts "antibanding=strong"
+
+FATE_FILTER_PIXFMTS-$(CONFIG_IL_FILTER) += fate-filter-pixfmts-il
+fate-filter-pixfmts-il:    CMD = pixfmts "luma_mode=d:chroma_mode=d:alpha_mode=d"
+
+FATE_FILTER_PIXFMTS-$(CONFIG_KERNDEINT_FILTER) += fate-filter-pixfmts-kerndeint
+fate-filter-pixfmts-kerndeint: CMD = pixfmts "" "tinterlace=interleave_top,"
+
+FATE_FILTER_PIXFMTS-$(CONFIG_LUT_FILTER) += fate-filter-pixfmts-lut
+fate-filter-pixfmts-lut: CMD = pixfmts "c0=2*val:c1=2*val:c2=val/2:c3=negval+40"
+
+FATE_FILTER_PIXFMTS-$(CONFIG_NULL_FILTER) += fate-filter-pixfmts-null
+fate-filter-pixfmts-null:  CMD = pixfmts
+
+FATE_FILTER_PIXFMTS-$(CONFIG_PAD_FILTER) += fate-filter-pixfmts-pad
+fate-filter-pixfmts-pad:   CMD = pixfmts "500:400:20:20"
+
+FATE_FILTER_PIXFMTS-$(CONFIG_ROTATE_FILTER) += fate-filter-pixfmts-rotate
+fate-filter-pixfmts-rotate: CMD = pixfmts "2*PI*n/50"
+
+FATE_FILTER_PIXFMTS-$(CONFIG_SCALE_FILTER) += fate-filter-pixfmts-scale
+fate-filter-pixfmts-scale: CMD = pixfmts "200:100"
+
+FATE_FILTER_PIXFMTS-$(CONFIG_SUPER2XSAI_FILTER) += fate-filter-pixfmts-super2xsai
+fate-filter-pixfmts-super2xsai: CMD = pixfmts
+
+FATE_FILTER_PIXFMTS-$(CONFIG_SWAPUV_FILTER) += fate-filter-pixfmts-swapuv
+fate-filter-pixfmts-swapuv: CMD = pixfmts
+
+FATE_FILTER_PIXFMTS-$(CONFIG_TINTERLACE_FILTER) += fate-filter-pixfmts-tinterlace_merge
+fate-filter-pixfmts-tinterlace_merge: CMD = pixfmts "merge"
+
+FATE_FILTER_PIXFMTS-$(CONFIG_TINTERLACE_FILTER) += fate-filter-pixfmts-tinterlace_pad
+fate-filter-pixfmts-tinterlace_pad: CMD = pixfmts "pad"
+
+FATE_FILTER_PIXFMTS-$(CONFIG_VFLIP_FILTER) += fate-filter-pixfmts-vflip
+fate-filter-pixfmts-vflip: CMD = pixfmts
+
+$(FATE_FILTER_PIXFMTS-yes): libavfilter/filtfmts-test$(EXESUF)
+FATE_FILTER_VSYNTH-$(CONFIG_FORMAT_FILTER) += $(FATE_FILTER_PIXFMTS-yes)
+
+fate-filter-pixfmts: $(FATE_FILTER_PIXFMTS-yes)
+
 $(FATE_FILTER_VSYNTH-yes): $(VREF)
 $(FATE_FILTER_VSYNTH-yes): SRC = $(TARGET_PATH)/tests/vsynth1/%02d.pgm
 
diff --git a/tests/fate/flac.mak b/tests/fate/flac.mak
index 172f661..4a13404 100644
--- a/tests/fate/flac.mak
+++ b/tests/fate/flac.mak
@@ -12,12 +12,12 @@
 fate-flac-16-lpc-%:    OPTS = -lpc_type $(@:fate-flac-16-lpc-%=%)
 
 fate-flac-16-%: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav
-fate-flac-16-%: CMD = enc_dec_pcm flac wav s16le $(REF) -c flac $(OPTS)
+fate-flac-16-%: CMD = enc_dec_pcm flac wav s16le $(subst $(SAMPLES),$(TARGET_SAMPLES),$(REF)) -c flac $(OPTS)
 
 fate-flac-24-comp-%: OPTS = -compression_level $(@:fate-flac-24-comp-%=%)
 
 fate-flac-24-%: REF = $(SAMPLES)/audio-reference/divertimenti_2ch_96kHz_s24.wav
-fate-flac-24-%: CMD = enc_dec_pcm flac wav s24le $(REF) -c flac $(OPTS)
+fate-flac-24-%: CMD = enc_dec_pcm flac wav s24le $(subst $(SAMPLES),$(TARGET_SAMPLES),$(REF)) -c flac $(OPTS)
 
 fate-flac-%: CMP = oneoff
 fate-flac-%: FUZZ = 0
diff --git a/tests/fate/gif.mak b/tests/fate/gif.mak
index 110a067..feda240 100644
--- a/tests/fate/gif.mak
+++ b/tests/fate/gif.mak
@@ -1,14 +1,14 @@
 FATE_GIF += fate-gif-color
-fate-gif-color: CMD = framecrc -i $(SAMPLES)/gif/tc217.gif -pix_fmt bgra
+fate-gif-color: CMD = framecrc -i $(TARGET_SAMPLES)/gif/tc217.gif -pix_fmt bgra
 
 FATE_GIF += fate-gif-disposal-background
-fate-gif-disposal-background: CMD = framecrc -trans_color 0 -i $(SAMPLES)/gif/m4nb.gif -pix_fmt bgra
+fate-gif-disposal-background: CMD = framecrc -trans_color 0 -i $(TARGET_SAMPLES)/gif/m4nb.gif -pix_fmt bgra
 
 FATE_GIF += fate-gif-disposal-restore
-fate-gif-disposal-restore: CMD = framecrc -i $(SAMPLES)/gif/banner2.gif -pix_fmt bgra
+fate-gif-disposal-restore: CMD = framecrc -i $(TARGET_SAMPLES)/gif/banner2.gif -pix_fmt bgra
 
 FATE_GIF += fate-gif-gray
-fate-gif-gray: CMD = framecrc -i $(SAMPLES)/gif/Newtons_cradle_animation_book_2.gif -pix_fmt bgra
+fate-gif-gray: CMD = framecrc -i $(TARGET_SAMPLES)/gif/Newtons_cradle_animation_book_2.gif -pix_fmt bgra
 
 fate-gifenc%: fate-gif-color
 fate-gifenc%: PIXFMT = $(word 3, $(subst -, ,$(@)))
diff --git a/tests/fate/h264.mak b/tests/fate/h264.mak
index 2cbd5df..55270d0 100644
--- a/tests/fate/h264.mak
+++ b/tests/fate/h264.mak
@@ -64,6 +64,7 @@
             ci_mw_d                                                     \
             cvbs3_sony_c                                                \
             cvcanlma2_sony_c                                            \
+            cvfc1_sony_c                                                \
             cvfi1_sony_d                                                \
             cvfi1_sva_c                                                 \
             cvfi2_sony_h                                                \
@@ -200,194 +201,195 @@
 FATE_SAMPLES_AVCONV += $(FATE_H264-yes)
 fate-h264: $(FATE_H264-yes)
 
-fate-h264-conformance-aud_mw_e:                   CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/AUD_MW_E.264
-fate-h264-conformance-ba1_ft_c:                   CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/BA1_FT_C.264
-fate-h264-conformance-ba1_sony_d:                 CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/BA1_Sony_D.jsv
-fate-h264-conformance-ba2_sony_f:                 CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/BA2_Sony_F.jsv
-fate-h264-conformance-ba3_sva_c:                  CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/BA3_SVA_C.264
-fate-h264-conformance-ba_mw_d:                    CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/BA_MW_D.264
-fate-h264-conformance-bamq1_jvc_c:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/BAMQ1_JVC_C.264
-fate-h264-conformance-bamq2_jvc_c:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/BAMQ2_JVC_C.264
-fate-h264-conformance-banm_mw_d:                  CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/BANM_MW_D.264
-fate-h264-conformance-basqp1_sony_c:              CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/BASQP1_Sony_C.jsv
-fate-h264-conformance-caba1_sony_d:               CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABA1_Sony_D.jsv
-fate-h264-conformance-caba1_sva_b:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABA1_SVA_B.264
-fate-h264-conformance-caba2_sony_e:               CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABA2_Sony_E.jsv
-fate-h264-conformance-caba2_sva_b:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABA2_SVA_B.264
-fate-h264-conformance-caba3_sony_c:               CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABA3_Sony_C.jsv
-fate-h264-conformance-caba3_sva_b:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABA3_SVA_B.264
-fate-h264-conformance-caba3_toshiba_e:            CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABA3_TOSHIBA_E.264
-fate-h264-conformance-cabac_mot_fld0_full:        CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/camp_mot_fld0_full.26l
-fate-h264-conformance-cabac_mot_frm0_full:        CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/camp_mot_frm0_full.26l
-fate-h264-conformance-cabac_mot_mbaff0_full:      CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/camp_mot_mbaff0_full.26l
-fate-h264-conformance-cabac_mot_picaff0_full:     CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/camp_mot_picaff0_full.26l
-fate-h264-conformance-cabaci3_sony_b:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABACI3_Sony_B.jsv
-fate-h264-conformance-cabast3_sony_e:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABAST3_Sony_E.jsv
-fate-h264-conformance-cabastbr3_sony_b:           CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABASTBR3_Sony_B.jsv
-fate-h264-conformance-cabref3_sand_d:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABREF3_Sand_D.264
-fate-h264-conformance-cacqp3_sony_d:              CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CACQP3_Sony_D.jsv
-fate-h264-conformance-cafi1_sva_c:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAFI1_SVA_C.264
-fate-h264-conformance-cama1_sony_c:               CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMA1_Sony_C.jsv
-fate-h264-conformance-cama1_toshiba_b:            CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMA1_TOSHIBA_B.264
-fate-h264-conformance-cama1_vtc_c:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/cama1_vtc_c.avc
-fate-h264-conformance-cama2_vtc_b:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/cama2_vtc_b.avc
-fate-h264-conformance-cama3_sand_e:               CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMA3_Sand_E.264
-fate-h264-conformance-cama3_vtc_b:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/cama3_vtc_b.avc
-fate-h264-conformance-camaci3_sony_c:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMACI3_Sony_C.jsv
-fate-h264-conformance-camanl1_toshiba_b:          CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMANL1_TOSHIBA_B.264
-fate-h264-conformance-camanl2_toshiba_b:          CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMANL2_TOSHIBA_B.264
-fate-h264-conformance-camanl3_sand_e:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMANL3_Sand_E.264
-fate-h264-conformance-camasl3_sony_b:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMASL3_Sony_B.jsv
-fate-h264-conformance-camp_mot_mbaff_l30:         CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMP_MOT_MBAFF_L30.26l
-fate-h264-conformance-camp_mot_mbaff_l31:         CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMP_MOT_MBAFF_L31.26l
-fate-h264-conformance-canl1_sony_e:               CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANL1_Sony_E.jsv
-fate-h264-conformance-canl1_sva_b:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANL1_SVA_B.264
-fate-h264-conformance-canl1_toshiba_g:            CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANL1_TOSHIBA_G.264
-fate-h264-conformance-canl2_sony_e:               CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANL2_Sony_E.jsv
-fate-h264-conformance-canl2_sva_b:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANL2_SVA_B.264
-fate-h264-conformance-canl3_sony_c:               CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANL3_Sony_C.jsv
-fate-h264-conformance-canl3_sva_b:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANL3_SVA_B.264
-fate-h264-conformance-canl4_sva_b:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANL4_SVA_B.264
-fate-h264-conformance-canlma2_sony_c:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANLMA2_Sony_C.jsv
-fate-h264-conformance-canlma3_sony_c:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANLMA3_Sony_C.jsv
-fate-h264-conformance-capa1_toshiba_b:            CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAPA1_TOSHIBA_B.264
-fate-h264-conformance-capama3_sand_f:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAPAMA3_Sand_F.264
-fate-h264-conformance-capcm1_sand_e:              CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAPCM1_Sand_E.264
-fate-h264-conformance-capcmnl1_sand_e:            CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAPCMNL1_Sand_E.264
-fate-h264-conformance-capm3_sony_d:               CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAPM3_Sony_D.jsv
-fate-h264-conformance-caqp1_sony_b:               CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAQP1_Sony_B.jsv
-fate-h264-conformance-cavlc_mot_fld0_full_b:      CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/cvmp_mot_fld0_full_B.26l
-fate-h264-conformance-cavlc_mot_frm0_full_b:      CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/cvmp_mot_frm0_full_B.26l
-fate-h264-conformance-cavlc_mot_mbaff0_full_b:    CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/cvmp_mot_mbaff0_full_B.26l
-fate-h264-conformance-cavlc_mot_picaff0_full_b:   CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/cvmp_mot_picaff0_full_B.26l
-fate-h264-conformance-cawp1_toshiba_e:            CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAWP1_TOSHIBA_E.264
-fate-h264-conformance-cawp5_toshiba_e:            CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAWP5_TOSHIBA_E.264
-fate-h264-conformance-ci1_ft_b:                   CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CI1_FT_B.264
-fate-h264-conformance-ci_mw_d:                    CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CI_MW_D.264
-fate-h264-conformance-cvbs3_sony_c:               CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVBS3_Sony_C.jsv
-fate-h264-conformance-cvcanlma2_sony_c:           CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVCANLMA2_Sony_C.jsv
-fate-h264-conformance-cvfi1_sony_d:               CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVFI1_Sony_D.jsv
-fate-h264-conformance-cvfi1_sva_c:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVFI1_SVA_C.264
-fate-h264-conformance-cvfi2_sony_h:               CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVFI2_Sony_H.jsv
-fate-h264-conformance-cvfi2_sva_c:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVFI2_SVA_C.264
-fate-h264-conformance-cvma1_sony_d:               CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVMA1_Sony_D.jsv
-fate-h264-conformance-cvma1_toshiba_b:            CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVMA1_TOSHIBA_B.264
-fate-h264-conformance-cvmanl1_toshiba_b:          CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVMANL1_TOSHIBA_B.264
-fate-h264-conformance-cvmanl2_toshiba_b:          CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVMANL2_TOSHIBA_B.264
-fate-h264-conformance-cvmapaqp3_sony_e:           CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVMAPAQP3_Sony_E.jsv
-fate-h264-conformance-cvmaqp2_sony_g:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVMAQP2_Sony_G.jsv
-fate-h264-conformance-cvmaqp3_sony_d:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVMAQP3_Sony_D.jsv
-fate-h264-conformance-cvmp_mot_fld_l30_b:         CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVMP_MOT_FLD_L30_B.26l
-fate-h264-conformance-cvmp_mot_frm_l31_b:         CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVMP_MOT_FRM_L31_B.26l
-fate-h264-conformance-cvnlfi1_sony_c:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVNLFI1_Sony_C.jsv
-fate-h264-conformance-cvnlfi2_sony_h:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVNLFI2_Sony_H.jsv
-fate-h264-conformance-cvpa1_toshiba_b:            CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVPA1_TOSHIBA_B.264
-fate-h264-conformance-cvpcmnl1_sva_c:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVPCMNL1_SVA_C.264
-fate-h264-conformance-cvpcmnl2_sva_c:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVPCMNL2_SVA_C.264
-fate-h264-conformance-cvwp1_toshiba_e:            CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVWP1_TOSHIBA_E.264
-fate-h264-conformance-cvwp2_toshiba_e:            CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVWP2_TOSHIBA_E.264
-fate-h264-conformance-cvwp3_toshiba_e:            CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVWP3_TOSHIBA_E.264
-fate-h264-conformance-cvwp5_toshiba_e:            CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVWP5_TOSHIBA_E.264
-fate-h264-conformance-fi1_sony_e:                 CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FI1_Sony_E.jsv
-fate-h264-conformance-frext-alphaconformanceg:    CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/test8b43.264
-fate-h264-conformance-frext-bcrm_freh10:          CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/freh10.264 -vsync drop
-fate-h264-conformance-frext-brcm_freh11:          CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/freh11.264 -vsync drop
-fate-h264-conformance-frext-brcm_freh3:           CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/freh3.264
-fate-h264-conformance-frext-brcm_freh4:           CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/freh4.264 -vsync drop
-fate-h264-conformance-frext-brcm_freh5:           CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/freh5.264
-fate-h264-conformance-frext-brcm_freh8:           CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/freh8.264
-fate-h264-conformance-frext-brcm_freh9:           CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/freh9.264
-fate-h264-conformance-frext-freh12_b:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/Freh12_B.264
-fate-h264-conformance-frext-freh1_b:              CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/Freh1_B.264
-fate-h264-conformance-frext-freh2_b:              CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/Freh2_B.264
-fate-h264-conformance-frext-freh6:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/freh6.264 -vsync drop
-fate-h264-conformance-frext-freh7_b:              CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/Freh7_B.264 -vsync drop
-fate-h264-conformance-frext-frext01_jvc_d:        CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/FREXT01_JVC_D.264
-fate-h264-conformance-frext-frext02_jvc_c:        CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/FREXT02_JVC_C.264
-fate-h264-conformance-frext-frext1_panasonic_c:   CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/FRExt1_Panasonic.avc
-fate-h264-conformance-frext-frext2_panasonic_b:   CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/FRExt2_Panasonic.avc -vsync 0
-fate-h264-conformance-frext-frext3_panasonic_d:   CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/FRExt3_Panasonic.avc
-fate-h264-conformance-frext-frext4_panasonic_a:   CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/FRExt4_Panasonic.avc
-fate-h264-conformance-frext-frext_mmco4_sony_b:   CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/FRExt_MMCO4_Sony_B.264
-fate-h264-conformance-frext-hcaff1_hhi_b:         CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HCAFF1_HHI.264
-fate-h264-conformance-frext-hcafr1_hhi_c:         CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HCAFR1_HHI.264
-fate-h264-conformance-frext-hcafr2_hhi_a:         CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HCAFR2_HHI.264
-fate-h264-conformance-frext-hcafr3_hhi_a:         CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HCAFR3_HHI.264
-fate-h264-conformance-frext-hcafr4_hhi_a:         CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HCAFR4_HHI.264
-fate-h264-conformance-frext-hcamff1_hhi_b:        CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HCAMFF1_HHI.264
-fate-h264-conformance-frext-hi422fr10_sony_b:     CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/Hi422FR10_SONY_B.264
-fate-h264-conformance-frext-hi422fr13_sony_b:     CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/Hi422FR13_SONY_B.264 -pix_fmt yuv422p10le
-fate-h264-conformance-frext-hi422fr1_sony_a:      CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/Hi422FR1_SONY_A.jsv
-fate-h264-conformance-frext-hi422fr6_sony_a:      CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/Hi422FR6_SONY_A.jsv -pix_fmt yuv422p10le
-fate-h264-conformance-frext-hpca_brcm_c:          CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCA_BRCM_C.264
-fate-h264-conformance-frext-hpcadq_brcm_b:        CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCADQ_BRCM_B.264
-fate-h264-conformance-frext-hpcafl_bcrm_c:        CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCAFL_BRCM_C.264 -vsync drop
-fate-h264-conformance-frext-hpcaflnl_bcrm_c:      CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCAFLNL_BRCM_C.264 -vsync drop
-fate-h264-conformance-frext-hpcalq_brcm_b:        CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCALQ_BRCM_B.264
-fate-h264-conformance-frext-hpcamapalq_bcrm_b:    CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCAMAPALQ_BRCM_B.264 -vsync 0
-fate-h264-conformance-frext-hpcamolq_brcm_b:      CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCAMOLQ_BRCM_B.264
-fate-h264-conformance-frext-hpcanl_brcm_c:        CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCANL_BRCM_C.264
-fate-h264-conformance-frext-hpcaq2lq_brcm_b:      CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCAQ2LQ_BRCM_B.264
-fate-h264-conformance-frext-hpcv_brcm_a:          CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCV_BRCM_A.264
-fate-h264-conformance-frext-hpcvfl_bcrm_a:        CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCVFL_BRCM_A.264 -vsync drop
-fate-h264-conformance-frext-hpcvflnl_bcrm_a:      CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCVFLNL_BRCM_A.264 -vsync drop
-fate-h264-conformance-frext-hpcvmolq_brcm_b:      CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCVMOLQ_BRCM_B.264
-fate-h264-conformance-frext-hpcvnl_brcm_a:        CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCVNL_BRCM_A.264
-fate-h264-conformance-frext-pph10i1_panasonic_a:  CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH10I1_Panasonic_A.264 -pix_fmt yuv420p10le
-fate-h264-conformance-frext-pph10i2_panasonic_a:  CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH10I2_Panasonic_A.264 -pix_fmt yuv420p10le
-fate-h264-conformance-frext-pph10i3_panasonic_a:  CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH10I3_Panasonic_A.264 -pix_fmt yuv420p10le
-fate-h264-conformance-frext-pph10i4_panasonic_a:  CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH10I4_Panasonic_A.264 -pix_fmt yuv420p10le
-fate-h264-conformance-frext-pph10i5_panasonic_a:  CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH10I5_Panasonic_A.264 -pix_fmt yuv420p10le
-fate-h264-conformance-frext-pph10i6_panasonic_a:  CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH10I6_Panasonic_A.264 -pix_fmt yuv420p10le
-fate-h264-conformance-frext-pph10i7_panasonic_a:  CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH10I7_Panasonic_A.264 -pix_fmt yuv420p10le
-fate-h264-conformance-frext-pph422i1_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH422I1_Panasonic_A.264 -pix_fmt yuv422p10le
-fate-h264-conformance-frext-pph422i2_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH422I2_Panasonic_A.264 -pix_fmt yuv422p10le
-fate-h264-conformance-frext-pph422i3_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH422I3_Panasonic_A.264 -pix_fmt yuv422p10le
-fate-h264-conformance-frext-pph422i4_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH422I4_Panasonic_A.264 -pix_fmt yuv422p10le
-fate-h264-conformance-frext-pph422i5_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH422I5_Panasonic_A.264 -pix_fmt yuv422p10le
-fate-h264-conformance-frext-pph422i6_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH422I6_Panasonic_A.264 -pix_fmt yuv422p10le
-fate-h264-conformance-frext-pph422i7_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH422I7_Panasonic_A.264 -pix_fmt yuv422p10le
-fate-h264-conformance-hcbp2_hhi_a:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/HCBP2_HHI_A.264
-fate-h264-conformance-hcmp1_hhi_a:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/HCMP1_HHI_A.264
-fate-h264-conformance-ls_sva_d:                   CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/LS_SVA_D.264
-fate-h264-conformance-midr_mw_d:                  CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MIDR_MW_D.264
-fate-h264-conformance-mps_mw_a:                   CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MPS_MW_A.264
-fate-h264-conformance-mr1_bt_a:                   CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR1_BT_A.h264
-fate-h264-conformance-mr1_mw_a:                   CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR1_MW_A.264
-fate-h264-conformance-mr2_mw_a:                   CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR2_MW_A.264
-fate-h264-conformance-mr2_tandberg_e:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR2_TANDBERG_E.264
-fate-h264-conformance-mr3_tandberg_b:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR3_TANDBERG_B.264
-fate-h264-conformance-mr4_tandberg_c:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR4_TANDBERG_C.264
-fate-h264-conformance-mr5_tandberg_c:             CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR5_TANDBERG_C.264
-fate-h264-conformance-mr6_bt_b:                   CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR6_BT_B.h264
-fate-h264-conformance-mr7_bt_b:                   CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR7_BT_B.h264
-fate-h264-conformance-mr8_bt_b:                   CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR8_BT_B.h264
-fate-h264-conformance-mr9_bt_b:                   CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR9_BT_B.h264
-fate-h264-conformance-mv1_brcm_d:                 CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/src19td.IBP.264
-fate-h264-conformance-nl1_sony_d:                 CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/NL1_Sony_D.jsv
-fate-h264-conformance-nl2_sony_h:                 CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/NL2_Sony_H.jsv
-fate-h264-conformance-nl3_sva_e:                  CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/NL3_SVA_E.264
-fate-h264-conformance-nlmq1_jvc_c:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/NLMQ1_JVC_C.264
-fate-h264-conformance-nlmq2_jvc_c:                CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/NLMQ2_JVC_C.264
-fate-h264-conformance-nrf_mw_e:                   CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/NRF_MW_E.264
-fate-h264-conformance-sharp_mp_field_1_b:         CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/Sharp_MP_Field_1_B.jvt
-fate-h264-conformance-sharp_mp_field_2_b:         CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/Sharp_MP_Field_2_B.jvt
-fate-h264-conformance-sharp_mp_field_3_b:         CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/Sharp_MP_Field_3_B.jvt
-fate-h264-conformance-sharp_mp_paff_1r2:          CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/Sharp_MP_PAFF_1r2.jvt
-fate-h264-conformance-sharp_mp_paff_2r:           CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/Sharp_MP_PAFF_2.jvt
-fate-h264-conformance-sl1_sva_b:                  CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/SL1_SVA_B.264
-fate-h264-conformance-sva_ba1_b:                  CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/SVA_BA1_B.264
-fate-h264-conformance-sva_ba2_d:                  CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/SVA_BA2_D.264
-fate-h264-conformance-sva_base_b:                 CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/SVA_Base_B.264
-fate-h264-conformance-sva_cl1_e:                  CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/SVA_CL1_E.264
-fate-h264-conformance-sva_fm1_e:                  CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/SVA_FM1_E.264
-fate-h264-conformance-sva_nl1_b:                  CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/SVA_NL1_B.264
-fate-h264-conformance-sva_nl2_e:                  CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/SVA_NL2_E.264
+fate-h264-conformance-aud_mw_e:                   CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/AUD_MW_E.264
+fate-h264-conformance-ba1_ft_c:                   CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/BA1_FT_C.264
+fate-h264-conformance-ba1_sony_d:                 CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/BA1_Sony_D.jsv
+fate-h264-conformance-ba2_sony_f:                 CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/BA2_Sony_F.jsv
+fate-h264-conformance-ba3_sva_c:                  CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/BA3_SVA_C.264
+fate-h264-conformance-ba_mw_d:                    CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/BA_MW_D.264
+fate-h264-conformance-bamq1_jvc_c:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/BAMQ1_JVC_C.264
+fate-h264-conformance-bamq2_jvc_c:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/BAMQ2_JVC_C.264
+fate-h264-conformance-banm_mw_d:                  CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/BANM_MW_D.264
+fate-h264-conformance-basqp1_sony_c:              CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/BASQP1_Sony_C.jsv
+fate-h264-conformance-caba1_sony_d:               CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CABA1_Sony_D.jsv
+fate-h264-conformance-caba1_sva_b:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CABA1_SVA_B.264
+fate-h264-conformance-caba2_sony_e:               CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CABA2_Sony_E.jsv
+fate-h264-conformance-caba2_sva_b:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CABA2_SVA_B.264
+fate-h264-conformance-caba3_sony_c:               CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CABA3_Sony_C.jsv
+fate-h264-conformance-caba3_sva_b:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CABA3_SVA_B.264
+fate-h264-conformance-caba3_toshiba_e:            CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CABA3_TOSHIBA_E.264
+fate-h264-conformance-cabac_mot_fld0_full:        CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/camp_mot_fld0_full.26l
+fate-h264-conformance-cabac_mot_frm0_full:        CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/camp_mot_frm0_full.26l
+fate-h264-conformance-cabac_mot_mbaff0_full:      CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/camp_mot_mbaff0_full.26l
+fate-h264-conformance-cabac_mot_picaff0_full:     CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/camp_mot_picaff0_full.26l
+fate-h264-conformance-cabaci3_sony_b:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CABACI3_Sony_B.jsv
+fate-h264-conformance-cabast3_sony_e:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CABAST3_Sony_E.jsv
+fate-h264-conformance-cabastbr3_sony_b:           CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CABASTBR3_Sony_B.jsv
+fate-h264-conformance-cabref3_sand_d:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CABREF3_Sand_D.264
+fate-h264-conformance-cacqp3_sony_d:              CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CACQP3_Sony_D.jsv
+fate-h264-conformance-cafi1_sva_c:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAFI1_SVA_C.264
+fate-h264-conformance-cama1_sony_c:               CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMA1_Sony_C.jsv
+fate-h264-conformance-cama1_toshiba_b:            CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMA1_TOSHIBA_B.264
+fate-h264-conformance-cama1_vtc_c:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/cama1_vtc_c.avc
+fate-h264-conformance-cama2_vtc_b:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/cama2_vtc_b.avc
+fate-h264-conformance-cama3_sand_e:               CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMA3_Sand_E.264
+fate-h264-conformance-cama3_vtc_b:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/cama3_vtc_b.avc
+fate-h264-conformance-camaci3_sony_c:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMACI3_Sony_C.jsv
+fate-h264-conformance-camanl1_toshiba_b:          CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMANL1_TOSHIBA_B.264
+fate-h264-conformance-camanl2_toshiba_b:          CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMANL2_TOSHIBA_B.264
+fate-h264-conformance-camanl3_sand_e:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMANL3_Sand_E.264
+fate-h264-conformance-camasl3_sony_b:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMASL3_Sony_B.jsv
+fate-h264-conformance-camp_mot_mbaff_l30:         CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMP_MOT_MBAFF_L30.26l
+fate-h264-conformance-camp_mot_mbaff_l31:         CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMP_MOT_MBAFF_L31.26l
+fate-h264-conformance-canl1_sony_e:               CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANL1_Sony_E.jsv
+fate-h264-conformance-canl1_sva_b:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANL1_SVA_B.264
+fate-h264-conformance-canl1_toshiba_g:            CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANL1_TOSHIBA_G.264
+fate-h264-conformance-canl2_sony_e:               CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANL2_Sony_E.jsv
+fate-h264-conformance-canl2_sva_b:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANL2_SVA_B.264
+fate-h264-conformance-canl3_sony_c:               CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANL3_Sony_C.jsv
+fate-h264-conformance-canl3_sva_b:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANL3_SVA_B.264
+fate-h264-conformance-canl4_sva_b:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANL4_SVA_B.264
+fate-h264-conformance-canlma2_sony_c:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANLMA2_Sony_C.jsv
+fate-h264-conformance-canlma3_sony_c:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANLMA3_Sony_C.jsv
+fate-h264-conformance-capa1_toshiba_b:            CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAPA1_TOSHIBA_B.264
+fate-h264-conformance-capama3_sand_f:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAPAMA3_Sand_F.264
+fate-h264-conformance-capcm1_sand_e:              CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAPCM1_Sand_E.264
+fate-h264-conformance-capcmnl1_sand_e:            CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAPCMNL1_Sand_E.264
+fate-h264-conformance-capm3_sony_d:               CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAPM3_Sony_D.jsv
+fate-h264-conformance-caqp1_sony_b:               CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAQP1_Sony_B.jsv
+fate-h264-conformance-cavlc_mot_fld0_full_b:      CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/cvmp_mot_fld0_full_B.26l
+fate-h264-conformance-cavlc_mot_frm0_full_b:      CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/cvmp_mot_frm0_full_B.26l
+fate-h264-conformance-cavlc_mot_mbaff0_full_b:    CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/cvmp_mot_mbaff0_full_B.26l
+fate-h264-conformance-cavlc_mot_picaff0_full_b:   CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/cvmp_mot_picaff0_full_B.26l
+fate-h264-conformance-cawp1_toshiba_e:            CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAWP1_TOSHIBA_E.264
+fate-h264-conformance-cawp5_toshiba_e:            CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAWP5_TOSHIBA_E.264
+fate-h264-conformance-ci1_ft_b:                   CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CI1_FT_B.264
+fate-h264-conformance-ci_mw_d:                    CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CI_MW_D.264
+fate-h264-conformance-cvbs3_sony_c:               CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVBS3_Sony_C.jsv
+fate-h264-conformance-cvcanlma2_sony_c:           CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVCANLMA2_Sony_C.jsv
+fate-h264-conformance-cvfc1_sony_c:               CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/h264-conformance/CVFC1_Sony_C.jsv
+fate-h264-conformance-cvfi1_sony_d:               CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVFI1_Sony_D.jsv
+fate-h264-conformance-cvfi1_sva_c:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVFI1_SVA_C.264
+fate-h264-conformance-cvfi2_sony_h:               CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVFI2_Sony_H.jsv
+fate-h264-conformance-cvfi2_sva_c:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVFI2_SVA_C.264
+fate-h264-conformance-cvma1_sony_d:               CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVMA1_Sony_D.jsv
+fate-h264-conformance-cvma1_toshiba_b:            CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVMA1_TOSHIBA_B.264
+fate-h264-conformance-cvmanl1_toshiba_b:          CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVMANL1_TOSHIBA_B.264
+fate-h264-conformance-cvmanl2_toshiba_b:          CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVMANL2_TOSHIBA_B.264
+fate-h264-conformance-cvmapaqp3_sony_e:           CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVMAPAQP3_Sony_E.jsv
+fate-h264-conformance-cvmaqp2_sony_g:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVMAQP2_Sony_G.jsv
+fate-h264-conformance-cvmaqp3_sony_d:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVMAQP3_Sony_D.jsv
+fate-h264-conformance-cvmp_mot_fld_l30_b:         CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVMP_MOT_FLD_L30_B.26l
+fate-h264-conformance-cvmp_mot_frm_l31_b:         CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVMP_MOT_FRM_L31_B.26l
+fate-h264-conformance-cvnlfi1_sony_c:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVNLFI1_Sony_C.jsv
+fate-h264-conformance-cvnlfi2_sony_h:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVNLFI2_Sony_H.jsv
+fate-h264-conformance-cvpa1_toshiba_b:            CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVPA1_TOSHIBA_B.264
+fate-h264-conformance-cvpcmnl1_sva_c:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVPCMNL1_SVA_C.264
+fate-h264-conformance-cvpcmnl2_sva_c:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVPCMNL2_SVA_C.264
+fate-h264-conformance-cvwp1_toshiba_e:            CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVWP1_TOSHIBA_E.264
+fate-h264-conformance-cvwp2_toshiba_e:            CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVWP2_TOSHIBA_E.264
+fate-h264-conformance-cvwp3_toshiba_e:            CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVWP3_TOSHIBA_E.264
+fate-h264-conformance-cvwp5_toshiba_e:            CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVWP5_TOSHIBA_E.264
+fate-h264-conformance-fi1_sony_e:                 CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FI1_Sony_E.jsv
+fate-h264-conformance-frext-alphaconformanceg:    CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/test8b43.264
+fate-h264-conformance-frext-bcrm_freh10:          CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh10.264 -vsync drop
+fate-h264-conformance-frext-brcm_freh11:          CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh11.264 -vsync drop
+fate-h264-conformance-frext-brcm_freh3:           CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh3.264
+fate-h264-conformance-frext-brcm_freh4:           CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh4.264 -vsync drop
+fate-h264-conformance-frext-brcm_freh5:           CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh5.264
+fate-h264-conformance-frext-brcm_freh8:           CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh8.264
+fate-h264-conformance-frext-brcm_freh9:           CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh9.264
+fate-h264-conformance-frext-freh12_b:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/Freh12_B.264
+fate-h264-conformance-frext-freh1_b:              CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/Freh1_B.264
+fate-h264-conformance-frext-freh2_b:              CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/Freh2_B.264
+fate-h264-conformance-frext-freh6:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh6.264 -vsync drop
+fate-h264-conformance-frext-freh7_b:              CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/Freh7_B.264 -vsync drop
+fate-h264-conformance-frext-frext01_jvc_d:        CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/FREXT01_JVC_D.264
+fate-h264-conformance-frext-frext02_jvc_c:        CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/FREXT02_JVC_C.264
+fate-h264-conformance-frext-frext1_panasonic_c:   CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt1_Panasonic.avc
+fate-h264-conformance-frext-frext2_panasonic_b:   CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt2_Panasonic.avc -vsync 0
+fate-h264-conformance-frext-frext3_panasonic_d:   CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt3_Panasonic.avc
+fate-h264-conformance-frext-frext4_panasonic_a:   CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt4_Panasonic.avc
+fate-h264-conformance-frext-frext_mmco4_sony_b:   CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt_MMCO4_Sony_B.264
+fate-h264-conformance-frext-hcaff1_hhi_b:         CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFF1_HHI.264
+fate-h264-conformance-frext-hcafr1_hhi_c:         CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFR1_HHI.264
+fate-h264-conformance-frext-hcafr2_hhi_a:         CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFR2_HHI.264
+fate-h264-conformance-frext-hcafr3_hhi_a:         CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFR3_HHI.264
+fate-h264-conformance-frext-hcafr4_hhi_a:         CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFR4_HHI.264
+fate-h264-conformance-frext-hcamff1_hhi_b:        CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAMFF1_HHI.264
+fate-h264-conformance-frext-hi422fr10_sony_b:     CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/Hi422FR10_SONY_B.264
+fate-h264-conformance-frext-hi422fr13_sony_b:     CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/Hi422FR13_SONY_B.264 -pix_fmt yuv422p10le
+fate-h264-conformance-frext-hi422fr1_sony_a:      CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/Hi422FR1_SONY_A.jsv
+fate-h264-conformance-frext-hi422fr6_sony_a:      CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/Hi422FR6_SONY_A.jsv -pix_fmt yuv422p10le
+fate-h264-conformance-frext-hpca_brcm_c:          CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCA_BRCM_C.264
+fate-h264-conformance-frext-hpcadq_brcm_b:        CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCADQ_BRCM_B.264
+fate-h264-conformance-frext-hpcafl_bcrm_c:        CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAFL_BRCM_C.264 -vsync drop
+fate-h264-conformance-frext-hpcaflnl_bcrm_c:      CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAFLNL_BRCM_C.264 -vsync drop
+fate-h264-conformance-frext-hpcalq_brcm_b:        CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCALQ_BRCM_B.264
+fate-h264-conformance-frext-hpcamapalq_bcrm_b:    CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAMAPALQ_BRCM_B.264 -vsync 0
+fate-h264-conformance-frext-hpcamolq_brcm_b:      CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAMOLQ_BRCM_B.264
+fate-h264-conformance-frext-hpcanl_brcm_c:        CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCANL_BRCM_C.264
+fate-h264-conformance-frext-hpcaq2lq_brcm_b:      CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAQ2LQ_BRCM_B.264
+fate-h264-conformance-frext-hpcv_brcm_a:          CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCV_BRCM_A.264
+fate-h264-conformance-frext-hpcvfl_bcrm_a:        CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCVFL_BRCM_A.264 -vsync drop
+fate-h264-conformance-frext-hpcvflnl_bcrm_a:      CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCVFLNL_BRCM_A.264 -vsync drop
+fate-h264-conformance-frext-hpcvmolq_brcm_b:      CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCVMOLQ_BRCM_B.264
+fate-h264-conformance-frext-hpcvnl_brcm_a:        CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCVNL_BRCM_A.264
+fate-h264-conformance-frext-pph10i1_panasonic_a:  CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I1_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph10i2_panasonic_a:  CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I2_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph10i3_panasonic_a:  CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I3_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph10i4_panasonic_a:  CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I4_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph10i5_panasonic_a:  CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I5_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph10i6_panasonic_a:  CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I6_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph10i7_panasonic_a:  CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I7_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph422i1_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I1_Panasonic_A.264 -pix_fmt yuv422p10le
+fate-h264-conformance-frext-pph422i2_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I2_Panasonic_A.264 -pix_fmt yuv422p10le
+fate-h264-conformance-frext-pph422i3_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I3_Panasonic_A.264 -pix_fmt yuv422p10le
+fate-h264-conformance-frext-pph422i4_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I4_Panasonic_A.264 -pix_fmt yuv422p10le
+fate-h264-conformance-frext-pph422i5_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I5_Panasonic_A.264 -pix_fmt yuv422p10le
+fate-h264-conformance-frext-pph422i6_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I6_Panasonic_A.264 -pix_fmt yuv422p10le
+fate-h264-conformance-frext-pph422i7_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I7_Panasonic_A.264 -pix_fmt yuv422p10le
+fate-h264-conformance-hcbp2_hhi_a:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/HCBP2_HHI_A.264
+fate-h264-conformance-hcmp1_hhi_a:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/HCMP1_HHI_A.264
+fate-h264-conformance-ls_sva_d:                   CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/LS_SVA_D.264
+fate-h264-conformance-midr_mw_d:                  CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MIDR_MW_D.264
+fate-h264-conformance-mps_mw_a:                   CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MPS_MW_A.264
+fate-h264-conformance-mr1_bt_a:                   CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR1_BT_A.h264
+fate-h264-conformance-mr1_mw_a:                   CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR1_MW_A.264
+fate-h264-conformance-mr2_mw_a:                   CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR2_MW_A.264
+fate-h264-conformance-mr2_tandberg_e:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR2_TANDBERG_E.264
+fate-h264-conformance-mr3_tandberg_b:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR3_TANDBERG_B.264
+fate-h264-conformance-mr4_tandberg_c:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR4_TANDBERG_C.264
+fate-h264-conformance-mr5_tandberg_c:             CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR5_TANDBERG_C.264
+fate-h264-conformance-mr6_bt_b:                   CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR6_BT_B.h264
+fate-h264-conformance-mr7_bt_b:                   CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR7_BT_B.h264
+fate-h264-conformance-mr8_bt_b:                   CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR8_BT_B.h264
+fate-h264-conformance-mr9_bt_b:                   CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR9_BT_B.h264
+fate-h264-conformance-mv1_brcm_d:                 CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/src19td.IBP.264
+fate-h264-conformance-nl1_sony_d:                 CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/NL1_Sony_D.jsv
+fate-h264-conformance-nl2_sony_h:                 CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/NL2_Sony_H.jsv
+fate-h264-conformance-nl3_sva_e:                  CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/NL3_SVA_E.264
+fate-h264-conformance-nlmq1_jvc_c:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/NLMQ1_JVC_C.264
+fate-h264-conformance-nlmq2_jvc_c:                CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/NLMQ2_JVC_C.264
+fate-h264-conformance-nrf_mw_e:                   CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/NRF_MW_E.264
+fate-h264-conformance-sharp_mp_field_1_b:         CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_Field_1_B.jvt
+fate-h264-conformance-sharp_mp_field_2_b:         CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_Field_2_B.jvt
+fate-h264-conformance-sharp_mp_field_3_b:         CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_Field_3_B.jvt
+fate-h264-conformance-sharp_mp_paff_1r2:          CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_PAFF_1r2.jvt
+fate-h264-conformance-sharp_mp_paff_2r:           CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_PAFF_2.jvt
+fate-h264-conformance-sl1_sva_b:                  CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/SL1_SVA_B.264
+fate-h264-conformance-sva_ba1_b:                  CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/SVA_BA1_B.264
+fate-h264-conformance-sva_ba2_d:                  CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/SVA_BA2_D.264
+fate-h264-conformance-sva_base_b:                 CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/SVA_Base_B.264
+fate-h264-conformance-sva_cl1_e:                  CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/SVA_CL1_E.264
+fate-h264-conformance-sva_fm1_e:                  CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/SVA_FM1_E.264
+fate-h264-conformance-sva_nl1_b:                  CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/SVA_NL1_B.264
+fate-h264-conformance-sva_nl2_e:                  CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/SVA_NL2_E.264
 
-fate-h264-bsf-mp4toannexb:                        CMD = md5 -i $(SAMPLES)/h264/interlaced_crop.mp4 -vcodec copy -bsf h264_mp4toannexb -f h264
-fate-h264-crop-to-container:                      CMD = framemd5 -i $(SAMPLES)/h264/crop-to-container-dims-canon.mov
-fate-h264-extreme-plane-pred:                     CMD = framemd5 -i $(SAMPLES)/h264/extreme-plane-pred.h264
-fate-h264-interlace-crop:                         CMD = framecrc -i $(SAMPLES)/h264/interlaced_crop.mp4 -vframes 3
-fate-h264-lossless:                               CMD = framecrc -i $(SAMPLES)/h264/lossless.h264
+fate-h264-bsf-mp4toannexb:                        CMD = md5 -i $(TARGET_SAMPLES)/h264/interlaced_crop.mp4 -vcodec copy -bsf h264_mp4toannexb -f h264
+fate-h264-crop-to-container:                      CMD = framemd5 -i $(TARGET_SAMPLES)/h264/crop-to-container-dims-canon.mov
+fate-h264-extreme-plane-pred:                     CMD = framemd5 -i $(TARGET_SAMPLES)/h264/extreme-plane-pred.h264
+fate-h264-interlace-crop:                         CMD = framecrc -i $(TARGET_SAMPLES)/h264/interlaced_crop.mp4 -vframes 3
+fate-h264-lossless:                               CMD = framecrc -i $(TARGET_SAMPLES)/h264/lossless.h264
 
-fate-h264-reinit-%:                               CMD = framecrc -i $(SAMPLES)/h264/$(@:fate-h264-%=%).h264 -vf format=yuv444p10le,scale=352:288
+fate-h264-reinit-%:                               CMD = framecrc -i $(TARGET_SAMPLES)/h264/$(@:fate-h264-%=%).h264 -vf format=yuv444p10le,scale=w=352:h=288
diff --git a/tests/fate/image.mak b/tests/fate/image.mak
index 2a6a4b2..6b8e139 100644
--- a/tests/fate/image.mak
+++ b/tests/fate/image.mak
@@ -1,32 +1,49 @@
 FATE_IMAGE-$(call DEMDEC, IMAGE2, DPX) += fate-dpx
-fate-dpx: CMD = framecrc -i $(SAMPLES)/dpx/lighthouse_rgb48.dpx
+fate-dpx: CMD = framecrc -i $(TARGET_SAMPLES)/dpx/lighthouse_rgb48.dpx
+
+FATE_EXR += fate-exr-slice-raw
+fate-exr-slice-raw: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgba_slice_raw.exr -pix_fmt rgba64le
+
+FATE_EXR += fate-exr-slice-rle
+fate-exr-slice-rle: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgba_slice_rle.exr -pix_fmt rgba64le
+
+FATE_EXR += fate-exr-slice-zip1
+fate-exr-slice-zip1: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgba_slice_zip1.exr -pix_fmt rgba64le
+
+FATE_EXR += fate-exr-slice-zip16
+fate-exr-slice-zip16: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgba_slice_zip16.exr -pix_fmt rgba64le
+
+FATE_EXR-$(call DEMDEC, IMAGE2, EXR) += $(FATE_EXR)
+
+FATE_IMAGE += $(FATE_EXR-yes)
+fate-exr: $(FATE_EXR-yes)
 
 FATE_IMAGE-$(call DEMDEC, IMAGE2, PICTOR) += fate-pictor
-fate-pictor: CMD = framecrc -i $(SAMPLES)/pictor/MFISH.PIC -pix_fmt rgb24
+fate-pictor: CMD = framecrc -i $(TARGET_SAMPLES)/pictor/MFISH.PIC -pix_fmt rgb24
 
 FATE_IMAGE-$(call DEMDEC, IMAGE2, PTX) += fate-ptx
-fate-ptx: CMD = framecrc -i $(SAMPLES)/ptx/_113kw_pic.ptx -pix_fmt rgb24
+fate-ptx: CMD = framecrc -i $(TARGET_SAMPLES)/ptx/_113kw_pic.ptx -pix_fmt rgb24
 
 FATE_SUNRASTER += fate-sunraster-1bit-raw
-fate-sunraster-1bit-raw: CMD = framecrc -i $(SAMPLES)/sunraster/lena-1bit-raw.sun
+fate-sunraster-1bit-raw: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/lena-1bit-raw.sun
 
 FATE_SUNRASTER += fate-sunraster-1bit-rle
-fate-sunraster-1bit-rle: CMD = framecrc -i $(SAMPLES)/sunraster/lena-1bit-rle.sun
+fate-sunraster-1bit-rle: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/lena-1bit-rle.sun
 
 FATE_SUNRASTER += fate-sunraster-8bit-raw
-fate-sunraster-8bit-raw: CMD = framecrc -i $(SAMPLES)/sunraster/lena-8bit-raw.sun -pix_fmt rgb24
+fate-sunraster-8bit-raw: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/lena-8bit-raw.sun -pix_fmt rgb24
 
 FATE_SUNRASTER += fate-sunraster-8bit_gray-raw
-fate-sunraster-8bit_gray-raw: CMD = framecrc -i $(SAMPLES)/sunraster/gray.ras
+fate-sunraster-8bit_gray-raw: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/gray.ras
 
 FATE_SUNRASTER += fate-sunraster-8bit-rle
-fate-sunraster-8bit-rle: CMD = framecrc -i $(SAMPLES)/sunraster/lena-8bit-rle.sun -pix_fmt rgb24
+fate-sunraster-8bit-rle: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/lena-8bit-rle.sun -pix_fmt rgb24
 
 FATE_SUNRASTER += fate-sunraster-24bit-raw
-fate-sunraster-24bit-raw: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-raw.sun
+fate-sunraster-24bit-raw: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/lena-24bit-raw.sun
 
 FATE_SUNRASTER += fate-sunraster-24bit-rle
-fate-sunraster-24bit-rle: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-rle.sun
+fate-sunraster-24bit-rle: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/lena-24bit-rle.sun
 
 FATE_SUNRASTER-$(call DEMDEC, IMAGE2, SUNRAST) += $(FATE_SUNRASTER)
 
@@ -52,24 +69,24 @@
 FATE_IMAGE += $(FATE_TARGA-yes)
 fate-targa: $(FATE_TARGA-yes)
 
-fate-targa-conformance-CBW8:  CMD = framecrc -i $(SAMPLES)/targa-conformance/CBW8.TGA
-fate-targa-conformance-CCM8:  CMD = framecrc -i $(SAMPLES)/targa-conformance/CCM8.TGA  -pix_fmt rgba
-fate-targa-conformance-CTC16: CMD = framecrc -i $(SAMPLES)/targa-conformance/CTC16.TGA -pix_fmt rgb555le
-fate-targa-conformance-CTC24: CMD = framecrc -i $(SAMPLES)/targa-conformance/CTC24.TGA
-fate-targa-conformance-CTC32: CMD = framecrc -i $(SAMPLES)/targa-conformance/CTC32.TGA -pix_fmt bgra
-fate-targa-conformance-UBW8:  CMD = framecrc -i $(SAMPLES)/targa-conformance/UBW8.TGA
-fate-targa-conformance-UCM8:  CMD = framecrc -i $(SAMPLES)/targa-conformance/UCM8.TGA  -pix_fmt rgba
-fate-targa-conformance-UTC16: CMD = framecrc -i $(SAMPLES)/targa-conformance/UTC16.TGA -pix_fmt rgb555le
-fate-targa-conformance-UTC24: CMD = framecrc -i $(SAMPLES)/targa-conformance/UTC24.TGA
-fate-targa-conformance-UTC32: CMD = framecrc -i $(SAMPLES)/targa-conformance/UTC32.TGA -pix_fmt bgra
+fate-targa-conformance-CBW8:  CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/CBW8.TGA
+fate-targa-conformance-CCM8:  CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/CCM8.TGA  -pix_fmt rgba
+fate-targa-conformance-CTC16: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/CTC16.TGA -pix_fmt rgb555le
+fate-targa-conformance-CTC24: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/CTC24.TGA
+fate-targa-conformance-CTC32: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/CTC32.TGA -pix_fmt bgra
+fate-targa-conformance-UBW8:  CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/UBW8.TGA
+fate-targa-conformance-UCM8:  CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/UCM8.TGA  -pix_fmt rgba
+fate-targa-conformance-UTC16: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/UTC16.TGA -pix_fmt rgb555le
+fate-targa-conformance-UTC24: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/UTC24.TGA
+fate-targa-conformance-UTC32: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/UTC32.TGA -pix_fmt bgra
 
-fate-targa-top-to-bottom: CMD = framecrc -i $(SAMPLES)/targa/lena-top-to-bottom.tga
+fate-targa-top-to-bottom: CMD = framecrc -i $(TARGET_SAMPLES)/targa/lena-top-to-bottom.tga
 
 FATE_TIFF += fate-tiff-fax-g3
-fate-tiff-fax-g3: CMD = framecrc -i $(SAMPLES)/CCITT_fax/G31D.TIF
+fate-tiff-fax-g3: CMD = framecrc -i $(TARGET_SAMPLES)/CCITT_fax/G31D.TIF
 
 FATE_TIFF += fate-tiff-fax-g3s
-fate-tiff-fax-g3s: CMD = framecrc -i $(SAMPLES)/CCITT_fax/G31DS.TIF
+fate-tiff-fax-g3s: CMD = framecrc -i $(TARGET_SAMPLES)/CCITT_fax/G31DS.TIF
 
 FATE_TIFF-$(call DEMDEC, IMAGE2, TIFF) += $(FATE_TIFF)
 
@@ -77,7 +94,7 @@
 fate-tiff: $(FATE_TIFF-yes)
 
 FATE_IMAGE-$(call DEMDEC, IMAGE2, XFACE) += fate-xface
-fate-xface: CMD = framecrc -i $(SAMPLES)/xface/lena.xface
+fate-xface: CMD = framecrc -i $(TARGET_SAMPLES)/xface/lena.xface
 
 FATE_IMAGE += $(FATE_IMAGE-yes)
 
diff --git a/tests/fate/indeo.mak b/tests/fate/indeo.mak
index 5a99b46..e725a6b 100644
--- a/tests/fate/indeo.mak
+++ b/tests/fate/indeo.mak
@@ -1,14 +1,17 @@
 FATE_INDEO-$(call DEMDEC, AVI, INDEO2) += fate-indeo2
-fate-indeo2: CMD = framecrc -i $(SAMPLES)/rt21/VPAR0026.AVI
+fate-indeo2: CMD = framecrc -i $(TARGET_SAMPLES)/rt21/VPAR0026.AVI
 
 FATE_INDEO-$(call DEMDEC, MOV, INDEO3) += fate-indeo3
-fate-indeo3: CMD = framecrc -i $(SAMPLES)/iv32/cubes.mov
+fate-indeo3: CMD = framecrc -i $(TARGET_SAMPLES)/iv32/cubes.mov
+
+FATE_INDEO-$(call DEMDEC, AVI, INDEO3) += fate-indeo3-2
+fate-indeo3-2: CMD = framecrc -i $(TARGET_SAMPLES)/iv32/OPENINGH.avi
 
 FATE_INDEO-$(call DEMDEC, AVI, INDEO4) += fate-indeo4
-fate-indeo4: CMD = framecrc -i $(SAMPLES)/iv41/indeo41-partial.avi -an
+fate-indeo4: CMD = framecrc -i $(TARGET_SAMPLES)/iv41/indeo41-partial.avi -an
 
 FATE_INDEO-$(call DEMDEC, AVI, INDEO5) += fate-indeo5
-fate-indeo5: CMD = framecrc -i $(SAMPLES)/iv50/Educ_Movie_DeadlyForce.avi -an
+fate-indeo5: CMD = framecrc -i $(TARGET_SAMPLES)/iv50/Educ_Movie_DeadlyForce.avi -an
 
 FATE_SAMPLES_AVCONV += $(FATE_INDEO-yes)
 fate-indeo: $(FATE_INDEO-yes)
diff --git a/tests/fate/libavdevice.mak b/tests/fate/libavdevice.mak
new file mode 100644
index 0000000..cb6af51
--- /dev/null
+++ b/tests/fate/libavdevice.mak
@@ -0,0 +1,6 @@
+FATE_LIBAVDEVICE-yes += fate-timefilter
+fate-timefilter: libavdevice/timefilter-test$(EXESUF)
+fate-timefilter: CMD = run libavdevice/timefilter-test
+
+FATE-$(CONFIG_AVDEVICE) += $(FATE_LIBAVDEVICE-yes)
+fate-libavdevice: $(FATE_LIBAVDEVICE-yes)
diff --git a/tests/fate/libavformat.mak b/tests/fate/libavformat.mak
index 8332246..d532adc 100644
--- a/tests/fate/libavformat.mak
+++ b/tests/fate/libavformat.mak
@@ -1,14 +1,14 @@
-FATE_LIBAVFORMAT += fate-noproxy
+FATE_LIBAVFORMAT-$(CONFIG_NETWORK) += fate-noproxy
 fate-noproxy: libavformat/noproxy-test$(EXESUF)
 fate-noproxy: CMD = run libavformat/noproxy-test
 
-FATE_LIBAVFORMAT += fate-srtp
+FATE_LIBAVFORMAT-yes += fate-srtp
 fate-srtp: libavformat/srtp-test$(EXESUF)
 fate-srtp: CMD = run libavformat/srtp-test
 
-FATE_LIBAVFORMAT += fate-url
+FATE_LIBAVFORMAT-yes += fate-url
 fate-url: libavformat/url-test$(EXESUF)
 fate-url: CMD = run libavformat/url-test
 
-FATE-$(CONFIG_AVFORMAT) += $(FATE_LIBAVFORMAT)
+FATE-$(CONFIG_AVFORMAT) += $(FATE_LIBAVFORMAT-yes)
 fate-libavformat: $(FATE_LIBAVFORMAT)
diff --git a/tests/fate/libavutil.mak b/tests/fate/libavutil.mak
index 2508ba0..eeece47 100644
--- a/tests/fate/libavutil.mak
+++ b/tests/fate/libavutil.mak
@@ -54,6 +54,10 @@
 fate-md5: libavutil/md5-test$(EXESUF)
 fate-md5: CMD = run libavutil/md5-test
 
+FATE_LIBAVUTIL += fate-murmur3
+fate-murmur3: libavutil/murmur3-test$(EXESUF)
+fate-murmur3: CMD = run libavutil/murmur3-test
+
 FATE_LIBAVUTIL += fate-parseutils
 fate-parseutils: libavutil/parseutils-test$(EXESUF)
 fate-parseutils: CMD = run libavutil/parseutils-test
@@ -62,10 +66,23 @@
 fate-random_seed: libavutil/random_seed-test$(EXESUF)
 fate-random_seed: CMD = run libavutil/random_seed-test
 
+FATE_LIBAVUTIL += fate-ripemd
+fate-ripemd: libavutil/ripemd-test$(EXESUF)
+fate-ripemd: CMD = run libavutil/ripemd-test
+
 FATE_LIBAVUTIL += fate-sha
 fate-sha: libavutil/sha-test$(EXESUF)
 fate-sha: CMD = run libavutil/sha-test
 
+FATE_LIBAVUTIL += fate-sha512
+fate-sha512: libavutil/sha512-test$(EXESUF)
+fate-sha512: CMD = run libavutil/sha512-test
+
+FATE_LIBAVUTIL += fate-tree
+fate-tree: libavutil/tree-test$(EXESUF)
+fate-tree: CMD = run libavutil/tree-test
+fate-tree: REF = /dev/null
+
 FATE_LIBAVUTIL += fate-xtea
 fate-xtea: libavutil/xtea-test$(EXESUF)
 fate-xtea: CMD = run libavutil/xtea-test
diff --git a/tests/fate/lossless-audio.mak b/tests/fate/lossless-audio.mak
index 8dc0f06..0736a01 100644
--- a/tests/fate/lossless-audio.mak
+++ b/tests/fate/lossless-audio.mak
@@ -1,29 +1,26 @@
 FATE_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, MOV, ALAC) += fate-lossless-alac
-fate-lossless-alac: CMD = md5 -i $(SAMPLES)/lossless-audio/inside.m4a -f s16le
+fate-lossless-alac: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/inside.m4a -f s16le
 
 FATE_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, MLP, MLP) += fate-lossless-meridianaudio
-fate-lossless-meridianaudio: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.mlp -f s16le
-
-FATE_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, APE, APE) += fate-lossless-monkeysaudio
-fate-lossless-monkeysaudio: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.ape -f s16le
+fate-lossless-meridianaudio: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.mlp -f s16le
 
 FATE_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, RM, RALF) += fate-ralf
-fate-ralf: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.rmvb -vn -f s16le
+fate-ralf: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.rmvb -vn -f s16le
 
 FATE_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, SHORTEN, SHORTEN) += fate-lossless-shorten
-fate-lossless-shorten: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.shn -f s16le
+fate-lossless-shorten: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.shn -f s16le
 
 FATE_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, TAK, TAK) += fate-lossless-tak
-fate-lossless-tak: CMD = crc -i $(SAMPLES)/lossless-audio/luckynight-partial.tak
+fate-lossless-tak: CMD = crc -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.tak
 
 FATE_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, TTA, TTA) += fate-lossless-tta
-fate-lossless-tta: CMD = crc -i $(SAMPLES)/lossless-audio/inside.tta
+fate-lossless-tta: CMD = crc -i $(TARGET_SAMPLES)/lossless-audio/inside.tta
 
 FATE_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, TTA, TTA) += fate-lossless-tta-encrypted
-fate-lossless-tta-encrypted: CMD = crc -password ffmpeg -i $(SAMPLES)/lossless-audio/encrypted.tta
+fate-lossless-tta-encrypted: CMD = crc -password ffmpeg -i $(TARGET_SAMPLES)/lossless-audio/encrypted.tta
 
 FATE_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, ASF, WMALOSSLESS) += fate-lossless-wma
-fate-lossless-wma: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.wma -f s16le
+fate-lossless-wma: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.wma -f s16le
 
 FATE_SAMPLES_LOSSLESS_AUDIO += $(FATE_SAMPLES_LOSSLESS_AUDIO-yes)
 
diff --git a/tests/fate/lossless-video.mak b/tests/fate/lossless-video.mak
index f918ac4..11eba30 100644
--- a/tests/fate/lossless-video.mak
+++ b/tests/fate/lossless-video.mak
@@ -1,50 +1,56 @@
 FATE_CLLC += fate-cllc-argb
-fate-cllc-argb: CMD = framecrc -i $(SAMPLES)/cllc/sample-cllc-argb.avi
+fate-cllc-argb: CMD = framecrc -i $(TARGET_SAMPLES)/cllc/sample-cllc-argb.avi
 
 FATE_CLLC += fate-cllc-rgb
-fate-cllc-rgb: CMD = framecrc -i $(SAMPLES)/cllc/sample-cllc-rgb.avi
+fate-cllc-rgb: CMD = framecrc -i $(TARGET_SAMPLES)/cllc/sample-cllc-rgb.avi
+
+FATE_CLLC += fate-cllc-yuy2-noblock
+fate-cllc-yuy2-noblock: CMD = framecrc -i $(TARGET_SAMPLES)/cllc/sample-cllc-yuy2-noblock.avi
 
 FATE_LOSSLESS_VIDEO-$(call DEMDEC, AVI, CLLC) += $(FATE_CLLC)
 fate-cllc: $(FATE_CLLC)
 
 FATE_LAGARITH += fate-lagarith-rgb24
-fate-lagarith-rgb24: CMD = framecrc -i $(SAMPLES)/lagarith/lag-rgb24.avi
+fate-lagarith-rgb24: CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lag-rgb24.avi
 
 FATE_LAGARITH += fate-lagarith-rgb32
-fate-lagarith-rgb32: CMD = framecrc -i $(SAMPLES)/lagarith/lag-rgb32.avi -pix_fmt bgra
+fate-lagarith-rgb32: CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lag-rgb32.avi -pix_fmt bgra
 
 FATE_LAGARITH += fate-lagarith-yuy2
-fate-lagarith-yuy2: CMD = framecrc -i $(SAMPLES)/lagarith/lag-yuy2.avi
+fate-lagarith-yuy2: CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lag-yuy2.avi
 
 FATE_LAGARITH += fate-lagarith-yv12
-fate-lagarith-yv12: CMD = framecrc -i $(SAMPLES)/lagarith/lag-yv12.avi
+fate-lagarith-yv12: CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lag-yv12.avi
+
+FATE_LAGARITH += fate-lagarith-red
+fate-lagarith-red: CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lagarith-red.avi
 
 FATE_LOSSLESS_VIDEO-$(call DEMDEC, AVI, LAGARITH) += $(FATE_LAGARITH)
 fate-lagarith: $(FATE_LAGARITH)
 
 FATE_LOCO += fate-loco-rgb
-fate-loco-rgb: CMD = framecrc -i $(SAMPLES)/loco/pig-loco-rgb.avi
+fate-loco-rgb: CMD = framecrc -i $(TARGET_SAMPLES)/loco/pig-loco-rgb.avi
 
 FATE_LOCO += fate-loco-yuy2
-fate-loco-yuy2: CMD = framecrc -i $(SAMPLES)/loco/pig-loco-0.avi
+fate-loco-yuy2: CMD = framecrc -i $(TARGET_SAMPLES)/loco/pig-loco-0.avi
 
 FATE_LOSSLESS_VIDEO-$(call DEMDEC, AVI, LOCO) += $(FATE_LOCO)
 fate-loco: $(FATE_LOCO)
 
 FATE_LOSSLESS_VIDEO-$(call DEMDEC, AVI, MSRLE) += fate-msrle-8bit
-fate-msrle-8bit: CMD = framecrc -i $(SAMPLES)/msrle/Search-RLE.avi -pix_fmt rgb24
+fate-msrle-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/msrle/Search-RLE.avi -pix_fmt rgb24
 
 FATE_LOSSLESS_VIDEO-$(call DEMDEC, AVI, MSZH) += fate-mszh
-fate-mszh: CMD = framecrc -i $(SAMPLES)/lcl/mszh-1frame.avi
+fate-mszh: CMD = framecrc -i $(TARGET_SAMPLES)/lcl/mszh-1frame.avi
 
 FATE_LOSSLESS_VIDEO-$(call DEMDEC, AVI, VBLE) += fate-vble
-fate-vble: CMD = framecrc -i $(SAMPLES)/vble/flowers-partial-2MB.avi
+fate-vble: CMD = framecrc -i $(TARGET_SAMPLES)/vble/flowers-partial-2MB.avi
 
 FATE_LOSSLESS_VIDEO-$(call DEMDEC, AVI, ZEROCODEC) += fate-zerocodec
-fate-zerocodec: CMD = framecrc -i $(SAMPLES)/zerocodec/sample-zeco.avi
+fate-zerocodec: CMD = framecrc -i $(TARGET_SAMPLES)/zerocodec/sample-zeco.avi
 
 FATE_LOSSLESS_VIDEO-$(call DEMDEC, AVI, ZLIB) += fate-zlib
-fate-zlib: CMD = framecrc -i $(SAMPLES)/lcl/zlib-1frame.avi
+fate-zlib: CMD = framecrc -i $(TARGET_SAMPLES)/lcl/zlib-1frame.avi
 
 FATE_LOSSLESS_VIDEO += $(FATE_LOSSLESS_VIDEO-yes)
 
diff --git a/tests/fate/microsoft.mak b/tests/fate/microsoft.mak
index 6347f20..41954c0 100644
--- a/tests/fate/microsoft.mak
+++ b/tests/fate/microsoft.mak
@@ -1,46 +1,46 @@
 FATE_MICROSOFT-$(call DEMDEC, AVI, MSMPEG4V1) += fate-msmpeg4v1
-fate-msmpeg4v1: CMD = framecrc -flags +bitexact -idct simple -i $(SAMPLES)/msmpeg4v1/mpg4.avi -an
+fate-msmpeg4v1: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/msmpeg4v1/mpg4.avi -an
 
 FATE_MSVIDEO1 += fate-msvideo1-8bit
-fate-msvideo1-8bit: CMD = framecrc -i $(SAMPLES)/cram/skating.avi -t 1 -pix_fmt rgb24
+fate-msvideo1-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/cram/skating.avi -t 1 -pix_fmt rgb24
 
 FATE_MSVIDEO1 += fate-msvideo1-16bit
-fate-msvideo1-16bit: CMD = framecrc -i $(SAMPLES)/cram/clock-cram16.avi -pix_fmt rgb24
+fate-msvideo1-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/cram/clock-cram16.avi -pix_fmt rgb24
 
 FATE_MICROSOFT-$(call DEMDEC, AVI, MSVIDEO1) += $(FATE_MSVIDEO1)
 fate-msvideo1: $(FATE_MSVIDEO1)
 
 FATE_WMV8_DRM += fate-wmv8-drm
 # discard last packet to avoid fails due to overread of VC-1 decoder
-fate-wmv8-drm: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(SAMPLES)/wmv8/wmv_drm.wmv -an -vframes 162
+fate-wmv8-drm: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(TARGET_SAMPLES)/wmv8/wmv_drm.wmv -an -vframes 162
 
 FATE_WMV8_DRM += fate-wmv8-drm-nodec
-fate-wmv8-drm-nodec: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(SAMPLES)/wmv8/wmv_drm.wmv -acodec copy -vcodec copy
+fate-wmv8-drm-nodec: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(TARGET_SAMPLES)/wmv8/wmv_drm.wmv -acodec copy -vcodec copy
 
 #FATE_MICROSOFT += fate-wmv8-x8intra
 FATE_TESTS-no += fate-wmv8-x8intra
-fate-wmv8-x8intra: CMD = framecrc -flags +bitexact -idct 19 -i $(SAMPLES)/wmv8/wmv8_x8intra.wmv -an
+fate-wmv8-x8intra: CMD = framecrc -flags +bitexact -idct 19 -i $(TARGET_SAMPLES)/wmv8/wmv8_x8intra.wmv -an
 
 FATE_MICROSOFT-$(call DEMDEC, ASF, WMV3) += $(FATE_WMV8_DRM)
 fate-wmv8_drm: $(FATE_WMV8_DRM)
 
 FATE_VC1-$(CONFIG_VC1_DEMUXER) += fate-vc1_sa00040
-fate-vc1_sa00040: CMD = framecrc -i $(SAMPLES)/vc1/SA00040.vc1
+fate-vc1_sa00040: CMD = framecrc -i $(TARGET_SAMPLES)/vc1/SA00040.vc1
 
 FATE_VC1-$(CONFIG_VC1_DEMUXER) += fate-vc1_sa00050
-fate-vc1_sa00050: CMD = framecrc -i $(SAMPLES)/vc1/SA00050.vc1
+fate-vc1_sa00050: CMD = framecrc -i $(TARGET_SAMPLES)/vc1/SA00050.vc1
 
 FATE_VC1-$(CONFIG_VC1_DEMUXER) += fate-vc1_sa10091
-fate-vc1_sa10091: CMD = framecrc -i $(SAMPLES)/vc1/SA10091.vc1
+fate-vc1_sa10091: CMD = framecrc -i $(TARGET_SAMPLES)/vc1/SA10091.vc1
 
 FATE_VC1-$(CONFIG_VC1_DEMUXER) += fate-vc1_sa10143
-fate-vc1_sa10143: CMD = framecrc -i $(SAMPLES)/vc1/SA10143.vc1
+fate-vc1_sa10143: CMD = framecrc -i $(TARGET_SAMPLES)/vc1/SA10143.vc1
 
 FATE_VC1-$(CONFIG_VC1_DEMUXER) += fate-vc1_sa20021
-fate-vc1_sa20021: CMD = framecrc -i $(SAMPLES)/vc1/SA20021.vc1
+fate-vc1_sa20021: CMD = framecrc -i $(TARGET_SAMPLES)/vc1/SA20021.vc1
 
 FATE_VC1-$(CONFIG_MOV_DEMUXER) += fate-vc1-ism
-fate-vc1-ism: CMD = framecrc -i $(SAMPLES)/isom/vc1-wmapro.ism -an
+fate-vc1-ism: CMD = framecrc -i $(TARGET_SAMPLES)/isom/vc1-wmapro.ism -an
 
 FATE_MICROSOFT-$(CONFIG_VC1_DECODER) += $(FATE_VC1-yes)
 fate-vc1: $(FATE_VC1-yes)
diff --git a/tests/fate/monkeysaudio.mak b/tests/fate/monkeysaudio.mak
new file mode 100644
index 0000000..9ce872a
--- /dev/null
+++ b/tests/fate/monkeysaudio.mak
@@ -0,0 +1,20 @@
+APE_VERSIONS = 380 388 389b1 391b1 392b2 394b1
+
+define FATE_APE_SUITE
+FATE_APE += fate-lossless-monkeysaudio-$(1)-normal
+fate-lossless-monkeysaudio-$(1)-normal: CMD = crc -i $(TARGET_SAMPLES)/lossless-audio/luckynight-mac$(1)-c2000.ape -af atrim=end_sample=73728
+fate-lossless-monkeysaudio-$(1)-normal: REF = CRC=0x5d08c17e
+fate-lossless-monkeysaudio-$(1)-normal: CMP = oneline
+FATE_APE += fate-lossless-monkeysaudio-$(1)-extrahigh
+fate-lossless-monkeysaudio-$(1)-extrahigh: CMD = crc -i $(TARGET_SAMPLES)/lossless-audio/luckynight-mac$(1)-c4000.ape -af atrim=end_sample=73728
+fate-lossless-monkeysaudio-$(1)-extrahigh: REF = CRC=0x5d08c17e
+fate-lossless-monkeysaudio-$(1)-extrahigh: CMP = oneline
+endef
+
+$(foreach N,$(APE_VERSIONS),$(eval $(call FATE_APE_SUITE,$(N))))
+
+FATE_APE += fate-lossless-monkeysaudio-399
+fate-lossless-monkeysaudio-399: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.ape -f s16le
+
+FATE_SAMPLES_AVCONV-$(call DEMDEC, APE, APE) += $(FATE_APE)
+fate-lossless-monkeysaudio: $(FATE_APE)
diff --git a/tests/fate/mp3.mak b/tests/fate/mp3.mak
index 1986061..57ee084 100644
--- a/tests/fate/mp3.mak
+++ b/tests/fate/mp3.mak
@@ -1,33 +1,33 @@
 FATE_MP3 += fate-mp3-float-conf-compl
-fate-mp3-float-conf-compl: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/compl.bit
+fate-mp3-float-conf-compl: CMD = pcm -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/compl.bit
 fate-mp3-float-conf-compl: REF = $(SAMPLES)/mp3-conformance/compl.pcm
 
 FATE_MP3 += fate-mp3-float-conf-he_32khz
-fate-mp3-float-conf-he_32khz: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/he_32khz.bit -fs 343296
+fate-mp3-float-conf-he_32khz: CMD = pcm -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/he_32khz.bit -fs 343296
 fate-mp3-float-conf-he_32khz: REF = $(SAMPLES)/mp3-conformance/he_32khz.pcm
 
 FATE_MP3 += fate-mp3-float-conf-he_44khz
-fate-mp3-float-conf-he_44khz: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/he_44khz.bit -fs 942336
+fate-mp3-float-conf-he_44khz: CMD = pcm -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/he_44khz.bit -fs 942336
 fate-mp3-float-conf-he_44khz: REF = $(SAMPLES)/mp3-conformance/he_44khz.pcm
 
 FATE_MP3 += fate-mp3-float-conf-he_48khz
-fate-mp3-float-conf-he_48khz: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/he_48khz.bit -fs 343296
+fate-mp3-float-conf-he_48khz: CMD = pcm -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/he_48khz.bit -fs 343296
 fate-mp3-float-conf-he_48khz: REF = $(SAMPLES)/mp3-conformance/he_48khz.pcm
 
 FATE_MP3 += fate-mp3-float-conf-hecommon
-fate-mp3-float-conf-hecommon: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/hecommon.bit -fs 133632
+fate-mp3-float-conf-hecommon: CMD = pcm -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/hecommon.bit -fs 133632
 fate-mp3-float-conf-hecommon: REF = $(SAMPLES)/mp3-conformance/hecommon.pcm
 
 FATE_MP3 += fate-mp3-float-conf-si
-fate-mp3-float-conf-si: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/si.bit -fs 269568
+fate-mp3-float-conf-si: CMD = pcm -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/si.bit -fs 269568
 fate-mp3-float-conf-si: REF = $(SAMPLES)/mp3-conformance/si.pcm
 
 FATE_MP3 += fate-mp3-float-conf-si_block
-fate-mp3-float-conf-si_block: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/si_block.bit -fs 145152
+fate-mp3-float-conf-si_block: CMD = pcm -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/si_block.bit -fs 145152
 fate-mp3-float-conf-si_block: REF = $(SAMPLES)/mp3-conformance/si_block.pcm
 
 FATE_MP3 += fate-mp3-float-extra_overread
-fate-mp3-float-extra_overread: CMD = pcm -c:a mp3float -i $(SAMPLES)/mpegaudio/extra_overread.mp3
+fate-mp3-float-extra_overread: CMD = pcm -c:a mp3float -i $(TARGET_SAMPLES)/mpegaudio/extra_overread.mp3
 fate-mp3-float-extra_overread: REF = $(SAMPLES)/mpegaudio/extra_overread.pcm
 
 $(FATE_MP3): CMP = stddev
diff --git a/tests/fate/mpc.mak b/tests/fate/mpc.mak
index 53d236e..4a01273 100644
--- a/tests/fate/mpc.mak
+++ b/tests/fate/mpc.mak
@@ -1,11 +1,11 @@
 FATE_MPC-$(CONFIG_MPC_DEMUXER) += fate-mpc7-demux
-fate-mpc7-demux: CMD = crc -i $(SAMPLES)/musepack/inside-mp7.mpc -acodec copy
+fate-mpc7-demux: CMD = crc -i $(TARGET_SAMPLES)/musepack/inside-mp7.mpc -acodec copy
 
 FATE_MPC-$(CONFIG_MPC8_DEMUXER) += fate-mpc8-demux
-fate-mpc8-demux: CMD = crc -i $(SAMPLES)/musepack/inside-mp8.mpc -acodec copy
+fate-mpc8-demux: CMD = crc -i $(TARGET_SAMPLES)/musepack/inside-mp8.mpc -acodec copy
 
 FATE_MPC-$(call DEMDEC, MPC, MPC7) += fate-musepack7
-fate-musepack7: CMD = pcm -i $(SAMPLES)/musepack/inside-mp7.mpc
+fate-musepack7: CMD = pcm -i $(TARGET_SAMPLES)/musepack/inside-mp7.mpc
 fate-musepack7: CMP = oneoff
 fate-musepack7: REF = $(SAMPLES)/musepack/inside-mp7.pcm
 
diff --git a/tests/fate/pcm.mak b/tests/fate/pcm.mak
index 4a3822f..9ba4be5 100644
--- a/tests/fate/pcm.mak
+++ b/tests/fate/pcm.mak
@@ -1,26 +1,26 @@
 FATE_SAMPLES_PCM-$(call DEMDEC, WAV, PCM_U8) += fate-iff-pcm
-fate-iff-pcm: CMD = md5 -i $(SAMPLES)/iff/Bells -f s16le
+fate-iff-pcm: CMD = md5 -i $(TARGET_SAMPLES)/iff/Bells -f s16le
 
 FATE_SAMPLES_PCM-$(call DEMDEC, MPEGPS, PCM_DVD) += fate-pcm_dvd
-fate-pcm_dvd: CMD = framecrc -i $(SAMPLES)/pcm-dvd/coolitnow-partial.vob -vn
+fate-pcm_dvd: CMD = framecrc -i $(TARGET_SAMPLES)/pcm-dvd/coolitnow-partial.vob -vn
 
 FATE_SAMPLES_PCM-$(call DEMDEC, EA, PCM_S16LE_PLANAR) += fate-pcm-planar
-fate-pcm-planar: CMD = framecrc -i $(SAMPLES)/ea-mad/xeasport.mad -vn
+fate-pcm-planar: CMD = framecrc -i $(TARGET_SAMPLES)/ea-mad/xeasport.mad -vn
 
 FATE_SAMPLES_PCM-$(call DEMDEC, MOV, PCM_S16BE) += fate-pcm_s16be-stereo
-fate-pcm_s16be-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-twos.mov -f s16le
+fate-pcm_s16be-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-B-twos.mov -f s16le
 
 FATE_SAMPLES_PCM-$(call DEMDEC, MOV, PCM_S16LE) += fate-pcm_s16le-stereo
-fate-pcm_s16le-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-L-sowt.mov -f s16le
+fate-pcm_s16le-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-L-sowt.mov -f s16le
 
 FATE_SAMPLES_PCM-$(call DEMDEC, MOV, PCM_U8) += fate-pcm_u8-mono
-fate-pcm_u8-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-8-raw.mov -f s16le
+fate-pcm_u8-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-8-raw.mov -f s16le
 
 FATE_SAMPLES_PCM-$(call DEMDEC, MOV, PCM_U8) += fate-pcm_u8-stereo
-fate-pcm_u8-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-8-raw.mov -f s16le
+fate-pcm_u8-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-8-raw.mov -f s16le
 
 FATE_SAMPLES_PCM-$(call DEMDEC, W64, PCM_S16LE) += fate-w64
-fate-w64: CMD = crc -i $(SAMPLES)/w64/w64-pcm16.w64
+fate-w64: CMD = crc -i $(TARGET_SAMPLES)/w64/w64-pcm16.w64
 
 FATE_PCM-$(call ENCMUX, PCM_S24DAUD, DAUD) += fate-dcinema-encode
 fate-dcinema-encode: tests/data/asynth-96000-6.wav
diff --git a/tests/fate/probe.mak b/tests/fate/probe.mak
index 1166de4..9f9dd4a 100644
--- a/tests/fate/probe.mak
+++ b/tests/fate/probe.mak
@@ -17,4 +17,4 @@
 
 $(FATE_PROBE_FORMAT): ffprobe$(EXESUF)
 $(FATE_PROBE_FORMAT): CMP = oneline
-fate-probe-format-%: CMD = probefmt $(SAMPLES)/probe-format/$(@:fate-probe-format-%=%)
+fate-probe-format-%: CMD = probefmt $(TARGET_SAMPLES)/probe-format/$(@:fate-probe-format-%=%)
diff --git a/tests/fate/prores.mak b/tests/fate/prores.mak
index 00e2159..c608aef 100644
--- a/tests/fate/prores.mak
+++ b/tests/fate/prores.mak
@@ -3,12 +3,14 @@
               fate-prores-422_lt                                        \
               fate-prores-422_proxy                                     \
               fate-prores-alpha                                         \
+              fate-prores-transparency                                  \
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, PRORES) += $(FATE_PRORES)
 fate-prores: $(FATE_PRORES)
 
-fate-prores-422:       CMD = framecrc -flags +bitexact -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422.mov -pix_fmt yuv422p10le
-fate-prores-422_hq:    CMD = framecrc -flags +bitexact -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422_HQ.mov -pix_fmt yuv422p10le
-fate-prores-422_lt:    CMD = framecrc -flags +bitexact -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422_LT.mov -pix_fmt yuv422p10le
-fate-prores-422_proxy: CMD = framecrc -flags +bitexact -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422_Proxy.mov -pix_fmt yuv422p10le
-fate-prores-alpha:     CMD = framecrc -flags +bitexact -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_with_Alpha.mov -pix_fmt yuv444p10le
+fate-prores-422:       CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_422.mov -pix_fmt yuv422p10le
+fate-prores-422_hq:    CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_422_HQ.mov -pix_fmt yuv422p10le
+fate-prores-422_lt:    CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_422_LT.mov -pix_fmt yuv422p10le
+fate-prores-422_proxy: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_422_Proxy.mov -pix_fmt yuv422p10le
+fate-prores-alpha:     CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_with_Alpha.mov -pix_fmt yuva444p10le
+fate-prores-transparency: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/prores4444_with_transparency.mov -pix_fmt yuva444p10le
diff --git a/tests/fate/qt.mak b/tests/fate/qt.mak
index 03b2fce..6d78822 100644
--- a/tests/fate/qt.mak
+++ b/tests/fate/qt.mak
@@ -1,53 +1,53 @@
 FATE_QT-$(call DEMDEC, MOV, EIGHTBPS) += fate-8bps
-fate-8bps: CMD = framecrc -i $(SAMPLES)/8bps/full9iron-partial.mov -pix_fmt rgb24
+fate-8bps: CMD = framecrc -i $(TARGET_SAMPLES)/8bps/full9iron-partial.mov -pix_fmt rgb24
 
 FATE_QT-$(call DEMDEC, MOV, QDM2) += fate-qdm2
-fate-qdm2: CMD = pcm -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-QDM2.mov
+fate-qdm2: CMD = pcm -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-B-QDM2.mov
 fate-qdm2: CMP = oneoff
 fate-qdm2: REF = $(SAMPLES)/qt-surge-suite/surge-2-16-B-QDM2.pcm
 fate-qdm2: FUZZ = 2
 
 FATE_QT-$(call DEMDEC, MOV, PCM_ALAW) += fate-qt-alaw-mono
-fate-qt-alaw-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-16-B-alaw.mov -f s16le
+fate-qt-alaw-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-16-B-alaw.mov -f s16le
 
 FATE_QT-$(call DEMDEC, MOV, PCM_ALAW) += fate-qt-alaw-stereo
-fate-qt-alaw-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-alaw.mov -f s16le
+fate-qt-alaw-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-B-alaw.mov -f s16le
 
 FATE_QT-$(call DEMDEC, MOV, ADPCM_IMA_QT) += fate-qt-ima4-mono
-fate-qt-ima4-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-16-B-ima4.mov -f s16le
+fate-qt-ima4-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-16-B-ima4.mov -f s16le
 
 FATE_QT-$(call DEMDEC, MOV, ADPCM_IMA_QT) += fate-qt-ima4-stereo
-fate-qt-ima4-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-ima4.mov -f s16le
+fate-qt-ima4-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-B-ima4.mov -f s16le
 
 FATE_QT-$(call DEMDEC, MOV, MACE3) += fate-qt-mac3-mono
-fate-qt-mac3-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-8-MAC3.mov -f s16le
+fate-qt-mac3-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-8-MAC3.mov -f s16le
 
 FATE_QT-$(call DEMDEC, MOV, MACE3) += fate-qt-mac3-stereo
-fate-qt-mac3-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-8-MAC3.mov -f s16le
+fate-qt-mac3-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-8-MAC3.mov -f s16le
 
 FATE_QT-$(call DEMDEC, MOV, MACE6) += fate-qt-mac6-mono
-fate-qt-mac6-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-8-MAC6.mov -f s16le
+fate-qt-mac6-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-8-MAC6.mov -f s16le
 
 FATE_QT-$(call DEMDEC, MOV, MACE6) += fate-qt-mac6-stereo
-fate-qt-mac6-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-8-MAC6.mov -f s16le
+fate-qt-mac6-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-8-MAC6.mov -f s16le
 
 FATE_QT-$(call DEMDEC, MOV, PCM_MULAW) += fate-qt-ulaw-mono
-fate-qt-ulaw-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-16-B-ulaw.mov -f s16le
+fate-qt-ulaw-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-16-B-ulaw.mov -f s16le
 
 FATE_QT-$(call DEMDEC, MOV, PCM_MULAW) += fate-qt-ulaw-stereo
-fate-qt-ulaw-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-ulaw.mov -f s16le
+fate-qt-ulaw-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-B-ulaw.mov -f s16le
 
 FATE_QT-$(call DEMDEC, MOV, QDRAW) += fate-quickdraw
-fate-quickdraw: CMD = framecrc -i $(SAMPLES)/quickdraw/Airplane.mov -pix_fmt rgb24
+fate-quickdraw: CMD = framecrc -i $(TARGET_SAMPLES)/quickdraw/Airplane.mov -pix_fmt rgb24
 
 FATE_QT-$(call DEMDEC, MOV, RPZA) += fate-rpza
-fate-rpza: CMD = framecrc -i $(SAMPLES)/rpza/rpza2.mov -t 2 -pix_fmt rgb24
+fate-rpza: CMD = framecrc -i $(TARGET_SAMPLES)/rpza/rpza2.mov -t 2 -pix_fmt rgb24
 
 FATE_QT-$(call DEMDEC, MOV, SVQ1) += fate-svq1
-fate-svq1: CMD = framecrc -i $(SAMPLES)/svq1/marymary-shackles.mov -an -t 10
+fate-svq1: CMD = framecrc -i $(TARGET_SAMPLES)/svq1/marymary-shackles.mov -an -t 10
 
 FATE_QT-$(call ALLYES, MOV_DEMUXER SVQ3_DECODER ZLIB) += fate-svq3
-fate-svq3: CMD = framecrc -i $(SAMPLES)/svq3/Vertical400kbit.sorenson3.mov -t 6 -an
+fate-svq3: CMD = framecrc -i $(TARGET_SAMPLES)/svq3/Vertical400kbit.sorenson3.mov -t 6 -an
 
 FATE_QT += $(FATE_QT-yes)
 
diff --git a/tests/fate/qtrle.mak b/tests/fate/qtrle.mak
index d8a6ecf..774a816 100644
--- a/tests/fate/qtrle.mak
+++ b/tests/fate/qtrle.mak
@@ -1,23 +1,23 @@
 FATE_QTRLE += fate-qtrle-1bit
-fate-qtrle-1bit: CMD = framecrc -i $(SAMPLES)/qtrle/Animation-Monochrome.mov -an
+fate-qtrle-1bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/Animation-Monochrome.mov -an
 
 FATE_QTRLE += fate-qtrle-2bit
-fate-qtrle-2bit: CMD = framecrc -i $(SAMPLES)/qtrle/Animation-4Greys.mov -pix_fmt rgb24 -an
+fate-qtrle-2bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/Animation-4Greys.mov -pix_fmt rgb24 -an
 
 FATE_QTRLE += fate-qtrle-4bit
-fate-qtrle-4bit: CMD = framecrc -i $(SAMPLES)/qtrle/Animation-16Greys.mov -pix_fmt rgb24 -an
+fate-qtrle-4bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/Animation-16Greys.mov -pix_fmt rgb24 -an
 
 FATE_QTRLE += fate-qtrle-8bit
-fate-qtrle-8bit: CMD = framecrc -i $(SAMPLES)/qtrle/criticalpath-credits.mov -pix_fmt rgb24 -an
+fate-qtrle-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/criticalpath-credits.mov -pix_fmt rgb24 -an
 
 FATE_QTRLE += fate-qtrle-16bit
-fate-qtrle-16bit: CMD = framecrc -i $(SAMPLES)/qtrle/mr-cork-rle.mov -pix_fmt rgb24
+fate-qtrle-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/mr-cork-rle.mov -pix_fmt rgb24
 
 FATE_QTRLE += fate-qtrle-24bit
-fate-qtrle-24bit: CMD = framecrc -i $(SAMPLES)/qtrle/aletrek-rle.mov
+fate-qtrle-24bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/aletrek-rle.mov
 
 FATE_QTRLE += fate-qtrle-32bit
-fate-qtrle-32bit: CMD = framecrc -i $(SAMPLES)/qtrle/ultra_demo_720_480_32bpp_rle.mov -pix_fmt rgb24
+fate-qtrle-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/ultra_demo_720_480_32bpp_rle.mov -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, QTRLE) += $(FATE_QTRLE)
 fate-qtrle: $(FATE_QTRLE)
diff --git a/tests/fate/real.mak b/tests/fate/real.mak
index 6c640ad..82d7e3a 100644
--- a/tests/fate/real.mak
+++ b/tests/fate/real.mak
@@ -1,37 +1,37 @@
 FATE_REAL-$(call DEMDEC, RM, RA_144) += fate-ra-144
-fate-ra-144: CMD = md5 -i $(SAMPLES)/real/ra3_in_rm_file.rm -f s16le
+fate-ra-144: CMD = md5 -i $(TARGET_SAMPLES)/real/ra3_in_rm_file.rm -f s16le
 
 FATE_REAL-$(call DEMDEC, RM, RA_288) += fate-ra-288
-fate-ra-288: CMD = pcm -i $(SAMPLES)/real/ra_288.rm
+fate-ra-288: CMD = pcm -i $(TARGET_SAMPLES)/real/ra_288.rm
 fate-ra-288: CMP = oneoff
 fate-ra-288: REF = $(SAMPLES)/real/ra_288.pcm
 fate-ra-288: FUZZ = 2
 
 FATE_REAL-$(call DEMDEC, RM, COOK) += fate-ra-cook
-fate-ra-cook: CMD = pcm -i $(SAMPLES)/real/ra_cook.rm
+fate-ra-cook: CMD = pcm -i $(TARGET_SAMPLES)/real/ra_cook.rm
 fate-ra-cook: CMP = oneoff
 fate-ra-cook: REF = $(SAMPLES)/real/ra_cook.pcm
 
 FATE_REAL-$(call DEMDEC, RM, RV30) += fate-rv30
-fate-rv30: CMD = framecrc -flags +bitexact -idct simple -i $(SAMPLES)/real/rv30.rm -an
+fate-rv30: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/real/rv30.rm -an
 
 FATE_REAL-$(call DEMDEC, RM, RV40) += fate-rv40
-fate-rv40: CMD = framecrc -i $(SAMPLES)/real/spygames-2MB.rmvb -t 10 -an
+fate-rv40: CMD = framecrc -i $(TARGET_SAMPLES)/real/spygames-2MB.rmvb -t 10 -an
 
 FATE_SIPR += fate-sipr-5k0
-fate-sipr-5k0: CMD = pcm -i $(SAMPLES)/sipr/sipr_5k0.rm
+fate-sipr-5k0: CMD = pcm -i $(TARGET_SAMPLES)/sipr/sipr_5k0.rm
 fate-sipr-5k0: REF = $(SAMPLES)/sipr/sipr_5k0.pcm
 
 FATE_SIPR += fate-sipr-6k5
-fate-sipr-6k5: CMD = pcm -i $(SAMPLES)/sipr/sipr_6k5.rm
+fate-sipr-6k5: CMD = pcm -i $(TARGET_SAMPLES)/sipr/sipr_6k5.rm
 fate-sipr-6k5: REF = $(SAMPLES)/sipr/sipr_6k5.pcm
 
 FATE_SIPR += fate-sipr-8k5
-fate-sipr-8k5: CMD = pcm -i $(SAMPLES)/sipr/sipr_8k5.rm
+fate-sipr-8k5: CMD = pcm -i $(TARGET_SAMPLES)/sipr/sipr_8k5.rm
 fate-sipr-8k5: REF = $(SAMPLES)/sipr/sipr_8k5.pcm
 
 FATE_SIPR += fate-sipr-16k
-fate-sipr-16k: CMD = pcm -i $(SAMPLES)/sipr/sipr_16k.rm
+fate-sipr-16k: CMD = pcm -i $(TARGET_SAMPLES)/sipr/sipr_16k.rm
 fate-sipr-16k: REF = $(SAMPLES)/sipr/sipr_16k.pcm
 
 $(FATE_SIPR): CMP = oneoff
diff --git a/tests/fate/screen.mak b/tests/fate/screen.mak
index e1b854e..12250ca 100644
--- a/tests/fate/screen.mak
+++ b/tests/fate/screen.mak
@@ -1,63 +1,63 @@
 # FIXME dropped frames in this test because of coarse timebase
 FATE_SCREEN-$(call DEMDEC, AVI, CSCD) += fate-cscd
-fate-cscd: CMD = framecrc -i $(SAMPLES)/CSCD/sample_video.avi -an -pix_fmt rgb24
+fate-cscd: CMD = framecrc -i $(TARGET_SAMPLES)/CSCD/sample_video.avi -an -pix_fmt rgb24
 
 FATE_SCREEN-$(call DEMDEC, AVI, DXTORY) += fate-dxtory
-fate-dxtory: CMD = framecrc -i $(SAMPLES)/dxtory/dxtory_mic.avi
+fate-dxtory: CMD = framecrc -i $(TARGET_SAMPLES)/dxtory/dxtory_mic.avi
 
 FATE_FRAPS += fate-fraps-v0
-fate-fraps-v0: CMD = framecrc -i $(SAMPLES)/fraps/Griffin_Ragdoll01-partial.avi
+fate-fraps-v0: CMD = framecrc -i $(TARGET_SAMPLES)/fraps/Griffin_Ragdoll01-partial.avi
 
 FATE_FRAPS += fate-fraps-v1
-fate-fraps-v1: CMD = framecrc -i $(SAMPLES)/fraps/sample-v1.avi -an
+fate-fraps-v1: CMD = framecrc -i $(TARGET_SAMPLES)/fraps/sample-v1.avi -an
 
 FATE_FRAPS += fate-fraps-v2
-fate-fraps-v2: CMD = framecrc -i $(SAMPLES)/fraps/test3-nosound-partial.avi
+fate-fraps-v2: CMD = framecrc -i $(TARGET_SAMPLES)/fraps/test3-nosound-partial.avi
 
 FATE_FRAPS += fate-fraps-v3
-fate-fraps-v3: CMD = framecrc -i $(SAMPLES)/fraps/psclient-partial.avi -pix_fmt rgb24
+fate-fraps-v3: CMD = framecrc -i $(TARGET_SAMPLES)/fraps/psclient-partial.avi -pix_fmt rgb24
 
 FATE_FRAPS += fate-fraps-v4
-fate-fraps-v4: CMD = framecrc -i $(SAMPLES)/fraps/WoW_2006-11-03_14-58-17-19-nosound-partial.avi
+fate-fraps-v4: CMD = framecrc -i $(TARGET_SAMPLES)/fraps/WoW_2006-11-03_14-58-17-19-nosound-partial.avi
 
 FATE_FRAPS += fate-fraps-v5
-fate-fraps-v5: CMD = framecrc -i $(SAMPLES)/fraps/fraps-v5-bouncing-balls-partial.avi
+fate-fraps-v5: CMD = framecrc -i $(TARGET_SAMPLES)/fraps/fraps-v5-bouncing-balls-partial.avi
 
 FATE_SCREEN-$(call DEMDEC, AVI, FRAPS) += $(FATE_FRAPS)
 fate-fraps: $(FATE_FRAPS)
 
 FATE_TSCC += fate-tscc-15bit
-fate-tscc-15bit: CMD = framecrc -i $(SAMPLES)/tscc/oneminute.avi -t 15 -pix_fmt rgb24
+fate-tscc-15bit: CMD = framecrc -i $(TARGET_SAMPLES)/tscc/oneminute.avi -t 15 -pix_fmt rgb24
 
 FATE_TSCC += fate-tscc-32bit
-fate-tscc-32bit: CMD = framecrc -i $(SAMPLES)/tscc/2004-12-17-uebung9-partial.avi -pix_fmt rgb24 -an
+fate-tscc-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/tscc/2004-12-17-uebung9-partial.avi -pix_fmt rgb24 -an
 
 FATE_SCREEN-$(call DEMDEC, AVI, TSCC) += $(FATE_TSCC)
 fate-tscc: $(FATE_TSCC)
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, TSCC2) += fate-tscc2
-fate-tscc2: CMD = framecrc -i $(SAMPLES)/tscc/tsc2_16bpp.avi
+fate-tscc2: CMD = framecrc -i $(TARGET_SAMPLES)/tscc/tsc2_16bpp.avi
 
 FATE_VMNC += fate-vmnc-16bit
-fate-vmnc-16bit: CMD = framecrc -i $(SAMPLES)/VMnc/test.avi -pix_fmt rgb24
+fate-vmnc-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/VMnc/test.avi -pix_fmt rgb24
 
 FATE_VMNC += fate-vmnc-32bit
-fate-vmnc-32bit: CMD = framecrc -i $(SAMPLES)/VMnc/VS2k5DebugDemo-01-partial.avi -pix_fmt rgb24
+fate-vmnc-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/VMnc/VS2k5DebugDemo-01-partial.avi -pix_fmt rgb24
 
 FATE_SCREEN-$(call DEMDEC, AVI, VMNC) += $(FATE_VMNC)
 fate-vmnc: $(FATE_VMNC)
 
 FATE_ZMBV += fate-zmbv-8bit
-fate-zmbv-8bit: CMD = framecrc -i $(SAMPLES)/zmbv/wc2_001-partial.avi -an -pix_fmt rgb24
+fate-zmbv-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/zmbv/wc2_001-partial.avi -an -pix_fmt rgb24
 
 FATE_ZMBV += fate-zmbv-15bit
-fate-zmbv-15bit: CMD = framecrc -i $(SAMPLES)/zmbv/zmbv_15bit.avi -pix_fmt rgb24 -t 25
+fate-zmbv-15bit: CMD = framecrc -i $(TARGET_SAMPLES)/zmbv/zmbv_15bit.avi -pix_fmt rgb24 -t 25
 
 FATE_ZMBV += fate-zmbv-16bit
-fate-zmbv-16bit: CMD = framecrc -i $(SAMPLES)/zmbv/zmbv_16bit.avi -pix_fmt rgb24 -t 25
+fate-zmbv-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/zmbv/zmbv_16bit.avi -pix_fmt rgb24 -t 25
 
 FATE_ZMBV += fate-zmbv-32bit
-fate-zmbv-32bit: CMD = framecrc -i $(SAMPLES)/zmbv/zmbv_32bit.avi -pix_fmt rgb24 -t 25
+fate-zmbv-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/zmbv/zmbv_32bit.avi -pix_fmt rgb24 -t 25
 
 FATE_SCREEN-$(call DEMDEC, AVI, ZMBV) += $(FATE_ZMBV)
 fate-zmbv: $(FATE_ZMBV)
diff --git a/tests/fate/subtitles.mak b/tests/fate/subtitles.mak
index 8e586fb..33d798e 100644
--- a/tests/fate/subtitles.mak
+++ b/tests/fate/subtitles.mak
@@ -1,59 +1,59 @@
-FATE_SUBTITLES_ASS-$(call DEMDEC, AQTITLE, TEXT) += fate-sub-aqtitle
-fate-sub-aqtitle: CMD = md5 -i $(SAMPLES)/sub/AQTitle_capability_tester.aqt -f ass
+FATE_SUBTITLES_ASS-$(call ALLYES, AQTITLE_DEMUXER TEXT_DECODER ICONV) += fate-sub-aqtitle
+fate-sub-aqtitle: CMD = md5 -sub_charenc windows-1250 -i $(TARGET_SAMPLES)/sub/AQTitle_capability_tester.aqt -f ass
 
 FATE_SUBTITLES_ASS-$(call DEMDEC, JACOSUB, JACOSUB) += fate-sub-jacosub
-fate-sub-jacosub: CMD = md5 -i $(SAMPLES)/sub/JACOsub_capability_tester.jss -f ass
+fate-sub-jacosub: CMD = md5 -i $(TARGET_SAMPLES)/sub/JACOsub_capability_tester.jss -f ass
 
 FATE_SUBTITLES_ASS-$(call DEMDEC, MICRODVD, MICRODVD) += fate-sub-microdvd
-fate-sub-microdvd: CMD = md5 -i $(SAMPLES)/sub/MicroDVD_capability_tester.sub -f ass
+fate-sub-microdvd: CMD = md5 -i $(TARGET_SAMPLES)/sub/MicroDVD_capability_tester.sub -f ass
 
 FATE_SUBTITLES-$(call ALLYES, MICRODVD_DEMUXER MICRODVD_MUXER) += fate-sub-microdvd-remux
-fate-sub-microdvd-remux: CMD = md5 -i $(SAMPLES)/sub/MicroDVD_capability_tester.sub -c:s copy -f microdvd
+fate-sub-microdvd-remux: CMD = md5 -i $(TARGET_SAMPLES)/sub/MicroDVD_capability_tester.sub -c:s copy -f microdvd
 
 FATE_SUBTITLES_ASS-$(call DEMDEC, MOV, MOVTEXT) += fate-sub-movtext
-fate-sub-movtext: CMD = md5 -i $(SAMPLES)/sub/MovText_capability_tester.mp4 -f ass
+fate-sub-movtext: CMD = md5 -i $(TARGET_SAMPLES)/sub/MovText_capability_tester.mp4 -f ass
 
 FATE_SUBTITLES-$(call ENCDEC, MOVTEXT, MOV) += fate-sub-movtextenc
-fate-sub-movtextenc: CMD = md5 -i $(SAMPLES)/sub/MovText_capability_tester.mp4 -map 0 -scodec mov_text -f mp4 -flags +bitexact -movflags frag_keyframe+empty_moov
+fate-sub-movtextenc: CMD = md5 -i $(TARGET_SAMPLES)/sub/MovText_capability_tester.mp4 -map 0 -scodec mov_text -f mp4 -flags +bitexact -movflags frag_keyframe+empty_moov
 
 FATE_SUBTITLES_ASS-$(call DEMDEC, MPL2, MPL2) += fate-sub-mpl2
-fate-sub-mpl2: CMD = md5 -i $(SAMPLES)/sub/MPL2_capability_tester.txt -f ass
+fate-sub-mpl2: CMD = md5 -i $(TARGET_SAMPLES)/sub/MPL2_capability_tester.txt -f ass
 
 FATE_SUBTITLES_ASS-$(call DEMDEC, MPSUB, TEXT) += fate-sub-mpsub
-fate-sub-mpsub: CMD = md5 -i $(SAMPLES)/sub/MPSub_capability_tester.sub -f ass
+fate-sub-mpsub: CMD = md5 -i $(TARGET_SAMPLES)/sub/MPSub_capability_tester.sub -f ass
 
 FATE_SUBTITLES_ASS-$(call DEMDEC, MPSUB, TEXT) += fate-sub-mpsub-frames
-fate-sub-mpsub-frames: CMD = md5 -i $(SAMPLES)/sub/MPSub_capability_tester_frames.sub -f ass
+fate-sub-mpsub-frames: CMD = md5 -i $(TARGET_SAMPLES)/sub/MPSub_capability_tester_frames.sub -f ass
 
 FATE_SUBTITLES_ASS-$(call DEMDEC, PJS, PJS) += fate-sub-pjs
-fate-sub-pjs: CMD = md5 -i $(SAMPLES)/sub/PJS_capability_tester.pjs -f ass
+fate-sub-pjs: CMD = md5 -i $(TARGET_SAMPLES)/sub/PJS_capability_tester.pjs -f ass
 
 FATE_SUBTITLES_ASS-$(call DEMDEC, REALTEXT, REALTEXT) += fate-sub-realtext
-fate-sub-realtext: CMD = md5 -i $(SAMPLES)/sub/RealText_capability_tester.rt -f ass
+fate-sub-realtext: CMD = md5 -i $(TARGET_SAMPLES)/sub/RealText_capability_tester.rt -f ass
 
 FATE_SUBTITLES_ASS-$(call DEMDEC, SAMI, SAMI) += fate-sub-sami
-fate-sub-sami: CMD = md5 -i $(SAMPLES)/sub/SAMI_capability_tester.smi -f ass
+fate-sub-sami: CMD = md5 -i $(TARGET_SAMPLES)/sub/SAMI_capability_tester.smi -f ass
 
 FATE_SUBTITLES_ASS-$(call DEMDEC, SRT, SUBRIP) += fate-sub-srt
-fate-sub-srt: CMD = md5 -i $(SAMPLES)/sub/SubRip_capability_tester.srt -f ass
+fate-sub-srt: CMD = md5 -i $(TARGET_SAMPLES)/sub/SubRip_capability_tester.srt -f ass
 
 FATE_SUBTITLES-$(call ALLYES, MOV_DEMUXER MOVTEXT_DECODER SUBRIP_ENCODER) += fate-sub-subripenc
-fate-sub-subripenc: CMD = md5 -i $(SAMPLES)/sub/MovText_capability_tester.mp4 -scodec subrip -f srt
+fate-sub-subripenc: CMD = md5 -i $(TARGET_SAMPLES)/sub/MovText_capability_tester.mp4 -scodec subrip -f srt
 
-FATE_SUBTITLES_ASS-$(call DEMDEC, SUBVIEWER1, SUBVIEWER1) += fate-sub-subviewer1
-fate-sub-subviewer1: CMD = md5 -i $(SAMPLES)/sub/SubViewer1_capability_tester.sub -f ass
+FATE_SUBTITLES_ASS-$(call ALLYES, SUBVIEWER1_DEMUXER SUBVIEWER1_DECODER ICONV) += fate-sub-subviewer1
+fate-sub-subviewer1: CMD = md5 -sub_charenc windows-1250 -i $(TARGET_SAMPLES)/sub/SubViewer1_capability_tester.sub -f ass
 
 FATE_SUBTITLES_ASS-$(call DEMDEC, SUBVIEWER, SUBVIEWER) += fate-sub-subviewer
-fate-sub-subviewer: CMD = md5 -i $(SAMPLES)/sub/SubViewer_capability_tester.sub -f ass
+fate-sub-subviewer: CMD = md5 -i $(TARGET_SAMPLES)/sub/SubViewer_capability_tester.sub -f ass
 
 FATE_SUBTITLES_ASS-$(call DEMDEC, VPLAYER, VPLAYER) += fate-sub-vplayer
-fate-sub-vplayer: CMD = md5 -i $(SAMPLES)/sub/VPlayer_capability_tester.txt -f ass
+fate-sub-vplayer: CMD = md5 -i $(TARGET_SAMPLES)/sub/VPlayer_capability_tester.txt -f ass
 
 FATE_SUBTITLES_ASS-$(call DEMDEC, WEBVTT, WEBVTT) += fate-sub-webvtt
-fate-sub-webvtt: CMD = md5 -i $(SAMPLES)/sub/WebVTT_capability_tester.vtt -f ass
+fate-sub-webvtt: CMD = md5 -i $(TARGET_SAMPLES)/sub/WebVTT_capability_tester.vtt -f ass
 
 FATE_SUBTITLES_ASS-$(call ALLYES, MICRODVD_DEMUXER MICRODVD_DECODER ICONV) += fate-sub-charenc
-fate-sub-charenc: CMD = md5 -sub_charenc cp1251 -i $(SAMPLES)/sub/cp1251-subtitles.sub -f ass
+fate-sub-charenc: CMD = md5 -sub_charenc cp1251 -i $(TARGET_SAMPLES)/sub/cp1251-subtitles.sub -f ass
 
 FATE_SUBTITLES-$(call ENCMUX, ASS, ASS) += $(FATE_SUBTITLES_ASS-yes)
 FATE_SUBTITLES += $(FATE_SUBTITLES-yes)
diff --git a/tests/fate/utvideo.mak b/tests/fate/utvideo.mak
index 64d3896..6ec206b 100644
--- a/tests/fate/utvideo.mak
+++ b/tests/fate/utvideo.mak
@@ -1,29 +1,29 @@
 FATE_UTVIDEO += fate-utvideo_rgb_left
-fate-utvideo_rgb_left: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgb_left.avi
+fate-utvideo_rgb_left: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_rgb_left.avi
 
 FATE_UTVIDEO += fate-utvideo_rgb_median
-fate-utvideo_rgb_median: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgb_median.avi
+fate-utvideo_rgb_median: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_rgb_median.avi
 
 FATE_UTVIDEO += fate-utvideo_rgba_left
-fate-utvideo_rgba_left: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgba_left.avi
+fate-utvideo_rgba_left: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_rgba_left.avi
 
 FATE_UTVIDEO += fate-utvideo_rgba_median
-fate-utvideo_rgba_median: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgba_median.avi
+fate-utvideo_rgba_median: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_rgba_median.avi
 
 FATE_UTVIDEO += fate-utvideo_rgba_single_symbol
-fate-utvideo_rgba_single_symbol: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgba_single_symbol.avi
+fate-utvideo_rgba_single_symbol: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_rgba_single_symbol.avi
 
 FATE_UTVIDEO += fate-utvideo_yuv420_left
-fate-utvideo_yuv420_left: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_yuv420_left.avi
+fate-utvideo_yuv420_left: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_yuv420_left.avi
 
 FATE_UTVIDEO += fate-utvideo_yuv420_median
-fate-utvideo_yuv420_median: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_yuv420_median.avi
+fate-utvideo_yuv420_median: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_yuv420_median.avi
 
 FATE_UTVIDEO += fate-utvideo_yuv422_left
-fate-utvideo_yuv422_left: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_yuv422_left.avi
+fate-utvideo_yuv422_left: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_yuv422_left.avi
 
 FATE_UTVIDEO += fate-utvideo_yuv422_median
-fate-utvideo_yuv422_median: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_yuv422_median.avi
+fate-utvideo_yuv422_median: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_yuv422_median.avi
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, UTVIDEO) += $(FATE_UTVIDEO)
 fate-utvideo: $(FATE_UTVIDEO)
diff --git a/tests/fate/vcodec.mak b/tests/fate/vcodec.mak
index cc2ad28..fff606f 100644
--- a/tests/fate/vcodec.mak
+++ b/tests/fate/vcodec.mak
@@ -54,8 +54,9 @@
 fate-vsynth%-dv-50:              DECOPTS = -sws_flags neighbor
 fate-vsynth%-dv-50:              FMT     = dv
 
-FATE_VCODEC-$(call ENCDEC, FFV1, AVI)   += ffv1
+FATE_VCODEC-$(call ENCDEC, FFV1, AVI)   += ffv1 ffv1.0
 fate-vsynth%-ffv1:               ENCOPTS = -slices 4 -strict -2
+fate-vsynth%-ffv1.0:             CODEC   = ffv1
 
 FATE_VCODEC-$(call ENCDEC, FFVHUFF, AVI) += ffvhuff
 
@@ -89,9 +90,11 @@
 fate-vsynth%-jpegls:             ENCOPTS = -sws_flags neighbor+full_chroma_int
 fate-vsynth%-jpegls:             DECOPTS = -sws_flags area
 
-FATE_VCODEC-$(call ENCDEC, J2K, AVI) += j2k
-fate-vsynth%-j2k:                ENCOPTS = -qscale 7 -strict experimental -pix_fmt rgb24
-fate-vsynth%-j2k:                DECINOPTS = -vcodec j2k -strict experimental
+FATE_VCODEC-$(call ENCDEC, JPEG2000, AVI) += jpeg2000 jpeg2000-97
+fate-vsynth%-jpeg2000:                ENCOPTS = -qscale 7 -strict experimental -pred 1 -pix_fmt rgb24
+fate-vsynth%-jpeg2000:                DECINOPTS = -vcodec jpeg2000
+fate-vsynth%-jpeg2000-97:             ENCOPTS = -qscale 7 -strict experimental -pix_fmt rgb24
+fate-vsynth%-jpeg2000-97:             DECINOPTS = -vcodec jpeg2000
 
 FATE_VCODEC-$(call ENCDEC, LJPEG MJPEG, AVI) += ljpeg
 fate-vsynth%-ljpeg:              ENCOPTS = -strict -1
diff --git a/tests/fate/video.mak b/tests/fate/video.mak
index b98f1f0..c5527ce 100644
--- a/tests/fate/video.mak
+++ b/tests/fate/video.mak
@@ -1,288 +1,294 @@
 FATE_4XM += fate-4xm-1
-fate-4xm-1: CMD = framecrc -i $(SAMPLES)/4xm/version1.4xm -pix_fmt rgb24 -an
+fate-4xm-1: CMD = framecrc -i $(TARGET_SAMPLES)/4xm/version1.4xm -pix_fmt rgb24 -an
 
 FATE_4XM += fate-4xm-2
-fate-4xm-2: CMD = framecrc -i $(SAMPLES)/4xm/version2.4xm -pix_fmt rgb24 -an
+fate-4xm-2: CMD = framecrc -i $(TARGET_SAMPLES)/4xm/version2.4xm -pix_fmt rgb24 -an
 
 FATE_VIDEO-$(call DEMDEC, FOURXM, FOURXM) += $(FATE_4XM)
 fate-4xm: $(FATE_4XM)
 
 FATE_VIDEO-$(call DEMDEC, AVI, AASC) += fate-aasc
-fate-aasc: CMD = framecrc -i $(SAMPLES)/aasc/AASC-1.5MB.AVI -pix_fmt rgb24
+fate-aasc: CMD = framecrc -i $(TARGET_SAMPLES)/aasc/AASC-1.5MB.AVI -pix_fmt rgb24
 
 FATE_VIDEO-$(call DEMDEC, MM, MMVIDEO) += fate-alg-mm
-fate-alg-mm: CMD = framecrc -i $(SAMPLES)/alg-mm/ibmlogo.mm -an -pix_fmt rgb24
+fate-alg-mm: CMD = framecrc -i $(TARGET_SAMPLES)/alg-mm/ibmlogo.mm -an -pix_fmt rgb24
 
 FATE_VIDEO-$(call DEMDEC, AVI, AMV) += fate-amv
-fate-amv: CMD = framecrc -idct simple -i $(SAMPLES)/amv/MTV_high_res_320x240_sample_Penguin_Joke_MTV_from_WMV.amv -t 10 -an
+fate-amv: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/amv/MTV_high_res_320x240_sample_Penguin_Joke_MTV_from_WMV.amv -t 10 -an
 
 FATE_VIDEO-$(call DEMDEC, TTY, ANSI) += fate-ansi
-fate-ansi: CMD = framecrc -chars_per_frame 44100 -i $(SAMPLES)/ansi/TRE-IOM5.ANS -pix_fmt rgb24
+fate-ansi: CMD = framecrc -chars_per_frame 44100 -i $(TARGET_SAMPLES)/ansi/TRE-IOM5.ANS -pix_fmt rgb24
 
 FATE_VIDEO-$(call DEMDEC, TTY, ANSI) += fate-ansi256
-fate-ansi256: CMD = framecrc -chars_per_frame 44100 -i $(SAMPLES)/ansi/ansi256.ans -pix_fmt rgb24
+fate-ansi256: CMD = framecrc -chars_per_frame 44100 -i $(TARGET_SAMPLES)/ansi/ansi256.ans -pix_fmt rgb24
 
 FATE_VIDEO-$(call DEMDEC, RPL, ESCAPE124) += fate-armovie-escape124
-fate-armovie-escape124: CMD = framecrc -i $(SAMPLES)/rpl/ESCAPE.RPL -pix_fmt rgb24
+fate-armovie-escape124: CMD = framecrc -i $(TARGET_SAMPLES)/rpl/ESCAPE.RPL -pix_fmt rgb24
+
+FATE_VIDEO-$(call DEMDEC, RPL, ESCAPE130) += fate-armovie-escape130
+fate-armovie-escape130: CMD = framecrc -i $(TARGET_SAMPLES)/rpl/landing.rpl -an
 
 FATE_VIDEO-$(call DEMDEC, AVI, AURA) += fate-auravision-v1
-fate-auravision-v1: CMD = framecrc -i $(SAMPLES)/auravision/SOUVIDEO.AVI -an
+fate-auravision-v1: CMD = framecrc -i $(TARGET_SAMPLES)/auravision/SOUVIDEO.AVI -an
 
 FATE_VIDEO-$(call DEMDEC, AVI, AURA2) += fate-auravision-v2
-fate-auravision-v2: CMD = framecrc -i $(SAMPLES)/auravision/salma-hayek-in-ugly-betty-partial-avi -an
+fate-auravision-v2: CMD = framecrc -i $(TARGET_SAMPLES)/auravision/salma-hayek-in-ugly-betty-partial-avi -an
 
 FATE_VIDEO-$(call DEMDEC, BETHSOFTVID, BETHSOFTVID) += fate-bethsoft-vid
-fate-bethsoft-vid: CMD = framecrc -i $(SAMPLES)/bethsoft-vid/ANIM0001.VID -t 5 -pix_fmt rgb24
+fate-bethsoft-vid: CMD = framecrc -i $(TARGET_SAMPLES)/bethsoft-vid/ANIM0001.VID -t 5 -pix_fmt rgb24
 
 FATE_VIDEO-$(call DEMDEC, BFI, BFI) += fate-bfi
-fate-bfi: CMD = framecrc -i $(SAMPLES)/bfi/2287.bfi -pix_fmt rgb24
+fate-bfi: CMD = framecrc -i $(TARGET_SAMPLES)/bfi/2287.bfi -pix_fmt rgb24
 
 FATE_BINK_VIDEO += fate-bink-video-b
-fate-bink-video-b: CMD = framecrc -i $(SAMPLES)/bink/RISE.BIK -frames 30
+fate-bink-video-b: CMD = framecrc -i $(TARGET_SAMPLES)/bink/RISE.BIK -frames 30
 
 FATE_BINK_VIDEO += fate-bink-video-f
-fate-bink-video-f: CMD = framecrc -i $(SAMPLES)/bink/hol2br.bik
+fate-bink-video-f: CMD = framecrc -i $(TARGET_SAMPLES)/bink/hol2br.bik
 
 FATE_BINK_VIDEO += fate-bink-video-i
-fate-bink-video-i: CMD = framecrc -i $(SAMPLES)/bink/RazOnBull.bik -an
+fate-bink-video-i: CMD = framecrc -i $(TARGET_SAMPLES)/bink/RazOnBull.bik -an
 
 FATE_VIDEO-$(call DEMDEC, BINK, BINK) += $(FATE_BINK_VIDEO)
 
 FATE_VIDEO-$(call DEMDEC, BMV, BMV_VIDEO) += fate-bmv-video
-fate-bmv-video: CMD = framecrc -i $(SAMPLES)/bmv/SURFING-partial.BMV -pix_fmt rgb24 -an
+fate-bmv-video: CMD = framecrc -i $(TARGET_SAMPLES)/bmv/SURFING-partial.BMV -pix_fmt rgb24 -an
 
 FATE_VIDEO-$(call DEMDEC, MPEGPS, CAVS) += fate-cavs
-fate-cavs: CMD = framecrc -i $(SAMPLES)/cavs/cavs.mpg -an
+fate-cavs: CMD = framecrc -i $(TARGET_SAMPLES)/cavs/cavs.mpg -an
 
 FATE_VIDEO-$(call DEMDEC, CDG, CDGRAPHICS) += fate-cdgraphics
-fate-cdgraphics: CMD = framecrc -i $(SAMPLES)/cdgraphics/BrotherJohn.cdg -pix_fmt rgb24 -t 1
+fate-cdgraphics: CMD = framecrc -i $(TARGET_SAMPLES)/cdgraphics/BrotherJohn.cdg -pix_fmt rgb24 -t 1
 
 FATE_VIDEO-$(call DEMDEC, AVI, CLJR) += fate-cljr
-fate-cljr: CMD = framecrc -i $(SAMPLES)/cljr/testcljr-partial.avi
+fate-cljr: CMD = framecrc -i $(TARGET_SAMPLES)/cljr/testcljr-partial.avi
 
 FATE_VIDEO-$(call DEMDEC, AVI, PNG) += fate-corepng
-fate-corepng: CMD = framecrc -i $(SAMPLES)/png1/corepng-partial.avi
+fate-corepng: CMD = framecrc -i $(TARGET_SAMPLES)/png1/corepng-partial.avi
 
 FATE_VIDEO-$(call DEMDEC, AVS, AVS) += fate-creatureshock-avs
-fate-creatureshock-avs: CMD = framecrc -i $(SAMPLES)/creatureshock-avs/OUTATIME.AVS -pix_fmt rgb24
+fate-creatureshock-avs: CMD = framecrc -i $(TARGET_SAMPLES)/creatureshock-avs/OUTATIME.AVS -pix_fmt rgb24
 
 FATE_CVID-$(CONFIG_MOV_DEMUXER) += fate-cvid-palette
-fate-cvid-palette: CMD = framecrc -i $(SAMPLES)/cvid/catfight-cvid-pal8-partial.mov -pix_fmt rgb24 -an
+fate-cvid-palette: CMD = framecrc -i $(TARGET_SAMPLES)/cvid/catfight-cvid-pal8-partial.mov -pix_fmt rgb24 -an
 
 FATE_CVID-$(CONFIG_AVI_DEMUXER) += fate-cvid-partial
-fate-cvid-partial: CMD = framecrc -i $(SAMPLES)/cvid/laracroft-cinepak-partial.avi -an
+fate-cvid-partial: CMD = framecrc -i $(TARGET_SAMPLES)/cvid/laracroft-cinepak-partial.avi -an
 
 FATE_CVID-$(CONFIG_AVI_DEMUXER) += fate-cvid-grayscale
-fate-cvid-grayscale: CMD = framecrc -i $(SAMPLES)/cvid/pcitva15.avi -an
+fate-cvid-grayscale: CMD = framecrc -i $(TARGET_SAMPLES)/cvid/pcitva15.avi -an
 
 FATE_VIDEO-$(CONFIG_CINEPAK_DECODER) += $(FATE_CVID-yes)
 fate-cvid: $(FATE_CVID-yes)
 
 FATE_VIDEO-$(call DEMDEC, C93, C93) += fate-cyberia-c93
-fate-cyberia-c93: CMD = framecrc -i $(SAMPLES)/cyberia-c93/intro1.c93 -t 3 -pix_fmt rgb24
+fate-cyberia-c93: CMD = framecrc -i $(TARGET_SAMPLES)/cyberia-c93/intro1.c93 -t 3 -pix_fmt rgb24
 
 FATE_VIDEO-$(call DEMDEC, AVI, CYUV) += fate-cyuv
-fate-cyuv: CMD = framecrc -i $(SAMPLES)/cyuv/cyuv.avi
+fate-cyuv: CMD = framecrc -i $(TARGET_SAMPLES)/cyuv/cyuv.avi
 
 FATE_VIDEO-$(call DEMDEC, DSICIN, DSICINVIDEO) += fate-delphine-cin-video
-fate-delphine-cin-video: CMD = framecrc -i $(SAMPLES)/delphine-cin/LOGO-partial.CIN -pix_fmt rgb24 -an
+fate-delphine-cin-video: CMD = framecrc -i $(TARGET_SAMPLES)/delphine-cin/LOGO-partial.CIN -pix_fmt rgb24 -an
 
 FATE_VIDEO-$(call DEMDEC, ANM, ANM) += fate-deluxepaint-anm
-fate-deluxepaint-anm: CMD = framecrc -i $(SAMPLES)/deluxepaint-anm/INTRO1.ANM -pix_fmt rgb24
+fate-deluxepaint-anm: CMD = framecrc -i $(TARGET_SAMPLES)/deluxepaint-anm/INTRO1.ANM -pix_fmt rgb24
 
 FATE_VIDEO-$(call DEMDEC, DIRAC, DIRAC) += fate-dirac
-fate-dirac: CMD = framecrc -i $(SAMPLES)/dirac/vts.profile-main.drc
+fate-dirac: CMD = framecrc -i $(TARGET_SAMPLES)/dirac/vts.profile-main.drc
 
 FATE_TRUEMOTION1 += fate-truemotion1-15
-fate-truemotion1-15: CMD = framecrc -i $(SAMPLES)/duck/phant2-940.duk -pix_fmt rgb24 -an
+fate-truemotion1-15: CMD = framecrc -i $(TARGET_SAMPLES)/duck/phant2-940.duk -pix_fmt rgb24 -an
 
 FATE_TRUEMOTION1 += fate-truemotion1-24
-fate-truemotion1-24: CMD = framecrc -i $(SAMPLES)/duck/sonic3dblast_intro-partial.avi -pix_fmt rgb24 -an
+fate-truemotion1-24: CMD = framecrc -i $(TARGET_SAMPLES)/duck/sonic3dblast_intro-partial.avi -pix_fmt rgb24 -an
 
 FATE_VIDEO-$(call DEMDEC, AVI, TRUEMOTION1) += $(FATE_TRUEMOTION1)
 fate-truemotion1: $(FATE_TRUEMOTION1)
 
 FATE_VIDEO-$(call DEMDEC, AVI, TRUEMOTION2) += fate-truemotion2
-fate-truemotion2: CMD = framecrc -i $(SAMPLES)/duck/tm20.avi
+fate-truemotion2: CMD = framecrc -i $(TARGET_SAMPLES)/duck/tm20.avi
 
 FATE_DXA += fate-dxa-feeble
-fate-dxa-feeble: CMD = framecrc -i $(SAMPLES)/dxa/meetsquid.dxa -t 2 -pix_fmt rgb24 -an
+fate-dxa-feeble: CMD = framecrc -i $(TARGET_SAMPLES)/dxa/meetsquid.dxa -t 2 -pix_fmt rgb24 -an
 
 FATE_DXA += fate-dxa-scummvm
-fate-dxa-scummvm: CMD = framecrc -i $(SAMPLES)/dxa/scummvm.dxa -pix_fmt rgb24
+fate-dxa-scummvm: CMD = framecrc -i $(TARGET_SAMPLES)/dxa/scummvm.dxa -pix_fmt rgb24
 
 FATE_VIDEO-$(call DEMDEC, DXA, DXA) += $(FATE_DXA)
 fate-dxa: $(FATE_DXA)
 
 FATE_VIDEO-$(call DEMDEC, SEGAFILM, CINEPAK) += fate-film-cvid
-fate-film-cvid: CMD = framecrc -i $(SAMPLES)/film/logo-capcom.cpk -an
+fate-film-cvid: CMD = framecrc -i $(TARGET_SAMPLES)/film/logo-capcom.cpk -an
 
 FATE_FLIC += fate-flic-af11-palette-change
-fate-flic-af11-palette-change: CMD = framecrc -i $(SAMPLES)/fli/fli-engines.fli -t 3.3 -pix_fmt rgb24
+fate-flic-af11-palette-change: CMD = framecrc -i $(TARGET_SAMPLES)/fli/fli-engines.fli -t 3.31 -pix_fmt rgb24
 
 FATE_FLIC += fate-flic-af12
-fate-flic-af12: CMD = framecrc -i $(SAMPLES)/fli/jj00c2.fli -pix_fmt rgb24
+fate-flic-af12: CMD = framecrc -i $(TARGET_SAMPLES)/fli/jj00c2.fli -pix_fmt rgb24
 
 FATE_FLIC += fate-flic-magiccarpet
-fate-flic-magiccarpet: CMD = framecrc -i $(SAMPLES)/fli/intel.dat -pix_fmt rgb24
+fate-flic-magiccarpet: CMD = framecrc -i $(TARGET_SAMPLES)/fli/intel.dat -pix_fmt rgb24
 
 FATE_VIDEO-$(call DEMDEC, FLIC, FLIC) += $(FATE_FLIC)
 fate-flic: $(FATE_FLIC)
 
 FATE_VIDEO-$(call DEMDEC, AVI, FRWU) += fate-frwu
-fate-frwu: CMD = framecrc -i $(SAMPLES)/frwu/frwu.avi
+fate-frwu: CMD = framecrc -i $(TARGET_SAMPLES)/frwu/frwu.avi
 
 FATE_VIDEO-$(call DEMDEC, IDCIN, IDCIN) += fate-id-cin-video
-fate-id-cin-video: CMD = framecrc -i $(SAMPLES)/idcin/idlog-2MB.cin -pix_fmt rgb24
+fate-id-cin-video: CMD = framecrc -i $(TARGET_SAMPLES)/idcin/idlog-2MB.cin -pix_fmt rgb24
 
 FATE_VIDEO-$(call ENCDEC, ROQ PGMYUV, ROQ IMAGE2) += fate-idroq-video-encode
-fate-idroq-video-encode: CMD = md5 -f image2 -vcodec pgmyuv -i $(SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -sws_flags +bitexact -vf pad=512:512:80:112 -f roq -t 0.2
+fate-idroq-video-encode: CMD = md5 -f image2 -vcodec pgmyuv -i $(TARGET_SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -sws_flags +bitexact -vf pad=512:512:80:112 -f roq -t 0.2
 
 FATE_IFF-$(CONFIG_IFF_BYTERUN1_DECODER) += fate-iff-byterun1
-fate-iff-byterun1: CMD = framecrc -i $(SAMPLES)/iff/ASH.LBM -pix_fmt rgb24
+fate-iff-byterun1: CMD = framecrc -i $(TARGET_SAMPLES)/iff/ASH.LBM -pix_fmt rgb24
 
 FATE_IFF-$(CONFIG_EIGHTSVX_FIB_DECODER) += fate-iff-fibonacci
-fate-iff-fibonacci: CMD = md5 -i $(SAMPLES)/iff/dasboot-in-compressed -f s16le
+fate-iff-fibonacci: CMD = md5 -i $(TARGET_SAMPLES)/iff/dasboot-in-compressed -f s16le
 
 FATE_IFF-$(CONFIG_IFF_ILBM_DECODER) += fate-iff-ilbm
-fate-iff-ilbm: CMD = framecrc -i $(SAMPLES)/iff/lms-matriks.ilbm -pix_fmt rgb24
+fate-iff-ilbm: CMD = framecrc -i $(TARGET_SAMPLES)/iff/lms-matriks.ilbm -pix_fmt rgb24
 
 FATE_VIDEO-$(CONFIG_IFF_DEMUXER)  += $(FATE_IFF-yes)
 fate-iff: $(FATE_IFF-yes)
 
 FATE_VIDEO-$(call DEMDEC, IPMOVIE, INTERPLAY_VIDEO) += fate-interplay-mve-8bit
-fate-interplay-mve-8bit: CMD = framecrc -i $(SAMPLES)/interplay-mve/interplay-logo-2MB.mve -pix_fmt rgb24 -an
+fate-interplay-mve-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/interplay-mve/interplay-logo-2MB.mve -pix_fmt rgb24 -an
 
 FATE_VIDEO-$(call DEMDEC, IPMOVIE, INTERPLAY_VIDEO) += fate-interplay-mve-16bit
-fate-interplay-mve-16bit: CMD = framecrc -i $(SAMPLES)/interplay-mve/descent3-level5-16bit-partial.mve -pix_fmt rgb24 -an
+fate-interplay-mve-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/interplay-mve/descent3-level5-16bit-partial.mve -pix_fmt rgb24 -an
 
 FATE_VIDEO-$(call DEMDEC, MXF, JPEG2000) += fate-jpeg2000-dcinema
-fate-jpeg2000-dcinema: CMD = framecrc -flags +bitexact -i $(SAMPLES)/jpeg2000/chiens_dcinema2K.mxf
+fate-jpeg2000-dcinema: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/jpeg2000/chiens_dcinema2K.mxf -pix_fmt xyz12le
 
 FATE_VIDEO-$(call DEMDEC, JV, JV) += fate-jv
-fate-jv: CMD = framecrc -i $(SAMPLES)/jv/intro.jv -pix_fmt rgb24 -an
+fate-jv: CMD = framecrc -i $(TARGET_SAMPLES)/jv/intro.jv -pix_fmt rgb24 -an
 
 FATE_VIDEO-$(call DEMDEC, AVI, KGV1) += fate-kgv1
-fate-kgv1: CMD = framecrc -i $(SAMPLES)/kega/kgv1.avi -pix_fmt rgb555le -an
+fate-kgv1: CMD = framecrc -i $(TARGET_SAMPLES)/kega/kgv1.avi -pix_fmt rgb555le -an
 
 FATE_VIDEO-$(call DEMDEC, AVI, KMVC) += fate-kmvc
-fate-kmvc: CMD = framecrc -i $(SAMPLES)/KMVC/LOGO1.AVI -an -t 3 -pix_fmt rgb24
+fate-kmvc: CMD = framecrc -i $(TARGET_SAMPLES)/KMVC/LOGO1.AVI -an -t 3 -pix_fmt rgb24
 
 FATE_VIDEO-$(call DEMDEC, EA, MDEC) += fate-mdec
-fate-mdec: CMD = framecrc -idct simple -i $(SAMPLES)/ea-dct/NFS2Esprit-partial.dct -an
+fate-mdec: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/ea-dct/NFS2Esprit-partial.dct -an
 
 FATE_VIDEO-$(call DEMDEC, STR, MDEC) += fate-mdec-v3
-fate-mdec-v3: CMD = framecrc -idct simple -i $(SAMPLES)/psx-str/abc000_cut.str -an
+fate-mdec-v3: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/psx-str/abc000_cut.str -an
 
 FATE_VIDEO-$(call DEMDEC, MSNWC_TCP, MIMIC) += fate-mimic
-fate-mimic: CMD = framecrc -idct simple -i $(SAMPLES)/mimic/mimic2-womanloveffmpeg.cam
+fate-mimic: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/mimic/mimic2-womanloveffmpeg.cam
 
 FATE_VIDEO-$(call DEMDEC, MOV, MJPEGB) += fate-mjpegb
-fate-mjpegb: CMD = framecrc -idct simple -flags +bitexact -i $(SAMPLES)/mjpegb/mjpegb_part.mov -an
+fate-mjpegb: CMD = framecrc -idct simple -flags +bitexact -i $(TARGET_SAMPLES)/mjpegb/mjpegb_part.mov -an
 
 FATE_VIDEO-$(call DEMDEC, MVI, MOTIONPIXELS) += fate-motionpixels
-fate-motionpixels: CMD = framecrc -i $(SAMPLES)/motion-pixels/INTRO-partial.MVI -an -pix_fmt rgb24 -vframes 111
+fate-motionpixels: CMD = framecrc -i $(TARGET_SAMPLES)/motion-pixels/INTRO-partial.MVI -an -pix_fmt rgb24 -vframes 111
 
 FATE_VIDEO-$(call DEMDEC, MPEGTS, MPEG2VIDEO) += fate-mpeg2-field-enc
-fate-mpeg2-field-enc: CMD = framecrc -flags +bitexact -idct simple -i $(SAMPLES)/mpeg2/mpeg2_field_encoding.ts -an -vframes 30
+fate-mpeg2-field-enc: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg2/mpeg2_field_encoding.ts -an -vframes 30
 
 FATE_VIDEO-$(call DEMDEC, MXG, MXPEG) += fate-mxpeg
-fate-mxpeg: CMD = framecrc -idct simple -flags +bitexact -i $(SAMPLES)/mxpeg/m1.mxg -an
+fate-mxpeg: CMD = framecrc -idct simple -flags +bitexact -i $(TARGET_SAMPLES)/mxpeg/m1.mxg -an
 
 # FIXME dropped frames in this test because of coarse timebase
 FATE_NUV += fate-nuv-rtjpeg
-fate-nuv-rtjpeg: CMD = framecrc -idct simple -i $(SAMPLES)/nuv/Today.nuv -an
+fate-nuv-rtjpeg: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/nuv/Today.nuv -an
 
 FATE_NUV += fate-nuv-rtjpeg-fh
-fate-nuv-rtjpeg-fh: CMD = framecrc -idct simple -i $(SAMPLES)/nuv/rtjpeg_frameheader.nuv -an
+fate-nuv-rtjpeg-fh: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/nuv/rtjpeg_frameheader.nuv -an
 
 FATE_VIDEO-$(call DEMDEC, NUV, NUV) += $(FATE_NUV)
 fate-nuv: $(FATE_NUV)
 
 FATE_VIDEO-$(call DEMDEC, PAF, PAF_VIDEO) += fate-paf-video
-fate-paf-video: CMD = framecrc -i $(SAMPLES)/paf/hod1-partial.paf -pix_fmt rgb24 -an
+fate-paf-video: CMD = framecrc -i $(TARGET_SAMPLES)/paf/hod1-partial.paf -pix_fmt rgb24 -an
 
 FATE_VIDEO-$(call DEMDEC, AVI, QPEG) += fate-qpeg
-fate-qpeg: CMD = framecrc -i $(SAMPLES)/qpeg/Clock.avi -an -pix_fmt rgb24
+fate-qpeg: CMD = framecrc -i $(TARGET_SAMPLES)/qpeg/Clock.avi -an -pix_fmt rgb24
 
 FATE_VIDEO-$(call DEMDEC, AVI, R210) += fate-r210
-fate-r210: CMD = framecrc -i $(SAMPLES)/r210/r210.avi -pix_fmt rgb48le
+fate-r210: CMD = framecrc -i $(TARGET_SAMPLES)/r210/r210.avi -pix_fmt rgb48le
 
 FATE_VIDEO-$(call DEMDEC, RL2, RL2) += fate-rl2
-fate-rl2: CMD = framecrc -i $(SAMPLES)/rl2/Z4915300.RL2 -pix_fmt rgb24 -an
+fate-rl2: CMD = framecrc -i $(TARGET_SAMPLES)/rl2/Z4915300.RL2 -pix_fmt rgb24 -an
 
 FATE_VIDEO-$(call DEMDEC, ROQ, ROQ) += fate-roqvideo
-fate-roqvideo: CMD = framecrc -i $(SAMPLES)/idroq/idlogo.roq -an
+fate-roqvideo: CMD = framecrc -i $(TARGET_SAMPLES)/idroq/idlogo.roq -an
 
 FATE_VIDEO-$(call DEMDEC, SMUSH, SANM) += fate-sanm
-fate-sanm: CMD = framecrc -i $(SAMPLES)/smush/ronin_part.znm -an -pix_fmt rgb24
+fate-sanm: CMD = framecrc -i $(TARGET_SAMPLES)/smush/ronin_part.znm -an -pix_fmt rgb24
 
 FATE_VIDEO-$(call DEMDEC, VMD, VMDVIDEO) += fate-sierra-vmd-video
-fate-sierra-vmd-video: CMD = framecrc -i $(SAMPLES)/vmd/12.vmd -pix_fmt rgb24 -an
+fate-sierra-vmd-video: CMD = framecrc -i $(TARGET_SAMPLES)/vmd/12.vmd -pix_fmt rgb24 -an
 
 FATE_VIDEO-$(call DEMDEC, SMACKER, SMACKER) += fate-smacker-video
-fate-smacker-video: CMD = framecrc -i $(SAMPLES)/smacker/wetlogo.smk -pix_fmt rgb24 -an
+fate-smacker-video: CMD = framecrc -i $(TARGET_SAMPLES)/smacker/wetlogo.smk -pix_fmt rgb24 -an
 
 FATE_VIDEO-$(call DEMDEC, MOV, SMC) += fate-smc
-fate-smc: CMD = framecrc -i $(SAMPLES)/smc/cass_schi.qt -pix_fmt rgb24
+fate-smc: CMD = framecrc -i $(TARGET_SAMPLES)/smc/cass_schi.qt -pix_fmt rgb24
 
 FATE_VIDEO-$(call DEMDEC, AVI, SP5X) += fate-sp5x
-fate-sp5x: CMD = framecrc -idct simple -i $(SAMPLES)/sp5x/sp5x_problem.avi
+fate-sp5x: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/sp5x/sp5x_problem.avi
 
 FATE_VIDEO-$(call DEMDEC, THP, THP) += fate-thp
-fate-thp: CMD = framecrc -idct simple -i $(SAMPLES)/thp/pikmin2-opening1-partial.thp -an
+fate-thp: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/thp/pikmin2-opening1-partial.thp -an
 
 FATE_VIDEO-$(call DEMDEC, TIERTEXSEQ, TIERTEXSEQVIDEO) += fate-tiertex-seq
-fate-tiertex-seq: CMD = framecrc -i $(SAMPLES)/tiertex-seq/Gameover.seq -pix_fmt rgb24
+fate-tiertex-seq: CMD = framecrc -i $(TARGET_SAMPLES)/tiertex-seq/Gameover.seq -pix_fmt rgb24
 
 FATE_VIDEO-$(call DEMDEC, TMV, TMV) += fate-tmv
-fate-tmv: CMD = framecrc -i $(SAMPLES)/tmv/pop-partial.tmv -pix_fmt rgb24
+fate-tmv: CMD = framecrc -i $(TARGET_SAMPLES)/tmv/pop-partial.tmv -pix_fmt rgb24
 
 FATE_TXD += fate-txd-16bpp
-fate-txd-16bpp: CMD = framecrc -i $(SAMPLES)/txd/misc.txd -pix_fmt bgra -an
+fate-txd-16bpp: CMD = framecrc -i $(TARGET_SAMPLES)/txd/misc.txd -pix_fmt bgra -an
 
 FATE_TXD += fate-txd-pal8
-fate-txd-pal8: CMD = framecrc -i $(SAMPLES)/txd/outro.txd -pix_fmt rgb24 -an
+fate-txd-pal8: CMD = framecrc -i $(TARGET_SAMPLES)/txd/outro.txd -pix_fmt rgb24 -an
 
 FATE_VIDEO-$(call DEMDEC, TXD, TXD) += $(FATE_TXD)
 fate-txd: $(FATE_TXD)
 
 FATE_VIDEO-$(call DEMDEC, AVI, ULTI) += fate-ulti
-fate-ulti: CMD = framecrc -i $(SAMPLES)/ulti/hit12w.avi -an
+fate-ulti: CMD = framecrc -i $(TARGET_SAMPLES)/ulti/hit12w.avi -an
 
 FATE_VIDEO-$(call DEMDEC, AVI, V210) += fate-v210
-fate-v210: CMD = framecrc -i $(SAMPLES)/v210/v210_720p-partial.avi -pix_fmt yuv422p16be -an
+fate-v210: CMD = framecrc -i $(TARGET_SAMPLES)/v210/v210_720p-partial.avi -pix_fmt yuv422p16be -an
 
 FATE_VIDEO-$(call DEMDEC, MOV, V410) += fate-v410dec
-fate-v410dec: CMD = framecrc -i $(SAMPLES)/v410/lenav410.mov -pix_fmt yuv444p10le
+fate-v410dec: CMD = framecrc -i $(TARGET_SAMPLES)/v410/lenav410.mov -pix_fmt yuv444p10le
 
 FATE_VIDEO-$(call ENCDEC, V410 PGMYUV, AVI IMAGE2) += fate-v410enc
 fate-v410enc: $(VREF)
 fate-v410enc: CMD = md5 -f image2 -vcodec pgmyuv -i $(TARGET_PATH)/tests/vsynth1/%02d.pgm -flags +bitexact -vcodec v410 -f avi
 
 FATE_VIDEO-$(call DEMDEC, SIFF, VB) += fate-vb
-fate-vb: CMD = framecrc -i $(SAMPLES)/SIFF/INTRO_B.VB -t 3 -pix_fmt rgb24 -an
+fate-vb: CMD = framecrc -i $(TARGET_SAMPLES)/SIFF/INTRO_B.VB -t 3 -pix_fmt rgb24 -an
 
 FATE_VIDEO-$(call DEMDEC, AVI, VCR1) += fate-vcr1
-fate-vcr1: CMD = framecrc -i $(SAMPLES)/vcr1/VCR1test.avi -an
+fate-vcr1: CMD = framecrc -i $(TARGET_SAMPLES)/vcr1/VCR1test.avi -an
 
 FATE_VIDEO-$(call DEMDEC, AVI, XL) += fate-videoxl
-fate-videoxl: CMD = framecrc -i $(SAMPLES)/vixl/pig-vixl.avi
+fate-videoxl: CMD = framecrc -i $(TARGET_SAMPLES)/vixl/pig-vixl.avi
 
 FATE_VIDEO-$(call DEMDEC, WSVQA, VQA) += fate-vqa-cc
-fate-vqa-cc: CMD = framecrc -i $(SAMPLES)/vqa/cc-demo1-partial.vqa -pix_fmt rgb24 -an
+fate-vqa-cc: CMD = framecrc -i $(TARGET_SAMPLES)/vqa/cc-demo1-partial.vqa -pix_fmt rgb24 -an
 
 FATE_VIDEO-$(call DEMDEC, WC3, XAN_WC3) += fate-wc3movie-xan
-fate-wc3movie-xan: CMD = framecrc -i $(SAMPLES)/wc3movie/SC_32-part.MVE -pix_fmt rgb24
+fate-wc3movie-xan: CMD = framecrc -i $(TARGET_SAMPLES)/wc3movie/SC_32-part.MVE -pix_fmt rgb24
 
 FATE_VIDEO-$(call DEMDEC, AVI, WNV1) += fate-wnv1
-fate-wnv1: CMD = framecrc -i $(SAMPLES)/wnv1/wnv1-codec.avi -an
+fate-wnv1: CMD = framecrc -i $(TARGET_SAMPLES)/wnv1/wnv1-codec.avi -an
 
 FATE_VIDEO-$(call DEMDEC, YOP, YOP) += fate-yop
-fate-yop: CMD = framecrc -i $(SAMPLES)/yop/test1.yop -pix_fmt rgb24 -an
+fate-yop: CMD = framecrc -i $(TARGET_SAMPLES)/yop/test1.yop -pix_fmt rgb24 -an
 
 FATE_VIDEO-$(call DEMDEC, AVI, XAN_WC4) += fate-xxan-wc4
-fate-xxan-wc4: CMD = framecrc -i $(SAMPLES)/wc4-xan/wc4trailer-partial.avi -an
+fate-xxan-wc4: CMD = framecrc -i $(TARGET_SAMPLES)/wc4-xan/wc4trailer-partial.avi -an
+
+FATE_VIDEO-$(call DEMDEC, WAV, SMVJPEG) += fate-smvjpeg
+fate-smvjpeg: CMD = framecrc -idct simple -flags +bitexact -i $(TARGET_SAMPLES)/smv/clock.smv -an
 
 FATE_VIDEO += $(FATE_VIDEO-yes)
 
diff --git a/tests/fate/voice.mak b/tests/fate/voice.mak
index f27be18..44b5b93 100644
--- a/tests/fate/voice.mak
+++ b/tests/fate/voice.mak
@@ -1,5 +1,5 @@
 FATE_G722-$(call DEMDEC, G722, ADPCM_G722) += fate-g722dec-1
-fate-g722dec-1: CMD = framecrc -i $(SAMPLES)/g722/conf-adminmenu-162.g722
+fate-g722dec-1: CMD = framecrc -i $(TARGET_SAMPLES)/g722/conf-adminmenu-162.g722
 
 FATE_G722-$(call ENCMUX, ADPCM_G722, WAV) += fate-g722-encode
 fate-g722-encode: tests/data/asynth-16000-1.wav
@@ -10,28 +10,28 @@
 fate-g722: $(FATE_G722)
 
 FATE_G723_1 += fate-g723_1-dec-1
-fate-g723_1-dec-1: CMD = framecrc -postfilter 0 -i $(SAMPLES)/g723_1/ineqd53.tco
+fate-g723_1-dec-1: CMD = framecrc -postfilter 0 -i $(TARGET_SAMPLES)/g723_1/ineqd53.tco
 
 FATE_G723_1 += fate-g723_1-dec-2
-fate-g723_1-dec-2: CMD = framecrc -postfilter 0 -i $(SAMPLES)/g723_1/overd53.tco
+fate-g723_1-dec-2: CMD = framecrc -postfilter 0 -i $(TARGET_SAMPLES)/g723_1/overd53.tco
 
 FATE_G723_1 += fate-g723_1-dec-3
-fate-g723_1-dec-3: CMD = framecrc -postfilter 1 -i $(SAMPLES)/g723_1/overd63p.tco
+fate-g723_1-dec-3: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/overd63p.tco
 
 FATE_G723_1 += fate-g723_1-dec-4
-fate-g723_1-dec-4: CMD = framecrc -postfilter 0 -i $(SAMPLES)/g723_1/pathd53.tco
+fate-g723_1-dec-4: CMD = framecrc -postfilter 0 -i $(TARGET_SAMPLES)/g723_1/pathd53.tco
 
 FATE_G723_1 += fate-g723_1-dec-5
-fate-g723_1-dec-5: CMD = framecrc -postfilter 1 -i $(SAMPLES)/g723_1/pathd63p.tco
+fate-g723_1-dec-5: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/pathd63p.tco
 
 FATE_G723_1 += fate-g723_1-dec-6
-fate-g723_1-dec-6: CMD = framecrc -postfilter 1 -i $(SAMPLES)/g723_1/tamed63p.tco
+fate-g723_1-dec-6: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/tamed63p.tco
 
 FATE_G723_1 += fate-g723_1-dec-7
-fate-g723_1-dec-7: CMD = framecrc -postfilter 1 -i $(SAMPLES)/g723_1/dtx63b.tco
+fate-g723_1-dec-7: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/dtx63b.tco
 
 FATE_G723_1 += fate-g723_1-dec-8
-fate-g723_1-dec-8: CMD = framecrc -postfilter 1 -i $(SAMPLES)/g723_1/dtx63e.tco
+fate-g723_1-dec-8: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/dtx63e.tco
 
 FATE_G723_1-$(call DEMDEC, G723_1, G723_1) += $(FATE_G723_1)
 FATE_SAMPLES_AVCONV += $(FATE_G723_1-yes)
@@ -56,21 +56,21 @@
 fate-g726: $(FATE_G726)
 
 FATE_GSM-$(call DEMDEC, WAV, GSM) += fate-gsm-ms
-fate-gsm-ms: CMD = framecrc -i $(SAMPLES)/gsm/ciao.wav
+fate-gsm-ms: CMD = framecrc -i $(TARGET_SAMPLES)/gsm/ciao.wav
 
 FATE_GSM-$(call DEMDEC, MOV, GSM) += fate-gsm-toast
-fate-gsm-toast: CMD = framecrc -i $(SAMPLES)/gsm/sample-gsm-8000.mov -t 10
+fate-gsm-toast: CMD = framecrc -i $(TARGET_SAMPLES)/gsm/sample-gsm-8000.mov -t 10
 
 FATE_VOICE-yes += $(FATE_GSM-yes)
 fate-gsm: $(FATE_GSM)
 
 FATE_VOICE-$(call DEMDEC, QCP, QCELP) += fate-qcelp
-fate-qcelp: CMD = pcm -i $(SAMPLES)/qcp/0036580847.QCP
+fate-qcelp: CMD = pcm -i $(TARGET_SAMPLES)/qcp/0036580847.QCP
 fate-qcelp: CMP = oneoff
 fate-qcelp: REF = $(SAMPLES)/qcp/0036580847.pcm
 
 FATE_VOICE-$(call DEMDEC, WAV, TRUESPEECH) += fate-truespeech
-fate-truespeech: CMD = pcm -i $(SAMPLES)/truespeech/a6.wav
+fate-truespeech: CMD = pcm -i $(TARGET_SAMPLES)/truespeech/a6.wav
 fate-truespeech: CMP = oneoff
 fate-truespeech: REF = $(SAMPLES)/truespeech/a6.pcm
 
diff --git a/tests/fate/vorbis.mak b/tests/fate/vorbis.mak
index 39a9724..4b72373 100644
--- a/tests/fate/vorbis.mak
+++ b/tests/fate/vorbis.mak
@@ -1,83 +1,83 @@
 FATE_VORBIS += fate-vorbis-1
-fate-vorbis-1: CMD = pcm -i $(SAMPLES)/vorbis/1.0.1-test_small.ogg
+fate-vorbis-1: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/1.0.1-test_small.ogg
 fate-vorbis-1: REF = $(SAMPLES)/vorbis/1.0.1-test_small.pcm
 
 FATE_VORBIS += fate-vorbis-2
-fate-vorbis-2: CMD = pcm -i $(SAMPLES)/vorbis/1.0-test_small.ogg
+fate-vorbis-2: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/1.0-test_small.ogg
 fate-vorbis-2: REF = $(SAMPLES)/vorbis/1.0-test_small.pcm
 
 FATE_VORBIS += fate-vorbis-3
-fate-vorbis-3: CMD = pcm -i $(SAMPLES)/vorbis/beta3-test_small.ogg
+fate-vorbis-3: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/beta3-test_small.ogg
 fate-vorbis-3: REF = $(SAMPLES)/vorbis/beta3-test_small.pcm
 
 FATE_VORBIS += fate-vorbis-4
-fate-vorbis-4: CMD = pcm -i $(SAMPLES)/vorbis/beta4-test_small.ogg
+fate-vorbis-4: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/beta4-test_small.ogg
 fate-vorbis-4: REF = $(SAMPLES)/vorbis/beta4-test_small.pcm
 
 FATE_VORBIS += fate-vorbis-5
-fate-vorbis-5: CMD = pcm -i $(SAMPLES)/vorbis/chain-test1_small.ogg
+fate-vorbis-5: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/chain-test1_small.ogg
 fate-vorbis-5: REF = $(SAMPLES)/vorbis/chain-test1_small.pcm
 
 FATE_VORBIS += fate-vorbis-6
-fate-vorbis-6: CMD = pcm -i $(SAMPLES)/vorbis/chain-test2_small.ogg
+fate-vorbis-6: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/chain-test2_small.ogg
 fate-vorbis-6: REF = $(SAMPLES)/vorbis/chain-test2_small.pcm
 
 FATE_VORBIS += fate-vorbis-7
-fate-vorbis-7: CMD = pcm -i $(SAMPLES)/vorbis/highrate-test_small.ogg
+fate-vorbis-7: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/highrate-test_small.ogg
 fate-vorbis-7: REF = $(SAMPLES)/vorbis/highrate-test_small.pcm
 
 FATE_VORBIS += fate-vorbis-8
-fate-vorbis-8: CMD = pcm -i $(SAMPLES)/vorbis/lsp-test2_small.ogg
+fate-vorbis-8: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/lsp-test2_small.ogg
 fate-vorbis-8: REF = $(SAMPLES)/vorbis/lsp-test2_small.pcm
 
 FATE_VORBIS += fate-vorbis-9
-fate-vorbis-9: CMD = pcm -i $(SAMPLES)/vorbis/lsp-test3_small.ogg
+fate-vorbis-9: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/lsp-test3_small.ogg
 fate-vorbis-9: REF = $(SAMPLES)/vorbis/lsp-test3_small.pcm
 
 FATE_VORBIS += fate-vorbis-10
-fate-vorbis-10: CMD = pcm -i $(SAMPLES)/vorbis/lsp-test4_small.ogg
+fate-vorbis-10: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/lsp-test4_small.ogg
 fate-vorbis-10: REF = $(SAMPLES)/vorbis/lsp-test4_small.pcm
 
 FATE_VORBIS += fate-vorbis-11
-fate-vorbis-11: CMD = pcm -i $(SAMPLES)/vorbis/lsp-test_small.ogg
+fate-vorbis-11: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/lsp-test_small.ogg
 fate-vorbis-11: REF = $(SAMPLES)/vorbis/lsp-test_small.pcm
 
 FATE_VORBIS += fate-vorbis-12
-fate-vorbis-12: CMD = pcm -i $(SAMPLES)/vorbis/mono_small.ogg
+fate-vorbis-12: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/mono_small.ogg
 fate-vorbis-12: REF = $(SAMPLES)/vorbis/mono_small.pcm
 
 FATE_VORBIS += fate-vorbis-13
-fate-vorbis-13: CMD = pcm -i $(SAMPLES)/vorbis/moog_small.ogg
+fate-vorbis-13: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/moog_small.ogg
 fate-vorbis-13: REF = $(SAMPLES)/vorbis/moog_small.pcm
 fate-vorbis-13: FUZZ = 2
 
 FATE_VORBIS += fate-vorbis-14
-fate-vorbis-14: CMD = pcm -i $(SAMPLES)/vorbis/rc1-test_small.ogg
+fate-vorbis-14: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/rc1-test_small.ogg
 fate-vorbis-14: REF = $(SAMPLES)/vorbis/rc1-test_small.pcm
 
 FATE_VORBIS += fate-vorbis-15
-fate-vorbis-15: CMD = pcm -i $(SAMPLES)/vorbis/rc2-test2_small.ogg
+fate-vorbis-15: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/rc2-test2_small.ogg
 fate-vorbis-15: REF = $(SAMPLES)/vorbis/rc2-test2_small.pcm
 
 FATE_VORBIS += fate-vorbis-16
-fate-vorbis-16: CMD = pcm -i $(SAMPLES)/vorbis/rc2-test_small.ogg
+fate-vorbis-16: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/rc2-test_small.ogg
 fate-vorbis-16: REF = $(SAMPLES)/vorbis/rc2-test_small.pcm
 
 FATE_VORBIS += fate-vorbis-17
-fate-vorbis-17: CMD = pcm -i $(SAMPLES)/vorbis/rc3-test_small.ogg
+fate-vorbis-17: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/rc3-test_small.ogg
 fate-vorbis-17: REF = $(SAMPLES)/vorbis/rc3-test_small.pcm
 
 FATE_VORBIS += fate-vorbis-18
-fate-vorbis-18: CMD = pcm -i $(SAMPLES)/vorbis/sleepzor_small.ogg
+fate-vorbis-18: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/sleepzor_small.ogg
 fate-vorbis-18: REF = $(SAMPLES)/vorbis/sleepzor_small.pcm
 fate-vorbis-18: FUZZ = 2
 
 FATE_VORBIS += fate-vorbis-19
-fate-vorbis-19: CMD = pcm -i $(SAMPLES)/vorbis/test-short2_small.ogg
+fate-vorbis-19: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/test-short2_small.ogg
 fate-vorbis-19: REF = $(SAMPLES)/vorbis/test-short2_small.pcm
 
 FATE_VORBIS += fate-vorbis-20
-fate-vorbis-20: CMD = pcm -i $(SAMPLES)/vorbis/6.ogg
+fate-vorbis-20: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/6.ogg
 fate-vorbis-20: REF = $(SAMPLES)/vorbis/6.pcm
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, OGG, VORBIS) += $(FATE_VORBIS)
diff --git a/tests/fate/vpx.mak b/tests/fate/vpx.mak
index bb20dda..ba53a2a 100644
--- a/tests/fate/vpx.mak
+++ b/tests/fate/vpx.mak
@@ -1,29 +1,29 @@
 FATE_VP3-$(call DEMDEC, MATROSKA, THEORA) += fate-theora-coeff-level64
-fate-theora-coeff-level64: CMD = framecrc -flags +bitexact -i $(SAMPLES)/vp3/coeff_level64.mkv
+fate-theora-coeff-level64: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/vp3/coeff_level64.mkv
 
 FATE_VP3-$(call DEMDEC, AVI, VP3) += fate-vp31
-fate-vp31: CMD = framecrc -flags +bitexact -i $(SAMPLES)/vp3/vp31.avi
+fate-vp31: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/vp3/vp31.avi
 
 FATE_SAMPLES_AVCONV += $(FATE_VP3-yes)
 fate-vp3: $(FATE_VP3-yes)
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, VP5) += fate-vp5
-fate-vp5: CMD = framecrc -flags +bitexact -i $(SAMPLES)/vp5/potter512-400-partial.avi -an
+fate-vp5: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/vp5/potter512-400-partial.avi -an
 
 FATE_VP6-$(call DEMDEC, EA, VP6) += fate-vp60
-fate-vp60: CMD = framecrc -flags +bitexact -i $(SAMPLES)/ea-vp6/g36.vp6
+fate-vp60: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/ea-vp6/g36.vp6
 
 FATE_VP6-$(call DEMDEC, EA, VP6) += fate-vp61
-fate-vp61: CMD = framecrc -flags +bitexact -i $(SAMPLES)/ea-vp6/MovieSkirmishGondor.vp6 -t 4
+fate-vp61: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/ea-vp6/MovieSkirmishGondor.vp6 -t 4
 
 FATE_VP6-$(call DEMDEC, FLV, VP6A) += fate-vp6a
-fate-vp6a: CMD = framecrc -flags +bitexact -i $(SAMPLES)/flash-vp6/300x180-Scr-f8-056alpha.flv
+fate-vp6a: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/flash-vp6/300x180-Scr-f8-056alpha.flv
 
 FATE_VP6-$(call DEMDEC, FLV, VP6F) += fate-vp6f
-fate-vp6f: CMD = framecrc -flags +bitexact -i $(SAMPLES)/flash-vp6/clip1024.flv
+fate-vp6f: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/flash-vp6/clip1024.flv
 
 FATE_VP8-$(call DEMDEC, FLV, VP8) += fate-vp8-alpha
-fate-vp8-alpha: CMD = framecrc -i $(SAMPLES)/vp8_alpha/vp8_video_with_alpha.webm -vcodec copy
+fate-vp8-alpha: CMD = framecrc -i $(TARGET_SAMPLES)/vp8_alpha/vp8_video_with_alpha.webm -vcodec copy
 
 FATE_SAMPLES_AVCONV += $(FATE_VP6-yes)
 fate-vp6: $(FATE_VP6-yes)
@@ -32,7 +32,7 @@
 
 define FATE_VP8_SUITE
 FATE_VP8-$(CONFIG_IVF_DEMUXER) += fate-vp8-test-vector$(2)-$(1)
-fate-vp8-test-vector$(2)-$(1): CMD = framemd5 $(3) -i $(SAMPLES)/vp8-test-vectors-r1/vp80-00-comprehensive-$(1).ivf
+fate-vp8-test-vector$(2)-$(1): CMD = framemd5 $(3) -i $(TARGET_SAMPLES)/vp8-test-vectors-r1/vp80-00-comprehensive-$(1).ivf
 fate-vp8-test-vector$(2)-$(1): REF = $(SRC_PATH)/tests/ref/fate/vp8-test-vector-$(1)
 endef
 
@@ -42,11 +42,11 @@
 # FIXME this file contains two frames with identical timestamps,
 # so ffmpeg drops one of them
 FATE_VP8-$(CONFIG_IVF_DEMUXER) += fate-vp8-sign-bias$(1)
-fate-vp8-sign-bias$(1): CMD = framemd5 $(2) -i $(SAMPLES)/vp8/sintel-signbias.ivf
+fate-vp8-sign-bias$(1): CMD = framemd5 $(2) -i $(TARGET_SAMPLES)/vp8/sintel-signbias.ivf
 fate-vp8-sign-bias$(1): REF = $(SRC_PATH)/tests/ref/fate/vp8-sign-bias
 
 FATE_VP8-$(CONFIG_MATROSKA_DEMUXER) += fate-vp8-size-change$(1)
-fate-vp8-size-change$(1): CMD = framemd5 $(2) -flags +bitexact -i $(SAMPLES)/vp8/frame_size_change.webm -frames:v 30 -sws_flags bitexact+bilinear
+fate-vp8-size-change$(1): CMD = framemd5 $(2) -flags +bitexact -i $(TARGET_SAMPLES)/vp8/frame_size_change.webm -frames:v 30 -sws_flags bitexact+bilinear
 fate-vp8-size-change$(1): REF = $(SRC_PATH)/tests/ref/fate/vp8-size-change
 endef
 
diff --git a/tests/fate/vqf.mak b/tests/fate/vqf.mak
index 67ee61f..8b50d7a 100644
--- a/tests/fate/vqf.mak
+++ b/tests/fate/vqf.mak
@@ -1,10 +1,10 @@
 FATE_VQF-$(call DEMDEC, VQF, TWINVQ) += fate-twinvq
-fate-twinvq: CMD = pcm -i $(SAMPLES)/vqf/achterba.vqf
+fate-twinvq: CMD = pcm -i $(TARGET_SAMPLES)/vqf/achterba.vqf
 fate-twinvq: CMP = oneoff
 fate-twinvq: REF = $(SAMPLES)/vqf/achterba.pcm
 
 FATE_VQF-$(CONFIG_VQF_DEMUXER) += fate-vqf-demux
-fate-vqf-demux: CMD = md5 -i $(SAMPLES)/vqf/achterba.vqf -acodec copy -f framecrc
+fate-vqf-demux: CMD = md5 -i $(TARGET_SAMPLES)/vqf/achterba.vqf -acodec copy -f framecrc
 
 FATE_VQF += $(FATE_VQF-yes)
 
diff --git a/tests/fate/wavpack.mak b/tests/fate/wavpack.mak
index 8a1c301..04207c3 100644
--- a/tests/fate/wavpack.mak
+++ b/tests/fate/wavpack.mak
@@ -1,92 +1,102 @@
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += $(FATE_WAVPACK)
+
 # lossless
 
-FATE_WAVPACK += fate-wavpack-lossless-8bit
-fate-wavpack-lossless-8bit: CMD = md5 -i $(SAMPLES)/wavpack/lossless/8bit-partial.wv -f s8
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossless-8bit
+fate-wavpack-lossless-8bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/8bit-partial.wv -f s8
 
-FATE_WAVPACK += fate-wavpack-lossless-12bit
-fate-wavpack-lossless-12bit: CMD = md5 -i $(SAMPLES)/wavpack/lossless/12bit-partial.wv -f s16le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossless-12bit
+fate-wavpack-lossless-12bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/12bit-partial.wv -f s16le
 
-FATE_WAVPACK += fate-wavpack-lossless-16bit
-fate-wavpack-lossless-16bit: CMD = md5 -i $(SAMPLES)/wavpack/lossless/16bit-partial.wv -f s16le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossless-16bit
+fate-wavpack-lossless-16bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/16bit-partial.wv -f s16le
 
-FATE_WAVPACK += fate-wavpack-lossless-24bit
-fate-wavpack-lossless-24bit: CMD = md5 -i $(SAMPLES)/wavpack/lossless/24bit-partial.wv -f s24le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossless-24bit
+fate-wavpack-lossless-24bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/24bit-partial.wv -f s24le
 
-FATE_WAVPACK += fate-wavpack-lossless-32bit
-fate-wavpack-lossless-32bit: CMD = md5 -i $(SAMPLES)/wavpack/lossless/32bit_int-partial.wv -f s32le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossless-32bit
+fate-wavpack-lossless-32bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/32bit_int-partial.wv -f s32le
 
-FATE_WAVPACK += fate-wavpack-lossless-float
-fate-wavpack-lossless-float: CMD = md5 -i $(SAMPLES)/wavpack/lossless/32bit_float-partial.wv -f f32le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossless-float
+fate-wavpack-lossless-float: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/32bit_float-partial.wv -f f32le
 
 # lossy
 
-FATE_WAVPACK += fate-wavpack-lossy-8bit
-fate-wavpack-lossy-8bit: CMD = md5 -i $(SAMPLES)/wavpack/lossy/4.0_8-bit.wv -f s8
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossy-8bit
+fate-wavpack-lossy-8bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/4.0_8-bit.wv -f s8
 
-FATE_WAVPACK += fate-wavpack-lossy-16bit
-fate-wavpack-lossy-16bit: CMD = md5 -i $(SAMPLES)/wavpack/lossy/4.0_16-bit.wv -f s16le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossy-16bit
+fate-wavpack-lossy-16bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/4.0_16-bit.wv -f s16le
 
-FATE_WAVPACK += fate-wavpack-lossy-24bit
-fate-wavpack-lossy-24bit: CMD = md5 -i $(SAMPLES)/wavpack/lossy/4.0_24-bit.wv -f s24le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossy-24bit
+fate-wavpack-lossy-24bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/4.0_24-bit.wv -f s24le
 
-FATE_WAVPACK += fate-wavpack-lossy-32bit
-fate-wavpack-lossy-32bit: CMD = md5 -i $(SAMPLES)/wavpack/lossy/4.0_32-bit_int.wv -f s32le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossy-32bit
+fate-wavpack-lossy-32bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/4.0_32-bit_int.wv -f s32le
 
-FATE_WAVPACK += fate-wavpack-lossy-float
-fate-wavpack-lossy-float: CMD = md5 -i $(SAMPLES)/wavpack/lossy/2.0_32-bit_float.wv -f f32le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossy-float
+fate-wavpack-lossy-float: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/2.0_32-bit_float.wv -f f32le
 
 # channel configurations
 
-FATE_WAVPACK += fate-wavpack-channels-monofloat
-fate-wavpack-channels-monofloat: CMD = md5 -i $(SAMPLES)/wavpack/num_channels/mono_float-partial.wv -f f32le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-channels-monofloat
+fate-wavpack-channels-monofloat: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/mono_float-partial.wv -f f32le
 
-FATE_WAVPACK += fate-wavpack-channels-monoint
-fate-wavpack-channels-monoint: CMD = md5 -i $(SAMPLES)/wavpack/num_channels/mono_16bit_int.wv -f s16le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-channels-monoint
+fate-wavpack-channels-monoint: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/mono_16bit_int.wv -f s16le
 
-FATE_WAVPACK += fate-wavpack-channels-4.0
-fate-wavpack-channels-4.0: CMD = md5 -i $(SAMPLES)/wavpack/num_channels/edward_4.0_16bit-partial.wv -f s16le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-channels-4.0
+fate-wavpack-channels-4.0: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/edward_4.0_16bit-partial.wv -f s16le
 
-FATE_WAVPACK += fate-wavpack-channels-5.1
-fate-wavpack-channels-5.1: CMD = md5 -i $(SAMPLES)/wavpack/num_channels/panslab_sample_5.1_16bit-partial.wv -f s16le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-channels-5.1
+fate-wavpack-channels-5.1: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/panslab_sample_5.1_16bit-partial.wv -f s16le
 
-FATE_WAVPACK += fate-wavpack-channels-6.1
-fate-wavpack-channels-6.1: CMD = md5 -i $(SAMPLES)/wavpack/num_channels/eva_2.22_6.1_16bit-partial.wv -f s16le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-channels-6.1
+fate-wavpack-channels-6.1: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/eva_2.22_6.1_16bit-partial.wv -f s16le
 
-FATE_WAVPACK += fate-wavpack-channels-7.1
-fate-wavpack-channels-7.1: CMD = md5 -i $(SAMPLES)/wavpack/num_channels/panslab_sample_7.1_16bit-partial.wv -f s16le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-channels-7.1
+fate-wavpack-channels-7.1: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/panslab_sample_7.1_16bit-partial.wv -f s16le
 
 # speed modes
 
-FATE_WAVPACK += fate-wavpack-speed-default
-fate-wavpack-speed-default: CMD = md5 -i $(SAMPLES)/wavpack/speed_modes/default-partial.wv  -f s16le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-speed-default
+fate-wavpack-speed-default: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/speed_modes/default-partial.wv  -f s16le
 
-FATE_WAVPACK += fate-wavpack-speed-fast
-fate-wavpack-speed-fast: CMD = md5 -i $(SAMPLES)/wavpack/speed_modes/fast-partial.wv  -f s16le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-speed-fast
+fate-wavpack-speed-fast: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/speed_modes/fast-partial.wv  -f s16le
 
-FATE_WAVPACK += fate-wavpack-speed-high
-fate-wavpack-speed-high: CMD = md5 -i $(SAMPLES)/wavpack/speed_modes/high-partial.wv  -f s16le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-speed-high
+fate-wavpack-speed-high: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/speed_modes/high-partial.wv  -f s16le
 
-FATE_WAVPACK += fate-wavpack-speed-vhigh
-fate-wavpack-speed-vhigh: CMD = md5 -i $(SAMPLES)/wavpack/speed_modes/vhigh-partial.wv  -f s16le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-speed-vhigh
+fate-wavpack-speed-vhigh: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/speed_modes/vhigh-partial.wv  -f s16le
 
 # special cases
 
-FATE_WAVPACK += fate-wavpack-clipping
-fate-wavpack-clipping: CMD = md5 -i $(SAMPLES)/wavpack/special/clipping.wv -f s16le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-clipping
+fate-wavpack-clipping: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/clipping.wv -f s16le
 
-FATE_WAVPACK += fate-wavpack-cuesheet
-fate-wavpack-cuesheet: CMD = md5 -i $(SAMPLES)/wavpack/special/cue_sheet.wv -f s16le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-cuesheet
+fate-wavpack-cuesheet: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/cue_sheet.wv -f s16le
 
-FATE_WAVPACK += fate-wavpack-falsestereo
-fate-wavpack-falsestereo: CMD = md5 -i $(SAMPLES)/wavpack/special/false_stereo.wv -f s16le
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-falsestereo
+fate-wavpack-falsestereo: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/false_stereo.wv -f s16le
 
-FATE_WAVPACK += fate-wavpack-zerolsbs
-fate-wavpack-zerolsbs: CMD = md5 -i $(SAMPLES)/wavpack/special/zero_lsbs.wv -f s16le
-
-FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += $(FATE_WAVPACK)
+FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-zerolsbs
+fate-wavpack-zerolsbs: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/zero_lsbs.wv -f s16le
 
 FATE_WAVPACK-$(call DEMDEC, MATROSKA, WAVPACK) += fate-wavpack-matroskamode
-fate-wavpack-matroskamode: CMD = md5 -i $(SAMPLES)/wavpack/special/matroska_mode.mka -f s16le
+fate-wavpack-matroskamode: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/matroska_mode.mka -f s16le
+
+FATE_WAVPACK-$(call DEMMUX, WV, MATROSKA) += fate-wavpack-matroska_mux-mono
+fate-wavpack-matroska_mux-mono: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/mono_16bit_int.wv -c copy -flags +bitexact -f matroska
+fate-wavpack-matroska_mux-mono: CMP = oneline
+fate-wavpack-matroska_mux-mono: REF = 769c19bcd931d9e15f7d5aa7b390b0db
+
+FATE_WAVPACK-$(call DEMMUX, WV, MATROSKA) += fate-wavpack-matroska_mux-61
+fate-wavpack-matroska_mux-61: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/eva_2.22_6.1_16bit-partial.wv -c copy -flags +bitexact -f matroska
+fate-wavpack-matroska_mux-61: CMP = oneline
+fate-wavpack-matroska_mux-61: REF = 7f13234f0f3d5b7e00a4661412be025b
 
 FATE_SAMPLES_AVCONV += $(FATE_WAVPACK-yes)
 fate-wavpack: $(FATE_WAVPACK-yes)
diff --git a/tests/fate/wma.mak b/tests/fate/wma.mak
index b9a856c..1b8c5f9 100644
--- a/tests/fate/wma.mak
+++ b/tests/fate/wma.mak
@@ -1,13 +1,13 @@
 FATE_WMAPRO-$(call DEMDEC, ASF, WMAPRO) += fate-wmapro-2ch
-fate-wmapro-2ch: CMD = pcm -i $(SAMPLES)/wmapro/Beethovens_9th-1_small.wma
+fate-wmapro-2ch: CMD = pcm -i $(TARGET_SAMPLES)/wmapro/Beethovens_9th-1_small.wma
 fate-wmapro-2ch: REF = $(SAMPLES)/wmapro/Beethovens_9th-1_small.pcm
 
 FATE_WMAPRO-$(call DEMDEC, ASF, WMAPRO) += fate-wmapro-5.1
-fate-wmapro-5.1: CMD = pcm -i $(SAMPLES)/wmapro/latin_192_mulitchannel_cut.wma
+fate-wmapro-5.1: CMD = pcm -i $(TARGET_SAMPLES)/wmapro/latin_192_mulitchannel_cut.wma
 fate-wmapro-5.1: REF = $(SAMPLES)/wmapro/latin_192_mulitchannel_cut.pcm
 
 FATE_WMAPRO-$(call DEMDEC, MOV, WMAPRO) += fate-wmapro-ism
-fate-wmapro-ism: CMD = pcm -i $(SAMPLES)/isom/vc1-wmapro.ism -vn
+fate-wmapro-ism: CMD = pcm -i $(TARGET_SAMPLES)/isom/vc1-wmapro.ism -vn
 fate-wmapro-ism: REF = $(SAMPLES)/isom/vc1-wmapro.pcm
 
 $(FATE_WMAPRO-yes): CMP = oneoff
@@ -16,17 +16,17 @@
 fate-wmapro: $(FATE_WMAPRO-yes)
 
 FATE_WMAVOICE-$(call DEMDEC, ASF, WMAVOICE) += fate-wmavoice-7k
-fate-wmavoice-7k: CMD = pcm -i $(SAMPLES)/wmavoice/streaming_CBR-7K.wma
+fate-wmavoice-7k: CMD = pcm -i $(TARGET_SAMPLES)/wmavoice/streaming_CBR-7K.wma
 fate-wmavoice-7k: REF = $(SAMPLES)/wmavoice/streaming_CBR-7K.pcm
 fate-wmavoice-7k: FUZZ = 3
 
 FATE_WMAVOICE-$(call DEMDEC, ASF, WMAVOICE) += fate-wmavoice-11k
-fate-wmavoice-11k: CMD = pcm -i $(SAMPLES)/wmavoice/streaming_CBR-11K.wma
+fate-wmavoice-11k: CMD = pcm -i $(TARGET_SAMPLES)/wmavoice/streaming_CBR-11K.wma
 fate-wmavoice-11k: REF = $(SAMPLES)/wmavoice/streaming_CBR-11K.pcm
 fate-wmavoice-11k: FUZZ = 3
 
 FATE_WMAVOICE-$(call DEMDEC, ASF, WMAVOICE) += fate-wmavoice-19k
-fate-wmavoice-19k: CMD = pcm -i $(SAMPLES)/wmavoice/streaming_CBR-19K.wma
+fate-wmavoice-19k: CMD = pcm -i $(TARGET_SAMPLES)/wmavoice/streaming_CBR-19K.wma
 fate-wmavoice-19k: REF = $(SAMPLES)/wmavoice/streaming_CBR-19K.pcm
 fate-wmavoice-19k: FUZZ = 3
 
@@ -36,13 +36,13 @@
 fate-wmavoice: $(FATE_WMAVOICE-yes)
 
 FATE_WMA_ENCODE-$(call ENCDEC, WMAV1, ASF) += fate-wmav1-encode
-fate-wmav1-encode: CMD = enc_dec_pcm asf wav s16le $(REF) -c:a wmav1 -b:a 128k
+fate-wmav1-encode: CMD = enc_dec_pcm asf wav s16le $(subst $(SAMPLES),$(TARGET_SAMPLES),$(REF)) -c:a wmav1 -b:a 128k
 fate-wmav1-encode: CMP_SHIFT = -8192
 fate-wmav1-encode: CMP_TARGET = 291.06
 fate-wmav1-encode: SIZE_TOLERANCE = 4632
 
 FATE_WMA_ENCODE-$(call ENCDEC, WMAV2, ASF) += fate-wmav2-encode
-fate-wmav2-encode: CMD = enc_dec_pcm asf wav s16le $(REF) -c:a wmav2 -b:a 128k
+fate-wmav2-encode: CMD = enc_dec_pcm asf wav s16le $(subst $(SAMPLES),$(TARGET_SAMPLES),$(REF)) -c:a wmav2 -b:a 128k
 fate-wmav2-encode: CMP_SHIFT = -8192
 fate-wmav2-encode: CMP_TARGET = 258.32
 fate-wmav2-encode: SIZE_TOLERANCE = 4632
diff --git a/tests/filtergraphs/alphamerge_alphaextract_rgb b/tests/filtergraphs/alphamerge_alphaextract_rgb
new file mode 100644
index 0000000..1aa302d
--- /dev/null
+++ b/tests/filtergraphs/alphamerge_alphaextract_rgb
@@ -0,0 +1,4 @@
+sws_flags=+accurate_rnd+bitexact;
+format=bgra, split, alphamerge, split [x][y];
+[y]        alphaextract [alpha];
+[x][alpha] alphamerge
diff --git a/tests/filtergraphs/alphamerge_alphaextract_yuv b/tests/filtergraphs/alphamerge_alphaextract_yuv
new file mode 100644
index 0000000..ef3ea14
--- /dev/null
+++ b/tests/filtergraphs/alphamerge_alphaextract_yuv
@@ -0,0 +1,4 @@
+sws_flags=+accurate_rnd+bitexact;
+format=yuv420p, split, alphamerge, split [x][y];
+[y]        alphaextract [alpha];
+[x][alpha] alphamerge
diff --git a/tests/filtergraphs/gradfun b/tests/filtergraphs/gradfun
index 2923cb5..d93dcaf 100644
--- a/tests/filtergraphs/gradfun
+++ b/tests/filtergraphs/gradfun
@@ -1,2 +1,2 @@
 sws_flags=+accurate_rnd+bitexact;
-format=gray, perms=random, gradfun=10:8
+format=gray, perms=random, gradfun=10:8:enable='not(between(n,5,10))'
diff --git a/tests/filtergraphs/hqdn3d b/tests/filtergraphs/hqdn3d
new file mode 100644
index 0000000..7591822
--- /dev/null
+++ b/tests/filtergraphs/hqdn3d
@@ -0,0 +1 @@
+perms=random, hqdn3d=enable='not(between(t,5,6))'
diff --git a/tests/filtergraphs/overlay_rgb b/tests/filtergraphs/overlay_rgb
new file mode 100644
index 0000000..b060c01
--- /dev/null
+++ b/tests/filtergraphs/overlay_rgb
@@ -0,0 +1,4 @@
+sws_flags=+accurate_rnd+bitexact;
+split [main][over];
+[over] scale=88:72, pad=96:80:4:4 [overf];
+[main][overf] overlay=240:16:format=rgb
diff --git a/tests/filtergraphs/overlay_yuv420 b/tests/filtergraphs/overlay_yuv420
new file mode 100644
index 0000000..9ed1b2a
--- /dev/null
+++ b/tests/filtergraphs/overlay_yuv420
@@ -0,0 +1,4 @@
+sws_flags=+accurate_rnd+bitexact;
+split [main][over];
+[over] scale=88:72, pad=96:80:4:4 [overf];
+[main][overf] overlay=240:16:format=yuv420
diff --git a/tests/filtergraphs/overlay_yuv444 b/tests/filtergraphs/overlay_yuv444
new file mode 100644
index 0000000..bda0fd6
--- /dev/null
+++ b/tests/filtergraphs/overlay_yuv444
@@ -0,0 +1,4 @@
+sws_flags=+accurate_rnd+bitexact;
+split [main][over];
+[over] scale=88:72, pad=96:80:4:4 [overf];
+[main][overf] overlay=240:16:format=yuv444
diff --git a/tests/filtergraphs/scalenorm b/tests/filtergraphs/scalenorm
new file mode 100644
index 0000000..17b69de
--- /dev/null
+++ b/tests/filtergraphs/scalenorm
@@ -0,0 +1,4 @@
+sws_flags=+accurate_rnd+bitexact;
+testsrc=s=128x96  : d=1:r=5, format=yuv420p [a];
+testsrc=s=160x120 : d=1:r=5                 [b];
+[a][b] concat=unsafe=1, scale=flags=+accurate_rnd+bitexact
diff --git a/tests/lavf-regression.sh b/tests/lavf-regression.sh
index 196e965..cd96567 100755
--- a/tests/lavf-regression.sh
+++ b/tests/lavf-regression.sh
@@ -50,7 +50,7 @@
     outfile="$datadir/images/$1/"
     mkdir -p "$outfile"
     file=${outfile}%02d.$1
-    run_avconv $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $2 $ENC_OPTS -t 0.5 -y -qscale 10 $target_path/$file
+    run_avconv $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $2 $ENC_OPTS -frames 13 -y -qscale 10 $target_path/$file
     do_md5sum ${outfile}02.$1
     do_avconv_crc $file $DEC_OPTS -i $target_path/$file $3
     echo $(wc -c ${outfile}02.$1)
@@ -235,8 +235,8 @@
 do_image_formats pam
 do_image_formats pam "-pix_fmt rgba"
 do_image_formats pam "-pix_fmt gray"
-do_image_formats pam "-pix_fmt gray16be"
-do_image_formats pam "-pix_fmt rgb48be"
+do_image_formats pam "-pix_fmt gray16be" "-pix_fmt gray16be"
+do_image_formats pam "-pix_fmt rgb48be" "-pix_fmt rgb48be"
 do_image_formats pam "-pix_fmt monob"
 fi
 
@@ -246,8 +246,11 @@
 
 if [ -n "$do_dpx" ] ; then
 do_image_formats dpx
+do_image_formats dpx "-pix_fmt gbrp10le" "-pix_fmt gbrp10le"
+do_image_formats dpx "-pix_fmt gbrp12le"
 do_image_formats dpx "-pix_fmt rgb48le"
 do_image_formats dpx "-pix_fmt rgb48le -bits_per_raw_sample 10" "-pix_fmt rgb48le"
+do_image_formats dpx "-pix_fmt rgba64le"
 fi
 
 if [ -n "$do_xwd" ] ; then
diff --git a/tests/lavfi-regression.sh b/tests/lavfi-regression.sh
deleted file mode 100755
index d3e95d7..0000000
--- a/tests/lavfi-regression.sh
+++ /dev/null
@@ -1,141 +0,0 @@
-#!/bin/sh
-#
-# automatic regression test for libavfilter
-#
-#
-#set -x
-
-set -e
-
-. $(dirname $0)/regression-funcs.sh
-
-eval do_$test=y
-
-do_video_filter() {
-    label=$1
-    filters="$2"
-    shift 2
-    printf '%-20s' $label
-    run_avconv $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src    \
-        $ENC_OPTS -vf "$filters" -vcodec rawvideo $* -f nut md5:
-}
-
-do_lavfi_plain() {
-    vfilters="$2"
-
-    if [ $test = $1 ] ; then
-        do_video_filter $test "$2"
-    fi
-}
-
-do_lavfi() {
-    do_lavfi_plain $1 "$2"
-}
-
-do_lavfi_colormatrix() {
-    do_lavfi "${1}1" "$1=$4:$5,$1=$5:$3,$1=$3:$4,$1=$4:$3,$1=$3:$5,$1=$5:$2"
-    do_lavfi "${1}2" "$1=$2:$3,$1=$3:$2,$1=$2:$4,$1=$4:$2,$1=$2:$5,$1=$5:$4"
-}
-
-do_lavfi "crop"               "crop=iw-100:ih-100:100:100"
-do_lavfi "crop_scale"         "crop=iw-100:ih-100:100:100,scale=400:-1"
-do_lavfi "crop_scale_vflip"   "null,null,crop=iw-200:ih-200:200:200,crop=iw-20:ih-20:20:20,scale=200:200,scale=250:250,vflip,vflip,null,scale=200:200,crop=iw-100:ih-100:100:100,vflip,scale=200:200,null,vflip,crop=iw-100:ih-100:100:100,null"
-do_lavfi "crop_vflip"         "crop=iw-100:ih-100:100:100,vflip"
-do_lavfi "drawbox"            "drawbox=224:24:88:72:#FF8010@0.5"
-do_lavfi "edgedetect"         "format=gray,perms=random,edgedetect"
-do_lavfi "fade"               "fade=in:5:15,fade=out:30:15"
-do_lavfi "hue"                "perms=random,hue=s=sin(2*PI*t)+1"
-do_lavfi "idet"               "idet"
-do_lavfi "null"               "null"
-do_lavfi "overlay_rgb"        "split[m],scale=88:72,pad=96:80:4:4[o2];[m]fifo[o1],[o1][o2]overlay=240:16:format=rgb"
-do_lavfi "overlay_yuv420"     "split[m],scale=88:72,pad=96:80:4:4[o2];[m]fifo[o1],[o1][o2]overlay=240:16:format=yuv420"
-do_lavfi "overlay_yuv444"     "split[m],scale=88:72,pad=96:80:4:4[o2];[m]fifo[o1],[o1][o2]overlay=240:16:format=yuv444"
-do_lavfi "pad"                "pad=iw*1.5:ih*1.5:iw*0.3:ih*0.2"
-do_lavfi "pp"                 "pp=be/hb/vb/tn/l5/al"
-do_lavfi "pp2"                "pp=be/fq|16/h1/v1/lb"
-do_lavfi "pp3"                "pp=be/fq|8/ha|128|7/va/li"
-do_lavfi "pp4"                "pp=be/ci"
-do_lavfi "pp5"                "pp=md"
-do_lavfi "pp6"                "pp=be/fd"
-do_lavfi "scale200"           "scale=200:200"
-do_lavfi "scale500"           "scale=500:500"
-do_lavfi "select"             "select=not(eq(mod(n\,2)\,0)+eq(mod(n\,3)\,0))"
-do_lavfi "setdar"             "setdar=dar=16/9"
-do_lavfi "setsar"             "setsar=sar=16/11"
-do_lavfi "thumbnail"          "thumbnail=10"
-do_lavfi "tile"               "tile=3x3:nb_frames=5:padding=7:margin=2"
-do_lavfi "transpose"          "transpose"
-do_lavfi "unsharp"            "unsharp=11:11:-1.5:11:11:-1.5"
-do_lavfi "vflip"              "vflip"
-do_lavfi "vflip_crop"         "vflip,crop=iw-100:ih-100:100:100"
-do_lavfi "vflip_vflip"        "vflip,vflip"
-
-do_lavfi_plain "alphamerge_rgb"     "[in]format=bgra,split,alphamerge[out]"
-do_lavfi_plain "alphamerge_yuv"     "[in]format=yuv420p,split,alphamerge[out]"
-do_lavfi_plain "alphaextract_rgb"   "[in]format=bgra,split,alphamerge,split[o3][o4];[o4]alphaextract[alpha];[o3][alpha]alphamerge[out]"
-do_lavfi_plain "alphaextract_yuv"   "[in]format=yuv420p,split,alphamerge,split[o3][o4];[o4]alphaextract[alpha];[o3][alpha]alphamerge[out]"
-
-do_lavfi_colormatrix "colormatrix" bt709 fcc bt601 smpte240m
-
-do_lavfi_pixfmts(){
-    testname=$1;
-    test ${test%_[bl]e} = $testname || return 0
-    filter=$2
-    filter_args=$3
-    prefilter_chain=$4
-
-    showfiltfmts="$target_exec $target_path/libavfilter/filtfmts-test"
-    scale_exclude_fmts=${outfile}${testname}_scale_exclude_fmts
-    scale_in_fmts=${outfile}${testname}_scale_in_fmts
-    scale_out_fmts=${outfile}${testname}_scale_out_fmts
-    in_fmts=${outfile}${testname}_in_fmts
-
-    # exclude pixel formats which are not supported as input
-    $showfiltfmts scale | awk -F '[ \r]' '/^INPUT/{ fmt=substr($3, 5); print fmt }' | sort >$scale_in_fmts
-    $showfiltfmts scale | awk -F '[ \r]' '/^OUTPUT/{ fmt=substr($3, 5); print fmt }' | sort >$scale_out_fmts
-    comm -12 $scale_in_fmts $scale_out_fmts >$scale_exclude_fmts
-
-    $showfiltfmts $filter | awk -F '[ \r]' '/^INPUT/{ fmt=substr($3, 5); print fmt }' | sort >$in_fmts
-    pix_fmts=$(comm -12 $scale_exclude_fmts $in_fmts)
-
-    for pix_fmt in $pix_fmts; do
-        do_video_filter $pix_fmt "${prefilter_chain}format=$pix_fmt,$filter=$filter_args" -pix_fmt $pix_fmt
-    done
-
-    rm $in_fmts $scale_in_fmts $scale_out_fmts $scale_exclude_fmts
-}
-
-# all these filters have exactly one input and exactly one output
-do_lavfi_pixfmts "field"               "field"   "bottom"
-do_lavfi_pixfmts "histeq"              "histeq"  "antibanding=strong"
-do_lavfi_pixfmts "il"                  "il"      "luma_mode=d:chroma_mode=d:alpha_mode=d"
-do_lavfi_pixfmts "kerndeint"           "kerndeint" "" "tinterlace=interleave_top,"
-do_lavfi_pixfmts "pixfmts_copy"        "copy"    ""
-do_lavfi_pixfmts "pixfmts_crop"        "crop"    "100:100:100:100"
-do_lavfi_pixfmts "pixfmts_hflip"       "hflip"   ""
-do_lavfi_pixfmts "pixfmts_null"        "null"    ""
-do_lavfi_pixfmts "pixfmts_pad"         "pad"     "500:400:20:20"
-do_lavfi_pixfmts "pixfmts_pixdesctest" "pixdesctest"
-do_lavfi_pixfmts "pixfmts_scale"       "scale"   "200:100"
-do_lavfi_pixfmts "pixfmts_super2xsai"  "super2xsai"
-do_lavfi_pixfmts "pixfmts_vflip"       "vflip"
-do_lavfi_pixfmts "tinterlace_merge"    "tinterlace" "merge"
-do_lavfi_pixfmts "tinterlace_pad"      "tinterlace" "pad"
-
-do_lavfi_lavd() {
-    label=$1
-    graph=$2
-    shift 2
-    [ $test = $label ] || return 0
-    printf '%-20s' $label
-    run_avconv $DEC_OPTS -f lavfi -i $graph \
-        $ENC_OPTS -vcodec rawvideo $* -f nut md5:
-}
-
-do_lavfi_lavd "life"                 "life=s=40x40:r=5:seed=42:mold=64" -t 2
-do_lavfi_lavd "testsrc"              "testsrc=r=7:n=2:d=10"
-do_lavfi_lavd "scalenorm"            "sws_flags=+accurate_rnd+bitexact;testsrc=s=128x96:d=1:r=5,format=yuv420p[a];testsrc=s=160x120:d=1:r=5[b];[a][b]concat=unsafe=1,scale=flags=+accurate_rnd+bitexact"
-
-# TODO: add tests for
-# direct rendering,
-# chains with feedback loops
diff --git a/tests/ref/fate/adpcm-dtk b/tests/ref/fate/adpcm-dtk
new file mode 100644
index 0000000..3640e1c
--- /dev/null
+++ b/tests/ref/fate/adpcm-dtk
@@ -0,0 +1,33 @@
+#tb 0: 1/48000
+0,          0,          0,      896,     3584, 0xdae789d5
+0,        896,        896,      896,     3584, 0x168ed9b6
+0,       1792,       1792,      896,     3584, 0x8920c8d5
+0,       2688,       2688,      896,     3584, 0xaf0a3245
+0,       3584,       3584,      896,     3584, 0x884ee935
+0,       4480,       4480,      896,     3584, 0xe6a832ad
+0,       5376,       5376,      896,     3584, 0x1fa12ea2
+0,       6272,       6272,      896,     3584, 0xf119198c
+0,       7168,       7168,      896,     3584, 0x0a6dbf72
+0,       8064,       8064,      896,     3584, 0xd3467881
+0,       8960,       8960,      896,     3584, 0x25d504ec
+0,       9856,       9856,      896,     3584, 0x452730c9
+0,      10752,      10752,      896,     3584, 0x42b92ff1
+0,      11648,      11648,      896,     3584, 0x85c67bf3
+0,      12544,      12544,      896,     3584, 0xab4d99e9
+0,      13440,      13440,      896,     3584, 0xe5bfc4da
+0,      14336,      14336,      896,     3584, 0x7a5210e9
+0,      15232,      15232,      896,     3584, 0x5265fcd3
+0,      16128,      16128,      896,     3584, 0x76531427
+0,      17024,      17024,      896,     3584, 0xb2b8d7ab
+0,      17920,      17920,      896,     3584, 0x05a453e8
+0,      18816,      18816,      896,     3584, 0x742c45bb
+0,      19712,      19712,      896,     3584, 0x57aaee3b
+0,      20608,      20608,      896,     3584, 0x997bf703
+0,      21504,      21504,      896,     3584, 0xe2d14b13
+0,      22400,      22400,      896,     3584, 0xdafbdd2f
+0,      23296,      23296,      896,     3584, 0x448cec3a
+0,      24192,      24192,      896,     3584, 0xe6f6fb9c
+0,      25088,      25088,      896,     3584, 0x0310276a
+0,      25984,      25984,      896,     3584, 0x44bf04e9
+0,      26880,      26880,      896,     3584, 0xe2105d33
+0,      27776,      27776,      896,     3584, 0x08b7d5e0
diff --git a/tests/ref/fate/adpcm-ima-amv b/tests/ref/fate/adpcm-ima-amv
index ca7a168..4bd22af 100644
--- a/tests/ref/fate/adpcm-ima-amv
+++ b/tests/ref/fate/adpcm-ima-amv
@@ -158,4 +158,4 @@
 0,     215010,     215010,     1380,     2760, 0xb83548f4
 0,     216390,     216390,     1378,     2756, 0x22647962
 0,     217768,     217768,     1378,     2756, 0x14ca54d3
-0,     219146,     219146,     1378,     2756, 0x58754b3a
+0,     219146,     219146,     1354,     2708, 0x85e82e8d
diff --git a/tests/ref/fate/adpcm-ima-rad b/tests/ref/fate/adpcm-ima-rad
new file mode 100644
index 0000000..c5de1a6
--- /dev/null
+++ b/tests/ref/fate/adpcm-ima-rad
@@ -0,0 +1 @@
+495f0ae514c28c6bdcbd40811a17e2a5
diff --git a/tests/ref/fate/adpcm-ms-mono b/tests/ref/fate/adpcm-ms-mono
index 3bf44f8..c456708 100644
--- a/tests/ref/fate/adpcm-ms-mono
+++ b/tests/ref/fate/adpcm-ms-mono
@@ -43,4 +43,4 @@
 0,      20500,      20500,      500,     1000, 0xf195eb44
 0,      21000,      21000,      500,     1000, 0xa491f3ef
 0,      21500,      21500,      500,     1000, 0x2c036e18
-0,      22000,      22000,      500,     1000, 0x52d65e2a
+0,      22000,      22000,       50,      100, 0x0bd81f05
diff --git a/tests/ref/fate/armovie-escape130 b/tests/ref/fate/armovie-escape130
new file mode 100644
index 0000000..ee4ec26
--- /dev/null
+++ b/tests/ref/fate/armovie-escape130
@@ -0,0 +1,360 @@
+#tb 0: 1/15
+0,          0,          0,        1,    76800, 0x860502ee
+0,          1,          1,        1,    76800, 0x055da755
+0,          2,          2,        1,    76800, 0x67969220
+0,          3,          3,        1,    76800, 0xbb28885c
+0,          4,          4,        1,    76800, 0x4000a5dd
+0,          5,          5,        1,    76800, 0xfe1f6b04
+0,          6,          6,        1,    76800, 0x334cbe5d
+0,          7,          7,        1,    76800, 0x87d15088
+0,          8,          8,        1,    76800, 0x70248ad3
+0,          9,          9,        1,    76800, 0x29bcaea0
+0,         10,         10,        1,    76800, 0xee81d3e2
+0,         11,         11,        1,    76800, 0x5bdd3cbc
+0,         12,         12,        1,    76800, 0xd7a5e42e
+0,         13,         13,        1,    76800, 0xbb354f7c
+0,         14,         14,        1,    76800, 0x4c86e881
+0,         15,         15,        1,    76800, 0xc6acb7f4
+0,         16,         16,        1,    76800, 0x7701ca9c
+0,         17,         17,        1,    76800, 0x5555d472
+0,         18,         18,        1,    76800, 0xa8fbc2d6
+0,         19,         19,        1,    76800, 0x558ab4f2
+0,         20,         20,        1,    76800, 0x9eb5ab72
+0,         21,         21,        1,    76800, 0x4711a894
+0,         22,         22,        1,    76800, 0xd649c04c
+0,         23,         23,        1,    76800, 0x26b9d6cc
+0,         24,         24,        1,    76800, 0x6217e494
+0,         25,         25,        1,    76800, 0x85d7e232
+0,         26,         26,        1,    76800, 0x4059ddb0
+0,         27,         27,        1,    76800, 0x3581cae2
+0,         28,         28,        1,    76800, 0x1885c99e
+0,         29,         29,        1,    76800, 0xc87dcd66
+0,         30,         30,        1,    76800, 0x8645e084
+0,         31,         31,        1,    76800, 0xe17ed6b4
+0,         32,         32,        1,    76800, 0x2709c7b6
+0,         33,         33,        1,    76800, 0xded3ab34
+0,         34,         34,        1,    76800, 0x3e69a364
+0,         35,         35,        1,    76800, 0x90c7ae7e
+0,         36,         36,        1,    76800, 0x7dffba9a
+0,         37,         37,        1,    76800, 0x1311ce7a
+0,         38,         38,        1,    76800, 0x6663e5ce
+0,         39,         39,        1,    76800, 0x597d0173
+0,         40,         40,        1,    76800, 0x936b1ab3
+0,         41,         41,        1,    76800, 0x860f2157
+0,         42,         42,        1,    76800, 0x69cd2ffd
+0,         43,         43,        1,    76800, 0xd0a24429
+0,         44,         44,        1,    76800, 0x6fbd49b3
+0,         45,         45,        1,    76800, 0x6e866211
+0,         46,         46,        1,    76800, 0x8ed9615d
+0,         47,         47,        1,    76800, 0x5ef45ab1
+0,         48,         48,        1,    76800, 0x72174a5d
+0,         49,         49,        1,    76800, 0x9e1346e1
+0,         50,         50,        1,    76800, 0xbe2046ef
+0,         51,         51,        1,    76800, 0x6417511d
+0,         52,         52,        1,    76800, 0xdc7d59d7
+0,         53,         53,        1,    76800, 0xea8f5569
+0,         54,         54,        1,    76800, 0x77b45d67
+0,         55,         55,        1,    76800, 0x949566bf
+0,         56,         56,        1,    76800, 0x644c6e39
+0,         57,         57,        1,    76800, 0xe8e47155
+0,         58,         58,        1,    76800, 0x84eb80d3
+0,         59,         59,        1,    76800, 0x6ade8f99
+0,         60,         60,        1,    76800, 0x1359adf5
+0,         61,         61,        1,    76800, 0x3b8ab849
+0,         62,         62,        1,    76800, 0xb761c9af
+0,         63,         63,        1,    76800, 0x89f0ccf5
+0,         64,         64,        1,    76800, 0xf50dc989
+0,         65,         65,        1,    76800, 0xc9e8c37f
+0,         66,         66,        1,    76800, 0x91b1c6fb
+0,         67,         67,        1,    76800, 0x30accc59
+0,         68,         68,        1,    76800, 0x4dbbd735
+0,         69,         69,        1,    76800, 0x06ece049
+0,         70,         70,        1,    76800, 0x9112ebef
+0,         71,         71,        1,    76800, 0x4b9af209
+0,         72,         72,        1,    76800, 0x1063f2d5
+0,         73,         73,        1,    76800, 0xc00ef0eb
+0,         74,         74,        1,    76800, 0xfc76efa1
+0,         75,         75,        1,    76800, 0xd85cff3b
+0,         76,         76,        1,    76800, 0x2dc9fc19
+0,         77,         77,        1,    76800, 0xe5610674
+0,         78,         78,        1,    76800, 0xdfa5fdb5
+0,         79,         79,        1,    76800, 0xb7eef1d9
+0,         80,         80,        1,    76800, 0x3743ed2b
+0,         81,         81,        1,    76800, 0xaaf6a11d
+0,         82,         82,        1,    76800, 0xbd3dba25
+0,         83,         83,        1,    76800, 0x0d5a84c2
+0,         84,         84,        1,    76800, 0x04d3cede
+0,         85,         85,        1,    76800, 0xd0ed078b
+0,         86,         86,        1,    76800, 0x712c4257
+0,         87,         87,        1,    76800, 0x0866f074
+0,         88,         88,        1,    76800, 0x7bcbd610
+0,         89,         89,        1,    76800, 0xcfb16193
+0,         90,         90,        1,    76800, 0x08b2bf53
+0,         91,         91,        1,    76800, 0x8a89d293
+0,         92,         92,        1,    76800, 0xdceb169e
+0,         93,         93,        1,    76800, 0x91b53522
+0,         94,         94,        1,    76800, 0xc6f36e86
+0,         95,         95,        1,    76800, 0x64849fae
+0,         96,         96,        1,    76800, 0x7f060705
+0,         97,         97,        1,    76800, 0x100c7c79
+0,         98,         98,        1,    76800, 0xe6d3df05
+0,         99,         99,        1,    76800, 0x3947f65d
+0,        100,        100,        1,    76800, 0xfe52d0e1
+0,        101,        101,        1,    76800, 0x5a81b935
+0,        102,        102,        1,    76800, 0x3dabcb31
+0,        103,        103,        1,    76800, 0x0ae6dea9
+0,        104,        104,        1,    76800, 0x214c2dec
+0,        105,        105,        1,    76800, 0xeb526560
+0,        106,        106,        1,    76800, 0xbb618418
+0,        107,        107,        1,    76800, 0x61d9cbd0
+0,        108,        108,        1,    76800, 0x9d2660bb
+0,        109,        109,        1,    76800, 0xf4f5dc33
+0,        110,        110,        1,    76800, 0xe2551ec2
+0,        111,        111,        1,    76800, 0x5f971e3a
+0,        112,        112,        1,    76800, 0xa96c0cea
+0,        113,        113,        1,    76800, 0xd904cdeb
+0,        114,        114,        1,    76800, 0x0443a227
+0,        115,        115,        1,    76800, 0xf3e92457
+0,        116,        116,        1,    76800, 0x2df4d5b0
+0,        117,        117,        1,    76800, 0x72d4b018
+0,        118,        118,        1,    76800, 0x260ac3dc
+0,        119,        119,        1,    76800, 0x30160163
+0,        120,        120,        1,    76800, 0x76c7656f
+0,        121,        121,        1,    76800, 0xdc42bb23
+0,        122,        122,        1,    76800, 0xdbab366a
+0,        123,        123,        1,    76800, 0xf998ae66
+0,        124,        124,        1,    76800, 0x3b6afb62
+0,        125,        125,        1,    76800, 0x3fb3f76e
+0,        126,        126,        1,    76800, 0xc4f4d89a
+0,        127,        127,        1,    76800, 0xf448aa5a
+0,        128,        128,        1,    76800, 0xf9fed3c2
+0,        129,        129,        1,    76800, 0x8e4526bd
+0,        130,        130,        1,    76800, 0xa4be7a39
+0,        131,        131,        1,    76800, 0x07d376b9
+0,        132,        132,        1,    76800, 0x47993f51
+0,        133,        133,        1,    76800, 0x2f5816ad
+0,        134,        134,        1,    76800, 0x0f78187d
+0,        135,        135,        1,    76800, 0x5129e47e
+0,        136,        136,        1,    76800, 0x1050b9e2
+0,        137,        137,        1,    76800, 0x5ba278d2
+0,        138,        138,        1,    76800, 0xc5f5278e
+0,        139,        139,        1,    76800, 0xe406e093
+0,        140,        140,        1,    76800, 0x1b03c34f
+0,        141,        141,        1,    76800, 0xaad8b463
+0,        142,        142,        1,    76800, 0x4f90ad0d
+0,        143,        143,        1,    76800, 0x83a1b8b3
+0,        144,        144,        1,    76800, 0x682ccba1
+0,        145,        145,        1,    76800, 0xf44f0d22
+0,        146,        146,        1,    76800, 0x19c02d14
+0,        147,        147,        1,    76800, 0x01148baa
+0,        148,        148,        1,    76800, 0xff45dfbe
+0,        149,        149,        1,    76800, 0x05f8db6e
+0,        150,        150,        1,    76800, 0x9a129a6e
+0,        151,        151,        1,    76800, 0x93f8749e
+0,        152,        152,        1,    76800, 0x7dd1f89b
+0,        153,        153,        1,    76800, 0x3c81b16f
+0,        154,        154,        1,    76800, 0xefc3e567
+0,        155,        155,        1,    76800, 0x9fe26222
+0,        156,        156,        1,    76800, 0x85018ef4
+0,        157,        157,        1,    76800, 0x0aa984a4
+0,        158,        158,        1,    76800, 0xea45538e
+0,        159,        159,        1,    76800, 0x8e112454
+0,        160,        160,        1,    76800, 0xab76bf13
+0,        161,        161,        1,    76800, 0x9c1e32a1
+0,        162,        162,        1,    76800, 0xedb88ef8
+0,        163,        163,        1,    76800, 0x5371d475
+0,        164,        164,        1,    76800, 0x631a36eb
+0,        165,        165,        1,    76800, 0x6d4403ef
+0,        166,        166,        1,    76800, 0xdd67190b
+0,        167,        167,        1,    76800, 0x41b054a5
+0,        168,        168,        1,    76800, 0x53f55a99
+0,        169,        169,        1,    76800, 0x93182147
+0,        170,        170,        1,    76800, 0xcce0dd8c
+0,        171,        171,        1,    76800, 0x51f68932
+0,        172,        172,        1,    76800, 0x3d5e2f4a
+0,        173,        173,        1,    76800, 0x8baed3b3
+0,        174,        174,        1,    76800, 0xdc66509b
+0,        175,        175,        1,    76800, 0x1b81fb6c
+0,        176,        176,        1,    76800, 0x63e1f954
+0,        177,        177,        1,    76800, 0x75fd36a1
+0,        178,        178,        1,    76800, 0x68f1a18f
+0,        179,        179,        1,    76800, 0x8b0a1c76
+0,        180,        180,        1,    76800, 0x6d7b9810
+0,        181,        181,        1,    76800, 0x5dcdee4a
+0,        182,        182,        1,    76800, 0xf97c2187
+0,        183,        183,        1,    76800, 0x3e575d0d
+0,        184,        184,        1,    76800, 0x4fc6a723
+0,        185,        185,        1,    76800, 0xf5dcde6d
+0,        186,        186,        1,    76800, 0xc42204d2
+0,        187,        187,        1,    76800, 0x12cff747
+0,        188,        188,        1,    76800, 0xa11ae405
+0,        189,        189,        1,    76800, 0x7cd8d07f
+0,        190,        190,        1,    76800, 0xa100a8fb
+0,        191,        191,        1,    76800, 0x7e9e945b
+0,        192,        192,        1,    76800, 0x2ead8009
+0,        193,        193,        1,    76800, 0x755a7399
+0,        194,        194,        1,    76800, 0x25324c65
+0,        195,        195,        1,    76800, 0xe12ad1a4
+0,        196,        196,        1,    76800, 0x02366ec8
+0,        197,        197,        1,    76800, 0x1e8f0d5a
+0,        198,        198,        1,    76800, 0x0235d45b
+0,        199,        199,        1,    76800, 0x26d2b581
+0,        200,        200,        1,    76800, 0x304f1ccb
+0,        201,        201,        1,    76800, 0x4e1625ff
+0,        202,        202,        1,    76800, 0xfecc1f5b
+0,        203,        203,        1,    76800, 0x499714ff
+0,        204,        204,        1,    76800, 0xff240d1b
+0,        205,        205,        1,    76800, 0xc257ebf8
+0,        206,        206,        1,    76800, 0xf752cdfc
+0,        207,        207,        1,    76800, 0xb031b7cc
+0,        208,        208,        1,    76800, 0xb3f29c84
+0,        209,        209,        1,    76800, 0x77f66fd4
+0,        210,        210,        1,    76800, 0x9ef247ec
+0,        211,        211,        1,    76800, 0xdc32180c
+0,        212,        212,        1,    76800, 0x41bed8e5
+0,        213,        213,        1,    76800, 0x931b8b05
+0,        214,        214,        1,    76800, 0xe45b36f9
+0,        215,        215,        1,    76800, 0xc71bd626
+0,        216,        216,        1,    76800, 0x5b637aca
+0,        217,        217,        1,    76800, 0x3e8d1752
+0,        218,        218,        1,    76800, 0x5f9ca28b
+0,        219,        219,        1,    76800, 0x56d937bf
+0,        220,        220,        1,    76800, 0xe811c010
+0,        221,        221,        1,    76800, 0xca414fe8
+0,        222,        222,        1,    76800, 0x774ef141
+0,        223,        223,        1,    76800, 0xa44282f9
+0,        224,        224,        1,    76800, 0x30690641
+0,        225,        225,        1,    76800, 0xa833ad96
+0,        226,        226,        1,    76800, 0xe18d4932
+0,        227,        227,        1,    76800, 0xf934c0af
+0,        228,        228,        1,    76800, 0xdbc361b7
+0,        229,        229,        1,    76800, 0x7e0d0077
+0,        230,        230,        1,    76800, 0x2d3faaa4
+0,        231,        231,        1,    76800, 0xfa1a7708
+0,        232,        232,        1,    76800, 0xb60870a0
+0,        233,        233,        1,    76800, 0x5f5f7682
+0,        234,        234,        1,    76800, 0x47dc7564
+0,        235,        235,        1,    76800, 0x48f984c8
+0,        236,        236,        1,    76800, 0x7b0892a8
+0,        237,        237,        1,    76800, 0x56a0c014
+0,        238,        238,        1,    76800, 0x5dd1d854
+0,        239,        239,        1,    76800, 0xdfb0f698
+0,        240,        240,        1,    76800, 0xda051775
+0,        241,        241,        1,    76800, 0xa19c3eb1
+0,        242,        242,        1,    76800, 0xda74780d
+0,        243,        243,        1,    76800, 0x5dd28f7f
+0,        244,        244,        1,    76800, 0xf23fa74b
+0,        245,        245,        1,    76800, 0x4014c817
+0,        246,        246,        1,    76800, 0x0954ead7
+0,        247,        247,        1,    76800, 0xa8e319fe
+0,        248,        248,        1,    76800, 0x722e3f2c
+0,        249,        249,        1,    76800, 0xbee3702c
+0,        250,        250,        1,    76800, 0x19599172
+0,        251,        251,        1,    76800, 0x61c18ef0
+0,        252,        252,        1,    76800, 0xfb13780e
+0,        253,        253,        1,    76800, 0xd86e6b80
+0,        254,        254,        1,    76800, 0xf5cc6abc
+0,        255,        255,        1,    76800, 0x5fe86912
+0,        256,        256,        1,    76800, 0xba3d6efe
+0,        257,        257,        1,    76800, 0x23927f3e
+0,        258,        258,        1,    76800, 0x6947b124
+0,        259,        259,        1,    76800, 0x80e9f682
+0,        260,        260,        1,    76800, 0x6a393a9b
+0,        261,        261,        1,    76800, 0x5aff928b
+0,        262,        262,        1,    76800, 0xd81dfbab
+0,        263,        263,        1,    76800, 0x950166ca
+0,        264,        264,        1,    76800, 0xc7e6c6f0
+0,        265,        265,        1,    76800, 0x9aa328a1
+0,        266,        266,        1,    76800, 0x17de849b
+0,        267,        267,        1,    76800, 0xc4f7d9e3
+0,        268,        268,        1,    76800, 0x3f372bee
+0,        269,        269,        1,    76800, 0xaffc6e06
+0,        270,        270,        1,    76800, 0x94b8875c
+0,        271,        271,        1,    76800, 0xb713a42a
+0,        272,        272,        1,    76800, 0x8a89c232
+0,        273,        273,        1,    76800, 0xde65db42
+0,        274,        274,        1,    76800, 0x2c7dfaac
+0,        275,        275,        1,    76800, 0xa9202a71
+0,        276,        276,        1,    76800, 0x78715817
+0,        277,        277,        1,    76800, 0x3c0d8bb9
+0,        278,        278,        1,    76800, 0xa4cdbb61
+0,        279,        279,        1,    76800, 0xb9abd6ad
+0,        280,        280,        1,    76800, 0xecef0146
+0,        281,        281,        1,    76800, 0x82f22350
+0,        282,        282,        1,    76800, 0x17f442f2
+0,        283,        283,        1,    76800, 0xa6ea59e4
+0,        284,        284,        1,    76800, 0x62e452e6
+0,        285,        285,        1,    76800, 0xce2c454e
+0,        286,        286,        1,    76800, 0x27a821b4
+0,        287,        287,        1,    76800, 0x899f0f98
+0,        288,        288,        1,    76800, 0xe25dffb7
+0,        289,        289,        1,    76800, 0xa288ff17
+0,        290,        290,        1,    76800, 0x678500b0
+0,        291,        291,        1,    76800, 0xfe9c1216
+0,        292,        292,        1,    76800, 0x56da27a0
+0,        293,        293,        1,    76800, 0x62f239be
+0,        294,        294,        1,    76800, 0xa0a74b90
+0,        295,        295,        1,    76800, 0xc2f969a0
+0,        296,        296,        1,    76800, 0xe1ca7ad4
+0,        297,        297,        1,    76800, 0xf7938a7e
+0,        298,        298,        1,    76800, 0x3a339640
+0,        299,        299,        1,    76800, 0x44b79e0c
+0,        300,        300,        1,    76800, 0xd6e78ee6
+0,        301,        301,        1,    76800, 0xeecd91b6
+0,        302,        302,        1,    76800, 0x3ea99774
+0,        303,        303,        1,    76800, 0xd399967e
+0,        304,        304,        1,    76800, 0xc1e38de6
+0,        305,        305,        1,    76800, 0xd8ec7958
+0,        306,        306,        1,    76800, 0xe9e26992
+0,        307,        307,        1,    76800, 0xb6ee580a
+0,        308,        308,        1,    76800, 0xd56852f4
+0,        309,        309,        1,    76800, 0x997f4b9c
+0,        310,        310,        1,    76800, 0xc62841a6
+0,        311,        311,        1,    76800, 0x58063cee
+0,        312,        312,        1,    76800, 0xbaaf3e16
+0,        313,        313,        1,    76800, 0xac043a50
+0,        314,        314,        1,    76800, 0xa6c73a14
+0,        315,        315,        1,    76800, 0x1d614480
+0,        316,        316,        1,    76800, 0xc4e63b4c
+0,        317,        317,        1,    76800, 0x9d393b06
+0,        318,        318,        1,    76800, 0x9a902ef4
+0,        319,        319,        1,    76800, 0x6f872c74
+0,        320,        320,        1,    76800, 0x288a2f92
+0,        321,        321,        1,    76800, 0xb4832d76
+0,        322,        322,        1,    76800, 0x99e21c30
+0,        323,        323,        1,    76800, 0x287f0c90
+0,        324,        324,        1,    76800, 0xfd8bfe3f
+0,        325,        325,        1,    76800, 0x0a62f1d3
+0,        326,        326,        1,    76800, 0x2928eb4d
+0,        327,        327,        1,    76800, 0x2acfe487
+0,        328,        328,        1,    76800, 0x2b2ce339
+0,        329,        329,        1,    76800, 0x25d2e4c5
+0,        330,        330,        1,    76800, 0x0c14dd95
+0,        331,        331,        1,    76800, 0xfe8fdf29
+0,        332,        332,        1,    76800, 0x3afedd29
+0,        333,        333,        1,    76800, 0x3c85dd05
+0,        334,        334,        1,    76800, 0x9981db4d
+0,        335,        335,        1,    76800, 0xc4f9d501
+0,        336,        336,        1,    76800, 0xccd4d2d5
+0,        337,        337,        1,    76800, 0x229fdc41
+0,        338,        338,        1,    76800, 0x305de4ad
+0,        339,        339,        1,    76800, 0xb40eaef6
+0,        340,        340,        1,    76800, 0xb14f0431
+0,        341,        341,        1,    76800, 0x346b9280
+0,        342,        342,        1,    76800, 0x9198b4c0
+0,        343,        343,        1,    76800, 0xba1fde8f
+0,        344,        344,        1,    76800, 0x45260fa2
+0,        345,        345,        1,    76800, 0x69dd33cb
+0,        346,        346,        1,    76800, 0x6e10c599
+0,        347,        347,        1,    76800, 0x9dd33a40
+0,        348,        348,        1,    76800, 0x9dc7eb47
+0,        349,        349,        1,    76800, 0x8776f7df
+0,        350,        350,        1,    76800, 0xfd674e91
+0,        351,        351,        1,    76800, 0xcd69d151
+0,        352,        352,        1,    76800, 0xa8f69f9e
+0,        353,        353,        1,    76800, 0xf83587a2
+0,        354,        354,        1,    76800, 0xcb656e2a
+0,        355,        355,        1,    76800, 0x8c5e6b82
+0,        356,        356,        1,    76800, 0x880d5f56
+0,        357,        357,        1,    76800, 0x93405cce
+0,        358,        358,        1,    76800, 0x51345c1e
diff --git a/tests/ref/fate/bethsoft-vid b/tests/ref/fate/bethsoft-vid
index f59823c..9f96da1 100644
--- a/tests/ref/fate/bethsoft-vid
+++ b/tests/ref/fate/bethsoft-vid
@@ -140,4 +140,4 @@
 0,         68,         68,        1,   192000, 0x3ec3cce1
 1,      54760,      54760,      537,     1074, 0x142ce7ba
 0,         69,         69,        1,   192000, 0x159313a8
-1,      55297,      55297,      925,     1850, 0x7ff682f7
+1,      55297,      55297,      258,      516, 0x98885b26
diff --git a/tests/ref/fate/cllc-yuy2-noblock b/tests/ref/fate/cllc-yuy2-noblock
new file mode 100644
index 0000000..6ad59d5
--- /dev/null
+++ b/tests/ref/fate/cllc-yuy2-noblock
@@ -0,0 +1,17 @@
+#tb 0: 1001/30000
+0,          0,          0,        1,   614400, 0x088c51de
+0,          1,          1,        1,   614400, 0x93fff662
+0,          2,          2,        1,   614400, 0x90ba6c28
+0,          3,          3,        1,   614400, 0x55b7ae46
+0,          4,          4,        1,   614400, 0xef4fc678
+0,          5,          5,        1,   614400, 0xc838a54c
+0,          6,          6,        1,   614400, 0xb6016823
+0,          7,          7,        1,   614400, 0x7fd65ea7
+0,          8,          8,        1,   614400, 0xca9c35b9
+0,          9,          9,        1,   614400, 0x33f902ee
+0,         10,         10,        1,   614400, 0x53f2ea7a
+0,         11,         11,        1,   614400, 0x3ecae1c7
+0,         12,         12,        1,   614400, 0x2d8fd7cc
+0,         13,         13,        1,   614400, 0xd9dfc2ef
+0,         14,         14,        1,   614400, 0xaf95cef0
+0,         15,         15,        1,   614400, 0x6dcf5ed6
diff --git a/tests/ref/fate/crc b/tests/ref/fate/crc
index 1c24aea..89273d8 100644
--- a/tests/ref/fate/crc
+++ b/tests/ref/fate/crc
@@ -1,4 +1,5 @@
 crc EDB88320 = 3D5CDD04
 crc 04C11DB7 = E0BAF5C0
+crc 00864CFB = 326039
 crc 00008005 = BB1F
 crc 00000007 = E3
diff --git a/tests/ref/fate/cyberia-c93 b/tests/ref/fate/cyberia-c93
index 2c71e50..f02435c 100644
--- a/tests/ref/fate/cyberia-c93
+++ b/tests/ref/fate/cyberia-c93
@@ -36,7 +36,7 @@
 0,         30,         30,        1,   184320, 0x54975910
 0,         31,         31,        1,   184320, 0xf4857db9
 0,         32,         32,        1,   184320, 0x82d18161
-1,      42552,      42552,    14184,    28368, 0x9101e519
+1,      42552,      42552,     5835,    11670, 0x04aa0b1e
 0,         33,         33,        1,   184320, 0x06d93bd0
 0,         34,         34,        1,   184320, 0xa4304c00
 0,         35,         35,        1,   184320, 0x5f77d9cd
diff --git a/tests/ref/fate/exif-image-embedded b/tests/ref/fate/exif-image-embedded
new file mode 100644
index 0000000..4109c15
--- /dev/null
+++ b/tests/ref/fate/exif-image-embedded
@@ -0,0 +1,360 @@
+[FRAME]
+media_type=video
+key_frame=1
+pkt_pts=N/A
+pkt_pts_time=N/A
+pkt_dts=N/A
+pkt_dts_time=N/A
+pkt_duration=N/A
+pkt_duration_time=N/A
+pkt_pos=N/A
+pkt_size=15760
+width=263
+height=263
+pix_fmt=yuvj420p
+sample_aspect_ratio=1:1
+pict_type=I
+coded_picture_number=0
+display_picture_number=0
+interlaced_frame=0
+top_field_first=0
+repeat_pict=0
+TAG:UserComment=AppleMark
+
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=353600
+pkt_pts_time=0.025057
+pkt_dts=353600
+pkt_dts_time=0.025057
+pkt_duration=15040
+pkt_duration_time=0.001066
+pkt_pos=16292
+pkt_size=417
+sample_fmt=s16p
+nb_samples=47
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=368640
+pkt_pts_time=0.026122
+pkt_dts=368640
+pkt_dts_time=0.026122
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=16709
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=737280
+pkt_pts_time=0.052245
+pkt_dts=737280
+pkt_dts_time=0.052245
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=17127
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=1105920
+pkt_pts_time=0.078367
+pkt_dts=1105920
+pkt_dts_time=0.078367
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=17545
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=1474560
+pkt_pts_time=0.104490
+pkt_dts=1474560
+pkt_dts_time=0.104490
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=17963
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=1843200
+pkt_pts_time=0.130612
+pkt_dts=1843200
+pkt_dts_time=0.130612
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=18381
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=2211840
+pkt_pts_time=0.156735
+pkt_dts=2211840
+pkt_dts_time=0.156735
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=18799
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=2580480
+pkt_pts_time=0.182857
+pkt_dts=2580480
+pkt_dts_time=0.182857
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=19217
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=2949120
+pkt_pts_time=0.208980
+pkt_dts=2949120
+pkt_dts_time=0.208980
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=19635
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=3317760
+pkt_pts_time=0.235102
+pkt_dts=3317760
+pkt_dts_time=0.235102
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=20053
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=3686400
+pkt_pts_time=0.261224
+pkt_dts=3686400
+pkt_dts_time=0.261224
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=20471
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=4055040
+pkt_pts_time=0.287347
+pkt_dts=4055040
+pkt_dts_time=0.287347
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=20889
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=4423680
+pkt_pts_time=0.313469
+pkt_dts=4423680
+pkt_dts_time=0.313469
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=21307
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=4792320
+pkt_pts_time=0.339592
+pkt_dts=4792320
+pkt_dts_time=0.339592
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=21725
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=5160960
+pkt_pts_time=0.365714
+pkt_dts=5160960
+pkt_dts_time=0.365714
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=22143
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=5529600
+pkt_pts_time=0.391837
+pkt_dts=5529600
+pkt_dts_time=0.391837
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=22561
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=5898240
+pkt_pts_time=0.417959
+pkt_dts=5898240
+pkt_dts_time=0.417959
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=22979
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=6266880
+pkt_pts_time=0.444082
+pkt_dts=6266880
+pkt_dts_time=0.444082
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=23397
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=6635520
+pkt_pts_time=0.470204
+pkt_dts=6635520
+pkt_dts_time=0.470204
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=23815
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=7004160
+pkt_pts_time=0.496327
+pkt_dts=7004160
+pkt_dts_time=0.496327
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=24233
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
+[FRAME]
+media_type=audio
+key_frame=1
+pkt_pts=7372800
+pkt_pts_time=0.522449
+pkt_dts=7372800
+pkt_dts_time=0.522449
+pkt_duration=368640
+pkt_duration_time=0.026122
+pkt_pos=24651
+pkt_size=418
+sample_fmt=s16p
+nb_samples=1152
+channels=2
+channel_layout=stereo
+[/FRAME]
diff --git a/tests/ref/fate/exif-image-jpg b/tests/ref/fate/exif-image-jpg
new file mode 100644
index 0000000..a634a87
--- /dev/null
+++ b/tests/ref/fate/exif-image-jpg
@@ -0,0 +1,66 @@
+[FRAME]
+media_type=video
+key_frame=1
+pkt_pts=0
+pkt_pts_time=0.000000
+pkt_dts=0
+pkt_dts_time=0.000000
+pkt_duration=1
+pkt_duration_time=0.040000
+pkt_pos=N/A
+pkt_size=46095
+width=400
+height=225
+pix_fmt=yuvj422p
+sample_aspect_ratio=1:1
+pict_type=I
+coded_picture_number=0
+display_picture_number=0
+interlaced_frame=0
+top_field_first=0
+repeat_pict=0
+TAG:ImageDescription=
+TAG:Make=Canon
+TAG:Model=Canon PowerShot SX200 IS
+TAG:Orientation=1
+TAG:XResolution=180:1
+TAG:YResolution=180:1
+TAG:ResolutionUnit=2
+TAG:DateTime=2013:07:18 13:12:03
+TAG:YCbCrPositioning=2
+TAG:ExposureTime=1:1250
+TAG:FNumber=40:10
+TAG:ISOSpeedRatings=160
+TAG:ExifVersion=0221
+TAG:DateTimeOriginal=2013:07:18 13:12:03
+TAG:DateTimeDigitized=2013:07:18 13:12:03
+TAG:ComponentsConfiguration=
+TAG:CompressedBitsPerPixel=3:1
+TAG:ShutterSpeedValue=329:32
+TAG:ApertureValue=128:32
+TAG:ExposureBiasValue=0:3
+TAG:MaxApertureValue=113:32
+TAG:MeteringMode=5
+TAG:Flash=16
+TAG:FocalLength=5000:1000
+TAG:MakerNote=
+TAG:UserComment=
+TAG:FlashpixVersion=0100
+TAG:ColorSpace=1
+TAG:PixelXDimension=4000
+TAG:PixelYDimension=2248
+TAG:GPSLatitudeRef=R98
+TAG:GPSLatitude=0100
+TAG:0x1001=4000
+TAG:0x1002=2248
+TAG:FocalPlaneXResolution=4000000:244
+TAG:FocalPlaneYResolution=2248000:183
+TAG:FocalPlaneResolutionUnit=2
+TAG:SensingMethod=2
+TAG:FileSource=
+TAG:CustomRendered=0
+TAG:ExposureMode=0
+TAG:WhiteBalance=0
+TAG:DigitalZoomRatio=4000:4000
+TAG:SceneCaptureType=0
+[/FRAME]
diff --git a/tests/ref/fate/exif-image-tiff b/tests/ref/fate/exif-image-tiff
new file mode 100644
index 0000000..ddd85e5
--- /dev/null
+++ b/tests/ref/fate/exif-image-tiff
@@ -0,0 +1,25 @@
+[FRAME]
+media_type=video
+key_frame=1
+pkt_pts=0
+pkt_pts_time=0.000000
+pkt_dts=0
+pkt_dts_time=0.000000
+pkt_duration=1
+pkt_duration_time=0.040000
+pkt_pos=N/A
+pkt_size=67604
+width=200
+height=112
+pix_fmt=rgb24
+sample_aspect_ratio=N/A
+pict_type=?
+coded_picture_number=0
+display_picture_number=0
+interlaced_frame=0
+top_field_first=0
+repeat_pict=0
+TAG:document_name=image_small.tiff
+TAG:page_number=0 / 1
+TAG:software=ImageMagick 6.5.8-0 2010-02-09 Q16 http://www.imagemagick.org
+[/FRAME]
diff --git a/tests/ref/fate/exr-slice-raw b/tests/ref/fate/exr-slice-raw
new file mode 100644
index 0000000..a8b4b27
--- /dev/null
+++ b/tests/ref/fate/exr-slice-raw
@@ -0,0 +1,2 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3169800, 0x6a356d0d
diff --git a/tests/ref/fate/exr-slice-rle b/tests/ref/fate/exr-slice-rle
new file mode 100644
index 0000000..a8b4b27
--- /dev/null
+++ b/tests/ref/fate/exr-slice-rle
@@ -0,0 +1,2 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3169800, 0x6a356d0d
diff --git a/tests/ref/fate/exr-slice-zip1 b/tests/ref/fate/exr-slice-zip1
new file mode 100644
index 0000000..a8b4b27
--- /dev/null
+++ b/tests/ref/fate/exr-slice-zip1
@@ -0,0 +1,2 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3169800, 0x6a356d0d
diff --git a/tests/ref/fate/exr-slice-zip16 b/tests/ref/fate/exr-slice-zip16
new file mode 100644
index 0000000..a8b4b27
--- /dev/null
+++ b/tests/ref/fate/exr-slice-zip16
@@ -0,0 +1,2 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3169800, 0x6a356d0d
diff --git a/tests/ref/fate/ffprobe_compact b/tests/ref/fate/ffprobe_compact
index 470a3f7..04d8ce4 100644
--- a/tests/ref/fate/ffprobe_compact
+++ b/tests/ref/fate/ffprobe_compact
@@ -26,7 +26,7 @@
 frame|media_type=video|key_frame=1|pkt_pts=6144|pkt_pts_time=0.120000|pkt_dts=6144|pkt_dts_time=0.120000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=794307|pkt_size=N/A|width=320|height=240|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0
 packet|codec_type=video|stream_index=2|pts=6144|pts_time=0.120000|dts=6144|dts_time=0.120000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=30000|pos=1024731|flags=K
 frame|media_type=video|key_frame=1|pkt_pts=6144|pkt_pts_time=0.120000|pkt_dts=6144|pkt_dts_time=0.120000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=1024731|pkt_size=N/A|width=100|height=100|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0
-stream|index=0|codec_name=pcm_s16le|profile=unknown|codec_type=audio|codec_time_base=1/44100|codec_tag_string=PSD[16]|codec_tag=0x10445350|sample_fmt=s16|sample_rate=44100|channels=1|bits_per_sample=16|id=N/A|r_frame_rate=0/0|avg_frame_rate=0/0|time_base=1/44100|start_pts=0|start_time=0.000000|duration_ts=527406|duration=11.959320|bit_rate=705600|nb_frames=N/A|nb_read_frames=6|nb_read_packets=6|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|tag:E=mc²
-stream|index=1|codec_name=rawvideo|profile=unknown|codec_type=video|codec_time_base=1/51200|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=320|height=240|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=4:3|pix_fmt=rgb24|level=-99|timecode=N/A|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=612317|duration=11.959316|bit_rate=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|tag:title=foobar|tag:duration_ts=field-and-tags-conflict-attempt
-stream|index=2|codec_name=rawvideo|profile=unknown|codec_type=video|codec_time_base=1/51200|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=100|height=100|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=1:1|pix_fmt=rgb24|level=-99|timecode=N/A|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=612317|duration=11.959316|bit_rate=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0
-format|filename=tests/data/ffprobe-test.nut|nb_streams=3|format_name=nut|start_time=0.000000|duration=11.959320|size=1054812|bit_rate=705599|tag:title=ffprobe test file|tag:comment='A comment with CSV, XML & JSON special chars': <tag value="x">|tag:comment2=I ♥ Üñîçød€
+stream|index=0|codec_name=pcm_s16le|profile=unknown|codec_type=audio|codec_time_base=1/44100|codec_tag_string=PSD[16]|codec_tag=0x10445350|sample_fmt=s16|sample_rate=44100|channels=1|bits_per_sample=16|id=N/A|r_frame_rate=0/0|avg_frame_rate=0/0|time_base=1/44100|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=705600|nb_frames=N/A|nb_read_frames=6|nb_read_packets=6|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|tag:E=mc²
+stream|index=1|codec_name=rawvideo|profile=unknown|codec_type=video|codec_time_base=1/51200|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=320|height=240|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=4:3|pix_fmt=rgb24|level=-99|timecode=N/A|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|tag:title=foobar|tag:duration_ts=field-and-tags-conflict-attempt
+stream|index=2|codec_name=rawvideo|profile=unknown|codec_type=video|codec_time_base=1/51200|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=100|height=100|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=1:1|pix_fmt=rgb24|level=-99|timecode=N/A|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0
+format|filename=tests/data/ffprobe-test.nut|nb_streams=3|nb_programs=0|format_name=nut|start_time=0.000000|duration=0.120000|size=1054812|bit_rate=70320800|tag:title=ffprobe test file|tag:comment='A comment with CSV, XML & JSON special chars': <tag value="x">|tag:comment2=I ♥ Üñîçød€
diff --git a/tests/ref/fate/ffprobe_csv b/tests/ref/fate/ffprobe_csv
index 95b93b5..a11b321 100644
--- a/tests/ref/fate/ffprobe_csv
+++ b/tests/ref/fate/ffprobe_csv
@@ -26,7 +26,7 @@
 frame,video,1,6144,0.120000,6144,0.120000,2048,0.040000,794307,N/A,320,240,rgb24,1:1,I,0,0,0,0,0
 packet,video,2,6144,0.120000,6144,0.120000,2048,0.040000,N/A,N/A,30000,1024731,K
 frame,video,1,6144,0.120000,6144,0.120000,2048,0.040000,1024731,N/A,100,100,rgb24,1:1,I,0,0,0,0,0
-stream,0,pcm_s16le,unknown,audio,1/44100,PSD[16],0x10445350,s16,44100,1,16,N/A,0/0,0/0,1/44100,0,0.000000,527406,11.959320,705600,N/A,6,6,0,0,0,0,0,0,0,0,0,0,0,mc²
-stream,1,rawvideo,unknown,video,1/51200,RGB[24],0x18424752,320,240,0,1:1,4:3,rgb24,-99,N/A,N/A,25/1,25/1,1/51200,0,0.000000,612317,11.959316,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0,foobar,field-and-tags-conflict-attempt
-stream,2,rawvideo,unknown,video,1/51200,RGB[24],0x18424752,100,100,0,1:1,1:1,rgb24,-99,N/A,N/A,25/1,25/1,1/51200,0,0.000000,612317,11.959316,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0
-format,tests/data/ffprobe-test.nut,3,nut,0.000000,11.959320,1054812,705599,ffprobe test file,"'A comment with CSV, XML & JSON special chars': <tag value=""x"">",I ♥ Üñîçød€
+stream,0,pcm_s16le,unknown,audio,1/44100,PSD[16],0x10445350,s16,44100,1,16,N/A,0/0,0/0,1/44100,0,0.000000,N/A,N/A,705600,N/A,6,6,0,0,0,0,0,0,0,0,0,0,0,mc²
+stream,1,rawvideo,unknown,video,1/51200,RGB[24],0x18424752,320,240,0,1:1,4:3,rgb24,-99,N/A,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0,foobar,field-and-tags-conflict-attempt
+stream,2,rawvideo,unknown,video,1/51200,RGB[24],0x18424752,100,100,0,1:1,1:1,rgb24,-99,N/A,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0
+format,tests/data/ffprobe-test.nut,3,0,nut,0.000000,0.120000,1054812,70320800,ffprobe test file,"'A comment with CSV, XML & JSON special chars': <tag value=""x"">",I ♥ Üñîçød€
diff --git a/tests/ref/fate/ffprobe_default b/tests/ref/fate/ffprobe_default
index 6f6341d..f56bd8d 100644
--- a/tests/ref/fate/ffprobe_default
+++ b/tests/ref/fate/ffprobe_default
@@ -498,8 +498,8 @@
 time_base=1/44100
 start_pts=0
 start_time=0.000000
-duration_ts=527406
-duration=11.959320
+duration_ts=N/A
+duration=N/A
 bit_rate=705600
 nb_frames=N/A
 nb_read_frames=6
@@ -539,8 +539,8 @@
 time_base=1/51200
 start_pts=0
 start_time=0.000000
-duration_ts=612317
-duration=11.959316
+duration_ts=N/A
+duration=N/A
 bit_rate=N/A
 nb_frames=N/A
 nb_read_frames=4
@@ -581,8 +581,8 @@
 time_base=1/51200
 start_pts=0
 start_time=0.000000
-duration_ts=612317
-duration=11.959316
+duration_ts=N/A
+duration=N/A
 bit_rate=N/A
 nb_frames=N/A
 nb_read_frames=4
@@ -602,11 +602,12 @@
 [FORMAT]
 filename=tests/data/ffprobe-test.nut
 nb_streams=3
+nb_programs=0
 format_name=nut
 start_time=0.000000
-duration=11.959320
+duration=0.120000
 size=1054812
-bit_rate=705599
+bit_rate=70320800
 TAG:title=ffprobe test file
 TAG:comment='A comment with CSV, XML & JSON special chars': <tag value="x">
 TAG:comment2=I ♥ Üñîçød€
diff --git a/tests/ref/fate/ffprobe_flat b/tests/ref/fate/ffprobe_flat
index 324b94f..7cb9c3e 100644
--- a/tests/ref/fate/ffprobe_flat
+++ b/tests/ref/fate/ffprobe_flat
@@ -441,8 +441,8 @@
 streams.stream.0.time_base="1/44100"
 streams.stream.0.start_pts=0
 streams.stream.0.start_time="0.000000"
-streams.stream.0.duration_ts=527406
-streams.stream.0.duration="11.959320"
+streams.stream.0.duration_ts="N/A"
+streams.stream.0.duration="N/A"
 streams.stream.0.bit_rate="705600"
 streams.stream.0.nb_frames="N/A"
 streams.stream.0.nb_read_frames="6"
@@ -480,8 +480,8 @@
 streams.stream.1.time_base="1/51200"
 streams.stream.1.start_pts=0
 streams.stream.1.start_time="0.000000"
-streams.stream.1.duration_ts=612317
-streams.stream.1.duration="11.959316"
+streams.stream.1.duration_ts="N/A"
+streams.stream.1.duration="N/A"
 streams.stream.1.bit_rate="N/A"
 streams.stream.1.nb_frames="N/A"
 streams.stream.1.nb_read_frames="4"
@@ -520,8 +520,8 @@
 streams.stream.2.time_base="1/51200"
 streams.stream.2.start_pts=0
 streams.stream.2.start_time="0.000000"
-streams.stream.2.duration_ts=612317
-streams.stream.2.duration="11.959316"
+streams.stream.2.duration_ts="N/A"
+streams.stream.2.duration="N/A"
 streams.stream.2.bit_rate="N/A"
 streams.stream.2.nb_frames="N/A"
 streams.stream.2.nb_read_frames="4"
@@ -539,11 +539,12 @@
 streams.stream.2.disposition.attached_pic=0
 format.filename="tests/data/ffprobe-test.nut"
 format.nb_streams=3
+format.nb_programs=0
 format.format_name="nut"
 format.start_time="0.000000"
-format.duration="11.959320"
+format.duration="0.120000"
 format.size="1054812"
-format.bit_rate="705599"
+format.bit_rate="70320800"
 format.tags.title="ffprobe test file"
 format.tags.comment="'A comment with CSV, XML & JSON special chars': <tag value=\"x\">"
 format.tags.comment2="I ♥ Üñîçød€"
diff --git a/tests/ref/fate/ffprobe_ini b/tests/ref/fate/ffprobe_ini
index 63a03f6..c0254dc 100644
--- a/tests/ref/fate/ffprobe_ini
+++ b/tests/ref/fate/ffprobe_ini
@@ -500,8 +500,8 @@
 time_base=1/44100
 start_pts=0
 start_time=0.000000
-duration_ts=527406
-duration=11.959320
+duration_ts=N/A
+duration=N/A
 bit_rate=705600
 nb_frames=N/A
 nb_read_frames=6
@@ -545,8 +545,8 @@
 time_base=1/51200
 start_pts=0
 start_time=0.000000
-duration_ts=612317
-duration=11.959316
+duration_ts=N/A
+duration=N/A
 bit_rate=N/A
 nb_frames=N/A
 nb_read_frames=4
@@ -591,8 +591,8 @@
 time_base=1/51200
 start_pts=0
 start_time=0.000000
-duration_ts=612317
-duration=11.959316
+duration_ts=N/A
+duration=N/A
 bit_rate=N/A
 nb_frames=N/A
 nb_read_frames=4
@@ -614,11 +614,12 @@
 [format]
 filename=tests/data/ffprobe-test.nut
 nb_streams=3
+nb_programs=0
 format_name=nut
 start_time=0.000000
-duration=11.959320
+duration=0.120000
 size=1054812
-bit_rate=705599
+bit_rate=70320800
 
 [format.tags]
 title=ffprobe test file
diff --git a/tests/ref/fate/ffprobe_json b/tests/ref/fate/ffprobe_json
index 51404cb..ee5ddb9 100644
--- a/tests/ref/fate/ffprobe_json
+++ b/tests/ref/fate/ffprobe_json
@@ -486,8 +486,6 @@
             "time_base": "1/44100",
             "start_pts": 0,
             "start_time": "0.000000",
-            "duration_ts": 527406,
-            "duration": "11.959320",
             "bit_rate": "705600",
             "nb_read_frames": "6",
             "nb_read_packets": "6",
@@ -527,8 +525,6 @@
             "time_base": "1/51200",
             "start_pts": 0,
             "start_time": "0.000000",
-            "duration_ts": 612317,
-            "duration": "11.959316",
             "nb_read_frames": "4",
             "nb_read_packets": "4",
             "disposition": {
@@ -568,8 +564,6 @@
             "time_base": "1/51200",
             "start_pts": 0,
             "start_time": "0.000000",
-            "duration_ts": 612317,
-            "duration": "11.959316",
             "nb_read_frames": "4",
             "nb_read_packets": "4",
             "disposition": {
@@ -590,11 +584,12 @@
     "format": {
         "filename": "tests/data/ffprobe-test.nut",
         "nb_streams": 3,
+        "nb_programs": 0,
         "format_name": "nut",
         "start_time": "0.000000",
-        "duration": "11.959320",
+        "duration": "0.120000",
         "size": "1054812",
-        "bit_rate": "705599",
+        "bit_rate": "70320800",
         "tags": {
             "title": "ffprobe test file",
             "comment": "'A comment with CSV, XML & JSON special chars': <tag value=\"x\">",
diff --git a/tests/ref/fate/ffprobe_xml b/tests/ref/fate/ffprobe_xml
index 0600ad7..410f250 100644
--- a/tests/ref/fate/ffprobe_xml
+++ b/tests/ref/fate/ffprobe_xml
@@ -32,21 +32,21 @@
     </packets_and_frames>
 
     <streams>
-        <stream index="0" codec_name="pcm_s16le" codec_type="audio" codec_time_base="1/44100" codec_tag_string="PSD[16]" codec_tag="0x10445350" sample_fmt="s16" sample_rate="44100" channels="1" bits_per_sample="16" r_frame_rate="0/0" avg_frame_rate="0/0" time_base="1/44100" start_pts="0" start_time="0.000000" duration_ts="527406" duration="11.959320" bit_rate="705600" nb_read_frames="6" nb_read_packets="6">
+        <stream index="0" codec_name="pcm_s16le" codec_type="audio" codec_time_base="1/44100" codec_tag_string="PSD[16]" codec_tag="0x10445350" sample_fmt="s16" sample_rate="44100" channels="1" bits_per_sample="16" r_frame_rate="0/0" avg_frame_rate="0/0" time_base="1/44100" start_pts="0" start_time="0.000000" bit_rate="705600" nb_read_frames="6" nb_read_packets="6">
             <disposition default="0" dub="0" original="0" comment="0" lyrics="0" karaoke="0" forced="0" hearing_impaired="0" visual_impaired="0" clean_effects="0" attached_pic="0"/>
             <tag key="E" value="mc²"/>
         </stream>
-        <stream index="1" codec_name="rawvideo" codec_type="video" codec_time_base="1/51200" codec_tag_string="RGB[24]" codec_tag="0x18424752" width="320" height="240" has_b_frames="0" sample_aspect_ratio="1:1" display_aspect_ratio="4:3" pix_fmt="rgb24" level="-99" r_frame_rate="25/1" avg_frame_rate="25/1" time_base="1/51200" start_pts="0" start_time="0.000000" duration_ts="612317" duration="11.959316" nb_read_frames="4" nb_read_packets="4">
+        <stream index="1" codec_name="rawvideo" codec_type="video" codec_time_base="1/51200" codec_tag_string="RGB[24]" codec_tag="0x18424752" width="320" height="240" has_b_frames="0" sample_aspect_ratio="1:1" display_aspect_ratio="4:3" pix_fmt="rgb24" level="-99" r_frame_rate="25/1" avg_frame_rate="25/1" time_base="1/51200" start_pts="0" start_time="0.000000" nb_read_frames="4" nb_read_packets="4">
             <disposition default="0" dub="0" original="0" comment="0" lyrics="0" karaoke="0" forced="0" hearing_impaired="0" visual_impaired="0" clean_effects="0" attached_pic="0"/>
             <tag key="title" value="foobar"/>
             <tag key="duration_ts" value="field-and-tags-conflict-attempt"/>
         </stream>
-        <stream index="2" codec_name="rawvideo" codec_type="video" codec_time_base="1/51200" codec_tag_string="RGB[24]" codec_tag="0x18424752" width="100" height="100" has_b_frames="0" sample_aspect_ratio="1:1" display_aspect_ratio="1:1" pix_fmt="rgb24" level="-99" r_frame_rate="25/1" avg_frame_rate="25/1" time_base="1/51200" start_pts="0" start_time="0.000000" duration_ts="612317" duration="11.959316" nb_read_frames="4" nb_read_packets="4">
+        <stream index="2" codec_name="rawvideo" codec_type="video" codec_time_base="1/51200" codec_tag_string="RGB[24]" codec_tag="0x18424752" width="100" height="100" has_b_frames="0" sample_aspect_ratio="1:1" display_aspect_ratio="1:1" pix_fmt="rgb24" level="-99" r_frame_rate="25/1" avg_frame_rate="25/1" time_base="1/51200" start_pts="0" start_time="0.000000" nb_read_frames="4" nb_read_packets="4">
             <disposition default="0" dub="0" original="0" comment="0" lyrics="0" karaoke="0" forced="0" hearing_impaired="0" visual_impaired="0" clean_effects="0" attached_pic="0"/>
         </stream>
     </streams>
 
-    <format filename="tests/data/ffprobe-test.nut" nb_streams="3" format_name="nut" start_time="0.000000" duration="11.959320" size="1054812" bit_rate="705599">
+    <format filename="tests/data/ffprobe-test.nut" nb_streams="3" nb_programs="0" format_name="nut" start_time="0.000000" duration="0.120000" size="1054812" bit_rate="70320800">
         <tag key="title" value="ffprobe test file"/>
         <tag key="comment" value="&apos;A comment with CSV, XML &amp; JSON special chars&apos;: &lt;tag value=&quot;x&quot;&gt;"/>
         <tag key="comment2" value="I ♥ Üñîçød€"/>
diff --git a/tests/ref/fate/filter-alphaextract_alphamerge_rgb b/tests/ref/fate/filter-alphaextract_alphamerge_rgb
new file mode 100644
index 0000000..57c0e68
--- /dev/null
+++ b/tests/ref/fate/filter-alphaextract_alphamerge_rgb
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   405504, 0x17e87a9d
+0,          1,          1,        1,   405504, 0x9b07cfda
+0,          2,          2,        1,   405504, 0x2efd2717
+0,          3,          3,        1,   405504, 0xedeec4ba
+0,          4,          4,        1,   405504, 0x78c9f3b5
+0,          5,          5,        1,   405504, 0xd3c75d27
+0,          6,          6,        1,   405504, 0x7b8c24e9
+0,          7,          7,        1,   405504, 0x5d6ae060
+0,          8,          8,        1,   405504, 0x12851e22
+0,          9,          9,        1,   405504, 0x6c54eaf7
+0,         10,         10,        1,   405504, 0x611e8652
+0,         11,         11,        1,   405504, 0xe426baf9
+0,         12,         12,        1,   405504, 0x72112b99
+0,         13,         13,        1,   405504, 0xd3102813
+0,         14,         14,        1,   405504, 0xe48ca25d
+0,         15,         15,        1,   405504, 0xdd27a5f9
+0,         16,         16,        1,   405504, 0x772f82c5
+0,         17,         17,        1,   405504, 0xa96a87ee
+0,         18,         18,        1,   405504, 0x78e5ab05
+0,         19,         19,        1,   405504, 0x9b84a6e4
+0,         20,         20,        1,   405504, 0xab23f602
+0,         21,         21,        1,   405504, 0x18a7cb1d
+0,         22,         22,        1,   405504, 0xd27fa825
+0,         23,         23,        1,   405504, 0x444ebef2
+0,         24,         24,        1,   405504, 0x51631604
+0,         25,         25,        1,   405504, 0x95d090f9
+0,         26,         26,        1,   405504, 0x97ae65ca
+0,         27,         27,        1,   405504, 0x85afbb21
+0,         28,         28,        1,   405504, 0xf78fb50c
+0,         29,         29,        1,   405504, 0xbbb65a60
+0,         30,         30,        1,   405504, 0x1c75aae0
+0,         31,         31,        1,   405504, 0xd9637b9f
+0,         32,         32,        1,   405504, 0xb849d40e
+0,         33,         33,        1,   405504, 0xe9e4aff4
+0,         34,         34,        1,   405504, 0x8832a687
+0,         35,         35,        1,   405504, 0xf71521d0
+0,         36,         36,        1,   405504, 0x49742a99
+0,         37,         37,        1,   405504, 0x1aa2c332
+0,         38,         38,        1,   405504, 0x4f366e7c
+0,         39,         39,        1,   405504, 0x57039b9d
+0,         40,         40,        1,   405504, 0xc27dac6b
+0,         41,         41,        1,   405504, 0x8f85c9be
+0,         42,         42,        1,   405504, 0xcfdaa27d
+0,         43,         43,        1,   405504, 0x08ed5756
+0,         44,         44,        1,   405504, 0x75c3b126
+0,         45,         45,        1,   405504, 0xbce22eb4
+0,         46,         46,        1,   405504, 0x623c66fa
+0,         47,         47,        1,   405504, 0x5f963747
+0,         48,         48,        1,   405504, 0xcb74b070
+0,         49,         49,        1,   405504, 0xda8f6664
diff --git a/tests/ref/fate/filter-alphaextract_alphamerge_yuv b/tests/ref/fate/filter-alphaextract_alphamerge_yuv
new file mode 100644
index 0000000..37c3486
--- /dev/null
+++ b/tests/ref/fate/filter-alphaextract_alphamerge_yuv
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   253440, 0x1ada7ac4
+0,          1,          1,        1,   253440, 0x711c1599
+0,          2,          2,        1,   253440, 0x533017ea
+0,          3,          3,        1,   253440, 0x86c6865f
+0,          4,          4,        1,   253440, 0xe5962b75
+0,          5,          5,        1,   253440, 0xe45dae97
+0,          6,          6,        1,   253440, 0x2d6b8047
+0,          7,          7,        1,   253440, 0xdd48b706
+0,          8,          8,        1,   253440, 0xb7a7823a
+0,          9,          9,        1,   253440, 0xa491f11f
+0,         10,         10,        1,   253440, 0x48b9abd5
+0,         11,         11,        1,   253440, 0x7d72078e
+0,         12,         12,        1,   253440, 0xe6901732
+0,         13,         13,        1,   253440, 0x8866ee68
+0,         14,         14,        1,   253440, 0x603e8fbc
+0,         15,         15,        1,   253440, 0x25c5633d
+0,         16,         16,        1,   253440, 0x7ef22b82
+0,         17,         17,        1,   253440, 0xffb25705
+0,         18,         18,        1,   253440, 0x921f9560
+0,         19,         19,        1,   253440, 0xd367c2a4
+0,         20,         20,        1,   253440, 0x6962a02d
+0,         21,         21,        1,   253440, 0x780d2b78
+0,         22,         22,        1,   253440, 0xa7bdf61e
+0,         23,         23,        1,   253440, 0x19797146
+0,         24,         24,        1,   253440, 0x3128c3bd
+0,         25,         25,        1,   253440, 0x2a3df40e
+0,         26,         26,        1,   253440, 0x3eb71582
+0,         27,         27,        1,   253440, 0x57f8c64d
+0,         28,         28,        1,   253440, 0x7e5872b1
+0,         29,         29,        1,   253440, 0x2c092689
+0,         30,         30,        1,   253440, 0xe92f4956
+0,         31,         31,        1,   253440, 0x6b49e20f
+0,         32,         32,        1,   253440, 0x274e4d28
+0,         33,         33,        1,   253440, 0xc1660f8c
+0,         34,         34,        1,   253440, 0xca9e5566
+0,         35,         35,        1,   253440, 0x30fa342a
+0,         36,         36,        1,   253440, 0xcbf915fd
+0,         37,         37,        1,   253440, 0x27fa90f6
+0,         38,         38,        1,   253440, 0x777743aa
+0,         39,         39,        1,   253440, 0xe6104ff6
+0,         40,         40,        1,   253440, 0xed51cb35
+0,         41,         41,        1,   253440, 0x218d192d
+0,         42,         42,        1,   253440, 0x100a5c86
+0,         43,         43,        1,   253440, 0xddcc3023
+0,         44,         44,        1,   253440, 0x788ff77d
+0,         45,         45,        1,   253440, 0x4488fb59
+0,         46,         46,        1,   253440, 0x634ff895
+0,         47,         47,        1,   253440, 0xd68bccb6
+0,         48,         48,        1,   253440, 0x1a9810ff
+0,         49,         49,        1,   253440, 0x05beb75b
diff --git a/tests/ref/fate/filter-atrim-duration b/tests/ref/fate/filter-atrim-duration
new file mode 100644
index 0000000..a51dff7
--- /dev/null
+++ b/tests/ref/fate/filter-atrim-duration
@@ -0,0 +1,2 @@
+#tb 0: 1/44100
+0,       4410,       4410,      441,     1764, 0x61e374f7
diff --git a/tests/ref/fate/filter-atrim-mixed b/tests/ref/fate/filter-atrim-mixed
new file mode 100644
index 0000000..ae3281a
--- /dev/null
+++ b/tests/ref/fate/filter-atrim-mixed
@@ -0,0 +1,5 @@
+#tb 0: 1/44100
+0,       1025,       1025,     1023,     4092, 0x78560a4c
+0,       2048,       2048,     1024,     4096, 0xc477fa99
+0,       3072,       3072,     1024,     4096, 0x3bc0f14f
+0,       4096,       4096,      315,     1260, 0xe4b26b50
diff --git a/tests/ref/fate/filter-atrim-samples b/tests/ref/fate/filter-atrim-samples
new file mode 100644
index 0000000..3461666
--- /dev/null
+++ b/tests/ref/fate/filter-atrim-samples
@@ -0,0 +1,2 @@
+#tb 0: 1/44100
+0,         26,         26,       54,      216, 0x6b376c6c
diff --git a/tests/ref/fate/filter-atrim-time b/tests/ref/fate/filter-atrim-time
new file mode 100644
index 0000000..a368210
--- /dev/null
+++ b/tests/ref/fate/filter-atrim-time
@@ -0,0 +1,6 @@
+#tb 0: 1/44100
+0,       4410,       4410,      710,     2840, 0x658982a3
+0,       5120,       5120,     1024,     4096, 0xfd6a0070
+0,       6144,       6144,     1024,     4096, 0x0b01f4cf
+0,       7168,       7168,     1024,     4096, 0x6716fd93
+0,       8192,       8192,      628,     2512, 0xda5ddff8
diff --git a/tests/ref/fate/filter-colorchannelmixer b/tests/ref/fate/filter-colorchannelmixer
new file mode 100644
index 0000000..4e9e9d3
--- /dev/null
+++ b/tests/ref/fate/filter-colorchannelmixer
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   304128, 0x42900c13
+0,          1,          1,        1,   304128, 0xfb0439bc
+0,          2,          2,        1,   304128, 0x967b9f0d
+0,          3,          3,        1,   304128, 0xc2c92489
+0,          4,          4,        1,   304128, 0x024499b1
+0,          5,          5,        1,   304128, 0x66144785
+0,          6,          6,        1,   304128, 0x0e505bcd
+0,          7,          7,        1,   304128, 0xc8b26ed2
+0,          8,          8,        1,   304128, 0x14b5717b
+0,          9,          9,        1,   304128, 0x2ba3144a
+0,         10,         10,        1,   304128, 0x1185992b
+0,         11,         11,        1,   304128, 0xd55b289a
+0,         12,         12,        1,   304128, 0x59f2f3be
+0,         13,         13,        1,   304128, 0xfe4d6adf
+0,         14,         14,        1,   304128, 0x630806cc
+0,         15,         15,        1,   304128, 0x2deb2f19
+0,         16,         16,        1,   304128, 0xfbffa923
+0,         17,         17,        1,   304128, 0xb7770d46
+0,         18,         18,        1,   304128, 0xda09bd0e
+0,         19,         19,        1,   304128, 0x17a422d2
+0,         20,         20,        1,   304128, 0xbb6172f5
+0,         21,         21,        1,   304128, 0xcf639456
+0,         22,         22,        1,   304128, 0xdb0ae1ac
+0,         23,         23,        1,   304128, 0x850d6a68
+0,         24,         24,        1,   304128, 0xdc8409fb
+0,         25,         25,        1,   304128, 0x26216c51
+0,         26,         26,        1,   304128, 0x1d0004de
+0,         27,         27,        1,   304128, 0xed019a70
+0,         28,         28,        1,   304128, 0xb1abd985
+0,         29,         29,        1,   304128, 0xec1c14b2
+0,         30,         30,        1,   304128, 0x046db068
+0,         31,         31,        1,   304128, 0xa4fb1029
+0,         32,         32,        1,   304128, 0x49e05e61
+0,         33,         33,        1,   304128, 0x7668d6d1
+0,         34,         34,        1,   304128, 0x6dd0ce9d
+0,         35,         35,        1,   304128, 0x87983f5e
+0,         36,         36,        1,   304128, 0xb98278cf
+0,         37,         37,        1,   304128, 0x55186244
+0,         38,         38,        1,   304128, 0x3135e7ea
+0,         39,         39,        1,   304128, 0xdbf59a2c
+0,         40,         40,        1,   304128, 0x944cdc92
+0,         41,         41,        1,   304128, 0x5849dfe8
+0,         42,         42,        1,   304128, 0xaf9075ba
+0,         43,         43,        1,   304128, 0xb4f01118
+0,         44,         44,        1,   304128, 0x4dfb711f
+0,         45,         45,        1,   304128, 0xb558e732
+0,         46,         46,        1,   304128, 0xb23a171e
+0,         47,         47,        1,   304128, 0xb5c68065
+0,         48,         48,        1,   304128, 0xcf1b122e
+0,         49,         49,        1,   304128, 0x1e2d38e5
diff --git a/tests/ref/lavfi/colormatrix1 b/tests/ref/fate/filter-colormatrix1
similarity index 100%
rename from tests/ref/lavfi/colormatrix1
rename to tests/ref/fate/filter-colormatrix1
diff --git a/tests/ref/lavfi/colormatrix2 b/tests/ref/fate/filter-colormatrix2
similarity index 100%
rename from tests/ref/lavfi/colormatrix2
rename to tests/ref/fate/filter-colormatrix2
diff --git a/tests/ref/lavfi/crop b/tests/ref/fate/filter-crop
similarity index 100%
rename from tests/ref/lavfi/crop
rename to tests/ref/fate/filter-crop
diff --git a/tests/ref/lavfi/crop_scale b/tests/ref/fate/filter-crop_scale
similarity index 100%
rename from tests/ref/lavfi/crop_scale
rename to tests/ref/fate/filter-crop_scale
diff --git a/tests/ref/lavfi/crop_scale_vflip b/tests/ref/fate/filter-crop_scale_vflip
similarity index 100%
rename from tests/ref/lavfi/crop_scale_vflip
rename to tests/ref/fate/filter-crop_scale_vflip
diff --git a/tests/ref/lavfi/crop_vflip b/tests/ref/fate/filter-crop_vflip
similarity index 100%
rename from tests/ref/lavfi/crop_vflip
rename to tests/ref/fate/filter-crop_vflip
diff --git a/tests/ref/fate/filter-delogo b/tests/ref/fate/filter-delogo
index bc58777..80342ee 100644
--- a/tests/ref/fate/filter-delogo
+++ b/tests/ref/fate/filter-delogo
@@ -1,110 +1,110 @@
 #tb 0: 32768/982057
-0,          0,          0,        1,   126720, 0x689de87e
-0,          1,          1,        1,   126720, 0x3db9e91c
-0,          2,          2,        1,   126720, 0x3db9e91c
-0,          3,          3,        1,   126720, 0x3db9e91c
-0,          4,          4,        1,   126720, 0xfa6ae95e
-0,          5,          5,        1,   126720, 0x5bcbf0e6
-0,          6,          6,        1,   126720, 0x94a0f126
-0,          7,          7,        1,   126720, 0x0250f106
-0,          8,          8,        1,   126720, 0xcf6ab4bc
-0,          9,          9,        1,   126720, 0x429eb57c
-0,         10,         10,        1,   126720, 0x3bf0b5bc
-0,         11,         11,        1,   126720, 0xcaedb591
-0,         12,         12,        1,   126720, 0xa492b5ec
-0,         13,         13,        1,   126720, 0x2431b85c
-0,         14,         14,        1,   126720, 0x8283b8dc
-0,         15,         15,        1,   126720, 0xd71bb871
-0,         16,         16,        1,   126720, 0x698eb5cc
-0,         17,         17,        1,   126720, 0x4719aa98
-0,         18,         18,        1,   126720, 0x9ca1962c
-0,         19,         19,        1,   126720, 0x18cda460
-0,         20,         20,        1,   126720, 0xc230b716
-0,         21,         21,        1,   126720, 0x8451a4e2
-0,         22,         22,        1,   126720, 0x59e9a7ea
-0,         23,         23,        1,   126720, 0xc77ca73d
-0,         24,         24,        1,   126720, 0x725fb976
-0,         25,         25,        1,   126720, 0xb30da3b3
-0,         26,         26,        1,   126720, 0x7af2ea86
-0,         27,         27,        1,   126720, 0x40d4b4eb
-0,         28,         28,        1,   126720, 0x49d00307
-0,         29,         29,        1,   126720, 0x0654849c
-0,         30,         30,        1,   126720, 0xe46d0107
-0,         31,         31,        1,   126720, 0xa483b963
-0,         32,         32,        1,   126720, 0xd0e903f0
-0,         33,         33,        1,   126720, 0x964ed592
-0,         34,         34,        1,   126720, 0x23fbdb3c
-0,         35,         35,        1,   126720, 0x59fdace5
-0,         36,         36,        1,   126720, 0xb1e37954
-0,         37,         37,        1,   126720, 0x8ed9c554
-0,         38,         38,        1,   126720, 0xe3c4b39f
-0,         39,         39,        1,   126720, 0xfd17e0ce
-0,         40,         40,        1,   126720, 0xf26e1dcc
-0,         41,         41,        1,   126720, 0x13cc783c
-0,         42,         42,        1,   126720, 0x47ad47a1
-0,         43,         43,        1,   126720, 0x427c8b0d
-0,         44,         44,        1,   126720, 0x59d99901
-0,         45,         45,        1,   126720, 0xc40707da
-0,         46,         46,        1,   126720, 0xcd060dce
-0,         47,         47,        1,   126720, 0xed4024f6
-0,         48,         48,        1,   126720, 0x7decd2b4
-0,         49,         49,        1,   126720, 0xd1d2e730
-0,         50,         50,        1,   126720, 0x77cee457
-0,         51,         51,        1,   126720, 0xe78d02c0
-0,         52,         52,        1,   126720, 0xad0beb29
-0,         53,         53,        1,   126720, 0xc414eea2
-0,         54,         54,        1,   126720, 0x6a15f17d
-0,         55,         55,        1,   126720, 0x516027f6
-0,         56,         56,        1,   126720, 0x4eda9dce
-0,         57,         57,        1,   126720, 0x7d9bdba3
-0,         58,         58,        1,   126720, 0x7aa3d5c0
-0,         59,         59,        1,   126720, 0x7c7a04f9
-0,         60,         60,        1,   126720, 0x3e8fb6cc
-0,         61,         61,        1,   126720, 0xd5474916
-0,         62,         62,        1,   126720, 0xf3f62bab
-0,         63,         63,        1,   126720, 0x2f054987
-0,         64,         64,        1,   126720, 0x974c2e81
-0,         65,         65,        1,   126720, 0xe7e28a97
-0,         66,         66,        1,   126720, 0x45e38b41
-0,         67,         67,        1,   126720, 0x169c7f19
-0,         68,         68,        1,   126720, 0x91d90ee8
-0,         69,         69,        1,   126720, 0xdd653e24
-0,         70,         70,        1,   126720, 0x0da598c4
-0,         71,         71,        1,   126720, 0x687e62cc
-0,         72,         72,        1,   126720, 0x7631232d
-0,         73,         73,        1,   126720, 0xbd1ea826
-0,         74,         74,        1,   126720, 0xb55f7f4b
-0,         75,         75,        1,   126720, 0x923f3fc9
-0,         76,         76,        1,   126720, 0x15515301
-0,         77,         77,        1,   126720, 0x9ee066e5
-0,         78,         78,        1,   126720, 0x7c21664b
-0,         79,         79,        1,   126720, 0x36849100
-0,         80,         80,        1,   126720, 0x08b1f61a
-0,         81,         81,        1,   126720, 0x5bfca6e2
-0,         82,         82,        1,   126720, 0x929f60e3
-0,         83,         83,        1,   126720, 0xa2b55c29
-0,         84,         84,        1,   126720, 0x68bd3ff3
-0,         85,         85,        1,   126720, 0x30db5b29
-0,         86,         86,        1,   126720, 0x00578f9b
-0,         87,         87,        1,   126720, 0x18368642
-0,         88,         88,        1,   126720, 0xbcb83a80
-0,         89,         89,        1,   126720, 0x90f36b72
-0,         90,         90,        1,   126720, 0x85e46522
-0,         91,         91,        1,   126720, 0x2429660a
-0,         92,         92,        1,   126720, 0xf283dfe2
-0,         93,         93,        1,   126720, 0x896b27dc
-0,         94,         94,        1,   126720, 0x5af4f961
-0,         95,         95,        1,   126720, 0x31897085
-0,         96,         96,        1,   126720, 0x441ce33e
-0,         97,         97,        1,   126720, 0x903f8009
-0,         98,         98,        1,   126720, 0xbdf33dba
-0,         99,         99,        1,   126720, 0x8a364f36
-0,        100,        100,        1,   126720, 0xda5513f6
-0,        101,        101,        1,   126720, 0xd60012b3
-0,        102,        102,        1,   126720, 0x67bce7be
-0,        103,        103,        1,   126720, 0x697e6174
-0,        104,        104,        1,   126720, 0xbe3e3e90
-0,        105,        105,        1,   126720, 0xf3e4bba6
-0,        106,        106,        1,   126720, 0x8124a679
-0,        107,        107,        1,   126720, 0x58d1acde
-0,        108,        108,        1,   126720, 0xd8a15ba3
+0,          0,          0,        1,   126720, 0x77a5ebed
+0,          1,          1,        1,   126720, 0x4cc1ec8b
+0,          2,          2,        1,   126720, 0x4cc1ec8b
+0,          3,          3,        1,   126720, 0x4cc1ec8b
+0,          4,          4,        1,   126720, 0x0981eccd
+0,          5,          5,        1,   126720, 0x04fef463
+0,          6,          6,        1,   126720, 0x3dd3f4a3
+0,          7,          7,        1,   126720, 0xab74f483
+0,          8,          8,        1,   126720, 0x5ed7b7db
+0,          9,          9,        1,   126720, 0xd1fcb89b
+0,         10,         10,        1,   126720, 0xcb4eb8db
+0,         11,         11,        1,   126720, 0xdcc5b8a7
+0,         12,         12,        1,   126720, 0x33ffb90b
+0,         13,         13,        1,   126720, 0xb38fbb7b
+0,         14,         14,        1,   126720, 0x11f0bbfb
+0,         15,         15,        1,   126720, 0xe8f3bb87
+0,         16,         16,        1,   126720, 0xf8ecb8eb
+0,         17,         17,        1,   126720, 0x5db2ae48
+0,         18,         18,        1,   126720, 0x4e7999a6
+0,         19,         19,        1,   126720, 0xdb84a7a6
+0,         20,         20,        1,   126720, 0x9c4fba45
+0,         21,         21,        1,   126720, 0xe635a858
+0,         22,         22,        1,   126720, 0xd4eeab35
+0,         23,         23,        1,   126720, 0xc416aa56
+0,         24,         24,        1,   126720, 0x4c7ebca5
+0,         25,         25,        1,   126720, 0x2887a70e
+0,         26,         26,        1,   126720, 0xc978eaf1
+0,         27,         27,        1,   126720, 0x8a29b563
+0,         28,         28,        1,   126720, 0x275a0352
+0,         29,         29,        1,   126720, 0x446484bb
+0,         30,         30,        1,   126720, 0xdbe00151
+0,         31,         31,        1,   126720, 0x5874b9aa
+0,         32,         32,        1,   126720, 0xdeb30460
+0,         33,         33,        1,   126720, 0xc6d2d62a
+0,         34,         34,        1,   126720, 0x9270dbc7
+0,         35,         35,        1,   126720, 0x30e4ad59
+0,         36,         36,        1,   126720, 0x117479cd
+0,         37,         37,        1,   126720, 0x0567c5d2
+0,         38,         38,        1,   126720, 0x87c8b4a5
+0,         39,         39,        1,   126720, 0xe5c5e0d1
+0,         40,         40,        1,   126720, 0x78d61e3f
+0,         41,         41,        1,   126720, 0xda8d787f
+0,         42,         42,        1,   126720, 0xf32547f7
+0,         43,         43,        1,   126720, 0x70bc8b60
+0,         44,         44,        1,   126720, 0x3ad09927
+0,         45,         45,        1,   126720, 0x5d9607d6
+0,         46,         46,        1,   126720, 0x348a0e02
+0,         47,         47,        1,   126720, 0x7d21255c
+0,         48,         48,        1,   126720, 0x308ed32b
+0,         49,         49,        1,   126720, 0x79fbe734
+0,         50,         50,        1,   126720, 0xdc5de409
+0,         51,         51,        1,   126720, 0x4ee00283
+0,         52,         52,        1,   126720, 0x2697ea2e
+0,         53,         53,        1,   126720, 0x0885edeb
+0,         54,         54,        1,   126720, 0xc041f0d8
+0,         55,         55,        1,   126720, 0xa893272e
+0,         56,         56,        1,   126720, 0x55419d4e
+0,         57,         57,        1,   126720, 0xbc47dbb5
+0,         58,         58,        1,   126720, 0x9666d60b
+0,         59,         59,        1,   126720, 0xac5c054a
+0,         60,         60,        1,   126720, 0x4affb780
+0,         61,         61,        1,   126720, 0x2b7349eb
+0,         62,         62,        1,   126720, 0x75592d02
+0,         63,         63,        1,   126720, 0xdb904a83
+0,         64,         64,        1,   126720, 0xf85e2f93
+0,         65,         65,        1,   126720, 0x632f8be8
+0,         66,         66,        1,   126720, 0x96108ce4
+0,         67,         67,        1,   126720, 0xb68e816b
+0,         68,         68,        1,   126720, 0x89ca112f
+0,         69,         69,        1,   126720, 0x4bed40d3
+0,         70,         70,        1,   126720, 0xe4cb9b12
+0,         71,         71,        1,   126720, 0xa4f164ec
+0,         72,         72,        1,   126720, 0xd1aa2554
+0,         73,         73,        1,   126720, 0x0277aa01
+0,         74,         74,        1,   126720, 0x8ea280fd
+0,         75,         75,        1,   126720, 0xbae64170
+0,         76,         76,        1,   126720, 0xaf9b543b
+0,         77,         77,        1,   126720, 0x1b31680a
+0,         78,         78,        1,   126720, 0x7da4671e
+0,         79,         79,        1,   126720, 0x82b791cb
+0,         80,         80,        1,   126720, 0xd2fff6bb
+0,         81,         81,        1,   126720, 0x2395a793
+0,         82,         82,        1,   126720, 0x66586185
+0,         83,         83,        1,   126720, 0x99c55c63
+0,         84,         84,        1,   126720, 0x7e3f403e
+0,         85,         85,        1,   126720, 0x9eda5b9a
+0,         86,         86,        1,   126720, 0x27469047
+0,         87,         87,        1,   126720, 0xaa5b870e
+0,         88,         88,        1,   126720, 0x70423b2a
+0,         89,         89,        1,   126720, 0x70d86c0a
+0,         90,         90,        1,   126720, 0x4bd065f3
+0,         91,         91,        1,   126720, 0xd71f66bb
+0,         92,         92,        1,   126720, 0x5333e081
+0,         93,         93,        1,   126720, 0xdf0b28d6
+0,         94,         94,        1,   126720, 0x6c48fa53
+0,         95,         95,        1,   126720, 0x9438712d
+0,         96,         96,        1,   126720, 0x9910e3ec
+0,         97,         97,        1,   126720, 0xb0ea80dd
+0,         98,         98,        1,   126720, 0x71983e67
+0,         99,         99,        1,   126720, 0x18924fe6
+0,        100,        100,        1,   126720, 0x9ca014b9
+0,        101,        101,        1,   126720, 0x45f013a0
+0,        102,        102,        1,   126720, 0xf697e8a9
+0,        103,        103,        1,   126720, 0x214a626a
+0,        104,        104,        1,   126720, 0xb2873fb5
+0,        105,        105,        1,   126720, 0xfb47bc52
+0,        106,        106,        1,   126720, 0x63b7a708
+0,        107,        107,        1,   126720, 0x1904ad40
+0,        108,        108,        1,   126720, 0x80015b91
diff --git a/tests/ref/fate/filter-drawbox b/tests/ref/fate/filter-drawbox
index 869b9f3..c63d2fc 100644
--- a/tests/ref/fate/filter-drawbox
+++ b/tests/ref/fate/filter-drawbox
@@ -1,51 +1,51 @@
 #tb 0: 1/25
-0,          0,          0,        1,   152064, 0x7eee5ca3
-0,          1,          1,        1,   152064, 0x61125759
-0,          2,          2,        1,   152064, 0x2a64f47f
-0,          3,          3,        1,   152064, 0xc1089594
-0,          4,          4,        1,   152064, 0xd9e18830
-0,          5,          5,        1,   152064, 0xeb135e03
-0,          6,          6,        1,   152064, 0x6a5b40d7
-0,          7,          7,        1,   152064, 0x0a356a16
-0,          8,          8,        1,   152064, 0xfc1d7858
-0,          9,          9,        1,   152064, 0xa04bfeb8
-0,         10,         10,        1,   152064, 0x2d952ef0
-0,         11,         11,        1,   152064, 0x7f360233
-0,         12,         12,        1,   152064, 0xdd2bd142
-0,         13,         13,        1,   152064, 0xd231ad4a
-0,         14,         14,        1,   152064, 0x0543400e
-0,         15,         15,        1,   152064, 0x8252be2b
-0,         16,         16,        1,   152064, 0xd9f702be
-0,         17,         17,        1,   152064, 0xed5cf787
-0,         18,         18,        1,   152064, 0xf9472f8e
-0,         19,         19,        1,   152064, 0x89e4a60b
-0,         20,         20,        1,   152064, 0x1f12c1f5
-0,         21,         21,        1,   152064, 0x76eaf390
-0,         22,         22,        1,   152064, 0x60b5eba3
-0,         23,         23,        1,   152064, 0xf09e348c
-0,         24,         24,        1,   152064, 0x1afabf8a
-0,         25,         25,        1,   152064, 0xd16c558e
-0,         26,         26,        1,   152064, 0x78634796
-0,         27,         27,        1,   152064, 0xcd13b1e3
-0,         28,         28,        1,   152064, 0x59c2c6e5
-0,         29,         29,        1,   152064, 0x265e6beb
-0,         30,         30,        1,   152064, 0x82c656af
-0,         31,         31,        1,   152064, 0x919e923c
-0,         32,         32,        1,   152064, 0xc428fc15
-0,         33,         33,        1,   152064, 0x488760cd
-0,         34,         34,        1,   152064, 0x0a080c93
-0,         35,         35,        1,   152064, 0xaab649e6
-0,         36,         36,        1,   152064, 0x9b34edaa
-0,         37,         37,        1,   152064, 0x44e12816
-0,         38,         38,        1,   152064, 0x03777927
-0,         39,         39,        1,   152064, 0x6644573e
-0,         40,         40,        1,   152064, 0x18574df7
-0,         41,         41,        1,   152064, 0x5dce82f6
-0,         42,         42,        1,   152064, 0xb8be9205
-0,         43,         43,        1,   152064, 0xb927eacb
-0,         44,         44,        1,   152064, 0x303ec874
-0,         45,         45,        1,   152064, 0x05eb3c6f
-0,         46,         46,        1,   152064, 0x74a614d6
-0,         47,         47,        1,   152064, 0x6d078969
-0,         48,         48,        1,   152064, 0xe57a7ae0
-0,         49,         49,        1,   152064, 0xd6fca9ec
+0,          0,          0,        1,   152064, 0x9ada9be9
+0,          1,          1,        1,   152064, 0xb0ec7d59
+0,          2,          2,        1,   152064, 0x938816b8
+0,          3,          3,        1,   152064, 0x1d8fac2e
+0,          4,          4,        1,   152064, 0x8ed4bbf6
+0,          5,          5,        1,   152064, 0xc9e585de
+0,          6,          6,        1,   152064, 0xf1e83c0b
+0,          7,          7,        1,   152064, 0xed0e5981
+0,          8,          8,        1,   152064, 0x6fc55e8c
+0,          9,          9,        1,   152064, 0xcf3e2eb5
+0,         10,         10,        1,   152064, 0xe62d4dcf
+0,         11,         11,        1,   152064, 0xd30712cd
+0,         12,         12,        1,   152064, 0xcb99d3e8
+0,         13,         13,        1,   152064, 0x6b9cb3ed
+0,         14,         14,        1,   152064, 0xb96774c1
+0,         15,         15,        1,   152064, 0xfae0f615
+0,         16,         16,        1,   152064, 0xeb211f65
+0,         17,         17,        1,   152064, 0xc9f7ff9f
+0,         18,         18,        1,   152064, 0xe5bc2b7f
+0,         19,         19,        1,   152064, 0x8f82a022
+0,         20,         20,        1,   152064, 0xb8e5bb92
+0,         21,         21,        1,   152064, 0x051aeb1a
+0,         22,         22,        1,   152064, 0x5b3ce556
+0,         23,         23,        1,   152064, 0xda552e9c
+0,         24,         24,        1,   152064, 0x865ebca1
+0,         25,         25,        1,   152064, 0xd77b6d16
+0,         26,         26,        1,   152064, 0xcf7e89d8
+0,         27,         27,        1,   152064, 0xe340d477
+0,         28,         28,        1,   152064, 0x8167c0e4
+0,         29,         29,        1,   152064, 0xa6af7555
+0,         30,         30,        1,   152064, 0x305a6def
+0,         31,         31,        1,   152064, 0xf395b657
+0,         32,         32,        1,   152064, 0x6f6bdfdc
+0,         33,         33,        1,   152064, 0x976c50ff
+0,         34,         34,        1,   152064, 0x89661e9d
+0,         35,         35,        1,   152064, 0x001760a0
+0,         36,         36,        1,   152064, 0x7ac624ba
+0,         37,         37,        1,   152064, 0x40941960
+0,         38,         38,        1,   152064, 0x89917c8a
+0,         39,         39,        1,   152064, 0xcf4667e5
+0,         40,         40,        1,   152064, 0x985f6670
+0,         41,         41,        1,   152064, 0x5368a016
+0,         42,         42,        1,   152064, 0x2f04b620
+0,         43,         43,        1,   152064, 0x637f1129
+0,         44,         44,        1,   152064, 0x4b41f131
+0,         45,         45,        1,   152064, 0x6e786dea
+0,         46,         46,        1,   152064, 0xeafa55b3
+0,         47,         47,        1,   152064, 0xfdf2d102
+0,         48,         48,        1,   152064, 0x127abdfa
+0,         49,         49,        1,   152064, 0x0e4ae6c7
diff --git a/tests/ref/fate/filter-edgedetect b/tests/ref/fate/filter-edgedetect
new file mode 100644
index 0000000..5044eed
--- /dev/null
+++ b/tests/ref/fate/filter-edgedetect
@@ -0,0 +1 @@
+edgedetect          9d67cf98d604f5dbde6f20a88664c683
diff --git a/tests/ref/fate/filter-fade b/tests/ref/fate/filter-fade
index 3acd889..9d691ce 100644
--- a/tests/ref/fate/filter-fade
+++ b/tests/ref/fate/filter-fade
@@ -1,51 +1,51 @@
 #tb 0: 1/25
 0,          0,          0,        1,   152064, 0xb4e6c735
-0,          1,          1,        1,   152064, 0xbfa36592
-0,          2,          2,        1,   152064, 0x8678003e
-0,          3,          3,        1,   152064, 0xb1e9b1a3
-0,          4,          4,        1,   152064, 0x6ccf66ac
-0,          5,          5,        1,   152064, 0x3390056b
-0,          6,          6,        1,   152064, 0x4fcae508
-0,          7,          7,        1,   152064, 0x2528a210
-0,          8,          8,        1,   152064, 0x8128070e
-0,          9,          9,        1,   152064, 0xc991f27d
-0,         10,         10,        1,   152064, 0xe97a9a8b
-0,         11,         11,        1,   152064, 0x71cb32fb
-0,         12,         12,        1,   152064, 0x0b395f46
-0,         13,         13,        1,   152064, 0x362c1742
-0,         14,         14,        1,   152064, 0x14d23d11
-0,         15,         15,        1,   152064, 0x4d11a4d6
-0,         16,         16,        1,   152064, 0xee808ebb
-0,         17,         17,        1,   152064, 0x1d69964c
-0,         18,         18,        1,   152064, 0xfd5c30e6
-0,         19,         19,        1,   152064, 0xcd69b313
-0,         20,         20,        1,   152064, 0x3d75953b
-0,         21,         21,        1,   152064, 0xd6c698ea
-0,         22,         22,        1,   152064, 0x25006f22
-0,         23,         23,        1,   152064, 0x44e6a8a7
-0,         24,         24,        1,   152064, 0x0c251d62
+0,          1,          1,        1,   152064, 0xb4e6c735
+0,          2,          2,        1,   152064, 0xb4e6c735
+0,          3,          3,        1,   152064, 0xb4e6c735
+0,          4,          4,        1,   152064, 0xb4e6c735
+0,          5,          5,        1,   152064, 0xb4e6c735
+0,          6,          6,        1,   152064, 0x1f3b0657
+0,          7,          7,        1,   152064, 0x6e7547e6
+0,          8,          8,        1,   152064, 0x1197524c
+0,          9,          9,        1,   152064, 0xb4cdb293
+0,         10,         10,        1,   152064, 0xdd7cf1b8
+0,         11,         11,        1,   152064, 0x360b1005
+0,         12,         12,        1,   152064, 0x11a49918
+0,         13,         13,        1,   152064, 0xa10dd4f9
+0,         14,         14,        1,   152064, 0x78da71d7
+0,         15,         15,        1,   152064, 0x105e4cc0
+0,         16,         16,        1,   152064, 0x54bfa1c5
+0,         17,         17,        1,   152064, 0xd666559e
+0,         18,         18,        1,   152064, 0xd93faa1c
+0,         19,         19,        1,   152064, 0xb1af85ed
+0,         20,         20,        1,   152064, 0xfc7bf570
+0,         21,         21,        1,   152064, 0x9dc72412
+0,         22,         22,        1,   152064, 0x445d1d59
+0,         23,         23,        1,   152064, 0x2f2768ef
+0,         24,         24,        1,   152064, 0xce09f9d6
 0,         25,         25,        1,   152064, 0x95579936
-0,         26,         26,        1,   152064, 0x8156c4f5
-0,         27,         27,        1,   152064, 0xca743348
-0,         28,         28,        1,   152064, 0x56a1373d
-0,         29,         29,        1,   152064, 0x17360ed3
-0,         30,         30,        1,   152064, 0x245243a1
-0,         31,         31,        1,   152064, 0xdd5ff4df
-0,         32,         32,        1,   152064, 0x2b979f45
-0,         33,         33,        1,   152064, 0x8a74da27
-0,         34,         34,        1,   152064, 0x27a7cd9f
-0,         35,         35,        1,   152064, 0xaa543c0f
-0,         36,         36,        1,   152064, 0xd72b5d8a
-0,         37,         37,        1,   152064, 0x8538f93d
-0,         38,         38,        1,   152064, 0x3fdc67b7
-0,         39,         39,        1,   152064, 0x4fe2154f
-0,         40,         40,        1,   152064, 0x908e09fb
-0,         41,         41,        1,   152064, 0x75ca5951
-0,         42,         42,        1,   152064, 0xd4a2ef14
-0,         43,         43,        1,   152064, 0x32d343a7
-0,         44,         44,        1,   152064, 0x59733ac8
-0,         45,         45,        1,   152064, 0x268d64da
-0,         46,         46,        1,   152064, 0x813eaf95
-0,         47,         47,        1,   152064, 0xf098ff5b
-0,         48,         48,        1,   152064, 0xc5b85c26
-0,         49,         49,        1,   152064, 0xc0f79718
+0,         26,         26,        1,   152064, 0x43d796b5
+0,         27,         27,        1,   152064, 0xd780d887
+0,         28,         28,        1,   152064, 0x76d2a455
+0,         29,         29,        1,   152064, 0x6dc3650e
+0,         30,         30,        1,   152064, 0x0f9d6aca
+0,         31,         31,        1,   152064, 0xddae8141
+0,         32,         32,        1,   152064, 0x67cb8f24
+0,         33,         33,        1,   152064, 0xc7a72348
+0,         34,         34,        1,   152064, 0x0d7a1144
+0,         35,         35,        1,   152064, 0x39adfb3d
+0,         36,         36,        1,   152064, 0x0ecc70d5
+0,         37,         37,        1,   152064, 0xf3a6805e
+0,         38,         38,        1,   152064, 0xc3bd71ad
+0,         39,         39,        1,   152064, 0xa9be9730
+0,         40,         40,        1,   152064, 0xab9af790
+0,         41,         41,        1,   152064, 0x4c3ccd25
+0,         42,         42,        1,   152064, 0xbc83c58a
+0,         43,         43,        1,   152064, 0x94877df4
+0,         44,         44,        1,   152064, 0xa2360ea6
+0,         45,         45,        1,   152064, 0xb4e6c735
+0,         46,         46,        1,   152064, 0xb4e6c735
+0,         47,         47,        1,   152064, 0xb4e6c735
+0,         48,         48,        1,   152064, 0xb4e6c735
+0,         49,         49,        1,   152064, 0xb4e6c735
diff --git a/tests/ref/fate/filter-gradfun-sample b/tests/ref/fate/filter-gradfun-sample
index dca442f..595f82a 100644
--- a/tests/ref/fate/filter-gradfun-sample
+++ b/tests/ref/fate/filter-gradfun-sample
@@ -1,21 +1,21 @@
 #tb 0: 1/10
-0,          0,          0,        1,    76800, 0xc87b6728
-0,          1,          1,        1,    76800, 0xb0b24bc8
-0,          2,          2,        1,    76800, 0x45a22d68
-0,          3,          3,        1,    76800, 0x1821013b
-0,          4,          4,        1,    76800, 0xfb17dc4f
-0,          5,          5,        1,    76800, 0x8e7eb458
-0,          6,          6,        1,    76800, 0x0df37d02
-0,          7,          7,        1,    76800, 0x18e4500d
-0,          8,          8,        1,    76800, 0x639316b0
-0,          9,          9,        1,    76800, 0xce00e560
-0,         10,         10,        1,    76800, 0xd533b42c
-0,         11,         11,        1,    76800, 0x0772794c
-0,         12,         12,        1,    76800, 0x99544be0
-0,         13,         13,        1,    76800, 0x5f1a16c1
-0,         14,         14,        1,    76800, 0x90bfe8ac
-0,         15,         15,        1,    76800, 0xbd9bb834
-0,         16,         16,        1,    76800, 0x658d8053
-0,         17,         17,        1,    76800, 0x21cc5656
-0,         18,         18,        1,    76800, 0x6d39208b
-0,         19,         19,        1,    76800, 0x17b0f8cb
+0,          0,          0,        1,    76800, 0xea62ab65
+0,          1,          1,        1,    76800, 0xbc0d8b58
+0,          2,          2,        1,    76800, 0x682967d0
+0,          3,          3,        1,    76800, 0x2f1d3353
+0,          4,          4,        1,    76800, 0x0f3306c5
+0,          5,          5,        1,    76800, 0x1f026ce0
+0,          6,          6,        1,    76800, 0xefff2a28
+0,          7,          7,        1,    76800, 0xa7daf536
+0,          8,          8,        1,    76800, 0x8b95b1b2
+0,          9,          9,        1,    76800, 0x821b76c2
+0,         10,         10,        1,    76800, 0x48193d3d
+0,         11,         11,        1,    76800, 0x6182634a
+0,         12,         12,        1,    76800, 0x442b2dcc
+0,         13,         13,        1,    76800, 0x83e2ee26
+0,         14,         14,        1,    76800, 0x47d8b74d
+0,         15,         15,        1,    76800, 0x412b7dcd
+0,         16,         16,        1,    76800, 0x65e33b7c
+0,         17,         17,        1,    76800, 0xb04a0915
+0,         18,         18,        1,    76800, 0x5405c876
+0,         19,         19,        1,    76800, 0xce6d98bc
diff --git a/tests/ref/fate/filter-hqdn3d-sample b/tests/ref/fate/filter-hqdn3d-sample
index d69e6db..97718f9 100644
--- a/tests/ref/fate/filter-hqdn3d-sample
+++ b/tests/ref/fate/filter-hqdn3d-sample
@@ -44,16 +44,16 @@
 0,         42,         42,        1,   115200, 0x5e04197b
 0,         43,         43,        1,   115200, 0x6b846e24
 0,         44,         44,        1,   115200, 0x026e7a0b
-0,         45,         45,        1,   115200, 0xf8c6708b
-0,         46,         46,        1,   115200, 0x3fe75c63
-0,         47,         47,        1,   115200, 0xf56467b1
-0,         48,         48,        1,   115200, 0xf1230483
-0,         49,         49,        1,   115200, 0x35a615ce
-0,         50,         50,        1,   115200, 0x30b42d7b
-0,         51,         51,        1,   115200, 0x8b7f22a1
-0,         52,         52,        1,   115200, 0x03a2e789
-0,         53,         53,        1,   115200, 0x15532e9e
-0,         54,         54,        1,   115200, 0xbe85f37a
+0,         45,         45,        1,   115200, 0xef23db9d
+0,         46,         46,        1,   115200, 0x9e94265d
+0,         47,         47,        1,   115200, 0x2830098a
+0,         48,         48,        1,   115200, 0xf5d211d6
+0,         49,         49,        1,   115200, 0xb96b22b0
+0,         50,         50,        1,   115200, 0x9acda7c9
+0,         51,         51,        1,   115200, 0xed7b40f6
+0,         52,         52,        1,   115200, 0x8250278f
+0,         53,         53,        1,   115200, 0xa10003e0
+0,         54,         54,        1,   115200, 0xe67b5513
 0,         55,         55,        1,   115200, 0x2c581d60
 0,         56,         56,        1,   115200, 0xd7a506ed
 0,         57,         57,        1,   115200, 0x35e09799
diff --git a/tests/ref/lavfi/hue b/tests/ref/fate/filter-hue
similarity index 100%
rename from tests/ref/lavfi/hue
rename to tests/ref/fate/filter-hue
diff --git a/tests/ref/lavfi/idet b/tests/ref/fate/filter-idet
similarity index 100%
rename from tests/ref/lavfi/idet
rename to tests/ref/fate/filter-idet
diff --git a/tests/ref/fate/filter-lavd-life b/tests/ref/fate/filter-lavd-life
new file mode 100644
index 0000000..565f88a
--- /dev/null
+++ b/tests/ref/fate/filter-lavd-life
@@ -0,0 +1,11 @@
+#tb 0: 1/5
+0,          0,          0,        1,     4800, 0xf2a15b15
+0,          1,          1,        1,     4800, 0x78c29dcf
+0,          2,          2,        1,     4800, 0x28509d6e
+0,          3,          3,        1,     4800, 0xb9d0841a
+0,          4,          4,        1,     4800, 0x53ac6a72
+0,          5,          5,        1,     4800, 0x6e6a6587
+0,          6,          6,        1,     4800, 0x6de46287
+0,          7,          7,        1,     4800, 0x7e0d5b95
+0,          8,          8,        1,     4800, 0xf30f5a1b
+0,          9,          9,        1,     4800, 0x84505420
diff --git a/tests/ref/fate/filter-lavd-scalenorm b/tests/ref/fate/filter-lavd-scalenorm
new file mode 100644
index 0000000..4d09a0d
--- /dev/null
+++ b/tests/ref/fate/filter-lavd-scalenorm
@@ -0,0 +1,11 @@
+#tb 0: 1/5
+0,          0,          0,        1,    18432, 0xdd8a4db8
+0,          1,          1,        1,    18432, 0xc0144dbe
+0,          2,          2,        1,    18432, 0x1d264db6
+0,          3,          3,        1,    18432, 0x49e44dcb
+0,          4,          4,        1,    18432, 0x81404dc1
+0,          5,          5,        1,    18432, 0xd163688e
+0,          6,          6,        1,    18432, 0x63f869bb
+0,          7,          7,        1,    18432, 0xee606528
+0,          8,          8,        1,    18432, 0x44445e77
+0,          9,          9,        1,    18432, 0x830a57b4
diff --git a/tests/ref/fate/filter-lavd-testsrc b/tests/ref/fate/filter-lavd-testsrc
new file mode 100644
index 0000000..0ea5a49
--- /dev/null
+++ b/tests/ref/fate/filter-lavd-testsrc
@@ -0,0 +1,71 @@
+#tb 0: 1/7
+0,          0,          0,        1,   230400, 0x88c4d19a
+0,          1,          1,        1,   230400, 0xcc930a2e
+0,          2,          2,        1,   230400, 0x8e1b0e23
+0,          3,          3,        1,   230400, 0xff3b5a72
+0,          4,          4,        1,   230400, 0xb0ad3760
+0,          5,          5,        1,   230400, 0x8013eaaf
+0,          6,          6,        1,   230400, 0xa6eaa9c3
+0,          7,          7,        1,   230400, 0xef4695a2
+0,          8,          8,        1,   230400, 0x8f144889
+0,          9,          9,        1,   230400, 0x693779f9
+0,         10,         10,        1,   230400, 0xedaf92f0
+0,         11,         11,        1,   230400, 0x1c39d7c4
+0,         12,         12,        1,   230400, 0xb72589bb
+0,         13,         13,        1,   230400, 0x61c2de4a
+0,         14,         14,        1,   230400, 0xc46085ae
+0,         15,         15,        1,   230400, 0xad059d62
+0,         16,         16,        1,   230400, 0xe82ea157
+0,         17,         17,        1,   230400, 0xa30aeda6
+0,         18,         18,        1,   230400, 0x7f86ca94
+0,         19,         19,        1,   230400, 0x4c4f7df2
+0,         20,         20,        1,   230400, 0x535a3d06
+0,         21,         21,        1,   230400, 0x449262ff
+0,         22,         22,        1,   230400, 0x971c15e6
+0,         23,         23,        1,   230400, 0xda1d4756
+0,         24,         24,        1,   230400, 0x78ad604d
+0,         25,         25,        1,   230400, 0x72d8a521
+0,         26,         26,        1,   230400, 0x8f395718
+0,         27,         27,        1,   230400, 0x6e57aba7
+0,         28,         28,        1,   230400, 0x54ad968f
+0,         29,         29,        1,   230400, 0x59d9ae43
+0,         30,         30,        1,   230400, 0x843fb238
+0,         31,         31,        1,   230400, 0x0f77fe87
+0,         32,         32,        1,   230400, 0x8c8adb75
+0,         33,         33,        1,   230400, 0xdd568ed3
+0,         34,         34,        1,   230400, 0x38bd4de7
+0,         35,         35,        1,   230400, 0x62ad62ff
+0,         36,         36,        1,   230400, 0x1f0215e6
+0,         37,         37,        1,   230400, 0xe8534756
+0,         38,         38,        1,   230400, 0x3d36604d
+0,         39,         39,        1,   230400, 0x0c57a521
+0,         40,         40,        1,   230400, 0x2b555718
+0,         41,         41,        1,   230400, 0x2a3faba7
+0,         42,         42,        1,   230400, 0x4e0a74cd
+0,         43,         43,        1,   230400, 0xa06b8c81
+0,         44,         44,        1,   230400, 0x61f39076
+0,         45,         45,        1,   230400, 0xd313dcc5
+0,         46,         46,        1,   230400, 0x8485b9b3
+0,         47,         47,        1,   230400, 0x53eb6d11
+0,         48,         48,        1,   230400, 0x7ac22c25
+0,         49,         49,        1,   230400, 0xce7b84c1
+0,         50,         50,        1,   230400, 0x6e4937a8
+0,         51,         51,        1,   230400, 0x486c6918
+0,         52,         52,        1,   230400, 0xcce4820f
+0,         53,         53,        1,   230400, 0xfb5fc6e3
+0,         54,         54,        1,   230400, 0x965a78da
+0,         55,         55,        1,   230400, 0x40f7cd69
+0,         56,         56,        1,   230400, 0x68db63ec
+0,         57,         57,        1,   230400, 0x51807ba0
+0,         58,         58,        1,   230400, 0x8ca97f95
+0,         59,         59,        1,   230400, 0x4785cbe4
+0,         60,         60,        1,   230400, 0x2401a8d2
+0,         61,         61,        1,   230400, 0xf0bb5c30
+0,         62,         62,        1,   230400, 0xf7c61b44
+0,         63,         63,        1,   230400, 0x7d7e521e
+0,         64,         64,        1,   230400, 0xd0080505
+0,         65,         65,        1,   230400, 0x13183675
+0,         66,         66,        1,   230400, 0xb1994f6c
+0,         67,         67,        1,   230400, 0xabc49440
+0,         68,         68,        1,   230400, 0xc8254637
+0,         69,         69,        1,   230400, 0xa7439ac6
diff --git a/tests/ref/fate/filter-mcdeint-fast b/tests/ref/fate/filter-mcdeint-fast
new file mode 100644
index 0000000..000d43b
--- /dev/null
+++ b/tests/ref/fate/filter-mcdeint-fast
@@ -0,0 +1,31 @@
+#tb 0: 1/25
+0,          9,          9,        1,   622080, 0xb3b66c5c
+0,         10,         10,        1,   622080, 0xc6568bd7
+0,         11,         11,        1,   622080, 0xa5b543c3
+0,         12,         12,        1,   622080, 0x4095ac51
+0,         13,         13,        1,   622080, 0xccd8c1d9
+0,         14,         14,        1,   622080, 0x84a88f22
+0,         15,         15,        1,   622080, 0x7273c26b
+0,         16,         16,        1,   622080, 0xac188c41
+0,         17,         17,        1,   622080, 0xf32f6fb4
+0,         18,         18,        1,   622080, 0xd696ccce
+0,         19,         19,        1,   622080, 0x9778a418
+0,         20,         20,        1,   622080, 0xf2b5be2e
+0,         21,         21,        1,   622080, 0x653ee12a
+0,         22,         22,        1,   622080, 0xe7fce188
+0,         23,         23,        1,   622080, 0x6e9f1deb
+0,         24,         24,        1,   622080, 0x33090aac
+0,         25,         25,        1,   622080, 0x840a57f1
+0,         26,         26,        1,   622080, 0x635e430a
+0,         27,         27,        1,   622080, 0x52f98809
+0,         28,         28,        1,   622080, 0xc567b6a5
+0,         29,         29,        1,   622080, 0x4134f583
+0,         30,         30,        1,   622080, 0xd02a73bc
+0,         31,         31,        1,   622080, 0x763085d6
+0,         32,         32,        1,   622080, 0x77fdc7a6
+0,         33,         33,        1,   622080, 0x77f71b9f
+0,         34,         34,        1,   622080, 0x71c91244
+0,         35,         35,        1,   622080, 0xc7b86da5
+0,         36,         36,        1,   622080, 0x1edf8890
+0,         37,         37,        1,   622080, 0x03c82bec
+0,         38,         38,        1,   622080, 0x148b6a04
diff --git a/tests/ref/fate/filter-mcdeint-medium b/tests/ref/fate/filter-mcdeint-medium
new file mode 100644
index 0000000..80ba484
--- /dev/null
+++ b/tests/ref/fate/filter-mcdeint-medium
@@ -0,0 +1,31 @@
+#tb 0: 1/25
+0,          9,          9,        1,   622080, 0xb3b66c5c
+0,         10,         10,        1,   622080, 0xc69368eb
+0,         11,         11,        1,   622080, 0x76bdde33
+0,         12,         12,        1,   622080, 0x5a04d7a6
+0,         13,         13,        1,   622080, 0x68eacaec
+0,         14,         14,        1,   622080, 0x1e888865
+0,         15,         15,        1,   622080, 0x188ad805
+0,         16,         16,        1,   622080, 0x268e94ce
+0,         17,         17,        1,   622080, 0x89da806c
+0,         18,         18,        1,   622080, 0x507ec6c9
+0,         19,         19,        1,   622080, 0xf20ba69b
+0,         20,         20,        1,   622080, 0x5786a96e
+0,         21,         21,        1,   622080, 0xf9d2fd6e
+0,         22,         22,        1,   622080, 0x4b69ef51
+0,         23,         23,        1,   622080, 0x19a22b06
+0,         24,         24,        1,   622080, 0x13a30e94
+0,         25,         25,        1,   622080, 0x02435f86
+0,         26,         26,        1,   622080, 0x06794a00
+0,         27,         27,        1,   622080, 0x289e8aea
+0,         28,         28,        1,   622080, 0x494ab1a4
+0,         29,         29,        1,   622080, 0xc1c6f5da
+0,         30,         30,        1,   622080, 0x1f6d6764
+0,         31,         31,        1,   622080, 0xaa898832
+0,         32,         32,        1,   622080, 0x6935c412
+0,         33,         33,        1,   622080, 0x825e2a67
+0,         34,         34,        1,   622080, 0xd8ee113a
+0,         35,         35,        1,   622080, 0x9ffc7f17
+0,         36,         36,        1,   622080, 0xa7819ac8
+0,         37,         37,        1,   622080, 0xa412377d
+0,         38,         38,        1,   622080, 0x538376bc
diff --git a/tests/ref/lavfi/null b/tests/ref/fate/filter-null
similarity index 100%
rename from tests/ref/lavfi/null
rename to tests/ref/fate/filter-null
diff --git a/tests/ref/fate/filter-overlay_rgb b/tests/ref/fate/filter-overlay_rgb
new file mode 100644
index 0000000..2b1ce18
--- /dev/null
+++ b/tests/ref/fate/filter-overlay_rgb
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   304128, 0xd4531e28
+0,          1,          1,        1,   304128, 0xfb069ecd
+0,          2,          2,        1,   304128, 0x4c376898
+0,          3,          3,        1,   304128, 0x5a0c7282
+0,          4,          4,        1,   304128, 0x4802850a
+0,          5,          5,        1,   304128, 0xf670e9cc
+0,          6,          6,        1,   304128, 0x5189c380
+0,          7,          7,        1,   304128, 0x14d6de42
+0,          8,          8,        1,   304128, 0xb65df5f1
+0,          9,          9,        1,   304128, 0xc2f89ef5
+0,         10,         10,        1,   304128, 0xde29db6b
+0,         11,         11,        1,   304128, 0x10a71aae
+0,         12,         12,        1,   304128, 0xf53d02ef
+0,         13,         13,        1,   304128, 0x4b3632ca
+0,         14,         14,        1,   304128, 0xce140f66
+0,         15,         15,        1,   304128, 0x4bedf6f1
+0,         16,         16,        1,   304128, 0xcc5edbd0
+0,         17,         17,        1,   304128, 0x836a556a
+0,         18,         18,        1,   304128, 0x3537c635
+0,         19,         19,        1,   304128, 0x400df2dd
+0,         20,         20,        1,   304128, 0x4292ccb3
+0,         21,         21,        1,   304128, 0x2f71db21
+0,         22,         22,        1,   304128, 0xa40b997c
+0,         23,         23,        1,   304128, 0xeee30551
+0,         24,         24,        1,   304128, 0x4f7bf0cb
+0,         25,         25,        1,   304128, 0x9a70dfe0
+0,         26,         26,        1,   304128, 0xc140124f
+0,         27,         27,        1,   304128, 0x275bca59
+0,         28,         28,        1,   304128, 0x4c62ceee
+0,         29,         29,        1,   304128, 0xc1d54279
+0,         30,         30,        1,   304128, 0xae7ef047
+0,         31,         31,        1,   304128, 0x331570a8
+0,         32,         32,        1,   304128, 0x10db2de2
+0,         33,         33,        1,   304128, 0xcc60fdfb
+0,         34,         34,        1,   304128, 0xe2cffcfa
+0,         35,         35,        1,   304128, 0x5a7ff1fb
+0,         36,         36,        1,   304128, 0xa39a4e47
+0,         37,         37,        1,   304128, 0x79e40e52
+0,         38,         38,        1,   304128, 0x53d0d393
+0,         39,         39,        1,   304128, 0xeb5fcfc1
+0,         40,         40,        1,   304128, 0x8923f95f
+0,         41,         41,        1,   304128, 0xd27a2b71
+0,         42,         42,        1,   304128, 0xe4fdd79e
+0,         43,         43,        1,   304128, 0xcd8fb238
+0,         44,         44,        1,   304128, 0x65e6eaaf
+0,         45,         45,        1,   304128, 0x41bfcb1b
+0,         46,         46,        1,   304128, 0xbecabb09
+0,         47,         47,        1,   304128, 0xfa04a0ef
+0,         48,         48,        1,   304128, 0xa43d9356
+0,         49,         49,        1,   304128, 0x56fd6ae0
diff --git a/tests/ref/fate/filter-overlay_yuv420 b/tests/ref/fate/filter-overlay_yuv420
new file mode 100644
index 0000000..c79518e
--- /dev/null
+++ b/tests/ref/fate/filter-overlay_yuv420
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   152064, 0xd5ac29f3
+0,          1,          1,        1,   152064, 0x95110a80
+0,          2,          2,        1,   152064, 0xe5c59adc
+0,          3,          3,        1,   152064, 0xe54df17c
+0,          4,          4,        1,   152064, 0xab22e1ac
+0,          5,          5,        1,   152064, 0x1a5db284
+0,          6,          6,        1,   152064, 0x6ee1895d
+0,          7,          7,        1,   152064, 0xb091cdff
+0,          8,          8,        1,   152064, 0x4df4dcd3
+0,          9,          9,        1,   152064, 0xb00ef49e
+0,         10,         10,        1,   152064, 0x11b61be4
+0,         11,         11,        1,   152064, 0x4e6d0b38
+0,         12,         12,        1,   152064, 0x029d65db
+0,         13,         13,        1,   152064, 0x8123d3a6
+0,         14,         14,        1,   152064, 0xbdd3701f
+0,         15,         15,        1,   152064, 0x958916e7
+0,         16,         16,        1,   152064, 0xe7973608
+0,         17,         17,        1,   152064, 0xd6be4edf
+0,         18,         18,        1,   152064, 0x3571a14f
+0,         19,         19,        1,   152064, 0xde150ddd
+0,         20,         20,        1,   152064, 0xb5e33eb1
+0,         21,         21,        1,   152064, 0xdd258601
+0,         22,         22,        1,   152064, 0x4335a59d
+0,         23,         23,        1,   152064, 0xa652cb99
+0,         24,         24,        1,   152064, 0x42cc6e6e
+0,         25,         25,        1,   152064, 0xc7540c4b
+0,         26,         26,        1,   152064, 0xb495dc85
+0,         27,         27,        1,   152064, 0x2aa11cfa
+0,         28,         28,        1,   152064, 0x8e4d44de
+0,         29,         29,        1,   152064, 0x2e9e550f
+0,         30,         30,        1,   152064, 0x995839ee
+0,         31,         31,        1,   152064, 0xb55647d7
+0,         32,         32,        1,   152064, 0x7fc556f7
+0,         33,         33,        1,   152064, 0x894f9acf
+0,         34,         34,        1,   152064, 0x5ea68479
+0,         35,         35,        1,   152064, 0x9d0fdb97
+0,         36,         36,        1,   152064, 0x8e6d4cff
+0,         37,         37,        1,   152064, 0xb315621c
+0,         38,         38,        1,   152064, 0x307b23a1
+0,         39,         39,        1,   152064, 0x41f246da
+0,         40,         40,        1,   152064, 0x8af934d5
+0,         41,         41,        1,   152064, 0x5d327ac0
+0,         42,         42,        1,   152064, 0x49b46cdf
+0,         43,         43,        1,   152064, 0x799eb970
+0,         44,         44,        1,   152064, 0x424b88cc
+0,         45,         45,        1,   152064, 0xfbcff8df
+0,         46,         46,        1,   152064, 0x70f7c722
+0,         47,         47,        1,   152064, 0x29a55d83
+0,         48,         48,        1,   152064, 0xff2430be
+0,         49,         49,        1,   152064, 0x02438701
diff --git a/tests/ref/fate/filter-overlay_yuv444 b/tests/ref/fate/filter-overlay_yuv444
new file mode 100644
index 0000000..01b92dc
--- /dev/null
+++ b/tests/ref/fate/filter-overlay_yuv444
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   405504, 0xbbfccc5d
+0,          1,          1,        1,   405504, 0xac9682d3
+0,          2,          2,        1,   405504, 0x6f7426c4
+0,          3,          3,        1,   405504, 0x43469a25
+0,          4,          4,        1,   405504, 0x75f7e902
+0,          5,          5,        1,   405504, 0xad19a433
+0,          6,          6,        1,   405504, 0xf11090f3
+0,          7,          7,        1,   405504, 0xe8ce9d18
+0,          8,          8,        1,   405504, 0xcf24926c
+0,          9,          9,        1,   405504, 0x740999d2
+0,         10,         10,        1,   405504, 0xb588dabd
+0,         11,         11,        1,   405504, 0x3e49d8d1
+0,         12,         12,        1,   405504, 0xe3d980ae
+0,         13,         13,        1,   405504, 0x70c9c2a3
+0,         14,         14,        1,   405504, 0x6b704efc
+0,         15,         15,        1,   405504, 0x43e92e97
+0,         16,         16,        1,   405504, 0x36c884fa
+0,         17,         17,        1,   405504, 0xaf19b6d7
+0,         18,         18,        1,   405504, 0x5478dbb2
+0,         19,         19,        1,   405504, 0xb09f552c
+0,         20,         20,        1,   405504, 0x0bb97177
+0,         21,         21,        1,   405504, 0xaf2b8660
+0,         22,         22,        1,   405504, 0xe0ef2941
+0,         23,         23,        1,   405504, 0x5d934bc5
+0,         24,         24,        1,   405504, 0x5fff55ec
+0,         25,         25,        1,   405504, 0xcdf4359f
+0,         26,         26,        1,   405504, 0x3a773cd9
+0,         27,         27,        1,   405504, 0x73991118
+0,         28,         28,        1,   405504, 0x7dc1088b
+0,         29,         29,        1,   405504, 0x878e06c8
+0,         30,         30,        1,   405504, 0xcfee8070
+0,         31,         31,        1,   405504, 0x563a6a8b
+0,         32,         32,        1,   405504, 0xb6af32d8
+0,         33,         33,        1,   405504, 0x7a0e3783
+0,         34,         34,        1,   405504, 0xcd3e3835
+0,         35,         35,        1,   405504, 0x0e7df06c
+0,         36,         36,        1,   405504, 0x61aaa4ff
+0,         37,         37,        1,   405504, 0x3c5998cc
+0,         38,         38,        1,   405504, 0x81b5c32a
+0,         39,         39,        1,   405504, 0xf8ca41ad
+0,         40,         40,        1,   405504, 0x109aa08e
+0,         41,         41,        1,   405504, 0xb9c6a26f
+0,         42,         42,        1,   405504, 0xd221a69f
+0,         43,         43,        1,   405504, 0x670bda84
+0,         44,         44,        1,   405504, 0xf9903d5b
+0,         45,         45,        1,   405504, 0xe19d1db4
+0,         46,         46,        1,   405504, 0xcefa1fea
+0,         47,         47,        1,   405504, 0x00b9fe31
+0,         48,         48,        1,   405504, 0x051a319f
+0,         49,         49,        1,   405504, 0x2d73bdd5
diff --git a/tests/ref/lavfi/pad b/tests/ref/fate/filter-pad
similarity index 100%
rename from tests/ref/lavfi/pad
rename to tests/ref/fate/filter-pad
diff --git a/tests/ref/lavfi/pixfmts_pixdesctest b/tests/ref/fate/filter-pixdesc
similarity index 85%
rename from tests/ref/lavfi/pixfmts_pixdesctest
rename to tests/ref/fate/filter-pixdesc
index 05d5e0f..56373fb 100644
--- a/tests/ref/lavfi/pixfmts_pixdesctest
+++ b/tests/ref/fate/filter-pixdesc
@@ -15,23 +15,23 @@
 bgr565le            ed027571692aecd522aa65a90cc7e09b
 bgr8                71ef789609c746c2e7e4be9dec29062c
 bgra                0364b074268682ea46168742a8239f7d
-gbrp                89d6e4b116e3bd542fa09a19a977ad16
-gbrp10be            5dc62e2d01fa7c19a57abe48246f2232
-gbrp10le            0cac205a304b59811ce30fcad49b3527
-gbrp12be            de1d2a6b1d189bce9b9a2cf322c31c24
-gbrp12le            e3267ef00bb48778df21a386416d2e14
-gbrp14be            7979d158b30c0b45db97aba2228d15fc
-gbrp14le            d32b6c73a820f9d03a779a996924893d
-gbrp9be             2478d1c27ae4ec94ec4b5e439128af0c
-gbrp9le             640240ca2663e48f0bacd8edb5242c7d
-gray                1e5e2b8548843a6898eedd9c974c422c
+gbrap               412a2449fdfaeb5ebdf5e4196cc7391a
+gbrp                4778f8cc2bdbcd65e272ea1761cdca6d
+gbrp10be            0be11fe4b2324054be6f949e81966691
+gbrp10le            173f89ae58fd4d01d6a365318e4da3b1
+gbrp12be            1f5231ed7e4589a3ec98fa79134bdc6a
+gbrp12le            cc4830a263fecadeea535c4938b5cee1
+gbrp14be            6f5143374536e1cf1595260e91c86b7b
+gbrp14le            937ff1dd9f498b39f9e882316e371fbf
+gbrp9be             c76ab5850c9bc72bbbf36caa6d1c5ac7
+gbrp9le             5ad363dc9570187ad3e3f2344fbb30cf
+gray                2ee2ea2340d0ecf2dfa6f90f87384799
 gray16be            389f4e5a8ab413b3af32767b59ed7f9e
 gray16le            a1f912941247e45b394b9cf4f0e81130
 monob               309b5785a36bd988d17e15d88f4ffad1
 monow               8809a02bc69b58d1114b09ca79ebffad
 nv12                75e90c54d858b993e99f4ee6d2a2a38f
 nv21                8831a3f411015d45fbc5dd191245ba9c
-pal8                13de2a1c3c80cb64d14e2bc4f6f461d0
 rgb0                5774780b3c532896300fa326fcde01a8
 rgb24               c71ba90f69f15c8275232bb3f62d0ced
 rgb444be            26eaec65d7efd2b0c9c13b47dfd9b241
@@ -45,7 +45,11 @@
 rgb565le            20757fafe4756e62d845b2ab4c0b8f93
 rgb8                e01614f5416dcc8ad365ad7a57afc9fb
 rgba                53796fa4c392a1b2659595b6a284f8c4
+rgba64be            c05fbb1ada1b48fb1eb192fc200af2b6
+rgba64le            1b826cc613666f545274e8a7799d69f1
 uyvy422             3f411f947e3ac8f842c88e717d68bd9a
+xyz12be             71f608adceed8e8997aa463203b1a648
+xyz12le             dc524e3726ba1df0d2f406db3a2c08aa
 yuv410p             7dcf3f4770c8b494290ceacd2c2ce6db
 yuv411p             9461b188dab6f8b90d9a27e353a89f58
 yuv420p             61fffd2d8425759a33ae07e718d0242d
@@ -103,6 +107,7 @@
 yuva444p16le        a9272ac197e4a4195662ce90f533976c
 yuva444p9be         f72f646ef07cdab613420585aba041ac
 yuva444p9le         6d431b0a27bf4f86ea44ef5f14247a01
+yuvj411p            037accc8e48ac9928a580cddf444f129
 yuvj420p            73661456012f20cda81207b14bb0c0a5
 yuvj422p            aa97862b57f47c5a6506156e9aaf129a
 yuvj440p            ff8b9884a49d546b035f5d2ac1e673df
diff --git a/tests/ref/lavfi/pixfmts_copy b/tests/ref/fate/filter-pixfmts-copy
similarity index 85%
rename from tests/ref/lavfi/pixfmts_copy
rename to tests/ref/fate/filter-pixfmts-copy
index 68ec828..edb246b 100644
--- a/tests/ref/lavfi/pixfmts_copy
+++ b/tests/ref/fate/filter-pixfmts-copy
@@ -15,16 +15,17 @@
 bgr565le            ed027571692aecd522aa65a90cc7e09b
 bgr8                71ef789609c746c2e7e4be9dec29062c
 bgra                0364b074268682ea46168742a8239f7d
-gbrp                89d6e4b116e3bd542fa09a19a977ad16
-gbrp10be            5dc62e2d01fa7c19a57abe48246f2232
-gbrp10le            0cac205a304b59811ce30fcad49b3527
-gbrp12be            de1d2a6b1d189bce9b9a2cf322c31c24
-gbrp12le            e3267ef00bb48778df21a386416d2e14
-gbrp14be            7979d158b30c0b45db97aba2228d15fc
-gbrp14le            d32b6c73a820f9d03a779a996924893d
-gbrp9be             2478d1c27ae4ec94ec4b5e439128af0c
-gbrp9le             640240ca2663e48f0bacd8edb5242c7d
-gray                1e5e2b8548843a6898eedd9c974c422c
+gbrap               412a2449fdfaeb5ebdf5e4196cc7391a
+gbrp                4778f8cc2bdbcd65e272ea1761cdca6d
+gbrp10be            0be11fe4b2324054be6f949e81966691
+gbrp10le            173f89ae58fd4d01d6a365318e4da3b1
+gbrp12be            1f5231ed7e4589a3ec98fa79134bdc6a
+gbrp12le            cc4830a263fecadeea535c4938b5cee1
+gbrp14be            6f5143374536e1cf1595260e91c86b7b
+gbrp14le            937ff1dd9f498b39f9e882316e371fbf
+gbrp9be             c76ab5850c9bc72bbbf36caa6d1c5ac7
+gbrp9le             5ad363dc9570187ad3e3f2344fbb30cf
+gray                2ee2ea2340d0ecf2dfa6f90f87384799
 gray16be            389f4e5a8ab413b3af32767b59ed7f9e
 gray16le            a1f912941247e45b394b9cf4f0e81130
 monob               309b5785a36bd988d17e15d88f4ffad1
@@ -45,7 +46,11 @@
 rgb565le            20757fafe4756e62d845b2ab4c0b8f93
 rgb8                e01614f5416dcc8ad365ad7a57afc9fb
 rgba                53796fa4c392a1b2659595b6a284f8c4
+rgba64be            c05fbb1ada1b48fb1eb192fc200af2b6
+rgba64le            1b826cc613666f545274e8a7799d69f1
 uyvy422             3f411f947e3ac8f842c88e717d68bd9a
+xyz12be             b91ff224254afceb4a8f803d56eb52a1
+xyz12le             dc524e3726ba1df0d2f406db3a2c08aa
 yuv410p             7dcf3f4770c8b494290ceacd2c2ce6db
 yuv411p             9461b188dab6f8b90d9a27e353a89f58
 yuv420p             61fffd2d8425759a33ae07e718d0242d
@@ -103,6 +108,7 @@
 yuva444p16le        a9272ac197e4a4195662ce90f533976c
 yuva444p9be         f72f646ef07cdab613420585aba041ac
 yuva444p9le         6d431b0a27bf4f86ea44ef5f14247a01
+yuvj411p            037accc8e48ac9928a580cddf444f129
 yuvj420p            73661456012f20cda81207b14bb0c0a5
 yuvj422p            aa97862b57f47c5a6506156e9aaf129a
 yuvj440p            ff8b9884a49d546b035f5d2ac1e673df
diff --git a/tests/ref/fate/filter-pixfmts-crop b/tests/ref/fate/filter-pixfmts-crop
new file mode 100644
index 0000000..9651fb9
--- /dev/null
+++ b/tests/ref/fate/filter-pixfmts-crop
@@ -0,0 +1,112 @@
+0bgr                ba367adf7943b91cf7f98aefe3f7f9ea
+0rgb                c83c555fe20def126bf1b8967442aa97
+abgr                ef31d9057f6e65a7c3308a1b1daa98fa
+argb                5e5e261c4870e0de05d56ff640b9550a
+bgr0                c8729ca08c5d29ecd5ca21c0ea8c54ce
+bgr24               44bec15f35513de7e957b3d59b53cb7b
+bgr444be            d56f795721020fc7a598e3b07f3fba1e
+bgr444le            53224fc7360806c19fbd873e13fd0c68
+bgr48be             0b5ebce3c48eb8614d79e204b5268603
+bgr48le             c4ab61a8b9d502132730c6abb6ffd84c
+bgr4_byte           cab930dbe1fe77d58b41837ecdcb8460
+bgr555be            67162782fdb86813f446d8e1c21c73e9
+bgr555le            85913cfa8dab465f7dcfcfe7f9001a01
+bgr565be            ee9a1debb896d41c53a026f9e6ce006b
+bgr565le            ab7b6055bc3b6b7edc9a5e4de43ec90d
+bgr8                f85ff16e21d922ad6d32648ef3acfbfb
+bgra                9f2e37d73ad3b759fc9d6b12ee668c38
+gbrap               32c0326859b41ae1fee015648162c6a0
+gbrp                0f59d3a61d391c3dea6f6e5861e9c2f7
+gbrp10be            bc12b34950af11e3f1016acbe2d5dec5
+gbrp10le            0ff56c84154050f992fefc357449da9a
+gbrp12be            b2154eaa6344a37ace82e42b757585e2
+gbrp12le            77956c63e99444fc61c306643acba403
+gbrp14be            3ab29f18610ce10ce2e5c99b1af78415
+gbrp14le            d1465f7280f35aa0a70709e5a7bee1a4
+gbrp9be             f17b7ba66ba35ed0fcbbb5c32c7e0f56
+gbrp9le             fc11219debfbe8dd8c3d6f0ef92c4d50
+gray                6d34024704f862c75db3ba6989a4a039
+gray16be            02ac848ad4e28c06938599563ba81ff7
+gray16le            672aebfeb8a0f4067b3c6064340056e4
+nv12                923a313a7013fb0e87608155ef6aa9a4
+nv21                21e6b9273bb74203beabeb9edb9cf95c
+pal8                e1fd50b8a8a67fb5abd8b44abc778bbb
+rgb0                8bd7785a8421b3f60e5eae2d2968a546
+rgb24               d044123f1fe50f656f2101dd3f091ead
+rgb444be            6a076e84d0cdbae2ba29412a28587e81
+rgb444le            f82d127ca2a40ec822171b79a11df65d
+rgb48be             ef5507f88948b54218911d12e1dbef36
+rgb48le             6d045d5990d6ada64a112e3b581a7b38
+rgb4_byte           0f0f9ee31c65dc60da49bf98a1b06dcf
+rgb555be            48fa619bfd04f6dee05416b02605c031
+rgb555le            292cff1f824e49076bad50a07ab1c749
+rgb565be            0dd6f6a5a8713bd1c3d9826bb7a88eab
+rgb565le            6afd85faa8c6f0f330969539178eb9a2
+rgb8                87cf541b110e35a6f9a983e9cde85e15
+rgba                7abe1af7b97f5b9a7aa5ad3e4bf32f76
+rgba64be            2eed28b61af25790c02cc658e5f86b9b
+rgba64le            de8bc34c6d573488d87e87ce8c7ad07f
+xyz12be             7ea4ce13143195dfe1ed340bc9e86b2f
+xyz12le             e4e86ef100e07cda561a22811f242e5d
+yuv410p             126e0da1da4fd89be28087b8367bbb36
+yuv411p             b94f0af107fc4796aca70c0a36d374c5
+yuv420p             74c6b331bd30f005e6c75a192423ad90
+yuv420p10be         1321772e0586e9b89386e792ed9f5277
+yuv420p10le         726b637741fe28c26d57a1dd814ef14b
+yuv420p12be         5c3bf63a61fe41acb958614d4a7c8923
+yuv420p12le         073c6fa32443c1df26243b598fb5a34e
+yuv420p14be         9460b8507137516ae437d00380921cb9
+yuv420p14le         fd162a79436a9585ed44814fa3dc02fd
+yuv420p16be         2d3c84ebff77479e8c5b6e3e59ec4e45
+yuv420p16le         e2c906f2751609bf8cbcbeb2f629319a
+yuv420p9be          d40531645b7ddecf4778f652549c121c
+yuv420p9le          fbffd583dd189a546cf4df144a735f66
+yuv422p             124bc8d668072de1bb3b894cc4bae859
+yuv422p10be         3d6195bb0c4cc9498ef42227839db9d5
+yuv422p10le         d19bdc9ba4e76b38c076ac93e99e6ef4
+yuv422p12be         f2c2f23269fa969e3e3f0ba5e065bc98
+yuv422p12le         6d07ba50dcdaf43bd8b73233ed11e4d9
+yuv422p14be         3115c4c01f6a8b9930b32ec8a12f52ac
+yuv422p14le         00ba7302e4e4db2c70ba0712f2fc8574
+yuv422p16be         3ec47e2709107fcc388b5e0abebf7eaf
+yuv422p16le         a4183a62917bf8568fe11ff446dd18f9
+yuv422p9be          05c2d9a95f329133a9fa03c46eaaf0cd
+yuv422p9le          ea559e7009aef6c36de0daa8061740f7
+yuv440p             15c81c685fa5b9db95150caff14ff83f
+yuv444p             12b752f78af72666627cea2d0c274cdb
+yuv444p10be         6a5d1574657bdadd435c59227b6772d0
+yuv444p10le         cc6e8453e6ffeeca98055722f9833fb0
+yuv444p12be         39086bcf3ad336391c2a378b32d9cd1b
+yuv444p12le         ccc98011edecb7c643e6250c34ae9b3d
+yuv444p14be         b05b5999610b1369d0873212543697f8
+yuv444p14le         a4ae35bb8a377d593635126671d1af30
+yuv444p16be         f2bf0e22a1d184e37eaa199a76cf22ba
+yuv444p16le         c11b151dced5c8854d385373fa4dcc8f
+yuv444p9be          0b4e2a096a7ada2d6fab3f7d5160326c
+yuv444p9le          04b00046c0409849f89bca191298257b
+yuva420p            920c5d1b965eeb72e3a0e343696face3
+yuva420p10be        c2d580dee6da641c176c6357e74d14bd
+yuva420p10le        51781f8328a0ad69466e729cfc31bbc6
+yuva420p16be        1855e36526638e5d364b1d29bd49141b
+yuva420p16le        2476b93493a30cce3c8fe07ea3ce3761
+yuva420p9be         7c9d877f0c06529d60beb5fcbe5a6f47
+yuva420p9le         392387fc9b414576e003abed4f8bf389
+yuva422p            1bc930cf64afc7cc99362fee5d8e08d8
+yuva422p10be        3382c54dd78aec916210edef29aa268f
+yuva422p10le        93862b68e0dc6ea812fa36fbb1641b48
+yuva422p16be        a44509ccee5dd71a67f8138a8dca7620
+yuva422p16le        4a0b4f7cb3fda825acd6eeef7efa4aae
+yuva422p9be         f3d9d423699ccf369b50ea7dfefb16da
+yuva422p9le         f65115fd89e0cbabc975a15e764b4d30
+yuva444p            1cf9c2dddb0e2f082eca981b2226bdb1
+yuva444p10be        e60f55491f67bb69962e4c2a29868da2
+yuva444p10le        6a7a95f6af4ef3ce47e2b20bc2453746
+yuva444p16be        0caa51254006811d244e150fa34f2e90
+yuva444p16le        5f073f7771254bace1d07279c56c9613
+yuva444p9be         3d64778ebee876c77e77066fd57336b9
+yuva444p9le         85a80221022b5de7cb3233845392d8c6
+yuvj411p            55f4d5f22146e7771ec4e5729a438f48
+yuvj420p            f9183e49f42bae31d7d85b92161fa82f
+yuvj422p            aabeed60a6e1b2cf88665ac627bf531f
+yuvj440p            5ae4f404b42f3167f978473d9a3737fc
+yuvj444p            6728997f65b879fd5a3175cb449a8f0c
diff --git a/tests/ref/lavfi/field b/tests/ref/fate/filter-pixfmts-field
similarity index 85%
rename from tests/ref/lavfi/field
rename to tests/ref/fate/filter-pixfmts-field
index 68a4643..d4822b1 100644
--- a/tests/ref/lavfi/field
+++ b/tests/ref/fate/filter-pixfmts-field
@@ -15,16 +15,17 @@
 bgr565le            6dd85cd5e19266c53a54cbcf06d396a7
 bgr8                9669f6974f0fc1c0afa1c7d4df093c0b
 bgra                f7cabae31dd7465dab2203f45db646f8
-gbrp                55eab469e3e02ccc5a358565d9b1eaa7
-gbrp10be            38753e9ac21e13d76d1a83bd7272c026
-gbrp10le            a65ff11ee79ae698550218549288e6cc
-gbrp12be            5f49bf3190b98221dab95056ab46bd96
-gbrp12le            3d1cd386205bc690407c81a007a79170
-gbrp14be            60e2efec11a36e7cb0db95e01603d9eb
-gbrp14le            fdcdecdd2c8dc13561a3788ce0487c85
-gbrp9be             86380bf8eaeee32ec40d776f699394e5
-gbrp9le             1286d4558d9bc7c3d68261f4b43e3ba9
-gray                66a09b53f7d3f79dcb6096f3ec3740c5
+gbrap               fdb15f25cd6db3d19a7df727e0f4de3a
+gbrp                0867ccbcdf50a02871ad7788e3e0931e
+gbrp10be            c452475d38b13a4707634eff74001215
+gbrp10le            009a9f7ba2ac9a8c67269bf3a76581c5
+gbrp12be            e1e01fbefb6ab400a7eb460aa9ad6acd
+gbrp12le            cf2fd4db9e69d82acb0aedfc094ebc9a
+gbrp14be            52ce4bffdd04a2f51ab2d3ae4e78dfa5
+gbrp14le            775b50257b848007c4ef3441ba772db1
+gbrp9be             c293422f1395bfddc788282eef139ed6
+gbrp9le             0d2bb77c25d84611ec6222f3dffe11c0
+gray                42a0ad7625a0481183e375e38679d8d3
 gray16be            a447af6482b922c9997ac02e5d3535f1
 gray16le            c1dd0db327295898ff282d07f48c105d
 monob               1b7fb7e69a913a0a1c0dffc54e5899ea
@@ -45,7 +46,11 @@
 rgb565le            53bbd558fb0dcd82f1fad83ea855c3ad
 rgb8                67bfdd4fa88b1ab9be876f42dfc75683
 rgba                d0ebdf1495bc6b7e9d3bfbe2813a9d16
+rgba64be            53363baf266592e0ac02b3f8242ec4fb
+rgba64le            a630eaa38545b2be741f000ab58451e5
 uyvy422             a6a52504a16f09b8f2ec2405bc8190b5
+xyz12be             33d0b7ef124a9e94d2d13a2cad1dfc00
+xyz12le             bab6403abf58e69575900802ffef8f38
 yuv410p             3feb55b1e2a385b488c82e808a12587b
 yuv411p             ab3dd8e6cf1452afe2d2e976e4726370
 yuv420p             52e26ad198368e2326bef97cdfa6a2bb
@@ -103,6 +108,7 @@
 yuva444p16le        41f1a82eb686d7191bdb00206f723247
 yuva444p9be         413d01385a8b008031b2ab3ef0b9eff4
 yuva444p9le         33ede0bd20bfd85489d266ac81d035d6
+yuvj411p            dbcc5e7ef64335ad30b8b9717bfa63d9
 yuvj420p            762dc6a157d0bee72da3e3d852668aef
 yuvj422p            8cec955c1c62b00b6798361ef82962b7
 yuvj440p            7b469444994d8b52766ee461bcb795ea
diff --git a/tests/ref/lavfi/pixfmts_hflip b/tests/ref/fate/filter-pixfmts-hflip
similarity index 85%
rename from tests/ref/lavfi/pixfmts_hflip
rename to tests/ref/fate/filter-pixfmts-hflip
index ee5c2d3..d672346 100644
--- a/tests/ref/lavfi/pixfmts_hflip
+++ b/tests/ref/fate/filter-pixfmts-hflip
@@ -15,16 +15,17 @@
 bgr565le            4b4c708d4ad222f41734dce68e9d48b6
 bgr8                ad1db7a17cdfab2ede6f22c2415a3fbf
 bgra                85fa06ad9fd156c3179a647a2e741b60
-gbrp                95fde5b6a767cf8d2679a4a6d18fdbe7
-gbrp10be            5ddc834dbf2198f6b1af36c66b185e2c
-gbrp10le            04814cbb805b66e8e085c7db4a548deb
-gbrp12be            8184b00342421c366764c091e9174260
-gbrp12le            1519cba0b6ddd7ee3df7c97670f1cbd5
-gbrp14be            10872df155aab67a13b98ad162908896
-gbrp14le            5fd363517fca5ef0ac725d1c047f2e75
-gbrp9be             187c83736d4fe1d7c8491609debc8f86
-gbrp9le             5476b0787da2d928d98d4cda60537fb5
-gray                35b50e78d5d27255f43e642a404dd708
+gbrap               5fbf0a36ee9486161a862a4b2d6f8242
+gbrp                8b00ca96932c9bce5bca01ee621e0957
+gbrp10be            df96591083deab8382c1907ea1e99e9e
+gbrp10le            98769f5176bd3872f494aea8039d8475
+gbrp12be            9a0ee0322bbd7a25ffd85b0070c5a563
+gbrp12le            2f3899d712ee3e1510b0f442ceaeb505
+gbrp14be            966af80018ebf6b0576004362c1ba395
+gbrp14le            297e71281660b905711330a86eca8a71
+gbrp9be             8268b9a1e9f4d6a42e57db9c81d82fa5
+gbrp9le             b3a09bba825e16e6d160328706a9f62f
+gray                aaa9c2fe3c2a2a43a4b35226ea689b3c
 gray16be            d206a080739d89cb7dc0009ad4082ed4
 gray16le            7ebcfd9401ba85e584230de8fc02986d
 nv12                719adbc47fa74e92f83150921917483f
@@ -43,6 +44,10 @@
 rgb565le            b0a2b4817775289cfc415bb951f9ae0c
 rgb8                22fdbd14ce296c1afa9bb4a6ea09b3fe
 rgba                a37789c4df73c3bd8648ad1fe9d3f991
+rgba64be            286067334e4bca33fba7ebb1706890a2
+rgba64le            2a8b3dd5045df299259636d8e6b62589
+xyz12be             079dac329f0d93df7a7e71b260f13dd9
+xyz12le             31c4f953548326b27920c5939bcf2cce
 yuv410p             a1280c2b9b562dba3c2d35a1e5fc4b23
 yuv411p             6bf10756ac5c7841db63a97106ff911b
 yuv420p             45f4a06481f2cd8e28fb29c7c151e110
@@ -100,6 +105,7 @@
 yuva444p16le        1e144cc9ea16429c1655c67e2f12f5c9
 yuva444p9be         e37fa0743bf720fbe31605714d7f7ad6
 yuva444p9le         9bd4083c1384a55e91f02630161dc4c3
+yuvj411p            042671398bc17a5f52aa9d791b361c5c
 yuvj420p            86370b945c5d19d809ee92386d476a53
 yuvj422p            d3bda08bd4b92a256a8ec8432c4767d1
 yuvj440p            dbae7083c82f20a38fc55e6f8bc374bc
diff --git a/tests/ref/lavfi/histeq b/tests/ref/fate/filter-pixfmts-histeq
similarity index 100%
rename from tests/ref/lavfi/histeq
rename to tests/ref/fate/filter-pixfmts-histeq
diff --git a/tests/ref/lavfi/il b/tests/ref/fate/filter-pixfmts-il
similarity index 85%
rename from tests/ref/lavfi/il
rename to tests/ref/fate/filter-pixfmts-il
index d4a8142..d9a7a86 100644
--- a/tests/ref/lavfi/il
+++ b/tests/ref/fate/filter-pixfmts-il
@@ -15,16 +15,17 @@
 bgr565le            485b2b6f589a936d6fb12d0033809dca
 bgr8                d7fae34b87a67556c273585d9140ff96
 bgra                7b4abc57f0ee99a0226e9bfd5d25cf9e
-gbrp                b85cfeb0e34559ffb4b2e4f1209a3712
-gbrp10be            5487219fee31607d6b19aa0d302fb42f
-gbrp10le            7975e53a9e03a8acfa877334ae5e9d1d
-gbrp12be            34bd529e3b085e813e7471e5a5951423
-gbrp12le            14716b36ee4043158f24b49b6a723213
-gbrp14be            426ac36ea666041afd39f842dbdd683c
-gbrp14le            e0823115de7b2e44c25e1c59dd204ac1
-gbrp9be             0db6ce2fe6a7fc2d5c7d6d4f0decd112
-gbrp9le             00a1a9fe310753a28c0512568a317c67
-gray                4dd4ea934fdbf689fdcf665856c402ff
+gbrap               583131faa19f062f6523321da52066de
+gbrp                a2db88b8efce6681a3c858be2c229a33
+gbrp10be            714a32d10c27395406f4e4afb20a2216
+gbrp10le            e44229ebb1cf96d3ce1960d092e0dfc2
+gbrp12be            09fc9ba31c8c0c8c9cd89767fda92800
+gbrp12le            2c778bcef911d43795e3f6c3b97be09f
+gbrp14be            35d6dc9135fe910dc26b64f03de2d42b
+gbrp14le            778c97b5ed06b9f1a230840a15771bac
+gbrp9be             b9fc10ab1ddad0e7945d6b047725d078
+gbrp9le             ef3d6bc8069b95cae31100908a7fa967
+gray                2cadbaed81ee12181bda9f4aa87ddbc0
 gray16be            cd9c1367dabd2f1858ae4f31693e622f
 gray16le            4ef774c282280d7ed4780690df6e5cb4
 monob               07cffe7f5f25f39c3aa38866303791c6
@@ -44,7 +45,11 @@
 rgb565le            a97549f25e63dd0dd404db41bbe05c07
 rgb8                a35d3c3b9b87261c7417076a8b18fdb8
 rgba                8ca9c8db589615ebbaa964be4ce62d08
+rgba64be            576dfc2fd1937f9e594c4004fafd83f2
+rgba64le            7938eccc1f05f13710ec351767b47a36
 uyvy422             8be40aded4b407ff66305911ba5ce2ce
+xyz12be             ba8a8152ca6e8b338e1dc5ace0a729b6
+xyz12le             1f20849dcf44539ce351346c73bdff1a
 yuv410p             92112d85ba4f74cbd3044945c0f33402
 yuv411p             b6b22000e5275c92baf5afc417c32a70
 yuv420p             fca7fbbff753612a718ee13e1dfe2af2
@@ -102,6 +107,7 @@
 yuva444p16le        7b8e5963f19e6fe7fd409b34af014489
 yuva444p9be         6d2905a9e61ce4ff5b3d7b972a7333eb
 yuva444p9le         e2ffdb1d867a1b78f3bd38d600b17193
+yuvj411p            840bb5fc87ba0d3101d5c25b3f480923
 yuvj420p            d1a8d9cf6b4035ac5d6439ab2754b09d
 yuvj422p            d20df6138cdf62d7f3b93eb1277827d6
 yuvj440p            17a24a86f279febaebb66d65509088e8
diff --git a/tests/ref/lavfi/kerndeint b/tests/ref/fate/filter-pixfmts-kerndeint
similarity index 100%
rename from tests/ref/lavfi/kerndeint
rename to tests/ref/fate/filter-pixfmts-kerndeint
diff --git a/tests/ref/fate/filter-pixfmts-lut b/tests/ref/fate/filter-pixfmts-lut
new file mode 100644
index 0000000..387464be2
--- /dev/null
+++ b/tests/ref/fate/filter-pixfmts-lut
@@ -0,0 +1,19 @@
+abgr                c1e31c876e806cbfa8ef58441d1dee6f
+argb                1239bf03999d8767c2e03863e22955a8
+bgr24               0ed1377b8c34489e716650edb593494d
+bgra                87a4b656459a5f8ee2a0e5a994c61439
+rgb24               a1466d9fc7d1726dda3bfe80dfcc1b44
+rgba                980b5fb376926ca9c5a0a5b82a0ab162
+yuv410p             ec9e2e31c1c702676362f5445efd4354
+yuv411p             9caecd7961e1011db685cc4d60220fd1
+yuv420p             8796295e7d132dd0f616fed149633ad9
+yuv422p             2a3f79670546a0e582ab00cb83bb3b79
+yuv440p             d7e3ffabdb376f49a02cd641907df726
+yuv444p             13ef53a3dd3f77516e2c5237bf43b0c5
+yuva420p            34c07d6c05233f333a933a50a3dbfa61
+yuva422p            352406873ef88f865af0f27760f37663
+yuva444p            8efb7b3d809946fdf01f3c426a6cdf83
+yuvj420p            5a8771944ba995a831ca272526f440e5
+yuvj422p            ab379523c4e79ca1e3c72adc46b918ff
+yuvj440p            8e82847ed2f7a3a22ebdb2372e941fc4
+yuvj444p            4a98641643a7a51292c61c71e221ddc4
diff --git a/tests/ref/lavfi/pixfmts_copy b/tests/ref/fate/filter-pixfmts-null
similarity index 85%
copy from tests/ref/lavfi/pixfmts_copy
copy to tests/ref/fate/filter-pixfmts-null
index 68ec828..edb246b 100644
--- a/tests/ref/lavfi/pixfmts_copy
+++ b/tests/ref/fate/filter-pixfmts-null
@@ -15,16 +15,17 @@
 bgr565le            ed027571692aecd522aa65a90cc7e09b
 bgr8                71ef789609c746c2e7e4be9dec29062c
 bgra                0364b074268682ea46168742a8239f7d
-gbrp                89d6e4b116e3bd542fa09a19a977ad16
-gbrp10be            5dc62e2d01fa7c19a57abe48246f2232
-gbrp10le            0cac205a304b59811ce30fcad49b3527
-gbrp12be            de1d2a6b1d189bce9b9a2cf322c31c24
-gbrp12le            e3267ef00bb48778df21a386416d2e14
-gbrp14be            7979d158b30c0b45db97aba2228d15fc
-gbrp14le            d32b6c73a820f9d03a779a996924893d
-gbrp9be             2478d1c27ae4ec94ec4b5e439128af0c
-gbrp9le             640240ca2663e48f0bacd8edb5242c7d
-gray                1e5e2b8548843a6898eedd9c974c422c
+gbrap               412a2449fdfaeb5ebdf5e4196cc7391a
+gbrp                4778f8cc2bdbcd65e272ea1761cdca6d
+gbrp10be            0be11fe4b2324054be6f949e81966691
+gbrp10le            173f89ae58fd4d01d6a365318e4da3b1
+gbrp12be            1f5231ed7e4589a3ec98fa79134bdc6a
+gbrp12le            cc4830a263fecadeea535c4938b5cee1
+gbrp14be            6f5143374536e1cf1595260e91c86b7b
+gbrp14le            937ff1dd9f498b39f9e882316e371fbf
+gbrp9be             c76ab5850c9bc72bbbf36caa6d1c5ac7
+gbrp9le             5ad363dc9570187ad3e3f2344fbb30cf
+gray                2ee2ea2340d0ecf2dfa6f90f87384799
 gray16be            389f4e5a8ab413b3af32767b59ed7f9e
 gray16le            a1f912941247e45b394b9cf4f0e81130
 monob               309b5785a36bd988d17e15d88f4ffad1
@@ -45,7 +46,11 @@
 rgb565le            20757fafe4756e62d845b2ab4c0b8f93
 rgb8                e01614f5416dcc8ad365ad7a57afc9fb
 rgba                53796fa4c392a1b2659595b6a284f8c4
+rgba64be            c05fbb1ada1b48fb1eb192fc200af2b6
+rgba64le            1b826cc613666f545274e8a7799d69f1
 uyvy422             3f411f947e3ac8f842c88e717d68bd9a
+xyz12be             b91ff224254afceb4a8f803d56eb52a1
+xyz12le             dc524e3726ba1df0d2f406db3a2c08aa
 yuv410p             7dcf3f4770c8b494290ceacd2c2ce6db
 yuv411p             9461b188dab6f8b90d9a27e353a89f58
 yuv420p             61fffd2d8425759a33ae07e718d0242d
@@ -103,6 +108,7 @@
 yuva444p16le        a9272ac197e4a4195662ce90f533976c
 yuva444p9be         f72f646ef07cdab613420585aba041ac
 yuva444p9le         6d431b0a27bf4f86ea44ef5f14247a01
+yuvj411p            037accc8e48ac9928a580cddf444f129
 yuvj420p            73661456012f20cda81207b14bb0c0a5
 yuvj422p            aa97862b57f47c5a6506156e9aaf129a
 yuvj440p            ff8b9884a49d546b035f5d2ac1e673df
diff --git a/tests/ref/lavfi/pixfmts_pad b/tests/ref/fate/filter-pixfmts-pad
similarity index 84%
rename from tests/ref/lavfi/pixfmts_pad
rename to tests/ref/fate/filter-pixfmts-pad
index 192ff6a..82f30b6 100644
--- a/tests/ref/lavfi/pixfmts_pad
+++ b/tests/ref/fate/filter-pixfmts-pad
@@ -5,8 +5,9 @@
 bgr0                c55368036cccbb0af471d6bd82abe02a
 bgr24               67f9fd70dc6d9896b7122976b33932b4
 bgra                c8dd017b5a3b55e8b9d0ac1cdcf327bd
-gbrp                74f83deee9866bbdce3f91fa2aeddaaa
-gray                b1abadae3718522aa57a7972da8cbe17
+gbrap               8551b62534034c8aaebaa7d9fdefdfe9
+gbrp                9257834cbecf3842c2a6a820601a7504
+gray                ca280f6888a9b66688b5f8ea68fe454a
 rgb0                b1977b45634c4db58a183a07feb2acff
 rgb24               e73de9dc0fdd78f4853c168603cc7aba
 rgba                5a36df3c5ba623b589728a5a442e98e2
@@ -19,6 +20,7 @@
 yuva420p            b5bdefbb0c5b302b6d18ee4df7c1d7c7
 yuva422p            8b56b36d9eb3c382d2a5a695107e759d
 yuva444p            389cf95e98bf24684a42d5d67b913e16
+yuvj411p            5f10066e6a85d4785064ccdbb7259775
 yuvj420p            d182ac937d312e4894c1bc548883bf1c
 yuvj422p            26ac91b5daf6f2f1f3c22be489e994a3
 yuvj440p            63e2b94f81e0a6f2868055a4c8258b63
diff --git a/tests/ref/fate/filter-pixfmts-rotate b/tests/ref/fate/filter-pixfmts-rotate
new file mode 100644
index 0000000..0438aef
--- /dev/null
+++ b/tests/ref/fate/filter-pixfmts-rotate
@@ -0,0 +1,20 @@
+0bgr                1040a5c4645582fc271f7be40ea5aaf7
+0rgb                7f21fcf8fd658de854b75dd8c47b0b00
+abgr                24f441d2e6e67cae2d3451aa1dad23a7
+argb                993002f41f621d04cd76278e466c03eb
+bgr0                efe11efe2840fa84ee95cdb913463bc1
+bgr24               d0f449e8b38e07c947bd808f441a8ace
+bgra                54cebf01881cb63ec3727f7cc23b0a6b
+gbrap               6d69c0cd0cba6300065f8d990e35b081
+gbrp                db3b6345d2a5c0fb524f93486d97193e
+gray                5a896c38449a0fb08129a7394952eb31
+rgb0                c29f92ff5224044c7272c763fa5321e6
+rgb24               739f0eb47e76ce5c87354d5631ac2d5b
+rgba                f25570a798f24e8174729d978872c272
+yuv410p             22e673170464119cafb1a973c5a8080c
+yuv420p             afed4567a1b2d54ca9bc87bbdfff9a34
+yuv444p             df57aba68928092b54f6b75ab01e3110
+yuva420p            ad9bdb4f21855550a6f94e2d96588097
+yuva444p            b6a345f46ef75814033f733ccb4da42e
+yuvj420p            ccc0724c2ff91daa3848db1f4d91d010
+yuvj444p            9165b6e7c647c93cd24011d931890edb
diff --git a/tests/ref/lavfi/pixfmts_scale b/tests/ref/fate/filter-pixfmts-scale
similarity index 85%
rename from tests/ref/lavfi/pixfmts_scale
rename to tests/ref/fate/filter-pixfmts-scale
index 9bc3ced..a2eb723 100644
--- a/tests/ref/lavfi/pixfmts_scale
+++ b/tests/ref/fate/filter-pixfmts-scale
@@ -15,16 +15,17 @@
 bgr565le            f524e9f16bdd68b247dbcb621e543fc0
 bgr8                68a3a395043dc57335ad1f8e891229c5
 bgra                3eaf5489b8aa13a3388aad3751b597bf
-gbrp                7b83ae32c1f76bd634e50f4797a74e92
-gbrp10be            77dae432c42fad019c286753b0e4b0a8
-gbrp10le            7d3e7341423b1206e8a6a3a02b48b5d7
-gbrp12be            2c237c413e765024eb3f73d8c5e03df8
-gbrp12le            9a0c9eda1f16d640663c729d4bb88024
-gbrp14be            2b4f1928a5ef53d0a216b3b10fa11ca0
-gbrp14le            47100ec39fad45579de1dff56fe17117
-gbrp9be             c345137de0aa4b0536a00009e8e11267
-gbrp9le             b798662b2ba4cdf21ad6a6d4c1fe1b72
-gray                045c35e6cc7d41460f2b96b3e254deab
+gbrap               76ddf2bedea40c8743f4117b786d4773
+gbrp                e2704defddf1cb8d75f0c80fec6491d3
+gbrp10be            7dce0805f7ead7d480bd83323d76bf9c
+gbrp10le            24b220d50ffcb3fdffe11ef63f0ea758
+gbrp12be            49ae16b634cd12b108c0ac153f053549
+gbrp12le            889da16199f9cf1449d93cc0ca8c5a15
+gbrp14be            e63375705d6915035c7bce0faa4934e5
+gbrp14le            eb6cb4555edb175d807fe1b5382d2fc7
+gbrp9be             2c9adb80abc16546cac69b4872aaf557
+gbrp9le             fcfa1684553e3e185179462bca347649
+gray                c45dcee08887f43dc463f79d7ecd7d68
 gray16be            70064f9acdc5e3935ccda67e765bf2fb
 gray16le            578241fb43029e5ae841a3c94d940dce
 monob               91ec2a25b13f6ca34d42da778b217de0
@@ -45,7 +46,11 @@
 rgb565le            301a4d41f0db3aaed341d812ed0d7927
 rgb8                8e5786e83099bc89d2e38a76e6dfcc52
 rgba                de6a65b8c01bdad84e575202ca8b66a0
+rgba64be            5ce6f591ac8be4edcf5c3350d2d2d3f5
+rgba64le            12baab5162019de2053db39a3bfca868
 uyvy422             479105bc4c7fbb4a33ca8745aa8c2de8
+xyz12be             6769a0b3b3b6d7a674542c8cd3e3644e
+xyz12le             b4f967df71db5c38c222f9236c341031
 yuv410p             d0daa93f5cee83360e219e39563ab6da
 yuv411p             e5c8f3ca024a88dd07e0a92db3e2133d
 yuv420p             485d9af8608f926ffffbf42230b4150d
@@ -103,6 +108,7 @@
 yuva444p16le        c017c229aacb832a12c2297fb080a7a0
 yuva444p9be         8bfb5decfc8b71478b090a5b48c316c3
 yuva444p9le         2c7bfb90f7db9faab6862537801e1143
+yuvj411p            4e37fb8600e001c387bc67cd8cf8ce33
 yuvj420p            31386dce60a2dcc493da5d0ed9d880df
 yuvj422p            492452e50a3fe66724840cad29be4098
 yuvj440p            7632893e81d3f4f3ace3755f97479897
diff --git a/tests/ref/lavfi/pixfmts_super2xsai b/tests/ref/fate/filter-pixfmts-super2xsai
similarity index 100%
rename from tests/ref/lavfi/pixfmts_super2xsai
rename to tests/ref/fate/filter-pixfmts-super2xsai
diff --git a/tests/ref/fate/filter-pixfmts-swapuv b/tests/ref/fate/filter-pixfmts-swapuv
new file mode 100644
index 0000000..7bc3e3d
--- /dev/null
+++ b/tests/ref/fate/filter-pixfmts-swapuv
@@ -0,0 +1,62 @@
+yuv410p             5b295ab25ea56129be1a901d19b14f94
+yuv411p             d764e5278d2745f497a099468ce08f6d
+yuv420p             7c44249ab61c7974edd269966884a357
+yuv420p10be         ffe06addb7ffe7742ff885bffccda9d9
+yuv420p10le         285d971c468cad73a4d9669939ee942d
+yuv420p12be         2f7e4da722d45a757c5fb38031685165
+yuv420p12le         9db66b795b28e654136f8a5170482b4a
+yuv420p14be         35b9055f4b92a78a9b312f1471ffa270
+yuv420p14le         61817af578e8c6b5cacb120dca9008b0
+yuv420p16be         75e0bbe9a4f29e96eeae88207208827e
+yuv420p16le         340538ba047c5739242cd043d1f6c67b
+yuv420p9be          5e5bf3d0249cf5cdbd31bb58746e766b
+yuv420p9le          8adc79b7768cc8f7220381c3fe8f3090
+yuv422p             6c2d87652f18bc1b0e40cf794a061bd2
+yuv422p10be         711e7e00ab91aeee82e18ed84117345a
+yuv422p10le         cdb2c605b45a3ce840dc967bcca5893f
+yuv422p12be         ff378d3990ef37e6b43aee27880be256
+yuv422p12le         9e023fe6f0fc4626e3b2733326c8ff34
+yuv422p14be         f9f144674eb0b6945d9e7c8c3f84e2ee
+yuv422p14le         dc7fc4fcbc9b571f357df173d3521f98
+yuv422p16be         45a44b3298488c4979a5c184c95720f8
+yuv422p16le         479e36c10a498669ea003192289eee85
+yuv422p9be          37eaf23d5f5a331e949f7b4ec50a44ae
+yuv422p9le          267710ff84ef671419982f04cc111ad6
+yuv440p             5cd5fd358c63e130eacb77867c486f7d
+yuv444p             22bf5f86ca3e9fff950d2b2ea6da65be
+yuv444p10be         97a809d37853acb4864ef75f6e3aff24
+yuv444p10le         5081c59d16157eabc73d49c6b903d530
+yuv444p12be         183bff4f9470a4d4f980aac98a9181e7
+yuv444p12le         a57dc2f043659d1d1c7260b76e5d8745
+yuv444p14be         a0fd8199b6a05e799c3646e6dacff968
+yuv444p14le         1107f410652e9ecb4540b3d896c1252f
+yuv444p16be         f285bda960402c031303d8da5ab2f5f6
+yuv444p16le         dd72a55624c37d955bc66f54dd7d0770
+yuv444p9be          02fac80656a1aa16573ac89bf3bcb2ae
+yuv444p9le          f9009efe8e174f7b62edd9496d375af9
+yuva420p            99559efdc598a611e8a445726aae52df
+yuva420p10be        5ebfba649292669bf4a42ae812811ac9
+yuva420p10le        b3ca09bde07e20e6674390f7946b6e93
+yuva420p16be        10d49b187aa0e9f6980c0fe2583a403f
+yuva420p16le        8520c00011f8040ce3d760b4d73bdf40
+yuva420p9be         ab70cda1f3ae2822a70e84fec2130f6e
+yuva420p9le         70b5fc0e4b4d48c36530ea4ef1e3353b
+yuva422p            05fb65386a03cd61094348b15cd4bc8c
+yuva422p10be        3ffe3b85704883bbf9666b06afa0e1dc
+yuva422p10le        47a89fc53f0777f8cb973ccd25f2f09e
+yuva422p16be        805df2b4709283b34002b25e2e229e0a
+yuva422p16le        675315e192ded36ccec229a4aea28e89
+yuva422p9be         aedf684bcacc4e2375622ba9fd4f3846
+yuva422p9le         41aa087d23cfa8fae5a4e6406442fa8f
+yuva444p            70d4cba3980d5a1c16d5c29526e71ee5
+yuva444p10be        a0e80fe85810531348352b47ba4b712d
+yuva444p10le        c0caa122748be4a1467ce0f0600165cc
+yuva444p16be        5722e1a5b09b3808e5bbd9a7db1add49
+yuva444p16le        342725e837355d66019ec05ffa5b6c4c
+yuva444p9be         bcea6ad30ced293dbba9d7a6780d52ec
+yuva444p9le         bbd56cf86dadd7db8625d3679c6acc45
+yuvj411p            8c6457a0ec6d796884e88f88ae17c9e3
+yuvj420p            06d3226d86dbd01cd359d8a1507d0e6b
+yuvj422p            8f87a2f4261297545b53b3f237c5bf1a
+yuvj440p            92c7d84f41d703878ae53911d03d23c9
+yuvj444p            1eda19f660d5902e047bb8c43f182fb3
diff --git a/tests/ref/lavfi/tinterlace_merge b/tests/ref/fate/filter-pixfmts-tinterlace_merge
similarity index 89%
rename from tests/ref/lavfi/tinterlace_merge
rename to tests/ref/fate/filter-pixfmts-tinterlace_merge
index 300713f..07bd5cf 100644
--- a/tests/ref/lavfi/tinterlace_merge
+++ b/tests/ref/fate/filter-pixfmts-tinterlace_merge
@@ -1,4 +1,4 @@
-gray                c996e583bbc5a6f380463142eb77b7c6
+gray                6575994300fa6c32755e68a9c7398247
 yuv410p             c9bad1317b496071d6d895238638e07d
 yuv420p             9794d11e59ec7bcdf9e30a433e4137b1
 yuv422p             e852e61e455db8ee3981ea942d510b0f
diff --git a/tests/ref/lavfi/tinterlace_pad b/tests/ref/fate/filter-pixfmts-tinterlace_pad
similarity index 89%
rename from tests/ref/lavfi/tinterlace_pad
rename to tests/ref/fate/filter-pixfmts-tinterlace_pad
index 722ac85..81152a3 100644
--- a/tests/ref/lavfi/tinterlace_pad
+++ b/tests/ref/fate/filter-pixfmts-tinterlace_pad
@@ -1,4 +1,4 @@
-gray                25a7d1ccf1a06c1a8a0520c1e6cb30ff
+gray                28646014a43963751d1862332972f60d
 yuv410p             17163d1b4f21d894598fc62e6aeb8141
 yuv420p             f8bbae33295741c1c17d33ff8ee16f7f
 yuv422p             4fa67d1580d3453942bb0950c5784f6e
diff --git a/tests/ref/lavfi/pixfmts_vflip b/tests/ref/fate/filter-pixfmts-vflip
similarity index 85%
rename from tests/ref/lavfi/pixfmts_vflip
rename to tests/ref/fate/filter-pixfmts-vflip
index 7990c3e..83347b5 100644
--- a/tests/ref/lavfi/pixfmts_vflip
+++ b/tests/ref/fate/filter-pixfmts-vflip
@@ -15,16 +15,17 @@
 bgr565le            9fab295d966386d4ef99d5b43066da47
 bgr8                275ce12eeb05de67a6915f67cbb43ce5
 bgra                d29c35871248c476c366e678db580982
-gbrp                7852e9bbe52cfad9bab8081a5c7a5a31
-gbrp10be            f591c6c98396baf3242837827081f2f7
-gbrp10le            c5edb9bb566edbc8c478595ac6ab070f
-gbrp12be            c61c19ad1bcca18719dd071e2cb77287
-gbrp12le            334a6c802ae0e15d9e0950c27ce4a457
-gbrp14be            e24459d3b4a1e9c56ec3658c525b7a32
-gbrp14le            99207ef7c7dcb1d1369dc3fe3b5dc261
-gbrp9be             1daea1677f8a62c5a1ef8959c5e0e4b0
-gbrp9le             e3cca50b844e7dd326eadf6e38fab84b
-gray                a53528cdf80ed31c9897042a2ea16618
+gbrap               29844a8e4334493fdd2d499bcb532535
+gbrp                d3f2823513bfdac8f714385513cc396b
+gbrp10be            49b93ac01777e4bafcb9afd4d9d74533
+gbrp10le            61c0cbb0978d26494d3a233042e1e256
+gbrp12be            36f58621c2a10141cdae56c82cd99946
+gbrp12le            33dd0c50bc6c9cec92e8afcce076dff3
+gbrp14be            488b314f58b3e41d67c1b093ce19a7fb
+gbrp14le            48b4273ff29b6b68a05a6027254ff75e
+gbrp9be             b4361a1ad66cdff0d32d4af769a8a960
+gbrp9le             5bc148ca18ff1bf7095e78a4e65ed8ab
+gray                800813149a825964025e75cf14ec528b
 gray16be            9b23f3e79c54a6ccb62e0135a32e3045
 gray16le            93cfa8fbb2a86ead275ce1817444e6d5
 monob               c395a8efb9477b4ec53a77326e41ccd7
@@ -45,7 +46,11 @@
 rgb565le            991576c5d3308a73068a826543b3e7af
 rgb8                42230235c5a2a66c0f9a2fcd20f9f5cd
 rgba                a6973a2940a378d2a8284194da26eec0
+rgba64be            52ee01b66ee3d52e4726a12fbb819950
+rgba64le            60541d81afcea71a27629c4e5d137dcb
 uyvy422             21c48162379321bb83ec2399535f9253
+xyz12be             7070af64e30fa689e3627b1dde7506f4
+xyz12le             4c4b31100b836638e7e61181997c49e1
 yuv410p             8699f50c04f8ac931aa5a8306827364b
 yuv411p             47af34559b92b68851df4c2b170f7736
 yuv420p             c59b35b82b5a195128736021913b35a4
@@ -103,6 +108,7 @@
 yuva444p16le        6f54a8cff38c54a235b92a0f1314e0aa
 yuva444p9be         7472bb4b0c774d5d741035086d5e4330
 yuva444p9le         ae11ddd5a3e8d69a36989f6f2a8897a1
+yuvj411p            be518349f35aa67e048b854ff2da60c4
 yuvj420p            200b0332de9944e76c94d2e0699a5a2d
 yuvj422p            a19a89ef145305cf224ef5aa247d075a
 yuvj440p            4240c9348d28af5f3edd0e642002bd2c
diff --git a/tests/ref/lavfi/pp b/tests/ref/fate/filter-pp
similarity index 100%
rename from tests/ref/lavfi/pp
rename to tests/ref/fate/filter-pp
diff --git a/tests/ref/lavfi/pp2 b/tests/ref/fate/filter-pp2
similarity index 100%
rename from tests/ref/lavfi/pp2
rename to tests/ref/fate/filter-pp2
diff --git a/tests/ref/lavfi/pp3 b/tests/ref/fate/filter-pp3
similarity index 100%
rename from tests/ref/lavfi/pp3
rename to tests/ref/fate/filter-pp3
diff --git a/tests/ref/lavfi/pp4 b/tests/ref/fate/filter-pp4
similarity index 100%
rename from tests/ref/lavfi/pp4
rename to tests/ref/fate/filter-pp4
diff --git a/tests/ref/lavfi/pp5 b/tests/ref/fate/filter-pp5
similarity index 100%
rename from tests/ref/lavfi/pp5
rename to tests/ref/fate/filter-pp5
diff --git a/tests/ref/lavfi/pp6 b/tests/ref/fate/filter-pp6
similarity index 100%
rename from tests/ref/lavfi/pp6
rename to tests/ref/fate/filter-pp6
diff --git a/tests/ref/lavfi/scale200 b/tests/ref/fate/filter-scale200
similarity index 100%
rename from tests/ref/lavfi/scale200
rename to tests/ref/fate/filter-scale200
diff --git a/tests/ref/lavfi/scale500 b/tests/ref/fate/filter-scale500
similarity index 100%
rename from tests/ref/lavfi/scale500
rename to tests/ref/fate/filter-scale500
diff --git a/tests/ref/lavfi/select b/tests/ref/fate/filter-select
similarity index 100%
rename from tests/ref/lavfi/select
rename to tests/ref/fate/filter-select
diff --git a/tests/ref/fate/filter-separatefields b/tests/ref/fate/filter-separatefields
new file mode 100644
index 0000000..46cb470
--- /dev/null
+++ b/tests/ref/fate/filter-separatefields
@@ -0,0 +1,101 @@
+#tb 0: 1/50
+0,          0,          0,        1,    76032, 0x99276ab9
+0,          1,          1,        1,    76032, 0x0b071f36
+0,          2,          2,        1,    76032, 0x8b03b0e8
+0,          3,          3,        1,    76032, 0x3e10b45a
+0,          4,          4,        1,    76032, 0x67a27817
+0,          5,          5,        1,    76032, 0xb3537e33
+0,          6,          6,        1,    76032, 0xc4e78689
+0,          7,          7,        1,    76032, 0x5f11fa18
+0,          8,          8,        1,    76032, 0x7867f720
+0,          9,          9,        1,    76032, 0xb584bf23
+0,         10,         10,        1,    76032, 0x7c4ae6cf
+0,         11,         11,        1,    76032, 0x4b43c208
+0,         12,         12,        1,    76032, 0x974d3882
+0,         13,         13,        1,    76032, 0xfb0543a1
+0,         14,         14,        1,    76032, 0x91da8418
+0,         15,         15,        1,    76032, 0x45260794
+0,         16,         16,        1,    76032, 0xe65397d0
+0,         17,         17,        1,    76032, 0xfa09e847
+0,         18,         18,        1,    76032, 0x3adcfa2c
+0,         19,         19,        1,    76032, 0xa0103eda
+0,         20,         20,        1,    76032, 0xee821b94
+0,         21,         21,        1,    76032, 0xb8cf2bcc
+0,         22,         22,        1,    76032, 0x6e50db83
+0,         23,         23,        1,    76032, 0x2cd12152
+0,         24,         24,        1,    76032, 0x482961d0
+0,         25,         25,        1,    76032, 0x9a304b91
+0,         26,         26,        1,    76032, 0x2591f07b
+0,         27,         27,        1,    76032, 0x1410b199
+0,         28,         28,        1,    76032, 0x1fc9c234
+0,         29,         29,        1,    76032, 0x4a8dcb9a
+0,         30,         30,        1,    76032, 0xda4b81c7
+0,         31,         31,        1,    76032, 0x45ef8d2f
+0,         32,         32,        1,    76032, 0x07fda976
+0,         33,         33,        1,    76032, 0x19cfa493
+0,         34,         34,        1,    76032, 0xdb453b41
+0,         35,         35,        1,    76032, 0xeebefd78
+0,         36,         36,        1,    76032, 0xdb7830bf
+0,         37,         37,        1,    76032, 0x1bc13a0d
+0,         38,         38,        1,    76032, 0xf811e6af
+0,         39,         39,        1,    76032, 0x5bb6f541
+0,         40,         40,        1,    76032, 0xadfc0b2a
+0,         41,         41,        1,    76032, 0x473fea46
+0,         42,         42,        1,    76032, 0xc4541cec
+0,         43,         43,        1,    76032, 0x5e500726
+0,         44,         44,        1,    76032, 0x54df18fa
+0,         45,         45,        1,    76032, 0x6470045f
+0,         46,         46,        1,    76032, 0x01139a0b
+0,         47,         47,        1,    76032, 0x8690ced5
+0,         48,         48,        1,    76032, 0x9796b3f0
+0,         49,         49,        1,    76032, 0x1bee45e6
+0,         50,         50,        1,    76032, 0xacf4c872
+0,         51,         51,        1,    76032, 0x0183d0b5
+0,         52,         52,        1,    76032, 0xeea54bf9
+0,         53,         53,        1,    76032, 0xb42d4abc
+0,         54,         54,        1,    76032, 0x8be07d8b
+0,         55,         55,        1,    76032, 0x9ac75afc
+0,         56,         56,        1,    76032, 0x96bd3717
+0,         57,         57,        1,    76032, 0xbcca6d3e
+0,         58,         58,        1,    76032, 0x3e2edf44
+0,         59,         59,        1,    76032, 0x1b1385bb
+0,         60,         60,        1,    76032, 0xd4c2d759
+0,         61,         61,        1,    76032, 0x67119362
+0,         62,         62,        1,    76032, 0x96327b89
+0,         63,         63,        1,    76032, 0x9b914995
+0,         64,         64,        1,    76032, 0xf1d024b9
+0,         65,         65,        1,    76032, 0xd0e1d7d4
+0,         66,         66,        1,    76032, 0x11e97010
+0,         67,         67,        1,    76032, 0x0ab90a20
+0,         68,         68,        1,    76032, 0xf7ce7e72
+0,         69,         69,        1,    76032, 0x6edec4f7
+0,         70,         70,        1,    76032, 0xbb96a608
+0,         71,         71,        1,    76032, 0x8502eee4
+0,         72,         72,        1,    76032, 0xc27994cb
+0,         73,         73,        1,    76032, 0x6dbba2d1
+0,         74,         74,        1,    76032, 0xe85e04f8
+0,         75,         75,        1,    76032, 0x4bbbfcf1
+0,         76,         76,        1,    76032, 0x8b5a2465
+0,         77,         77,        1,    76032, 0x8a5434e7
+0,         78,         78,        1,    76032, 0xc34578d9
+0,         79,         79,        1,    76032, 0xc2f0d5f5
+0,         80,         80,        1,    76032, 0x90bd2102
+0,         81,         81,        1,    76032, 0xafda3823
+0,         82,         82,        1,    76032, 0x66972a74
+0,         83,         83,        1,    76032, 0xc9d17394
+0,         84,         84,        1,    76032, 0x961cdc22
+0,         85,         85,        1,    76032, 0x6816e378
+0,         86,         86,        1,    76032, 0x4c383925
+0,         87,         87,        1,    76032, 0xf522e7b8
+0,         88,         88,        1,    76032, 0xc1616f33
+0,         89,         89,        1,    76032, 0xad14952f
+0,         90,         90,        1,    76032, 0xe4e11fcd
+0,         91,         91,        1,    76032, 0xca655ea6
+0,         92,         92,        1,    76032, 0x7b18f45f
+0,         93,         93,        1,    76032, 0xb2325f91
+0,         94,         94,        1,    76032, 0xb08d7400
+0,         95,         95,        1,    76032, 0x74ec51c2
+0,         96,         96,        1,    76032, 0xc15a0713
+0,         97,         97,        1,    76032, 0x3838ad70
+0,         98,         98,        1,    76032, 0x74b6bc3f
+0,         99,         99,        1,    76032, 0x29f41cab
diff --git a/tests/ref/lavfi/setdar b/tests/ref/fate/filter-setdar
similarity index 100%
rename from tests/ref/lavfi/setdar
rename to tests/ref/fate/filter-setdar
diff --git a/tests/ref/lavfi/setsar b/tests/ref/fate/filter-setsar
similarity index 100%
rename from tests/ref/lavfi/setsar
rename to tests/ref/fate/filter-setsar
diff --git a/tests/ref/fate/filter-stereo3d-abr-ml b/tests/ref/fate/filter-stereo3d-abr-ml
new file mode 100644
index 0000000..d0597a7
--- /dev/null
+++ b/tests/ref/fate/filter-stereo3d-abr-ml
@@ -0,0 +1,6 @@
+#tb 0: 1/25
+0,          0,          0,        1,    76032, 0xad4c8a22
+0,          1,          1,        1,    76032, 0x0dfdc6ad
+0,          2,          2,        1,    76032, 0x6341da83
+0,          3,          3,        1,    76032, 0x8dbcb05f
+0,          4,          4,        1,    76032, 0xad87bbee
diff --git a/tests/ref/fate/filter-stereo3d-abr-mr b/tests/ref/fate/filter-stereo3d-abr-mr
new file mode 100644
index 0000000..44a8091
--- /dev/null
+++ b/tests/ref/fate/filter-stereo3d-abr-mr
@@ -0,0 +1,6 @@
+#tb 0: 1/25
+0,          0,          0,        1,    76032, 0x5d0effbe
+0,          1,          1,        1,    76032, 0x5bb49e95
+0,          2,          2,        1,    76032, 0xb6301bc7
+0,          3,          3,        1,    76032, 0x7cf1d042
+0,          4,          4,        1,    76032, 0x24fafa55
diff --git a/tests/ref/fate/filter-stereo3d-al-sbsl b/tests/ref/fate/filter-stereo3d-al-sbsl
new file mode 100644
index 0000000..b19cbb8
--- /dev/null
+++ b/tests/ref/fate/filter-stereo3d-al-sbsl
@@ -0,0 +1,6 @@
+#tb 0: 2/25
+0,          0,          0,        1,   304128, 0xb9c0ef40
+0,          1,          1,        1,   304128, 0xfa0b7709
+0,          2,          2,        1,   304128, 0x14255f47
+0,          3,          3,        1,   304128, 0xa9da07de
+0,          4,          4,        1,   304128, 0x9d64b93b
diff --git a/tests/ref/fate/filter-stereo3d-ar-abl b/tests/ref/fate/filter-stereo3d-ar-abl
new file mode 100644
index 0000000..0358199
--- /dev/null
+++ b/tests/ref/fate/filter-stereo3d-ar-abl
@@ -0,0 +1,6 @@
+#tb 0: 2/25
+0,          0,          0,        1,   304128, 0x7babef40
+0,          1,          1,        1,   304128, 0x287d7709
+0,          2,          2,        1,   304128, 0x385f5f47
+0,          3,          3,        1,   304128, 0x503507de
+0,          4,          4,        1,   304128, 0xb97db93b
diff --git a/tests/ref/fate/filter-stereo3d-sbsl-abl b/tests/ref/fate/filter-stereo3d-sbsl-abl
new file mode 100644
index 0000000..273e520
--- /dev/null
+++ b/tests/ref/fate/filter-stereo3d-sbsl-abl
@@ -0,0 +1,6 @@
+#tb 0: 1/25
+0,          0,          0,        1,   152064, 0x2f9389ef
+0,          1,          1,        1,   152064, 0x16c66551
+0,          2,          2,        1,   152064, 0xd779f64a
+0,          3,          3,        1,   152064, 0x7a7c80b0
+0,          4,          4,        1,   152064, 0x0702b652
diff --git a/tests/ref/fate/filter-stereo3d-sbsl-abr b/tests/ref/fate/filter-stereo3d-sbsl-abr
new file mode 100644
index 0000000..c827e3c
--- /dev/null
+++ b/tests/ref/fate/filter-stereo3d-sbsl-abr
@@ -0,0 +1,6 @@
+#tb 0: 1/25
+0,          0,          0,        1,   152064, 0xd1f489ef
+0,          1,          1,        1,   152064, 0xe4fe6551
+0,          2,          2,        1,   152064, 0xd0d9f64a
+0,          3,          3,        1,   152064, 0xfd3a80b0
+0,          4,          4,        1,   152064, 0x488eb652
diff --git a/tests/ref/fate/filter-stereo3d-sbsl-al b/tests/ref/fate/filter-stereo3d-sbsl-al
new file mode 100644
index 0000000..5c8a429
--- /dev/null
+++ b/tests/ref/fate/filter-stereo3d-sbsl-al
@@ -0,0 +1,6 @@
+#tb 0: 1/50
+0,          0,          0,        1,    76032, 0x3ff06515
+0,          1,          1,        1,    76032, 0x00d824da
+0,          2,          2,        1,    76032, 0x64a33c64
+0,          3,          3,        1,    76032, 0xeef328ed
+0,          4,          4,        1,    76032, 0x4bb209cc
diff --git a/tests/ref/fate/filter-stereo3d-sbsl-sbsr b/tests/ref/fate/filter-stereo3d-sbsl-sbsr
new file mode 100644
index 0000000..b417ae4
--- /dev/null
+++ b/tests/ref/fate/filter-stereo3d-sbsl-sbsr
@@ -0,0 +1,6 @@
+#tb 0: 1/25
+0,          0,          0,        1,   152064, 0xbe2f89ef
+0,          1,          1,        1,   152064, 0x4c806551
+0,          2,          2,        1,   152064, 0x8165f64a
+0,          3,          3,        1,   152064, 0xadf280b0
+0,          4,          4,        1,   152064, 0x6677b652
diff --git a/tests/ref/fate/filter-telecine b/tests/ref/fate/filter-telecine
new file mode 100644
index 0000000..b8a13a9
--- /dev/null
+++ b/tests/ref/fate/filter-telecine
@@ -0,0 +1,63 @@
+#tb 0: 4/125
+0,          0,          0,        1,   152064, 0x05b789ef
+0,          1,          1,        1,   152064, 0x4bb46551
+0,          2,          2,        1,   152064, 0x40692c80
+0,          3,          3,        1,   152064, 0xd7ad04cb
+0,          4,          4,        1,   152064, 0x2a8380b0
+0,          5,          5,        1,   152064, 0x4de3b652
+0,          6,          6,        1,   152064, 0xedb5a8e6
+0,          7,          7,        1,   152064, 0x549dfa8a
+0,          8,          8,        1,   152064, 0x447bc7b9
+0,          9,          9,        1,   152064, 0x5ab58bac
+0,         10,         10,        1,   152064, 0x1f1b8026
+0,         11,         11,        1,   152064, 0x91373915
+0,         12,         12,        1,   152064, 0x90895a6e
+0,         13,         13,        1,   152064, 0x793d075e
+0,         14,         14,        1,   152064, 0x30f5fcd5
+0,         15,         15,        1,   152064, 0xc711ad61
+0,         16,         16,        1,   152064, 0x24eca223
+0,         17,         17,        1,   152064, 0x0a4073dc
+0,         18,         18,        1,   152064, 0x06e34d70
+0,         19,         19,        1,   152064, 0xa91c0f05
+0,         20,         20,        1,   152064, 0x8e364e18
+0,         21,         21,        1,   152064, 0xb15d38c8
+0,         22,         22,        1,   152064, 0x6b2b2e46
+0,         23,         23,        1,   152064, 0xbd2320cb
+0,         24,         24,        1,   152064, 0xf34ddbff
+0,         25,         25,        1,   152064, 0xfc7bf570
+0,         26,         26,        1,   152064, 0x9dc72412
+0,         27,         27,        1,   152064, 0xa1242020
+0,         28,         28,        1,   152064, 0x1f939e6a
+0,         29,         29,        1,   152064, 0x2f2768ef
+0,         30,         30,        1,   152064, 0xce09f9d6
+0,         31,         31,        1,   152064, 0x95579936
+0,         32,         32,        1,   152064, 0x41181cbd
+0,         33,         33,        1,   152064, 0xe9cec847
+0,         34,         34,        1,   152064, 0xd780d887
+0,         35,         35,        1,   152064, 0x76d2a455
+0,         36,         36,        1,   152064, 0x6dc3650e
+0,         37,         37,        1,   152064, 0x8d165d23
+0,         38,         38,        1,   152064, 0x64f10efa
+0,         39,         39,        1,   152064, 0xe295c51e
+0,         40,         40,        1,   152064, 0xd766fc8d
+0,         41,         41,        1,   152064, 0xe22f7a30
+0,         42,         42,        1,   152064, 0xd8c68892
+0,         43,         43,        1,   152064, 0x26516b0e
+0,         44,         44,        1,   152064, 0xfa8d94fb
+0,         45,         45,        1,   152064, 0x4c9737ab
+0,         46,         46,        1,   152064, 0xa50d01f8
+0,         47,         47,        1,   152064, 0x82f12165
+0,         48,         48,        1,   152064, 0x113fadc0
+0,         49,         49,        1,   152064, 0x88734edd
+0,         50,         50,        1,   152064, 0xd2735925
+0,         51,         51,        1,   152064, 0xd4e49e08
+0,         52,         52,        1,   152064, 0x8cd54fc5
+0,         53,         53,        1,   152064, 0xae821cac
+0,         54,         54,        1,   152064, 0x575c20ec
+0,         55,         55,        1,   152064, 0xfd500471
+0,         56,         56,        1,   152064, 0x61b47e73
+0,         57,         57,        1,   152064, 0x213d5314
+0,         58,         58,        1,   152064, 0xb4ddd391
+0,         59,         59,        1,   152064, 0x6e88c5c2
+0,         60,         60,        1,   152064, 0xbb87b483
+0,         61,         61,        1,   152064, 0x4bbad8ea
diff --git a/tests/ref/lavfi/thumbnail b/tests/ref/fate/filter-thumbnail
similarity index 100%
rename from tests/ref/lavfi/thumbnail
rename to tests/ref/fate/filter-thumbnail
diff --git a/tests/ref/lavfi/tile b/tests/ref/fate/filter-tile
similarity index 100%
rename from tests/ref/lavfi/tile
rename to tests/ref/fate/filter-tile
diff --git a/tests/ref/fate/filter-trim-duration b/tests/ref/fate/filter-trim-duration
new file mode 100644
index 0000000..db74add
--- /dev/null
+++ b/tests/ref/fate/filter-trim-duration
@@ -0,0 +1,2 @@
+#tb 0: 1/25
+0,         10,         10,        1,   152064, 0xb45c4760
diff --git a/tests/ref/fate/filter-trim-frame b/tests/ref/fate/filter-trim-frame
new file mode 100644
index 0000000..1749afd
--- /dev/null
+++ b/tests/ref/fate/filter-trim-frame
@@ -0,0 +1,8 @@
+#tb 0: 1/25
+0,          3,          3,        1,   152064, 0xceb080b0
+0,          4,          4,        1,   152064, 0x473db652
+0,          5,          5,        1,   152064, 0x287da8e6
+0,          6,          6,        1,   152064, 0x68b47c23
+0,          7,          7,        1,   152064, 0xe9028bac
+0,          8,          8,        1,   152064, 0x28ff8026
+0,          9,          9,        1,   152064, 0x2d7c3915
diff --git a/tests/ref/fate/filter-trim-mixed b/tests/ref/fate/filter-trim-mixed
new file mode 100644
index 0000000..5e003f6
--- /dev/null
+++ b/tests/ref/fate/filter-trim-mixed
@@ -0,0 +1,10 @@
+#tb 0: 1/25
+0,          1,          1,        1,   152064, 0x7f5f6551
+0,          2,          2,        1,   152064, 0xc566f64a
+0,          3,          3,        1,   152064, 0xceb080b0
+0,          4,          4,        1,   152064, 0x473db652
+0,          5,          5,        1,   152064, 0x287da8e6
+0,          6,          6,        1,   152064, 0x68b47c23
+0,          7,          7,        1,   152064, 0xe9028bac
+0,          8,          8,        1,   152064, 0x28ff8026
+0,          9,          9,        1,   152064, 0x2d7c3915
diff --git a/tests/ref/fate/filter-trim-time b/tests/ref/fate/filter-trim-time
new file mode 100644
index 0000000..2f86025
--- /dev/null
+++ b/tests/ref/fate/filter-trim-time
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0,          0,          0,        1,   152064, 0x6e4f89ef
+0,          1,          1,        1,   152064, 0x7f5f6551
diff --git a/tests/ref/fate/filter-unsharp b/tests/ref/fate/filter-unsharp
index 5dcf40f..613163b 100644
--- a/tests/ref/fate/filter-unsharp
+++ b/tests/ref/fate/filter-unsharp
@@ -1,51 +1,51 @@
 #tb 0: 1/25
-0,          0,          0,        1,   152064, 0x19a94798
-0,          1,          1,        1,   152064, 0xc88b24f4
-0,          2,          2,        1,   152064, 0xd027b44b
-0,          3,          3,        1,   152064, 0xa9fb3e54
-0,          4,          4,        1,   152064, 0x2991747d
-0,          5,          5,        1,   152064, 0x1dc267fc
-0,          6,          6,        1,   152064, 0xe9063293
-0,          7,          7,        1,   152064, 0xc23e41a4
-0,          8,          8,        1,   152064, 0xaa433dc5
-0,          9,          9,        1,   152064, 0x22b0f0a3
-0,         10,         10,        1,   152064, 0x796d08d8
-0,         11,         11,        1,   152064, 0xa2babd6b
-0,         12,         12,        1,   152064, 0x531e6a62
-0,         13,         13,        1,   152064, 0xc8fa5b9d
-0,         14,         14,        1,   152064, 0x33e54ae8
-0,         15,         15,        1,   152064, 0x86dfd0b8
-0,         16,         16,        1,   152064, 0x101f1170
-0,         17,         17,        1,   152064, 0x230eef00
-0,         18,         18,        1,   152064, 0xa5ee1c5e
-0,         19,         19,        1,   152064, 0x241893c6
-0,         20,         20,        1,   152064, 0x86a0a883
-0,         21,         21,        1,   152064, 0x12b4d8f7
-0,         22,         22,        1,   152064, 0xb220d497
-0,         23,         23,        1,   152064, 0xbaea200e
-0,         24,         24,        1,   152064, 0x6d96b7f3
-0,         25,         25,        1,   152064, 0xc70d4ebb
-0,         26,         26,        1,   152064, 0x20df50af
-0,         27,         27,        1,   152064, 0xfce89174
-0,         28,         28,        1,   152064, 0x74be5c8e
-0,         29,         29,        1,   152064, 0x51f419a6
-0,         30,         30,        1,   152064, 0x790621e7
-0,         31,         31,        1,   152064, 0x37387da2
-0,         32,         32,        1,   152064, 0x8228baa4
-0,         33,         33,        1,   152064, 0xdd2a42b7
-0,         34,         34,        1,   152064, 0xa28bfc63
-0,         35,         35,        1,   152064, 0xe8284337
-0,         36,         36,        1,   152064, 0xb1dae9fe
-0,         37,         37,        1,   152064, 0x0378c0af
-0,         38,         38,        1,   152064, 0x79c514d4
-0,         39,         39,        1,   152064, 0x043e0347
-0,         40,         40,        1,   152064, 0x4d11131b
-0,         41,         41,        1,   152064, 0xb2a05924
-0,         42,         42,        1,   152064, 0xd0097464
-0,         43,         43,        1,   152064, 0x32dfd8c0
-0,         44,         44,        1,   152064, 0xd9ecbf03
-0,         45,         45,        1,   152064, 0x8dcc403f
-0,         46,         46,        1,   152064, 0x95e81af7
-0,         47,         47,        1,   152064, 0xb8018b25
-0,         48,         48,        1,   152064, 0xeecf7281
-0,         49,         49,        1,   152064, 0x23e49602
+0,          0,          0,        1,   152064, 0x58100735
+0,          1,          1,        1,   152064, 0x2967e43d
+0,          2,          2,        1,   152064, 0x6f0c786d
+0,          3,          3,        1,   152064, 0xaf1fff7c
+0,          4,          4,        1,   152064, 0xee583651
+0,          5,          5,        1,   152064, 0xf50c280f
+0,          6,          6,        1,   152064, 0x3eeff2e9
+0,          7,          7,        1,   152064, 0xb43c0fc7
+0,          8,          8,        1,   152064, 0x55733232
+0,          9,          9,        1,   152064, 0x78b5b9fe
+0,         10,         10,        1,   152064, 0x8b39c410
+0,         11,         11,        1,   152064, 0x1a2b686f
+0,         12,         12,        1,   152064, 0xee622ce9
+0,         13,         13,        1,   152064, 0x9f8a2f4f
+0,         14,         14,        1,   152064, 0xd6210d42
+0,         15,         15,        1,   152064, 0x598a8e88
+0,         16,         16,        1,   152064, 0xeeaccbfa
+0,         17,         17,        1,   152064, 0xe2a3b094
+0,         18,         18,        1,   152064, 0x2becd63d
+0,         19,         19,        1,   152064, 0x2cfd46c6
+0,         20,         20,        1,   152064, 0x781b616e
+0,         21,         21,        1,   152064, 0x90908f49
+0,         22,         22,        1,   152064, 0x136d8950
+0,         23,         23,        1,   152064, 0xe3b8dfa4
+0,         24,         24,        1,   152064, 0x9a857595
+0,         25,         25,        1,   152064, 0x9d5d16f3
+0,         26,         26,        1,   152064, 0xad0815e6
+0,         27,         27,        1,   152064, 0xbd485852
+0,         28,         28,        1,   152064, 0x379023e0
+0,         29,         29,        1,   152064, 0x47c3e49e
+0,         30,         30,        1,   152064, 0x435eead9
+0,         31,         31,        1,   152064, 0x6ef8445d
+0,         32,         32,        1,   152064, 0x13258191
+0,         33,         33,        1,   152064, 0x09adfa4b
+0,         34,         34,        1,   152064, 0xd67e9f1f
+0,         35,         35,        1,   152064, 0x456e1298
+0,         36,         36,        1,   152064, 0x9998b485
+0,         37,         37,        1,   152064, 0xca1f8859
+0,         38,         38,        1,   152064, 0x9d1ad87c
+0,         39,         39,        1,   152064, 0x37a7cfac
+0,         40,         40,        1,   152064, 0xde3ad5a8
+0,         41,         41,        1,   152064, 0xf40c20d3
+0,         42,         42,        1,   152064, 0x35a23e85
+0,         43,         43,        1,   152064, 0xda1fa02a
+0,         44,         44,        1,   152064, 0xe4ae84e9
+0,         45,         45,        1,   152064, 0x113dfdbb
+0,         46,         46,        1,   152064, 0xe50fd571
+0,         47,         47,        1,   152064, 0xd6a043ef
+0,         48,         48,        1,   152064, 0xabfd3940
+0,         49,         49,        1,   152064, 0xdf085a8d
diff --git a/tests/ref/lavfi/vflip b/tests/ref/fate/filter-vflip
similarity index 100%
rename from tests/ref/lavfi/vflip
rename to tests/ref/fate/filter-vflip
diff --git a/tests/ref/lavfi/vflip_crop b/tests/ref/fate/filter-vflip_crop
similarity index 100%
rename from tests/ref/lavfi/vflip_crop
rename to tests/ref/fate/filter-vflip_crop
diff --git a/tests/ref/lavfi/vflip_vflip b/tests/ref/fate/filter-vflip_vflip
similarity index 100%
rename from tests/ref/lavfi/vflip_vflip
rename to tests/ref/fate/filter-vflip_vflip
diff --git a/tests/ref/fate/gifenc-bgr4_byte b/tests/ref/fate/gifenc-bgr4_byte
index 67b32af..dceaf52 100644
--- a/tests/ref/fate/gifenc-bgr4_byte
+++ b/tests/ref/fate/gifenc-bgr4_byte
@@ -1,56 +1,56 @@
 #tb 0: 1/100
-0,          0,          0,        1,      507, 0x91080fbf
+0,          0,          0,        1,      508, 0xa1b80fc0
 0,         10,         10,        1,      213, 0x4f554bd7, S=1,     1024, 0xb6327c81
-0,         20,         20,        1,      130, 0xfe2d2987, S=1,     1024, 0xae3a7c81
+0,         20,         20,        1,      131, 0x283b2988, S=1,     1024, 0xae3a7c81
 0,         30,         30,        1,      384, 0xc4fea72a, S=1,     1024, 0xb6327c81
 0,         40,         40,        1,      381, 0x050ba2b8, S=1,     1024, 0x9e4a7c81
 0,         50,         50,        1,      430, 0x00cfb2ae, S=1,     1024, 0x9e4a7c81
-0,         60,         60,        1,      517, 0xefb5d826, S=1,     1024, 0x9e4a7c81
+0,         60,         60,        1,      518, 0xc8e5d827, S=1,     1024, 0x9e4a7c81
 0,         70,         70,        1,      535, 0x326ce62a, S=1,     1024, 0x9e4a7c81
-0,         80,         80,        1,      437, 0x7c5db7bf, S=1,     1024, 0xb6327c81
+0,         80,         80,        1,      438, 0x34d6b7c0, S=1,     1024, 0xb6327c81
 0,         90,         90,        1,      923, 0x9fb1a37c, S=1,     1024, 0xb6327c81
-0,        100,        100,        1,      693, 0xa7b549a4, S=1,     1024, 0xb6327c81
+0,        100,        100,        1,      694, 0xf20449a5, S=1,     1024, 0xb6327c81
 0,        110,        110,        1,     1194, 0x67cd2ab5, S=1,     1024, 0xb6327c81
 0,        120,        120,        1,     1291, 0x1d23539d, S=1,     1024, 0xb6327c81
 0,        130,        130,        1,     1245, 0x065f32e6, S=1,     1024, 0xb6327c81
 0,        140,        140,        1,     1330, 0x83ec51a4, S=1,     1024, 0xb6327c81
-0,        150,        150,        1,     1275, 0xf0f438db, S=1,     1024, 0xb6327c81
-0,        160,        160,        1,     1474, 0xb41c97ee, S=1,     1024, 0xb6327c81
-0,        170,        170,        1,     1783, 0x86164ae5, S=1,     1024, 0xde0a7c81
+0,        150,        150,        1,     1276, 0x2acf38dc, S=1,     1024, 0xb6327c81
+0,        160,        160,        1,     1475, 0x4cd197ef, S=1,     1024, 0xb6327c81
+0,        170,        170,        1,     1784, 0xd1e84ae6, S=1,     1024, 0xde0a7c81
 0,        180,        180,        1,     1675, 0x092dfa86, S=1,     1024, 0xde0a7c81
 0,        190,        190,        1,     1509, 0x639aaa00, S=1,     1024, 0xde0a7c81
 0,        200,        200,        1,     1705, 0xfd3719d5, S=1,     1024, 0xde0a7c81
 0,        210,        210,        1,     1745, 0x8a761db4, S=1,     1024, 0xde0a7c81
 0,        220,        220,        1,     1642, 0x18830245, S=1,     1024, 0xde0a7c81
-0,        230,        230,        1,     1717, 0x1d251ebd, S=1,     1024, 0xde0a7c81
+0,        230,        230,        1,     1718, 0x3c8d1ebe, S=1,     1024, 0xde0a7c81
 0,        240,        240,        1,     1900, 0x2ea879d1, S=1,     1024, 0xde0a7c81
-0,        250,        250,        1,     1806, 0xb071522f, S=1,     1024, 0xde0a7c81
+0,        250,        250,        1,     1807, 0x02b35230, S=1,     1024, 0xde0a7c81
 0,        260,        260,        1,     1915, 0x22d48344, S=1,     1024, 0xde0a7c81
 0,        270,        270,        1,     2100, 0x55fcd063, S=1,     1024, 0xde0a7c81
 0,        280,        280,        1,     2700, 0x7cc5f08b, S=1,     1024, 0xde0a7c81
 0,        290,        290,        1,     2673, 0xb997a80d, S=1,     1024, 0xde0a7c81
-0,        300,        300,        1,     2894, 0x62d9484c, S=1,     1024, 0xde0a7c81
+0,        300,        300,        1,     2895, 0xab69484d, S=1,     1024, 0xde0a7c81
 0,        310,        310,        1,     3257, 0xf753cf24, S=1,     1024, 0xde0a7c81
 0,        320,        320,        1,     3179, 0x34f2c13b, S=1,     1024, 0xde0a7c81
 0,        330,        330,        1,     3296, 0x7c06e72f, S=1,     1024, 0xde0a7c81
-0,        340,        340,        1,     3599, 0xd65f7633, S=1,     1024, 0xde0a7c81
-0,        350,        350,        1,     3698, 0x0b9e9fe2, S=1,     1024, 0xde0a7c81
+0,        340,        340,        1,     3600, 0x4ca67634, S=1,     1024, 0xde0a7c81
+0,        350,        350,        1,     3699, 0xabe89fe3, S=1,     1024, 0xde0a7c81
 0,        360,        360,        1,     3814, 0x1869d3f4, S=1,     1024, 0xde0a7c81
-0,        370,        370,        1,     3626, 0x9be87da6, S=1,     1024, 0xde0a7c81
+0,        370,        370,        1,     3627, 0x19bd7da7, S=1,     1024, 0xde0a7c81
 0,        380,        380,        1,     2950, 0x048a6055, S=1,     1024, 0xde0a7c81
 0,        390,        390,        1,     3086, 0x64ec8fc2, S=1,     1024, 0xde0a7c81
-0,        400,        400,        1,     3093, 0x94cc8552, S=1,     1024, 0xde0a7c81
+0,        400,        400,        1,     3094, 0x1a388553, S=1,     1024, 0xde0a7c81
 0,        410,        410,        1,     3456, 0x01432c82, S=1,     1024, 0xde0a7c81
-0,        420,        420,        1,     4107, 0x9bea5c65, S=1,     1024, 0xde0a7c81
-0,        430,        430,        1,     4216, 0x23875ba3, S=1,     1024, 0xde0a7c81
+0,        420,        420,        1,     4108, 0xf9505c66, S=1,     1024, 0xde0a7c81
+0,        430,        430,        1,     4217, 0x7f985ba4, S=1,     1024, 0xde0a7c81
 0,        440,        440,        1,     3613, 0xd0684d83, S=1,     1024, 0xde0a7c81
-0,        450,        450,        1,     3909, 0x1995e691, S=1,     1024, 0xde0a7c81
-0,        460,        460,        1,     4460, 0x791ce33c, S=1,     1024, 0xde0a7c81
-0,        470,        470,        1,     4592, 0x04ed2dd0, S=1,     1024, 0xde0a7c81
-0,        480,        480,        1,     4821, 0xbff89882, S=1,     1024, 0xde0a7c81
-0,        490,        490,        1,     5397, 0xf483c31d, S=1,     1024, 0xde0a7c81
+0,        450,        450,        1,     3910, 0x0070e692, S=1,     1024, 0xde0a7c81
+0,        460,        460,        1,     4461, 0x5cc9e33d, S=1,     1024, 0xde0a7c81
+0,        470,        470,        1,     4593, 0x33a32dd1, S=1,     1024, 0xde0a7c81
+0,        480,        480,        1,     4822, 0x59549883, S=1,     1024, 0xde0a7c81
+0,        490,        490,        1,     5398, 0xb7bac31e, S=1,     1024, 0xde0a7c81
 0,        500,        500,        1,     5266, 0x21c695aa, S=1,     1024, 0xde0a7c81
-0,        510,        510,        1,     5415, 0x0efce3ec, S=1,     1024, 0xde0a7c81
+0,        510,        510,        1,     5416, 0xf305e3ed, S=1,     1024, 0xde0a7c81
 0,        520,        520,        1,     5519, 0x857d071f, S=1,     1024, 0xde0a7c81
 0,        530,        530,        1,     5701, 0x8f885c9c, S=1,     1024, 0xde0a7c81
 0,        540,        540,        1,     6160, 0x48523e83, S=1,     1024, 0xde0a7c81
@@ -69,7 +69,7 @@
 0,        670,        670,        1,     7556, 0x89c1a712, S=1,     1024, 0xde0a7c81
 0,        680,        680,        1,     7413, 0x553970a4, S=1,     1024, 0xde0a7c81
 0,        690,        690,        1,     7476, 0x24d2a761, S=1,     1024, 0xde0a7c81
-0,        700,        700,        1,     7595, 0x0ba1e430, S=1,     1024, 0xde0a7c81
+0,        700,        700,        1,     7596, 0xf072e431, S=1,     1024, 0xde0a7c81
 0,        710,        710,        1,     7756, 0x131205c0, S=1,     1024, 0xde0a7c81
 0,        720,        720,        1,     8015, 0xf4536a7f, S=1,     1024, 0xde0a7c81
 0,        730,        730,        1,     8128, 0xba80be2b, S=1,     1024, 0xde0a7c81
@@ -101,22 +101,22 @@
 0,        990,        990,        1,    11111, 0x34eb4c13, S=1,     1024, 0xde0a7c81
 0,       1000,       1000,        1,    11194, 0x584f6b73, S=1,     1024, 0xde0a7c81
 0,       1010,       1010,        1,    11240, 0xc90ba13f, S=1,     1024, 0xde0a7c81
-0,       1020,       1020,        1,    11482, 0x6521f3c4, S=1,     1024, 0xde0a7c81
+0,       1020,       1020,        1,    11483, 0x59c4f3c5, S=1,     1024, 0xde0a7c81
 0,       1030,       1030,        1,    11680, 0xc62c5bc1, S=1,     1024, 0xde0a7c81
 0,       1040,       1040,        1,    11785, 0xc9bab793, S=1,     1024, 0xde0a7c81
 0,       1050,       1050,        1,    11436, 0xc9c40809, S=1,     1024, 0xde0a7c81
-0,       1060,       1060,        1,    11927, 0x8135c9a6, S=1,     1024, 0xde0a7c81
+0,       1060,       1060,        1,    11928, 0x4b77c9a7, S=1,     1024, 0xde0a7c81
 0,       1070,       1070,        1,    11932, 0x722abcbe, S=1,     1024, 0xde0a7c81
-0,       1080,       1080,        1,    12280, 0x9cc46f52, S=1,     1024, 0xde0a7c81
+0,       1080,       1080,        1,    12281, 0x0d136f53, S=1,     1024, 0xde0a7c81
 0,       1090,       1090,        1,    12334, 0x04a47f78, S=1,     1024, 0xde0a7c81
 0,       1100,       1100,        1,    12452, 0xa02db188, S=1,     1024, 0xde0a7c81
 0,       1110,       1110,        1,    12695, 0x1a813b2e, S=1,     1024, 0xde0a7c81
-0,       1120,       1120,        1,    12667, 0x31c94f78, S=1,     1024, 0xde0a7c81
+0,       1120,       1120,        1,    12668, 0x81b24f79, S=1,     1024, 0xde0a7c81
 0,       1130,       1130,        1,    12957, 0x4da59f8c, S=1,     1024, 0xde0a7c81
-0,       1140,       1140,        1,    13053, 0x9a63df59, S=1,     1024, 0xde0a7c81
+0,       1140,       1140,        1,    13054, 0x7abedf5a, S=1,     1024, 0xde0a7c81
 0,       1150,       1150,        1,    13147, 0x138f2bbd, S=1,     1024, 0xde0a7c81
 0,       1160,       1160,        1,    13171, 0x43c1195f, S=1,     1024, 0xde0a7c81
-0,       1170,       1170,        1,    13197, 0xd32858d3, S=1,     1024, 0xde0a7c81
+0,       1170,       1170,        1,    13198, 0x2c8d58d4, S=1,     1024, 0xde0a7c81
 0,       1180,       1180,        1,    13211, 0x12c36193, S=1,     1024, 0xde0a7c81
 0,       1190,       1190,        1,    13210, 0xfe496107, S=1,     1024, 0xde0a7c81
 0,       1200,       1200,        1,    13467, 0x4d8ea128, S=1,     1024, 0xde0a7c81
@@ -147,8 +147,8 @@
 0,       1450,       1450,        1,    17149, 0x4074ca41, S=1,     1024, 0xde0a7c81
 0,       1460,       1460,        1,    17172, 0xf749b49f, S=1,     1024, 0xde0a7c81
 0,       1470,       1470,        1,    17315, 0x2abea8a0, S=1,     1024, 0xde0a7c81
-0,       1480,       1480,        1,    17396, 0x02ec1121, S=1,     1024, 0xde0a7c81
-0,       1490,       1490,        1,    17430, 0xdb5cf2d2, S=1,     1024, 0xde0a7c81
+0,       1480,       1480,        1,    17397, 0x14f71122, S=1,     1024, 0xde0a7c81
+0,       1490,       1490,        1,    17431, 0xce49f2d3, S=1,     1024, 0xde0a7c81
 0,       1500,       1500,        1,    17576, 0x7c6552ad, S=1,     1024, 0xde0a7c81
 0,       1510,       1510,        1,    17764, 0x1d198d60, S=1,     1024, 0xde0a7c81
 0,       1520,       1520,        1,    17826, 0xe1727f57, S=1,     1024, 0xde0a7c81
diff --git a/tests/ref/fate/gifenc-bgr8 b/tests/ref/fate/gifenc-bgr8
index 040c233..49db763 100644
--- a/tests/ref/fate/gifenc-bgr8
+++ b/tests/ref/fate/gifenc-bgr8
@@ -1,10 +1,10 @@
 #tb 0: 1/100
 0,          0,          0,        1,      552, 0x271a2dd3
 0,         10,         10,        1,      297, 0x90168a95, S=1,     1024, 0xf351799f
-0,         20,         20,        1,      437, 0xc31bce1a, S=1,     1024, 0xf351799f
+0,         20,         20,        1,      438, 0x91efce1b, S=1,     1024, 0xf351799f
 0,         30,         30,        1,      450, 0x7c2dcfad, S=1,     1024, 0xf351799f
 0,         40,         40,        1,      547, 0xc131fd3b, S=1,     1024, 0xf351799f
-0,         50,         50,        1,      613, 0x47b82005, S=1,     1024, 0xf351799f
+0,         50,         50,        1,      614, 0x68182006, S=1,     1024, 0xf351799f
 0,         60,         60,        1,      642, 0x78bb1f5f, S=1,     1024, 0xf351799f
 0,         70,         70,        1,      660, 0x35c033a2, S=1,     1024, 0xf351799f
 0,         80,         80,        1,      821, 0xaf30790b, S=1,     1024, 0xf351799f
@@ -16,56 +16,56 @@
 0,        140,        140,        1,     1720, 0xc95d45ec, S=1,     1024, 0xf351799f
 0,        150,        150,        1,     1910, 0x56cc831e, S=1,     1024, 0xf351799f
 0,        160,        160,        1,     2124, 0x9cc8e130, S=1,     1024, 0xf351799f
-0,        170,        170,        1,     2247, 0xdf2725b0, S=1,     1024, 0xf351799f
+0,        170,        170,        1,     2248, 0x05a325b1, S=1,     1024, 0xf351799f
 0,        180,        180,        1,     2311, 0xdc633703, S=1,     1024, 0xf351799f
 0,        190,        190,        1,     2408, 0x91c26f3e, S=1,     1024, 0xf351799f
 0,        200,        200,        1,     2601, 0x8cf3c157, S=1,     1024, 0xf351799f
-0,        210,        210,        1,     2686, 0x8e0b00e5, S=1,     1024, 0xf351799f
+0,        210,        210,        1,     2687, 0x8f6400e6, S=1,     1024, 0xf351799f
 0,        220,        220,        1,     2784, 0xaa880e55, S=1,     1024, 0xf351799f
 0,        230,        230,        1,     2884, 0x46f546f6, S=1,     1024, 0xf351799f
-0,        240,        240,        1,     2981, 0x050d7ad4, S=1,     1024, 0xf351799f
+0,        240,        240,        1,     2982, 0x807c7ad5, S=1,     1024, 0xf351799f
 0,        250,        250,        1,     3101, 0xbcc89bec, S=1,     1024, 0xf351799f
-0,        260,        260,        1,     3252, 0xdb80f3f9, S=1,     1024, 0xf351799f
+0,        260,        260,        1,     3253, 0xd032f3fa, S=1,     1024, 0xf351799f
 0,        270,        270,        1,     3329, 0xe4d42430, S=1,     1024, 0xf351799f
-0,        280,        280,        1,     3571, 0x6c7d8a9f, S=1,     1024, 0xf351799f
-0,        290,        290,        1,     3806, 0x4255f9f2, S=1,     1024, 0xf351799f
-0,        300,        300,        1,     2749, 0x64681c32, S=1,     1024, 0xf351799f
+0,        280,        280,        1,     3572, 0xf8058aa0, S=1,     1024, 0xf351799f
+0,        290,        290,        1,     3807, 0x3d2af9f3, S=1,     1024, 0xf351799f
+0,        300,        300,        1,     2750, 0x814d1c33, S=1,     1024, 0xf351799f
 0,        310,        310,        1,     4031, 0x3b077006, S=1,     1024, 0xf351799f
 0,        320,        320,        1,     3025, 0x86729c1c, S=1,     1024, 0xf351799f
-0,        330,        330,        1,     4294, 0xeb280b37, S=1,     1024, 0xf351799f
+0,        330,        330,        1,     4295, 0xf71b0b38, S=1,     1024, 0xf351799f
 0,        340,        340,        1,     2044, 0x5adcb93b, S=1,     1024, 0xf351799f
 0,        350,        350,        1,     3212, 0xcf79eeed, S=1,     1024, 0xf351799f
-0,        360,        360,        1,     2280, 0x1a394d2f, S=1,     1024, 0xf351799f
-0,        370,        370,        1,     3632, 0x66ad992e, S=1,     1024, 0xf351799f
+0,        360,        360,        1,     2281, 0x68464d30, S=1,     1024, 0xf351799f
+0,        370,        370,        1,     3633, 0x0010992f, S=1,     1024, 0xf351799f
 0,        380,        380,        1,     3552, 0x23697490, S=1,     1024, 0xf351799f
-0,        390,        390,        1,     3689, 0x868adbb7, S=1,     1024, 0xf351799f
+0,        390,        390,        1,     3690, 0x62afdbb8, S=1,     1024, 0xf351799f
 0,        400,        400,        1,     1558, 0x7a13e53b, S=1,     1024, 0xf351799f
-0,        410,        410,        1,      939, 0xe565cba1, S=1,     1024, 0xf351799f
+0,        410,        410,        1,      940, 0xb1b6cba2, S=1,     1024, 0xf351799f
 0,        420,        420,        1,      273, 0x3687799b, S=1,     1024, 0xf351799f
-0,        430,        430,        1,      929, 0x788ab0c3, S=1,     1024, 0xf351799f
+0,        430,        430,        1,      930, 0x29f3b0c4, S=1,     1024, 0xf351799f
 0,        440,        440,        1,      271, 0xe7af807c, S=1,     1024, 0xf351799f
 0,        450,        450,        1,      196, 0xf5ab51ee, S=1,     1024, 0xf351799f
 0,        460,        460,        1,     4299, 0x67ec0d55, S=1,     1024, 0xf351799f
-0,        470,        470,        1,     4894, 0x7315406b, S=1,     1024, 0xf351799f
-0,        480,        480,        1,     4927, 0x092e19d6, S=1,     1024, 0xf351799f
+0,        470,        470,        1,     4895, 0xb394406c, S=1,     1024, 0xf351799f
+0,        480,        480,        1,     4928, 0x233919d7, S=1,     1024, 0xf351799f
 0,        490,        490,        1,     4941, 0x58a357da, S=1,     1024, 0xf351799f
-0,        500,        500,        1,     4153, 0x7582ac32, S=1,     1024, 0xf351799f
-0,        510,        510,        1,     4677, 0xeaa3c04f, S=1,     1024, 0xf351799f
-0,        520,        520,        1,     4740, 0x636bb580, S=1,     1024, 0xf351799f
-0,        530,        530,        1,     4981, 0x31d556d4, S=1,     1024, 0xf351799f
+0,        500,        500,        1,     4154, 0x21f2ac33, S=1,     1024, 0xf351799f
+0,        510,        510,        1,     4678, 0xab3cc050, S=1,     1024, 0xf351799f
+0,        520,        520,        1,     4741, 0x1974b581, S=1,     1024, 0xf351799f
+0,        530,        530,        1,     4982, 0x891456d5, S=1,     1024, 0xf351799f
 0,        540,        540,        1,     5179, 0x860fc6a1, S=1,     1024, 0xf351799f
 0,        550,        550,        1,     5046, 0xce9183d3, S=1,     1024, 0xf351799f
 0,        560,        560,        1,     5140, 0xa6d7b9af, S=1,     1024, 0xf351799f
-0,        570,        570,        1,     4288, 0xbc3af716, S=1,     1024, 0xf351799f
+0,        570,        570,        1,     4289, 0xb415f717, S=1,     1024, 0xf351799f
 0,        580,        580,        1,     5079, 0xa8d59e01, S=1,     1024, 0xf351799f
 0,        590,        590,        1,     5284, 0xea34e3b3, S=1,     1024, 0xf351799f
 0,        600,        600,        1,     5426, 0x556a15cd, S=1,     1024, 0xf351799f
-0,        610,        610,        1,     4644, 0x7cc08935, S=1,     1024, 0xf351799f
+0,        610,        610,        1,     4645, 0x061e8936, S=1,     1024, 0xf351799f
 0,        620,        620,        1,     5263, 0x7536cf7d, S=1,     1024, 0xf351799f
 0,        630,        630,        1,     5221, 0x9fbac3ca, S=1,     1024, 0xf351799f
-0,        640,        640,        1,     5216, 0x65f09bd1, S=1,     1024, 0xf351799f
-0,        650,        650,        1,     5394, 0x1293ff65, S=1,     1024, 0xf351799f
-0,        660,        660,        1,     5219, 0x9aa2dcc4, S=1,     1024, 0xf351799f
+0,        640,        640,        1,     5217, 0x02269bd2, S=1,     1024, 0xf351799f
+0,        650,        650,        1,     5395, 0x120fff66, S=1,     1024, 0xf351799f
+0,        660,        660,        1,     5220, 0x77cedcc5, S=1,     1024, 0xf351799f
 0,        670,        670,        1,     5704, 0xba42dd96, S=1,     1024, 0xf351799f
 0,        680,        680,        1,     5636, 0xcb91a25b, S=1,     1024, 0xf351799f
 0,        690,        690,        1,     5818, 0x8dc0df92, S=1,     1024, 0xf351799f
@@ -83,7 +83,7 @@
 0,        810,        810,        1,     8358, 0x027279e8, S=1,     1024, 0xf351799f
 0,        820,        820,        1,     7708, 0x607f8e8b, S=1,     1024, 0xf351799f
 0,        830,        830,        1,     7412, 0x6bb2105f, S=1,     1024, 0xf351799f
-0,        840,        840,        1,     7540, 0xdc032153, S=1,     1024, 0xf351799f
+0,        840,        840,        1,     7541, 0xfdc02154, S=1,     1024, 0xf351799f
 0,        850,        850,        1,     7948, 0x916ecd8b, S=1,     1024, 0xf351799f
 0,        860,        860,        1,     8408, 0x1f97d414, S=1,     1024, 0xf351799f
 0,        870,        870,        1,     8056, 0x9cbf159c, S=1,     1024, 0xf351799f
@@ -93,12 +93,12 @@
 0,        910,        910,        1,     7768, 0x25ed7ee7, S=1,     1024, 0xf351799f
 0,        920,        920,        1,     7749, 0x6d8e978e, S=1,     1024, 0xf351799f
 0,        930,        930,        1,     8047, 0xec4b150c, S=1,     1024, 0xf351799f
-0,        940,        940,        1,     7617, 0x574430d4, S=1,     1024, 0xf351799f
+0,        940,        940,        1,     7618, 0x88cf30d5, S=1,     1024, 0xf351799f
 0,        950,        950,        1,     7979, 0x0eb1cf2a, S=1,     1024, 0xf351799f
 0,        960,        960,        1,    12062, 0xb49d9125, S=1,     1024, 0xf351799f
 0,        970,        970,        1,    12317, 0x2d8fd6e9, S=1,     1024, 0xf351799f
 0,        980,        980,        1,    12217, 0x9b3be549, S=1,     1024, 0xf351799f
-0,        990,        990,        1,    11226, 0x74889117, S=1,     1024, 0xf351799f
+0,        990,        990,        1,    11227, 0x067e9118, S=1,     1024, 0xf351799f
 0,       1000,       1000,        1,    11108, 0x5e5b0afd, S=1,     1024, 0xf351799f
 0,       1010,       1010,        1,    11366, 0xb38e8d15, S=1,     1024, 0xf351799f
 0,       1020,       1020,        1,    11896, 0xeb3e35ca, S=1,     1024, 0xf351799f
@@ -135,7 +135,7 @@
 0,       1330,       1330,        1,    17934, 0xb539974b, S=1,     1024, 0xf351799f
 0,       1340,       1340,        1,    17944, 0x2214ec94, S=1,     1024, 0xf351799f
 0,       1350,       1350,        1,    18238, 0x70f9ff1d, S=1,     1024, 0xf351799f
-0,       1360,       1360,        1,    18390, 0xb8319208, S=1,     1024, 0xf351799f
+0,       1360,       1360,        1,    18391, 0x4b149209, S=1,     1024, 0xf351799f
 0,       1370,       1370,        1,    18543, 0x45a1c02f, S=1,     1024, 0xf351799f
 0,       1380,       1380,        1,    18939, 0x2789a88c, S=1,     1024, 0xf351799f
 0,       1390,       1390,        1,    19145, 0x5daafd7a, S=1,     1024, 0xf351799f
@@ -166,7 +166,7 @@
 0,       1640,       1640,        1,    22460, 0xf9ceb0ac, S=1,     1024, 0xf351799f
 0,       1650,       1650,        1,    22861, 0xb05f0f84, S=1,     1024, 0xf351799f
 0,       1660,       1660,        1,    22746, 0x0df23a5c, S=1,     1024, 0xf351799f
-0,       1670,       1670,        1,    23164, 0x755347ac, S=1,     1024, 0xf351799f
+0,       1670,       1670,        1,    23165, 0xbd7147ad, S=1,     1024, 0xf351799f
 0,       1680,       1680,        1,    23273, 0x9781a34f, S=1,     1024, 0xf351799f
 0,       1690,       1690,        1,    23211, 0x69c7606b, S=1,     1024, 0xf351799f
 0,       1700,       1700,        1,    23648, 0xdafde037, S=1,     1024, 0xf351799f
diff --git a/tests/ref/fate/gifenc-gray b/tests/ref/fate/gifenc-gray
index 404237d..8fdc3b3 100644
--- a/tests/ref/fate/gifenc-gray
+++ b/tests/ref/fate/gifenc-gray
@@ -1,174 +1,174 @@
 #tb 0: 1/100
-0,          0,          0,        1,      568, 0xe1d43487
-0,         10,         10,        1,      142, 0x92d43281, S=1,     1024, 0xc2f67c9f
-0,         20,         20,        1,      130, 0x29383852, S=1,     1024, 0xc2f67c9f
-0,         30,         30,        1,      129, 0x036732fa, S=1,     1024, 0xc2f67c9f
-0,         40,         40,        1,      145, 0xcbc036bb, S=1,     1024, 0xc2f67c9f
-0,         50,         50,        1,      135, 0x6e4536d1, S=1,     1024, 0xc2f67c9f
-0,         60,         60,        1,      127, 0xe73f2f55, S=1,     1024, 0xc2f67c9f
-0,         70,         70,        1,      119, 0x7912307f, S=1,     1024, 0xc2f67c9f
-0,         80,         80,        1,      132, 0xce58343c, S=1,     1024, 0xc2f67c9f
-0,         90,         90,        1,      126, 0x1fcd2b9c, S=1,     1024, 0xc2f67c9f
-0,        100,        100,        1,      127, 0x6c293369, S=1,     1024, 0xc2f67c9f
-0,        110,        110,        1,      126, 0x19162e3f, S=1,     1024, 0xc2f67c9f
-0,        120,        120,        1,      119, 0x06602dec, S=1,     1024, 0xc2f67c9f
-0,        130,        130,        1,      118, 0x8b083037, S=1,     1024, 0xc2f67c9f
-0,        140,        140,        1,      115, 0xa8372c6d, S=1,     1024, 0xc2f67c9f
-0,        150,        150,        1,      114, 0x8d0f2dbd, S=1,     1024, 0xc2f67c9f
-0,        160,        160,        1,      129, 0xb5ab318d, S=1,     1024, 0xc2f67c9f
-0,        170,        170,        1,      129, 0x278e34bd, S=1,     1024, 0xc2f67c9f
-0,        180,        180,        1,      119, 0x408e3131, S=1,     1024, 0xc2f67c9f
-0,        190,        190,        1,      121, 0x069a2c25, S=1,     1024, 0xc2f67c9f
-0,        200,        200,        1,      127, 0x24793635, S=1,     1024, 0xc2f67c9f
-0,        210,        210,        1,      110, 0xe30a29cc, S=1,     1024, 0xc2f67c9f
-0,        220,        220,        1,      116, 0xf7b827f0, S=1,     1024, 0xc2f67c9f
-0,        230,        230,        1,      118, 0xf5f62ff6, S=1,     1024, 0xc2f67c9f
-0,        240,        240,        1,      115, 0xb7c92c27, S=1,     1024, 0xc2f67c9f
-0,        250,        250,        1,      114, 0x0a642b7e, S=1,     1024, 0xc2f67c9f
-0,        260,        260,        1,      114, 0x07b32c7c, S=1,     1024, 0xc2f67c9f
-0,        270,        270,        1,      118, 0x1f4432b8, S=1,     1024, 0xc2f67c9f
-0,        280,        280,        1,      144, 0xa81e3c75, S=1,     1024, 0xc2f67c9f
-0,        290,        290,        1,      121, 0xacb828d6, S=1,     1024, 0xc2f67c9f
-0,        300,        300,        1,      148, 0xb245426a, S=1,     1024, 0xc2f67c9f
-0,        310,        310,        1,      124, 0x3d173009, S=1,     1024, 0xc2f67c9f
-0,        320,        320,        1,      151, 0xa57c443d, S=1,     1024, 0xc2f67c9f
-0,        330,        330,        1,      121, 0x93da2d00, S=1,     1024, 0xc2f67c9f
-0,        340,        340,        1,      124, 0x1dd02f53, S=1,     1024, 0xc2f67c9f
-0,        350,        350,        1,      117, 0xb0942d05, S=1,     1024, 0xc2f67c9f
-0,        360,        360,        1,      117, 0xb5af292b, S=1,     1024, 0xc2f67c9f
-0,        370,        370,        1,      116, 0x731a30ff, S=1,     1024, 0xc2f67c9f
-0,        380,        380,        1,      123, 0x16342dde, S=1,     1024, 0xc2f67c9f
-0,        390,        390,        1,      117, 0xef9e2f92, S=1,     1024, 0xc2f67c9f
-0,        400,        400,        1,      110, 0x646e2a4a, S=1,     1024, 0xc2f67c9f
-0,        410,        410,        1,      110, 0xe44f2be1, S=1,     1024, 0xc2f67c9f
-0,        420,        420,        1,      108, 0x58f22c11, S=1,     1024, 0xc2f67c9f
-0,        430,        430,        1,      112, 0x2c702d3e, S=1,     1024, 0xc2f67c9f
-0,        440,        440,        1,      111, 0x7b412ab9, S=1,     1024, 0xc2f67c9f
-0,        450,        450,        1,      112, 0xe95d2dfb, S=1,     1024, 0xc2f67c9f
-0,        460,        460,        1,      109, 0x2baf2bde, S=1,     1024, 0xc2f67c9f
-0,        470,        470,        1,      114, 0x3a772c6a, S=1,     1024, 0xc2f67c9f
-0,        480,        480,        1,      110, 0xfe702831, S=1,     1024, 0xc2f67c9f
-0,        490,        490,        1,      125, 0xa31f344b, S=1,     1024, 0xc2f67c9f
-0,        500,        500,        1,      119, 0xbc31318d, S=1,     1024, 0xc2f67c9f
-0,        510,        510,        1,      115, 0xc7b62b8f, S=1,     1024, 0xc2f67c9f
-0,        520,        520,        1,      118, 0x7cf22dcb, S=1,     1024, 0xc2f67c9f
-0,        530,        530,        1,      119, 0xe16c2f96, S=1,     1024, 0xc2f67c9f
-0,        540,        540,        1,      119, 0x86d43604, S=1,     1024, 0xc2f67c9f
-0,        550,        550,        1,      109, 0x22b72af1, S=1,     1024, 0xc2f67c9f
-0,        560,        560,        1,      103, 0x12982731, S=1,     1024, 0xc2f67c9f
-0,        570,        570,        1,      114, 0x6ef22e10, S=1,     1024, 0xc2f67c9f
-0,        580,        580,        1,      109, 0x621b26dd, S=1,     1024, 0xc2f67c9f
-0,        590,        590,        1,      110, 0xfe062836, S=1,     1024, 0xc2f67c9f
-0,        600,        600,        1,      112, 0x4a8e2ce3, S=1,     1024, 0xc2f67c9f
-0,        610,        610,        1,      111, 0xa7ae2865, S=1,     1024, 0xc2f67c9f
-0,        620,        620,        1,      103, 0x80bc2b33, S=1,     1024, 0xc2f67c9f
-0,        630,        630,        1,      114, 0xc2f92f3f, S=1,     1024, 0xc2f67c9f
-0,        640,        640,        1,      108, 0x81332cdf, S=1,     1024, 0xc2f67c9f
-0,        650,        650,        1,      121, 0x0d1133ad, S=1,     1024, 0xc2f67c9f
-0,        660,        660,        1,      136, 0x2c0c3481, S=1,     1024, 0xc2f67c9f
-0,        670,        670,        1,      108, 0x55222d1f, S=1,     1024, 0xc2f67c9f
-0,        680,        680,        1,      125, 0x9cc536df, S=1,     1024, 0xc2f67c9f
-0,        690,        690,        1,      114, 0x04602ae4, S=1,     1024, 0xc2f67c9f
-0,        700,        700,        1,       99, 0xd58f291d, S=1,     1024, 0xc2f67c9f
-0,        710,        710,        1,       98, 0xcb8f2807, S=1,     1024, 0xc2f67c9f
-0,        720,        720,        1,      109, 0x7f292c9b, S=1,     1024, 0xc2f67c9f
-0,        730,        730,        1,      106, 0x3daa297f, S=1,     1024, 0xc2f67c9f
-0,        740,        740,        1,      100, 0xb7032b73, S=1,     1024, 0xc2f67c9f
-0,        750,        750,        1,       88, 0xd56b218e, S=1,     1024, 0xc2f67c9f
-0,        760,        760,        1,       93, 0xdcfd2353, S=1,     1024, 0xc2f67c9f
-0,        770,        770,        1,      112, 0x35322b03, S=1,     1024, 0xc2f67c9f
-0,        780,        780,        1,      112, 0x7c2b2d67, S=1,     1024, 0xc2f67c9f
-0,        790,        790,        1,      204, 0xd02c5bd9, S=1,     1024, 0xc2f67c9f
-0,        800,        800,        1,      204, 0x82055f0a, S=1,     1024, 0xc2f67c9f
-0,        810,        810,        1,      115, 0x76472e9b, S=1,     1024, 0xc2f67c9f
-0,        820,        820,        1,      110, 0x22b12abc, S=1,     1024, 0xc2f67c9f
-0,        830,        830,        1,      116, 0x50a0318e, S=1,     1024, 0xc2f67c9f
-0,        840,        840,        1,      115, 0x10632f57, S=1,     1024, 0xc2f67c9f
-0,        850,        850,        1,      120, 0x9c5631e3, S=1,     1024, 0xc2f67c9f
-0,        860,        860,        1,      114, 0x0e192ed8, S=1,     1024, 0xc2f67c9f
-0,        870,        870,        1,      109, 0xdedb2a99, S=1,     1024, 0xc2f67c9f
-0,        880,        880,        1,      105, 0x639c2cf5, S=1,     1024, 0xc2f67c9f
-0,        890,        890,        1,      117, 0x4aff2afa, S=1,     1024, 0xc2f67c9f
-0,        900,        900,        1,      103, 0x44842781, S=1,     1024, 0xc2f67c9f
-0,        910,        910,        1,      147, 0x22493e48, S=1,     1024, 0xc2f67c9f
-0,        920,        920,        1,      117, 0x3cb02d86, S=1,     1024, 0xc2f67c9f
-0,        930,        930,        1,      111, 0x813d2e1f, S=1,     1024, 0xc2f67c9f
-0,        940,        940,        1,       83, 0xb6961b02, S=1,     1024, 0xc2f67c9f
-0,        950,        950,        1,      159, 0x5f2e43d0, S=1,     1024, 0xc2f67c9f
-0,        960,        960,        1,      126, 0x56d42d1d, S=1,     1024, 0xc2f67c9f
-0,        970,        970,        1,      164, 0xea6c464d, S=1,     1024, 0xc2f67c9f
-0,        980,        980,        1,      133, 0x21113425, S=1,     1024, 0xc2f67c9f
-0,        990,        990,        1,      125, 0xfc6e322e, S=1,     1024, 0xc2f67c9f
-0,       1000,       1000,        1,      116, 0x226830da, S=1,     1024, 0xc2f67c9f
-0,       1010,       1010,        1,      130, 0xa71a317d, S=1,     1024, 0xc2f67c9f
-0,       1020,       1020,        1,      127, 0x5b5433af, S=1,     1024, 0xc2f67c9f
-0,       1030,       1030,        1,      172, 0x0ed64b21, S=1,     1024, 0xc2f67c9f
-0,       1040,       1040,        1,      142, 0x9733380f, S=1,     1024, 0xc2f67c9f
-0,       1050,       1050,        1,      184, 0x358b533c, S=1,     1024, 0xc2f67c9f
-0,       1060,       1060,        1,      155, 0x5304441c, S=1,     1024, 0xc2f67c9f
-0,       1070,       1070,        1,      139, 0x15743a98, S=1,     1024, 0xc2f67c9f
-0,       1080,       1080,        1,      129, 0xc5782f81, S=1,     1024, 0xc2f67c9f
-0,       1090,       1090,        1,      144, 0x1ee637c8, S=1,     1024, 0xc2f67c9f
-0,       1100,       1100,        1,      133, 0x69403297, S=1,     1024, 0xc2f67c9f
-0,       1110,       1110,        1,      192, 0x128553a4, S=1,     1024, 0xc2f67c9f
-0,       1120,       1120,        1,      159, 0xea783f5a, S=1,     1024, 0xc2f67c9f
-0,       1130,       1130,        1,      201, 0xc04252a1, S=1,     1024, 0xc2f67c9f
-0,       1140,       1140,        1,      161, 0xb56b44f6, S=1,     1024, 0xc2f67c9f
-0,       1150,       1150,        1,      136, 0x402130e8, S=1,     1024, 0xc2f67c9f
-0,       1160,       1160,        1,      117, 0x694c3490, S=1,     1024, 0xc2f67c9f
-0,       1170,       1170,        1,      151, 0x96803b5d, S=1,     1024, 0xc2f67c9f
-0,       1180,       1180,        1,      135, 0x9a9b399f, S=1,     1024, 0xc2f67c9f
-0,       1190,       1190,        1,      147, 0x7e83348d, S=1,     1024, 0xc2f67c9f
-0,       1200,       1200,        1,      135, 0x932e3720, S=1,     1024, 0xc2f67c9f
-0,       1210,       1210,        1,      183, 0x822946e2, S=1,     1024, 0xc2f67c9f
-0,       1220,       1220,        1,      116, 0x93652e25, S=1,     1024, 0xc2f67c9f
-0,       1230,       1230,        1,      117, 0x77063135, S=1,     1024, 0xc2f67c9f
-0,       1240,       1240,        1,      109, 0x12752965, S=1,     1024, 0xc2f67c9f
-0,       1250,       1250,        1,      111, 0x8fd62b54, S=1,     1024, 0xc2f67c9f
-0,       1260,       1260,        1,      188, 0x6c1850e5, S=1,     1024, 0xc2f67c9f
-0,       1270,       1270,        1,      121, 0x15003168, S=1,     1024, 0xc2f67c9f
-0,       1280,       1280,        1,      115, 0x93482f77, S=1,     1024, 0xc2f67c9f
-0,       1290,       1290,        1,      120, 0x36552de5, S=1,     1024, 0xc2f67c9f
-0,       1300,       1300,        1,      117, 0x74472f78, S=1,     1024, 0xc2f67c9f
-0,       1310,       1310,        1,      188, 0xadac5400, S=1,     1024, 0xc2f67c9f
-0,       1320,       1320,        1,      125, 0xccb83070, S=1,     1024, 0xc2f67c9f
-0,       1330,       1330,        1,      118, 0x606e2d29, S=1,     1024, 0xc2f67c9f
-0,       1340,       1340,        1,      130, 0x77eb3516, S=1,     1024, 0xc2f67c9f
-0,       1350,       1350,        1,      120, 0x500f3045, S=1,     1024, 0xc2f67c9f
-0,       1360,       1360,        1,      164, 0x729244f4, S=1,     1024, 0xc2f67c9f
-0,       1370,       1370,        1,      234, 0xff2969ee, S=1,     1024, 0xc2f67c9f
-0,       1380,       1380,        1,      207, 0xf9366155, S=1,     1024, 0xc2f67c9f
-0,       1390,       1390,        1,      210, 0x31555d58, S=1,     1024, 0xc2f67c9f
-0,       1400,       1400,        1,      118, 0x7f9a32bd, S=1,     1024, 0xc2f67c9f
-0,       1410,       1410,        1,      120, 0xfba63099, S=1,     1024, 0xc2f67c9f
-0,       1420,       1420,        1,      114, 0xcb382d23, S=1,     1024, 0xc2f67c9f
-0,       1430,       1430,        1,      115, 0x10f32bad, S=1,     1024, 0xc2f67c9f
-0,       1440,       1440,        1,      206, 0x405e630e, S=1,     1024, 0xc2f67c9f
-0,       1450,       1450,        1,      216, 0xf6e6635f, S=1,     1024, 0xc2f67c9f
-0,       1460,       1460,        1,      123, 0x43aa33b8, S=1,     1024, 0xc2f67c9f
-0,       1470,       1470,        1,      121, 0x780d3018, S=1,     1024, 0xc2f67c9f
-0,       1480,       1480,        1,      121, 0xdba92f73, S=1,     1024, 0xc2f67c9f
-0,       1490,       1490,        1,      118, 0x35b32e26, S=1,     1024, 0xc2f67c9f
-0,       1500,       1500,        1,      116, 0x79ff2c29, S=1,     1024, 0xc2f67c9f
-0,       1510,       1510,        1,      110, 0xb0552ba1, S=1,     1024, 0xc2f67c9f
-0,       1520,       1520,        1,      117, 0x08f62fd4, S=1,     1024, 0xc2f67c9f
-0,       1530,       1530,        1,      112, 0x0dac2e9d, S=1,     1024, 0xc2f67c9f
-0,       1540,       1540,        1,      142, 0x092138a5, S=1,     1024, 0xc2f67c9f
-0,       1550,       1550,        1,      119, 0x752a2fc6, S=1,     1024, 0xc2f67c9f
-0,       1560,       1560,        1,      105, 0xec5824cd, S=1,     1024, 0xc2f67c9f
-0,       1570,       1570,        1,      115, 0xea282f22, S=1,     1024, 0xc2f67c9f
-0,       1580,       1580,        1,      108, 0x60b72ece, S=1,     1024, 0xc2f67c9f
-0,       1590,       1590,        1,      139, 0x6ec63b92, S=1,     1024, 0xc2f67c9f
-0,       1600,       1600,        1,      216, 0x2c906371, S=1,     1024, 0xc2f67c9f
-0,       1610,       1610,        1,      226, 0x77b1687d, S=1,     1024, 0xc2f67c9f
-0,       1620,       1620,        1,      155, 0x8180455a, S=1,     1024, 0xc2f67c9f
-0,       1630,       1630,        1,      121, 0x66092c73, S=1,     1024, 0xc2f67c9f
-0,       1640,       1640,        1,      123, 0xf9f22cb9, S=1,     1024, 0xc2f67c9f
-0,       1650,       1650,        1,      220, 0x65525fcb, S=1,     1024, 0xc2f67c9f
-0,       1660,       1660,        1,      153, 0x4b9f414c, S=1,     1024, 0xc2f67c9f
-0,       1670,       1670,        1,      120, 0x072e3379, S=1,     1024, 0xc2f67c9f
-0,       1680,       1680,        1,      109, 0xe46a2b38, S=1,     1024, 0xc2f67c9f
-0,       1690,       1690,        1,      118, 0xf0f12d62, S=1,     1024, 0xc2f67c9f
-0,       1700,       1700,        1,      117, 0xcb9e2cbb, S=1,     1024, 0xc2f67c9f
-0,       1710,       1710,        1,      137, 0x1ae83718, S=1,     1024, 0xc2f67c9f
-0,       1720,       1720,        1,      161, 0x87364667, S=1,     1024, 0xc2f67c9f
+0,          0,          0,        1,      579, 0x0d0e3ab8
+0,         10,         10,        1,      150, 0x178b3a8c, S=1,     1024, 0xc2f67c9f
+0,         20,         20,        1,      155, 0x941743f5, S=1,     1024, 0xc2f67c9f
+0,         30,         30,        1,      144, 0x68c73711, S=1,     1024, 0xc2f67c9f
+0,         40,         40,        1,      152, 0xaf9a3f2e, S=1,     1024, 0xc2f67c9f
+0,         50,         50,        1,      136, 0x68593d85, S=1,     1024, 0xc2f67c9f
+0,         60,         60,        1,      134, 0x0dcb373f, S=1,     1024, 0xc2f67c9f
+0,         70,         70,        1,      129, 0x3baf3279, S=1,     1024, 0xc2f67c9f
+0,         80,         80,        1,      123, 0x9c963148, S=1,     1024, 0xc2f67c9f
+0,         90,         90,        1,      123, 0x5c272d6b, S=1,     1024, 0xc2f67c9f
+0,        100,        100,        1,      150, 0x5f8d41aa, S=1,     1024, 0xc2f67c9f
+0,        110,        110,        1,      134, 0x6f582fee, S=1,     1024, 0xc2f67c9f
+0,        120,        120,        1,      134, 0x85d53038, S=1,     1024, 0xc2f67c9f
+0,        130,        130,        1,      123, 0x6d2a2cb2, S=1,     1024, 0xc2f67c9f
+0,        140,        140,        1,      127, 0x1e78327b, S=1,     1024, 0xc2f67c9f
+0,        150,        150,        1,      119, 0xbafc2c31, S=1,     1024, 0xc2f67c9f
+0,        160,        160,        1,      138, 0x57553638, S=1,     1024, 0xc2f67c9f
+0,        170,        170,        1,      140, 0xf7423adb, S=1,     1024, 0xc2f67c9f
+0,        180,        180,        1,      122, 0x7e592f8b, S=1,     1024, 0xc2f67c9f
+0,        190,        190,        1,      123, 0xaa7d313c, S=1,     1024, 0xc2f67c9f
+0,        200,        200,        1,      140, 0x4fd63b34, S=1,     1024, 0xc2f67c9f
+0,        210,        210,        1,      123, 0x67753163, S=1,     1024, 0xc2f67c9f
+0,        220,        220,        1,      123, 0x02193147, S=1,     1024, 0xc2f67c9f
+0,        230,        230,        1,      124, 0xa85131e9, S=1,     1024, 0xc2f67c9f
+0,        240,        240,        1,      122, 0xef8731e2, S=1,     1024, 0xc2f67c9f
+0,        250,        250,        1,      122, 0x06d432c9, S=1,     1024, 0xc2f67c9f
+0,        260,        260,        1,      123, 0xcc8831cd, S=1,     1024, 0xc2f67c9f
+0,        270,        270,        1,      118, 0xa1d33166, S=1,     1024, 0xc2f67c9f
+0,        280,        280,        1,      159, 0xcc8c454c, S=1,     1024, 0xc2f67c9f
+0,        290,        290,        1,      140, 0x8a0231ad, S=1,     1024, 0xc2f67c9f
+0,        300,        300,        1,      163, 0xe78248d2, S=1,     1024, 0xc2f67c9f
+0,        310,        310,        1,      142, 0x3b293489, S=1,     1024, 0xc2f67c9f
+0,        320,        320,        1,      170, 0x5f504b12, S=1,     1024, 0xc2f67c9f
+0,        330,        330,        1,      146, 0x38a53693, S=1,     1024, 0xc2f67c9f
+0,        340,        340,        1,      132, 0xb18a3499, S=1,     1024, 0xc2f67c9f
+0,        350,        350,        1,      113, 0x55182bda, S=1,     1024, 0xc2f67c9f
+0,        360,        360,        1,      132, 0xaced3333, S=1,     1024, 0xc2f67c9f
+0,        370,        370,        1,      120, 0x9ffe2e4f, S=1,     1024, 0xc2f67c9f
+0,        380,        380,        1,      135, 0x6223351e, S=1,     1024, 0xc2f67c9f
+0,        390,        390,        1,      123, 0x269b3058, S=1,     1024, 0xc2f67c9f
+0,        400,        400,        1,      119, 0x17052def, S=1,     1024, 0xc2f67c9f
+0,        410,        410,        1,      119, 0x36da2ee2, S=1,     1024, 0xc2f67c9f
+0,        420,        420,        1,      120, 0x984e31be, S=1,     1024, 0xc2f67c9f
+0,        430,        430,        1,      114, 0xfd382c9d, S=1,     1024, 0xc2f67c9f
+0,        440,        440,        1,      125, 0x926a36c6, S=1,     1024, 0xc2f67c9f
+0,        450,        450,        1,      117, 0xbceb3183, S=1,     1024, 0xc2f67c9f
+0,        460,        460,        1,      116, 0xf4c72d82, S=1,     1024, 0xc2f67c9f
+0,        470,        470,        1,      124, 0x0c19343c, S=1,     1024, 0xc2f67c9f
+0,        480,        480,        1,      117, 0x1f032eb1, S=1,     1024, 0xc2f67c9f
+0,        490,        490,        1,      135, 0x31a437e6, S=1,     1024, 0xc2f67c9f
+0,        500,        500,        1,      131, 0x4c1735fe, S=1,     1024, 0xc2f67c9f
+0,        510,        510,        1,      122, 0xb7603463, S=1,     1024, 0xc2f67c9f
+0,        520,        520,        1,      122, 0x7f5e34e1, S=1,     1024, 0xc2f67c9f
+0,        530,        530,        1,      124, 0x9562350f, S=1,     1024, 0xc2f67c9f
+0,        540,        540,        1,      126, 0x18b33759, S=1,     1024, 0xc2f67c9f
+0,        550,        550,        1,      117, 0x748f3243, S=1,     1024, 0xc2f67c9f
+0,        560,        560,        1,      109, 0x72832fe7, S=1,     1024, 0xc2f67c9f
+0,        570,        570,        1,      120, 0x748a2e38, S=1,     1024, 0xc2f67c9f
+0,        580,        580,        1,      120, 0x61f82fb2, S=1,     1024, 0xc2f67c9f
+0,        590,        590,        1,      122, 0x2a6b3282, S=1,     1024, 0xc2f67c9f
+0,        600,        600,        1,      116, 0x8b542de6, S=1,     1024, 0xc2f67c9f
+0,        610,        610,        1,      119, 0xf33c318e, S=1,     1024, 0xc2f67c9f
+0,        620,        620,        1,      116, 0xff182f36, S=1,     1024, 0xc2f67c9f
+0,        630,        630,        1,      119, 0xeb9e2fcc, S=1,     1024, 0xc2f67c9f
+0,        640,        640,        1,      118, 0xe82d304e, S=1,     1024, 0xc2f67c9f
+0,        650,        650,        1,      137, 0x98303d30, S=1,     1024, 0xc2f67c9f
+0,        660,        660,        1,      149, 0x01123fff, S=1,     1024, 0xc2f67c9f
+0,        670,        670,        1,      115, 0x4ca92f75, S=1,     1024, 0xc2f67c9f
+0,        680,        680,        1,      131, 0xf4193bc0, S=1,     1024, 0xc2f67c9f
+0,        690,        690,        1,      115, 0xda5e2f30, S=1,     1024, 0xc2f67c9f
+0,        700,        700,        1,      100, 0x9ba32a58, S=1,     1024, 0xc2f67c9f
+0,        710,        710,        1,      109, 0xa47e2c91, S=1,     1024, 0xc2f67c9f
+0,        720,        720,        1,      120, 0x22452fd6, S=1,     1024, 0xc2f67c9f
+0,        730,        730,        1,      116, 0xd3c52c26, S=1,     1024, 0xc2f67c9f
+0,        740,        740,        1,      106, 0x95b42c9f, S=1,     1024, 0xc2f67c9f
+0,        750,        750,        1,       96, 0xfdc12639, S=1,     1024, 0xc2f67c9f
+0,        760,        760,        1,       99, 0x210f251b, S=1,     1024, 0xc2f67c9f
+0,        770,        770,        1,      119, 0x173b341c, S=1,     1024, 0xc2f67c9f
+0,        780,        780,        1,      119, 0x3bca2f29, S=1,     1024, 0xc2f67c9f
+0,        790,        790,        1,      213, 0x9e905d4c, S=1,     1024, 0xc2f67c9f
+0,        800,        800,        1,      209, 0xa0015e94, S=1,     1024, 0xc2f67c9f
+0,        810,        810,        1,      120, 0x36762bd4, S=1,     1024, 0xc2f67c9f
+0,        820,        820,        1,      119, 0x019b2edc, S=1,     1024, 0xc2f67c9f
+0,        830,        830,        1,      124, 0x211d30e7, S=1,     1024, 0xc2f67c9f
+0,        840,        840,        1,      125, 0x538732ff, S=1,     1024, 0xc2f67c9f
+0,        850,        850,        1,      123, 0x2887308a, S=1,     1024, 0xc2f67c9f
+0,        860,        860,        1,      119, 0x7ff930f4, S=1,     1024, 0xc2f67c9f
+0,        870,        870,        1,      119, 0xa50c2e16, S=1,     1024, 0xc2f67c9f
+0,        880,        880,        1,      107, 0x9ed02cea, S=1,     1024, 0xc2f67c9f
+0,        890,        890,        1,      119, 0xc234332a, S=1,     1024, 0xc2f67c9f
+0,        900,        900,        1,      115, 0x38353092, S=1,     1024, 0xc2f67c9f
+0,        910,        910,        1,      162, 0x6cda4644, S=1,     1024, 0xc2f67c9f
+0,        920,        920,        1,      124, 0x2f683081, S=1,     1024, 0xc2f67c9f
+0,        930,        930,        1,      116, 0x72952d04, S=1,     1024, 0xc2f67c9f
+0,        940,        940,        1,       84, 0x1a532301, S=1,     1024, 0xc2f67c9f
+0,        950,        950,        1,      176, 0xfb3c5400, S=1,     1024, 0xc2f67c9f
+0,        960,        960,        1,      137, 0x253132d1, S=1,     1024, 0xc2f67c9f
+0,        970,        970,        1,      179, 0x2b38528b, S=1,     1024, 0xc2f67c9f
+0,        980,        980,        1,      150, 0xbe413cbe, S=1,     1024, 0xc2f67c9f
+0,        990,        990,        1,      140, 0x9e93392a, S=1,     1024, 0xc2f67c9f
+0,       1000,       1000,        1,      129, 0x577e331e, S=1,     1024, 0xc2f67c9f
+0,       1010,       1010,        1,      146, 0x16ff3924, S=1,     1024, 0xc2f67c9f
+0,       1020,       1020,        1,      133, 0x756a3163, S=1,     1024, 0xc2f67c9f
+0,       1030,       1030,        1,      190, 0x3e865b77, S=1,     1024, 0xc2f67c9f
+0,       1040,       1040,        1,      159, 0xdf393fc8, S=1,     1024, 0xc2f67c9f
+0,       1050,       1050,        1,      188, 0x84be5168, S=1,     1024, 0xc2f67c9f
+0,       1060,       1060,        1,      163, 0x4c0e41f0, S=1,     1024, 0xc2f67c9f
+0,       1070,       1070,        1,      144, 0x5fda3792, S=1,     1024, 0xc2f67c9f
+0,       1080,       1080,        1,      136, 0x028c3800, S=1,     1024, 0xc2f67c9f
+0,       1090,       1090,        1,      150, 0x75d43a8d, S=1,     1024, 0xc2f67c9f
+0,       1100,       1100,        1,      134, 0x81123999, S=1,     1024, 0xc2f67c9f
+0,       1110,       1110,        1,      198, 0x0a875baa, S=1,     1024, 0xc2f67c9f
+0,       1120,       1120,        1,      169, 0xfdd7458c, S=1,     1024, 0xc2f67c9f
+0,       1130,       1130,        1,      210, 0x9b195be4, S=1,     1024, 0xc2f67c9f
+0,       1140,       1140,        1,      174, 0x0a424a76, S=1,     1024, 0xc2f67c9f
+0,       1150,       1150,        1,      137, 0xb1b535fd, S=1,     1024, 0xc2f67c9f
+0,       1160,       1160,        1,      122, 0x4d3f327b, S=1,     1024, 0xc2f67c9f
+0,       1170,       1170,        1,      152, 0x5e423b0c, S=1,     1024, 0xc2f67c9f
+0,       1180,       1180,        1,      137, 0xd13a39f7, S=1,     1024, 0xc2f67c9f
+0,       1190,       1190,        1,      156, 0x40864321, S=1,     1024, 0xc2f67c9f
+0,       1200,       1200,        1,      140, 0xbe1e393c, S=1,     1024, 0xc2f67c9f
+0,       1210,       1210,        1,      179, 0xaf204635, S=1,     1024, 0xc2f67c9f
+0,       1220,       1220,        1,      116, 0x5ac83123, S=1,     1024, 0xc2f67c9f
+0,       1230,       1230,        1,      118, 0x22bc2ec5, S=1,     1024, 0xc2f67c9f
+0,       1240,       1240,        1,      123, 0xc9b5302d, S=1,     1024, 0xc2f67c9f
+0,       1250,       1250,        1,      125, 0x5cee3077, S=1,     1024, 0xc2f67c9f
+0,       1260,       1260,        1,      194, 0xccc159ca, S=1,     1024, 0xc2f67c9f
+0,       1270,       1270,        1,      122, 0x4d243229, S=1,     1024, 0xc2f67c9f
+0,       1280,       1280,        1,      124, 0x948f330b, S=1,     1024, 0xc2f67c9f
+0,       1290,       1290,        1,      133, 0xd53c35ca, S=1,     1024, 0xc2f67c9f
+0,       1300,       1300,        1,      126, 0xc5543710, S=1,     1024, 0xc2f67c9f
+0,       1310,       1310,        1,      208, 0x6cf15ea2, S=1,     1024, 0xc2f67c9f
+0,       1320,       1320,        1,      131, 0xa8d33505, S=1,     1024, 0xc2f67c9f
+0,       1330,       1330,        1,      114, 0x0ae53001, S=1,     1024, 0xc2f67c9f
+0,       1340,       1340,        1,      129, 0xe9ff37c4, S=1,     1024, 0xc2f67c9f
+0,       1350,       1350,        1,      120, 0x02623359, S=1,     1024, 0xc2f67c9f
+0,       1360,       1360,        1,      164, 0x9dc545e5, S=1,     1024, 0xc2f67c9f
+0,       1370,       1370,        1,      245, 0xc170715a, S=1,     1024, 0xc2f67c9f
+0,       1380,       1380,        1,      215, 0xc93d5fbe, S=1,     1024, 0xc2f67c9f
+0,       1390,       1390,        1,      225, 0x14866349, S=1,     1024, 0xc2f67c9f
+0,       1400,       1400,        1,      123, 0x70cd2b64, S=1,     1024, 0xc2f67c9f
+0,       1410,       1410,        1,      124, 0xe9002fb5, S=1,     1024, 0xc2f67c9f
+0,       1420,       1420,        1,      125, 0x106e309b, S=1,     1024, 0xc2f67c9f
+0,       1430,       1430,        1,      122, 0x050e32b0, S=1,     1024, 0xc2f67c9f
+0,       1440,       1440,        1,      224, 0xf548614f, S=1,     1024, 0xc2f67c9f
+0,       1450,       1450,        1,      239, 0x125c6ade, S=1,     1024, 0xc2f67c9f
+0,       1460,       1460,        1,      127, 0x398734b6, S=1,     1024, 0xc2f67c9f
+0,       1470,       1470,        1,      126, 0x2ff431e5, S=1,     1024, 0xc2f67c9f
+0,       1480,       1480,        1,      124, 0x9583313b, S=1,     1024, 0xc2f67c9f
+0,       1490,       1490,        1,      126, 0xc1fc3692, S=1,     1024, 0xc2f67c9f
+0,       1500,       1500,        1,      123, 0xd0bf3170, S=1,     1024, 0xc2f67c9f
+0,       1510,       1510,        1,      117, 0x651f3032, S=1,     1024, 0xc2f67c9f
+0,       1520,       1520,        1,      119, 0x268a3078, S=1,     1024, 0xc2f67c9f
+0,       1530,       1530,        1,      117, 0x9e4d3283, S=1,     1024, 0xc2f67c9f
+0,       1540,       1540,        1,      149, 0x8f1043ba, S=1,     1024, 0xc2f67c9f
+0,       1550,       1550,        1,      127, 0x352338bc, S=1,     1024, 0xc2f67c9f
+0,       1560,       1560,        1,      113, 0xf877314e, S=1,     1024, 0xc2f67c9f
+0,       1570,       1570,        1,      128, 0x88103a62, S=1,     1024, 0xc2f67c9f
+0,       1580,       1580,        1,      111, 0xbf0630d9, S=1,     1024, 0xc2f67c9f
+0,       1590,       1590,        1,      146, 0x159c44f7, S=1,     1024, 0xc2f67c9f
+0,       1600,       1600,        1,      237, 0x4e45662e, S=1,     1024, 0xc2f67c9f
+0,       1610,       1610,        1,      233, 0x8f9e6354, S=1,     1024, 0xc2f67c9f
+0,       1620,       1620,        1,      160, 0x9c3f431f, S=1,     1024, 0xc2f67c9f
+0,       1630,       1630,        1,      125, 0xbd2b33c6, S=1,     1024, 0xc2f67c9f
+0,       1640,       1640,        1,      131, 0x3ecd3ba5, S=1,     1024, 0xc2f67c9f
+0,       1650,       1650,        1,      231, 0xdf286db6, S=1,     1024, 0xc2f67c9f
+0,       1660,       1660,        1,      153, 0xb6da408d, S=1,     1024, 0xc2f67c9f
+0,       1670,       1670,        1,      126, 0x6741365e, S=1,     1024, 0xc2f67c9f
+0,       1680,       1680,        1,      113, 0x658f2c90, S=1,     1024, 0xc2f67c9f
+0,       1690,       1690,        1,      125, 0xc0033320, S=1,     1024, 0xc2f67c9f
+0,       1700,       1700,        1,      122, 0xe38a2db1, S=1,     1024, 0xc2f67c9f
+0,       1710,       1710,        1,      145, 0x29d63e83, S=1,     1024, 0xc2f67c9f
+0,       1720,       1720,        1,      171, 0xc0e44b70, S=1,     1024, 0xc2f67c9f
diff --git a/tests/ref/fate/gifenc-pal8 b/tests/ref/fate/gifenc-pal8
index 4ae4d17..a483dab 100644
--- a/tests/ref/fate/gifenc-pal8
+++ b/tests/ref/fate/gifenc-pal8
@@ -1,42 +1,42 @@
 #tb 0: 1/100
 0,          0,          0,        1,     1320, 0x95d1a9e9, S=1,     1024, 0xec907a9e
 0,         10,         10,        1,     1463, 0xa697fe95, S=1,     1024, 0xec907a9e
-0,         20,         20,        1,     1637, 0x294d54f9, S=1,     1024, 0xec907a9e
+0,         20,         20,        1,     1638, 0x7ea154fa, S=1,     1024, 0xec907a9e
 0,         30,         30,        1,     1755, 0x7e0b9c4d, S=1,     1024, 0xec907a9e
 0,         40,         40,        1,     1896, 0x4aacc768, S=1,     1024, 0xec907a9e
 0,         50,         50,        1,     2038, 0x209d1490, S=1,     1024, 0xec907a9e
 0,         60,         60,        1,     2168, 0x0c405606, S=1,     1024, 0xec907a9e
 0,         70,         70,        1,     2258, 0xc2fa9229, S=1,     1024, 0xec907a9e
-0,         80,         80,        1,     2441, 0x2076ec47, S=1,     1024, 0xec907a9e
+0,         80,         80,        1,     2442, 0x0d4bec48, S=1,     1024, 0xec907a9e
 0,         90,         90,        1,     2565, 0x15742730, S=1,     1024, 0xec907a9e
 0,        100,        100,        1,     2733, 0x2eb57d95, S=1,     1024, 0xec907a9e
 0,        110,        110,        1,     2849, 0x9f16ad46, S=1,     1024, 0xec907a9e
 0,        120,        120,        1,     2981, 0xf139f908, S=1,     1024, 0xec907a9e
-0,        130,        130,        1,     3081, 0x0b2a4aeb, S=1,     1024, 0xec907a9e
+0,        130,        130,        1,     3082, 0x57144aec, S=1,     1024, 0xec907a9e
 0,        140,        140,        1,     3200, 0x35227f42, S=1,     1024, 0xec907a9e
-0,        150,        150,        1,     3315, 0x35edc001, S=1,     1024, 0xec907a9e
+0,        150,        150,        1,     3316, 0xf6d7c002, S=1,     1024, 0xec907a9e
 0,        160,        160,        1,     3462, 0x27a20d23, S=1,     1024, 0xec907a9e
-0,        170,        170,        1,     3599, 0x83c52b01, S=1,     1024, 0xec907a9e
+0,        170,        170,        1,     3600, 0xaecb2b02, S=1,     1024, 0xec907a9e
 0,        180,        180,        1,     3712, 0x947d49d1, S=1,     1024, 0xec907a9e
 0,        190,        190,        1,     3838, 0xf87eb223, S=1,     1024, 0xec907a9e
-0,        200,        200,        1,     3948, 0x5203eede, S=1,     1024, 0xec907a9e
-0,        210,        210,        1,     4083, 0x32101e33, S=1,     1024, 0xec907a9e
-0,        220,        220,        1,     4186, 0x6b0e5a13, S=1,     1024, 0xec907a9e
+0,        200,        200,        1,     3949, 0x4152eedf, S=1,     1024, 0xec907a9e
+0,        210,        210,        1,     4084, 0x512c1e34, S=1,     1024, 0xec907a9e
+0,        220,        220,        1,     4187, 0xc5715a14, S=1,     1024, 0xec907a9e
 0,        230,        230,        1,     4323, 0x6326a0f5, S=1,     1024, 0xec907a9e
 0,        240,        240,        1,     4426, 0x5f6bd655, S=1,     1024, 0xec907a9e
 0,        250,        250,        1,     4564, 0xc62005fd, S=1,     1024, 0xec907a9e
 0,        260,        260,        1,     4664, 0x43e97006, S=1,     1024, 0xec907a9e
 0,        270,        270,        1,     4808, 0xf6e08d4f, S=1,     1024, 0xec907a9e
 0,        280,        280,        1,     4932, 0x2d51e0b5, S=1,     1024, 0xec907a9e
-0,        290,        290,        1,     5071, 0x25e830c7, S=1,     1024, 0xec907a9e
-0,        300,        300,        1,     5246, 0x452e945c, S=1,     1024, 0xec907a9e
+0,        290,        290,        1,     5072, 0x577430c8, S=1,     1024, 0xec907a9e
+0,        300,        300,        1,     5247, 0xd9fe945d, S=1,     1024, 0xec907a9e
 0,        310,        310,        1,     5353, 0x27eec140, S=1,     1024, 0xec907a9e
-0,        320,        320,        1,     5535, 0xda38038c, S=1,     1024, 0xec907a9e
+0,        320,        320,        1,     5536, 0xde59038d, S=1,     1024, 0xec907a9e
 0,        330,        330,        1,     5691, 0x358970e4, S=1,     1024, 0xec907a9e
 0,        340,        340,        1,     5835, 0xd89201d8, S=1,     1024, 0xec907a9e
-0,        350,        350,        1,     5966, 0xfbee1fed, S=1,     1024, 0xec907a9e
+0,        350,        350,        1,     5967, 0x1c2e1fee, S=1,     1024, 0xec907a9e
 0,        360,        360,        1,     6082, 0xd4b88e90, S=1,     1024, 0xec907a9e
-0,        370,        370,        1,     6276, 0x1b02e684, S=1,     1024, 0xec907a9e
+0,        370,        370,        1,     6277, 0x020fe685, S=1,     1024, 0xec907a9e
 0,        380,        380,        1,     6382, 0xc1db2297, S=1,     1024, 0xec907a9e
 0,        390,        390,        1,     6509, 0xc65473a6, S=1,     1024, 0xec907a9e
 0,        400,        400,        1,     6621, 0xca917a35, S=1,     1024, 0xec907a9e
@@ -47,7 +47,7 @@
 0,        450,        450,        1,     7085, 0xc3427580, S=1,     1024, 0xec907a9e
 0,        460,        460,        1,     7242, 0x3d00c5f0, S=1,     1024, 0xec907a9e
 0,        470,        470,        1,     7349, 0x453fad59, S=1,     1024, 0xec907a9e
-0,        480,        480,        1,     7513, 0x96d12666, S=1,     1024, 0xec907a9e
+0,        480,        480,        1,     7514, 0xbd862667, S=1,     1024, 0xec907a9e
 0,        490,        490,        1,     7575, 0xf8cb3c77, S=1,     1024, 0xec907a9e
 0,        500,        500,        1,     7759, 0x1fe6ab40, S=1,     1024, 0xec907a9e
 0,        510,        510,        1,     7846, 0x3853fd0f, S=1,     1024, 0xec907a9e
@@ -89,22 +89,22 @@
 0,        870,        870,        1,    11632, 0xf4972bdf, S=1,     1024, 0xec907a9e
 0,        880,        880,        1,    11825, 0x0cd2548c, S=1,     1024, 0xec907a9e
 0,        890,        890,        1,    11864, 0x80758637, S=1,     1024, 0xec907a9e
-0,        900,        900,        1,    11949, 0x87c86fb9, S=1,     1024, 0xec907a9e
+0,        900,        900,        1,    11950, 0xf8246fba, S=1,     1024, 0xec907a9e
 0,        910,        910,        1,    12088, 0x1b99c82b, S=1,     1024, 0xec907a9e
-0,        920,        920,        1,    12160, 0x72fbf4ac, S=1,     1024, 0xec907a9e
+0,        920,        920,        1,    12161, 0x682cf4ad, S=1,     1024, 0xec907a9e
 0,        930,        930,        1,    12305, 0x9f62069a, S=1,     1024, 0xec907a9e
-0,        940,        940,        1,    12295, 0x0625d96b, S=1,     1024, 0xec907a9e
-0,        950,        950,        1,    12496, 0xe67cb2cf, S=1,     1024, 0xec907a9e
+0,        940,        940,        1,    12296, 0xe08dd96c, S=1,     1024, 0xec907a9e
+0,        950,        950,        1,    12497, 0x9a20b2d0, S=1,     1024, 0xec907a9e
 0,        960,        960,        1,    12660, 0x4d1d05ea, S=1,     1024, 0xec907a9e
 0,        970,        970,        1,    12763, 0x12542531, S=1,     1024, 0xec907a9e
-0,        980,        980,        1,    12916, 0x37c444db, S=1,     1024, 0xec907a9e
+0,        980,        980,        1,    12917, 0x7d0944dc, S=1,     1024, 0xec907a9e
 0,        990,        990,        1,    13021, 0xa1c89f22, S=1,     1024, 0xec907a9e
 0,       1000,       1000,        1,    13184, 0xe13ad0be, S=1,     1024, 0xec907a9e
 0,       1010,       1010,        1,    13315, 0x11b93a5d, S=1,     1024, 0xec907a9e
-0,       1020,       1020,        1,    13336, 0x128254ee, S=1,     1024, 0xec907a9e
+0,       1020,       1020,        1,    13337, 0x677e54ef, S=1,     1024, 0xec907a9e
 0,       1030,       1030,        1,    13536, 0x48b7b5de, S=1,     1024, 0xec907a9e
 0,       1040,       1040,        1,    13728, 0x03f4d302, S=1,     1024, 0xec907a9e
-0,       1050,       1050,        1,    13821, 0xfe4e97eb, S=1,     1024, 0xec907a9e
+0,       1050,       1050,        1,    13822, 0x973b97ec, S=1,     1024, 0xec907a9e
 0,       1060,       1060,        1,    14002, 0x0de77dfc, S=1,     1024, 0xec907a9e
 0,       1070,       1070,        1,    14156, 0xf1b1d4e1, S=1,     1024, 0xec907a9e
 0,       1080,       1080,        1,    14256, 0x355320cc, S=1,     1024, 0xec907a9e
diff --git a/tests/ref/fate/gifenc-rgb4_byte b/tests/ref/fate/gifenc-rgb4_byte
index 8a0595a..16696da 100644
--- a/tests/ref/fate/gifenc-rgb4_byte
+++ b/tests/ref/fate/gifenc-rgb4_byte
@@ -1,56 +1,56 @@
 #tb 0: 1/100
-0,          0,          0,        1,      507, 0xde1f113a
+0,          0,          0,        1,      508, 0xf04a113b
 0,         10,         10,        1,      213, 0x23c24d3d, S=1,     1024, 0xf7700427
-0,         20,         20,        1,      130, 0x2c222a38, S=1,     1024, 0x03730427
+0,         20,         20,        1,      131, 0x56d22a39, S=1,     1024, 0x03730427
 0,         30,         30,        1,      384, 0xb1d8a4bd, S=1,     1024, 0xf7700427
 0,         40,         40,        1,      381, 0x37a3a2c9, S=1,     1024, 0xf3740427
 0,         50,         50,        1,      430, 0x162bb3d3, S=1,     1024, 0xf3740427
-0,         60,         60,        1,      517, 0x411ad737, S=1,     1024, 0xf3740427
+0,         60,         60,        1,      518, 0x195bd738, S=1,     1024, 0xf3740427
 0,         70,         70,        1,      535, 0x12cde6b7, S=1,     1024, 0xf3740427
-0,         80,         80,        1,      437, 0xec54b945, S=1,     1024, 0x0b6b0427
+0,         80,         80,        1,      438, 0xa653b946, S=1,     1024, 0x0b6b0427
 0,         90,         90,        1,      923, 0xd2e2a35f, S=1,     1024, 0x0b6b0427
-0,        100,        100,        1,      693, 0x97064a1e, S=1,     1024, 0x0b6b0427
+0,        100,        100,        1,      694, 0xe1cf4a1f, S=1,     1024, 0x0b6b0427
 0,        110,        110,        1,     1194, 0xa6152c8a, S=1,     1024, 0x0b6b0427
 0,        120,        120,        1,     1291, 0x94d25581, S=1,     1024, 0x0b6b0427
 0,        130,        130,        1,     1245, 0x5b483525, S=1,     1024, 0x0b6b0427
 0,        140,        140,        1,     1330, 0xfb5351c8, S=1,     1024, 0x0b6b0427
-0,        150,        150,        1,     1275, 0x353c3913, S=1,     1024, 0x0b6b0427
-0,        160,        160,        1,     1474, 0x27399754, S=1,     1024, 0x0b6b0427
-0,        170,        170,        1,     1783, 0x9e024aa6, S=1,     1024, 0xecb30526
+0,        150,        150,        1,     1276, 0x6f403914, S=1,     1024, 0x0b6b0427
+0,        160,        160,        1,     1475, 0xbf459755, S=1,     1024, 0x0b6b0427
+0,        170,        170,        1,     1784, 0xe9954aa7, S=1,     1024, 0xecb30526
 0,        180,        180,        1,     1675, 0x219dfaf8, S=1,     1024, 0xecb30526
 0,        190,        190,        1,     1509, 0xd7f5abbe, S=1,     1024, 0xecb30526
 0,        200,        200,        1,     1705, 0x44a01729, S=1,     1024, 0xecb30526
 0,        210,        210,        1,     1745, 0x31ff1f89, S=1,     1024, 0xecb30526
 0,        220,        220,        1,     1642, 0x55420147, S=1,     1024, 0xecb30526
-0,        230,        230,        1,     1717, 0x4b8d1cb7, S=1,     1024, 0xecb30526
+0,        230,        230,        1,     1718, 0x68ef1cb8, S=1,     1024, 0xecb30526
 0,        240,        240,        1,     1900, 0xd7737a09, S=1,     1024, 0xecb30526
-0,        250,        250,        1,     1806, 0xfe1a513f, S=1,     1024, 0xecb30526
+0,        250,        250,        1,     1807, 0x4f6c5140, S=1,     1024, 0xecb30526
 0,        260,        260,        1,     1915, 0x976d80e6, S=1,     1024, 0xecb30526
 0,        270,        270,        1,     2100, 0x0ae6d1ce, S=1,     1024, 0xecb30526
 0,        280,        280,        1,     2700, 0x7a89f104, S=1,     1024, 0xecb30526
 0,        290,        290,        1,     2673, 0xf6b6a71d, S=1,     1024, 0xecb30526
-0,        300,        300,        1,     2894, 0x47eb484a, S=1,     1024, 0xecb30526
+0,        300,        300,        1,     2895, 0x9079484b, S=1,     1024, 0xecb30526
 0,        310,        310,        1,     3257, 0x0b0cd125, S=1,     1024, 0xecb30526
 0,        320,        320,        1,     3179, 0x3ee2c161, S=1,     1024, 0xecb30526
 0,        330,        330,        1,     3296, 0x6230e506, S=1,     1024, 0xecb30526
-0,        340,        340,        1,     3599, 0x8c2d75d6, S=1,     1024, 0xecb30526
-0,        350,        350,        1,     3698, 0x5a59a042, S=1,     1024, 0xecb30526
+0,        340,        340,        1,     3600, 0x021775d7, S=1,     1024, 0xecb30526
+0,        350,        350,        1,     3699, 0xfb03a043, S=1,     1024, 0xecb30526
 0,        360,        360,        1,     3814, 0x96a8d57e, S=1,     1024, 0xecb30526
-0,        370,        370,        1,     3626, 0xb3e67f8e, S=1,     1024, 0xecb30526
+0,        370,        370,        1,     3627, 0x33a37f8f, S=1,     1024, 0xecb30526
 0,        380,        380,        1,     2950, 0x50806197, S=1,     1024, 0xecb30526
 0,        390,        390,        1,     3086, 0x72068d4c, S=1,     1024, 0xecb30526
-0,        400,        400,        1,     3093, 0xa248861e, S=1,     1024, 0xecb30526
+0,        400,        400,        1,     3094, 0x2880861f, S=1,     1024, 0xecb30526
 0,        410,        410,        1,     3456, 0x6d232a96, S=1,     1024, 0xecb30526
-0,        420,        420,        1,     4107, 0xe70d5eba, S=1,     1024, 0xecb30526
-0,        430,        430,        1,     4216, 0xab3258f3, S=1,     1024, 0xecb30526
+0,        420,        420,        1,     4108, 0x46d75ebb, S=1,     1024, 0xecb30526
+0,        430,        430,        1,     4217, 0x04a258f4, S=1,     1024, 0xecb30526
 0,        440,        440,        1,     3613, 0x667f4ff8, S=1,     1024, 0xecb30526
-0,        450,        450,        1,     3909, 0xa7b0e73d, S=1,     1024, 0xecb30526
-0,        460,        460,        1,     4460, 0x7c8ae0be, S=1,     1024, 0xecb30526
-0,        470,        470,        1,     4592, 0x58112f48, S=1,     1024, 0xecb30526
-0,        480,        480,        1,     4821, 0x678d9b72, S=1,     1024, 0xecb30526
-0,        490,        490,        1,     5397, 0x79eabff3, S=1,     1024, 0xecb30526
+0,        450,        450,        1,     3910, 0x8f37e73e, S=1,     1024, 0xecb30526
+0,        460,        460,        1,     4461, 0x5db9e0bf, S=1,     1024, 0xecb30526
+0,        470,        470,        1,     4593, 0x883f2f49, S=1,     1024, 0xecb30526
+0,        480,        480,        1,     4822, 0x03d99b73, S=1,     1024, 0xecb30526
+0,        490,        490,        1,     5398, 0x39f7bff4, S=1,     1024, 0xecb30526
 0,        500,        500,        1,     5266, 0xd5ab9630, S=1,     1024, 0xecb30526
-0,        510,        510,        1,     5415, 0x76dce16e, S=1,     1024, 0xecb30526
+0,        510,        510,        1,     5416, 0x5876e16f, S=1,     1024, 0xecb30526
 0,        520,        520,        1,     5519, 0x30ed05d8, S=1,     1024, 0xecb30526
 0,        530,        530,        1,     5701, 0x5bae5af7, S=1,     1024, 0xecb30526
 0,        540,        540,        1,     6160, 0x98364177, S=1,     1024, 0xecb30526
@@ -69,7 +69,7 @@
 0,        670,        670,        1,     7556, 0x1aa2a694, S=1,     1024, 0xecb30526
 0,        680,        680,        1,     7413, 0xbc9e7718, S=1,     1024, 0xecb30526
 0,        690,        690,        1,     7476, 0xb2a1aba0, S=1,     1024, 0xecb30526
-0,        700,        700,        1,     7595, 0x4ce5e56c, S=1,     1024, 0xecb30526
+0,        700,        700,        1,     7596, 0x3301e56d, S=1,     1024, 0xecb30526
 0,        710,        710,        1,     7756, 0x8f2504f8, S=1,     1024, 0xecb30526
 0,        720,        720,        1,     8015, 0xd4146c80, S=1,     1024, 0xecb30526
 0,        730,        730,        1,     8128, 0x11b2bf4c, S=1,     1024, 0xecb30526
@@ -101,22 +101,22 @@
 0,        990,        990,        1,    11111, 0x5f8d504f, S=1,     1024, 0xecb30526
 0,       1000,       1000,        1,    11194, 0x3c7e6a77, S=1,     1024, 0xecb30526
 0,       1010,       1010,        1,    11240, 0x5112a0a3, S=1,     1024, 0xecb30526
-0,       1020,       1020,        1,    11482, 0xb938f4f9, S=1,     1024, 0xecb30526
+0,       1020,       1020,        1,    11483, 0xaf10f4fa, S=1,     1024, 0xecb30526
 0,       1030,       1030,        1,    11680, 0x44a25971, S=1,     1024, 0xecb30526
 0,       1040,       1040,        1,    11785, 0x7350b5db, S=1,     1024, 0xecb30526
 0,       1050,       1050,        1,    11436, 0xe3170ad5, S=1,     1024, 0xecb30526
-0,       1060,       1060,        1,    11927, 0x4ab8c884, S=1,     1024, 0xecb30526
+0,       1060,       1060,        1,    11928, 0x13d8c885, S=1,     1024, 0xecb30526
 0,       1070,       1070,        1,    11932, 0xecb5bdf7, S=1,     1024, 0xecb30526
-0,       1080,       1080,        1,    12280, 0xa0ea76d4, S=1,     1024, 0xecb30526
+0,       1080,       1080,        1,    12281, 0x18bb76d5, S=1,     1024, 0xecb30526
 0,       1090,       1090,        1,    12334, 0x16147fc3, S=1,     1024, 0xecb30526
 0,       1100,       1100,        1,    12452, 0x61a8b3d7, S=1,     1024, 0xecb30526
 0,       1110,       1110,        1,    12695, 0x8b703e74, S=1,     1024, 0xecb30526
-0,       1120,       1120,        1,    12667, 0xc75b5175, S=1,     1024, 0xecb30526
+0,       1120,       1120,        1,    12668, 0x19505176, S=1,     1024, 0xecb30526
 0,       1130,       1130,        1,    12957, 0x3b839f0d, S=1,     1024, 0xecb30526
-0,       1140,       1140,        1,    13053, 0xd3c9e3da, S=1,     1024, 0xecb30526
+0,       1140,       1140,        1,    13054, 0xb8a5e3db, S=1,     1024, 0xecb30526
 0,       1150,       1150,        1,    13147, 0xdf5c2e68, S=1,     1024, 0xecb30526
 0,       1160,       1160,        1,    13171, 0x15961ca2, S=1,     1024, 0xecb30526
-0,       1170,       1170,        1,    13197, 0xa5eb5717, S=1,     1024, 0xecb30526
+0,       1170,       1170,        1,    13198, 0xfd855718, S=1,     1024, 0xecb30526
 0,       1180,       1180,        1,    13211, 0x1a625e31, S=1,     1024, 0xecb30526
 0,       1190,       1190,        1,    13210, 0x246661c9, S=1,     1024, 0xecb30526
 0,       1200,       1200,        1,    13467, 0xfcaaa461, S=1,     1024, 0xecb30526
@@ -147,8 +147,8 @@
 0,       1450,       1450,        1,    17149, 0x435ecdd4, S=1,     1024, 0xecb30526
 0,       1460,       1460,        1,    17172, 0x045fb234, S=1,     1024, 0xecb30526
 0,       1470,       1470,        1,    17315, 0xc5ddadab, S=1,     1024, 0xecb30526
-0,       1480,       1480,        1,    17396, 0xe8ef15b5, S=1,     1024, 0xecb30526
-0,       1490,       1490,        1,    17430, 0x6f58f8bf, S=1,     1024, 0xecb30526
+0,       1480,       1480,        1,    17397, 0xff8e15b6, S=1,     1024, 0xecb30526
+0,       1490,       1490,        1,    17431, 0x6832f8c0, S=1,     1024, 0xecb30526
 0,       1500,       1500,        1,    17576, 0x5c2a5445, S=1,     1024, 0xecb30526
 0,       1510,       1510,        1,    17764, 0x609f8c3b, S=1,     1024, 0xecb30526
 0,       1520,       1520,        1,    17826, 0x538c8532, S=1,     1024, 0xecb30526
diff --git a/tests/ref/fate/gifenc-rgb8 b/tests/ref/fate/gifenc-rgb8
index 63789b7..226b26e 100644
--- a/tests/ref/fate/gifenc-rgb8
+++ b/tests/ref/fate/gifenc-rgb8
@@ -1,10 +1,10 @@
 #tb 0: 1/100
 0,          0,          0,        1,      552, 0x47602c6c
 0,         10,         10,        1,      297, 0x49dd8847, S=1,     1024, 0xcfc8799f
-0,         20,         20,        1,      437, 0x736bd351, S=1,     1024, 0xcfc8799f
+0,         20,         20,        1,      438, 0x4776d352, S=1,     1024, 0xcfc8799f
 0,         30,         30,        1,      450, 0x2254d187, S=1,     1024, 0xcfc8799f
 0,         40,         40,        1,      547, 0xe16104bc, S=1,     1024, 0xcfc8799f
-0,         50,         50,        1,      613, 0xef4c2026, S=1,     1024, 0xcfc8799f
+0,         50,         50,        1,      614, 0x0fdc2027, S=1,     1024, 0xcfc8799f
 0,         60,         60,        1,      642, 0xa0af1edf, S=1,     1024, 0xcfc8799f
 0,         70,         70,        1,      660, 0xd0763931, S=1,     1024, 0xcfc8799f
 0,         80,         80,        1,      821, 0xc38f7fac, S=1,     1024, 0xcfc8799f
@@ -16,56 +16,56 @@
 0,        140,        140,        1,     1720, 0xce854743, S=1,     1024, 0xcfc8799f
 0,        150,        150,        1,     1910, 0x2690866d, S=1,     1024, 0xcfc8799f
 0,        160,        160,        1,     2124, 0xa586dad0, S=1,     1024, 0xcfc8799f
-0,        170,        170,        1,     2247, 0x72982a87, S=1,     1024, 0xcfc8799f
+0,        170,        170,        1,     2248, 0x9ddc2a88, S=1,     1024, 0xcfc8799f
 0,        180,        180,        1,     2311, 0xd64235af, S=1,     1024, 0xcfc8799f
 0,        190,        190,        1,     2408, 0xe2a66cc9, S=1,     1024, 0xcfc8799f
 0,        200,        200,        1,     2601, 0xeab6c267, S=1,     1024, 0xcfc8799f
-0,        210,        210,        1,     2686, 0xfa990310, S=1,     1024, 0xcfc8799f
+0,        210,        210,        1,     2687, 0xfe1d0311, S=1,     1024, 0xcfc8799f
 0,        220,        220,        1,     2784, 0xca600dee, S=1,     1024, 0xcfc8799f
 0,        230,        230,        1,     2884, 0xc7134b99, S=1,     1024, 0xcfc8799f
-0,        240,        240,        1,     2981, 0x92507824, S=1,     1024, 0xcfc8799f
+0,        240,        240,        1,     2982, 0x0b1e7825, S=1,     1024, 0xcfc8799f
 0,        250,        250,        1,     3101, 0x3e029e0e, S=1,     1024, 0xcfc8799f
-0,        260,        260,        1,     3252, 0x8d3af677, S=1,     1024, 0xcfc8799f
+0,        260,        260,        1,     3253, 0x846af678, S=1,     1024, 0xcfc8799f
 0,        270,        270,        1,     3329, 0x29a81b71, S=1,     1024, 0xcfc8799f
-0,        280,        280,        1,     3571, 0x18a68a51, S=1,     1024, 0xcfc8799f
-0,        290,        290,        1,     3806, 0x192dfed1, S=1,     1024, 0xcfc8799f
-0,        300,        300,        1,     2749, 0xdf1e1f9d, S=1,     1024, 0xcfc8799f
+0,        280,        280,        1,     3572, 0xa3e08a52, S=1,     1024, 0xcfc8799f
+0,        290,        290,        1,     3807, 0x18e1fed2, S=1,     1024, 0xcfc8799f
+0,        300,        300,        1,     2750, 0xff6e1f9e, S=1,     1024, 0xcfc8799f
 0,        310,        310,        1,     4031, 0x6d4f7329, S=1,     1024, 0xcfc8799f
 0,        320,        320,        1,     3025, 0xb43c9e94, S=1,     1024, 0xcfc8799f
-0,        330,        330,        1,     4294, 0xb64a0a7f, S=1,     1024, 0xcfc8799f
+0,        330,        330,        1,     4295, 0xc1850a80, S=1,     1024, 0xcfc8799f
 0,        340,        340,        1,     2044, 0x0440c072, S=1,     1024, 0xcfc8799f
 0,        350,        350,        1,     3212, 0xe91af08f, S=1,     1024, 0xcfc8799f
-0,        360,        360,        1,     2280, 0x1ec34aa0, S=1,     1024, 0xcfc8799f
-0,        370,        370,        1,     3632, 0x11af9aa2, S=1,     1024, 0xcfc8799f
+0,        360,        360,        1,     2281, 0x6a414aa1, S=1,     1024, 0xcfc8799f
+0,        370,        370,        1,     3633, 0xac779aa3, S=1,     1024, 0xcfc8799f
 0,        380,        380,        1,     3552, 0xed2c75b2, S=1,     1024, 0xcfc8799f
-0,        390,        390,        1,     3689, 0x42a6dd0c, S=1,     1024, 0xcfc8799f
+0,        390,        390,        1,     3690, 0x2020dd0d, S=1,     1024, 0xcfc8799f
 0,        400,        400,        1,     1558, 0x2c14e4b2, S=1,     1024, 0xcfc8799f
-0,        410,        410,        1,      939, 0x7ae8cd8f, S=1,     1024, 0xcfc8799f
+0,        410,        410,        1,      940, 0x4927cd90, S=1,     1024, 0xcfc8799f
 0,        420,        420,        1,      273, 0x138c7831, S=1,     1024, 0xcfc8799f
-0,        430,        430,        1,      929, 0x42eeae3e, S=1,     1024, 0xcfc8799f
+0,        430,        430,        1,      930, 0xf1c3ae3f, S=1,     1024, 0xcfc8799f
 0,        440,        440,        1,      271, 0x6d338044, S=1,     1024, 0xcfc8799f
 0,        450,        450,        1,      196, 0xa5de5322, S=1,     1024, 0xcfc8799f
 0,        460,        460,        1,     4299, 0x5bac0d86, S=1,     1024, 0xcfc8799f
-0,        470,        470,        1,     4894, 0x8a7d39a5, S=1,     1024, 0xcfc8799f
-0,        480,        480,        1,     4927, 0xdd6113e7, S=1,     1024, 0xcfc8799f
+0,        470,        470,        1,     4895, 0xc43639a6, S=1,     1024, 0xcfc8799f
+0,        480,        480,        1,     4928, 0xf17d13e8, S=1,     1024, 0xcfc8799f
 0,        490,        490,        1,     4941, 0x71915520, S=1,     1024, 0xcfc8799f
-0,        500,        500,        1,     4153, 0x0f8cb8a5, S=1,     1024, 0xcfc8799f
-0,        510,        510,        1,     4677, 0x62cfc338, S=1,     1024, 0xcfc8799f
-0,        520,        520,        1,     4740, 0x4418bb44, S=1,     1024, 0xcfc8799f
-0,        530,        530,        1,     4981, 0xb93c5976, S=1,     1024, 0xcfc8799f
+0,        500,        500,        1,     4154, 0xc860b8a6, S=1,     1024, 0xcfc8799f
+0,        510,        510,        1,     4678, 0x2651c339, S=1,     1024, 0xcfc8799f
+0,        520,        520,        1,     4741, 0xffd6bb45, S=1,     1024, 0xcfc8799f
+0,        530,        530,        1,     4982, 0x132c5977, S=1,     1024, 0xcfc8799f
 0,        540,        540,        1,     5179, 0x97aac3a1, S=1,     1024, 0xcfc8799f
 0,        550,        550,        1,     5046, 0x836a80cd, S=1,     1024, 0xcfc8799f
 0,        560,        560,        1,     5140, 0xa725c1e7, S=1,     1024, 0xcfc8799f
-0,        570,        570,        1,     4288, 0x7eb6fbbf, S=1,     1024, 0xcfc8799f
+0,        570,        570,        1,     4289, 0x7b3afbc0, S=1,     1024, 0xcfc8799f
 0,        580,        580,        1,     5079, 0xb2e7a2de, S=1,     1024, 0xcfc8799f
 0,        590,        590,        1,     5284, 0xb757dfe1, S=1,     1024, 0xcfc8799f
 0,        600,        600,        1,     5426, 0xf9f11e57, S=1,     1024, 0xcfc8799f
-0,        610,        610,        1,     4644, 0x66f889e0, S=1,     1024, 0xcfc8799f
+0,        610,        610,        1,     4645, 0xf0f289e1, S=1,     1024, 0xcfc8799f
 0,        620,        620,        1,     5263, 0x8617d7e9, S=1,     1024, 0xcfc8799f
 0,        630,        630,        1,     5221, 0x26e3ca43, S=1,     1024, 0xcfc8799f
-0,        640,        640,        1,     5216, 0xf3399cfa, S=1,     1024, 0xcfc8799f
-0,        650,        650,        1,     5394, 0xe0c801ca, S=1,     1024, 0xcfc8799f
-0,        660,        660,        1,     5219, 0xff22e354, S=1,     1024, 0xcfc8799f
+0,        640,        640,        1,     5217, 0x90989cfb, S=1,     1024, 0xcfc8799f
+0,        650,        650,        1,     5395, 0xe29a01cb, S=1,     1024, 0xcfc8799f
+0,        660,        660,        1,     5220, 0xe2dee355, S=1,     1024, 0xcfc8799f
 0,        670,        670,        1,     5704, 0xcfbcd55e, S=1,     1024, 0xcfc8799f
 0,        680,        680,        1,     5636, 0x7fc2a1e5, S=1,     1024, 0xcfc8799f
 0,        690,        690,        1,     5818, 0x6090ebbd, S=1,     1024, 0xcfc8799f
@@ -83,7 +83,7 @@
 0,        810,        810,        1,     8358, 0x118781e0, S=1,     1024, 0xcfc8799f
 0,        820,        820,        1,     7708, 0xfc0c963d, S=1,     1024, 0xcfc8799f
 0,        830,        830,        1,     7412, 0xdcc311ee, S=1,     1024, 0xcfc8799f
-0,        840,        840,        1,     7540, 0x32fe19c0, S=1,     1024, 0xcfc8799f
+0,        840,        840,        1,     7541, 0x4d2819c1, S=1,     1024, 0xcfc8799f
 0,        850,        850,        1,     7948, 0xf12eca3d, S=1,     1024, 0xcfc8799f
 0,        860,        860,        1,     8408, 0x43add468, S=1,     1024, 0xcfc8799f
 0,        870,        870,        1,     8056, 0x2d162377, S=1,     1024, 0xcfc8799f
@@ -93,12 +93,12 @@
 0,        910,        910,        1,     7768, 0xb01e795a, S=1,     1024, 0xcfc8799f
 0,        920,        920,        1,     7749, 0x6ab39c12, S=1,     1024, 0xcfc8799f
 0,        930,        930,        1,     8047, 0x0e5f24aa, S=1,     1024, 0xcfc8799f
-0,        940,        940,        1,     7617, 0xa2c2340e, S=1,     1024, 0xcfc8799f
+0,        940,        940,        1,     7618, 0xd787340f, S=1,     1024, 0xcfc8799f
 0,        950,        950,        1,     7979, 0x0824c4df, S=1,     1024, 0xcfc8799f
 0,        960,        960,        1,    12062, 0xc46d9d92, S=1,     1024, 0xcfc8799f
 0,        970,        970,        1,    12317, 0x1314dc0c, S=1,     1024, 0xcfc8799f
 0,        980,        980,        1,    12217, 0x78c2ed30, S=1,     1024, 0xcfc8799f
-0,        990,        990,        1,    11226, 0x9ac08eb8, S=1,     1024, 0xcfc8799f
+0,        990,        990,        1,    11227, 0x2a578eb9, S=1,     1024, 0xcfc8799f
 0,       1000,       1000,        1,    11108, 0x4eaa068c, S=1,     1024, 0xcfc8799f
 0,       1010,       1010,        1,    11366, 0x48f8993f, S=1,     1024, 0xcfc8799f
 0,       1020,       1020,        1,    11896, 0x32414841, S=1,     1024, 0xcfc8799f
@@ -135,7 +135,7 @@
 0,       1330,       1330,        1,    17934, 0xb22cc97d, S=1,     1024, 0xcfc8799f
 0,       1340,       1340,        1,    17944, 0x0cd309c6, S=1,     1024, 0xcfc8799f
 0,       1350,       1350,        1,    18238, 0x6b7e3237, S=1,     1024, 0xcfc8799f
-0,       1360,       1360,        1,    18390, 0x888fc489, S=1,     1024, 0xcfc8799f
+0,       1360,       1360,        1,    18391, 0x4df3c48a, S=1,     1024, 0xcfc8799f
 0,       1370,       1370,        1,    18543, 0x90a2f238, S=1,     1024, 0xcfc8799f
 0,       1380,       1380,        1,    18939, 0xc57dda5b, S=1,     1024, 0xcfc8799f
 0,       1390,       1390,        1,    19145, 0x1267294a, S=1,     1024, 0xcfc8799f
@@ -166,7 +166,7 @@
 0,       1640,       1640,        1,    22460, 0x33e6bbfe, S=1,     1024, 0xcfc8799f
 0,       1650,       1650,        1,    22861, 0x18993510, S=1,     1024, 0xcfc8799f
 0,       1660,       1660,        1,    22746, 0xdff85615, S=1,     1024, 0xcfc8799f
-0,       1670,       1670,        1,    23164, 0x899866a2, S=1,     1024, 0xcfc8799f
+0,       1670,       1670,        1,    23165, 0xf0ac66a3, S=1,     1024, 0xcfc8799f
 0,       1680,       1680,        1,    23273, 0x13869ad9, S=1,     1024, 0xcfc8799f
 0,       1690,       1690,        1,    23211, 0xd30b6205, S=1,     1024, 0xcfc8799f
 0,       1700,       1700,        1,    23648, 0xa0cef01b, S=1,     1024, 0xcfc8799f
diff --git a/tests/ref/fate/h264-conformance-cvfc1_sony_c b/tests/ref/fate/h264-conformance-cvfc1_sony_c
new file mode 100644
index 0000000..1abe67f
--- /dev/null
+++ b/tests/ref/fate/h264-conformance-cvfc1_sony_c
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,    75600, 0x6f6a8c48
+0,          1,          1,        1,    75600, 0x4b7ac558
+0,          2,          2,        1,    75600, 0x907feda3
+0,          3,          3,        1,    75600, 0x7b2b17d2
+0,          4,          4,        1,    75600, 0x46d038e7
+0,          5,          5,        1,    75600, 0x90d463b3
+0,          6,          6,        1,    75600, 0xc00d7ec1
+0,          7,          7,        1,    75600, 0x10f69a60
+0,          8,          8,        1,    75600, 0x676aad50
+0,          9,          9,        1,    75600, 0x0a3fd3e0
+0,         10,         10,        1,    75600, 0xaee8fc87
+0,         11,         11,        1,    75600, 0xc9f41fbb
+0,         12,         12,        1,    75600, 0x183743dd
+0,         13,         13,        1,    75600, 0xf0385aa2
+0,         14,         14,        1,    75600, 0xad63782e
+0,         15,         15,        1,    75600, 0x9ed08c01
+0,         16,         16,        1,    75600, 0x79aba20e
+0,         17,         17,        1,    75600, 0x53d6c34c
+0,         18,         18,        1,    75600, 0x4cead515
+0,         19,         19,        1,    75600, 0xc701e3c8
+0,         20,         20,        1,    75600, 0xb278e37d
+0,         21,         21,        1,    75600, 0x02e6f95e
+0,         22,         22,        1,    75600, 0x5cdffef4
+0,         23,         23,        1,    75600, 0x6e0a1089
+0,         24,         24,        1,    75600, 0x23a919b5
+0,         25,         25,        1,    75600, 0x31f5391c
+0,         26,         26,        1,    75600, 0xaa2c3445
+0,         27,         27,        1,    75600, 0x42204340
+0,         28,         28,        1,    75600, 0x55924031
+0,         29,         29,        1,    75600, 0x6bc94d1b
+0,         30,         30,        1,    75600, 0x3e1a1e21
+0,         31,         31,        1,    75600, 0xaf4816fc
+0,         32,         32,        1,    75600, 0x322c1d18
+0,         33,         33,        1,    75600, 0xf59c1746
+0,         34,         34,        1,    75600, 0x875cfc24
+0,         35,         35,        1,    75600, 0x8657f65b
+0,         36,         36,        1,    75600, 0x7e78f95f
+0,         37,         37,        1,    75600, 0x7639e983
+0,         38,         38,        1,    75600, 0xcdaac5fa
+0,         39,         39,        1,    75600, 0x2b7ac473
+0,         40,         40,        1,    75600, 0x028cb98f
+0,         41,         41,        1,    75600, 0x023abda4
+0,         42,         42,        1,    75600, 0x9733ad92
+0,         43,         43,        1,    75600, 0xfb4f8cfe
+0,         44,         44,        1,    75600, 0xfef071b6
+0,         45,         45,        1,    75600, 0xf7513219
+0,         46,         46,        1,    75600, 0x9d6e3c98
+0,         47,         47,        1,    75600, 0xd5501ac7
+0,         48,         48,        1,    75600, 0xa00201f1
+0,         49,         49,        1,    75600, 0xee84e8c6
diff --git a/tests/ref/fate/hmac b/tests/ref/fate/hmac
index 7d2a437..27b95ba 100644
--- a/tests/ref/fate/hmac
+++ b/tests/ref/fate/hmac
@@ -1,6 +1,30 @@
 9294727a3638bb1c13f48ef8158bfc9d
 750c783e6ab0b503eaa86e310a5db738
 56be34521d144c88dbb8c733f0e8b3f6
-467cb2560355d7fa3ab2d6b939e6e47c
-5a6ffd741d3e23b12f78b1baee9e609a
-8b4b9d11c9e186c58f2a53b08ddfa436
+6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd
+6f630fad67cda0ee1fb1f562db3aa53e
+b617318655057264e28bc0b6fb378c8ef146be00
+effcdf6ae5eb2fa2d27416d5f184df9c259a7c79
+125d7342b9ac11cd91a39af48aa17b4f63f175d3
+aa4ae5e15272d00e95705637ce8a3b55ed402112
+e8e99d0f45237d786d6bbaa7965c7808bbff1a91
+896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22
+a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44
+7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea
+95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e
+3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1
+b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7
+5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843
+773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe
+60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54
+9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2
+afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6
+af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649
+88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e55966144b2a5ab39dc13814b94e3ab6e101a34f27
+4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05033ac4c60c2ef6ab4030fe8296248df163f44952
+6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82461e99c5a678cc31e799176d3860e6110c46523e
+87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854
+164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737
+fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb
+80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598
+e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58
diff --git a/tests/ref/fate/indeo3-2 b/tests/ref/fate/indeo3-2
new file mode 100644
index 0000000..702d06b
--- /dev/null
+++ b/tests/ref/fate/indeo3-2
@@ -0,0 +1,101 @@
+#tb 0: 200/2997
+0,          0,          0,        1,    67680, 0x532a4c40
+0,         37,         37,        1,    67680, 0x63d2757a
+0,         38,         38,        1,    67680, 0xb1dcf7d3
+0,         39,         39,        1,    67680, 0x3225ee89
+0,         40,         40,        1,    67680, 0x9a102730
+0,         41,         41,        1,    67680, 0xf266888b
+0,         42,         42,        1,    67680, 0xd3b30d01
+0,         43,         43,        1,    67680, 0x7c647901
+0,         44,         44,        1,    67680, 0x0838e924
+0,         45,         45,        1,    67680, 0x2d470a56
+0,         46,         46,        1,    67680, 0x3eb99bda
+0,         47,         47,        1,    67680, 0x2b89e9f7
+0,         48,         48,        1,    67680, 0xcc006f93
+0,         49,         49,        1,    67680, 0x967b33e8
+0,         50,         50,        1,    67680, 0xcebbbfd3
+0,         51,         51,        1,    67680, 0x68365b83
+0,         52,         52,        1,    67680, 0xf1b0e536
+0,         53,         53,        1,    67680, 0x292ecc68
+0,         54,         54,        1,    67680, 0x83329d20
+0,         55,         55,        1,    67680, 0xe6ea8f5a
+0,         56,         56,        1,    67680, 0xcef27038
+0,         57,         57,        1,    67680, 0xa30445e4
+0,         58,         58,        1,    67680, 0x61aef9f5
+0,         59,         59,        1,    67680, 0x20abe80c
+0,         60,         60,        1,    67680, 0x7182a479
+0,         61,         61,        1,    67680, 0x56db4ec8
+0,         62,         62,        1,    67680, 0x08c1c3d4
+0,         63,         63,        1,    67680, 0x0d8879ed
+0,         64,         64,        1,    67680, 0x8e4eb9b9
+0,         65,         65,        1,    67680, 0x4629639e
+0,         66,         66,        1,    67680, 0x990bcd94
+0,         67,         67,        1,    67680, 0x2ae85671
+0,         68,         68,        1,    67680, 0xec296417
+0,         69,         69,        1,    67680, 0x41adf8da
+0,         70,         70,        1,    67680, 0xa035008f
+0,         71,         71,        1,    67680, 0xf8845e14
+0,         72,         72,        1,    67680, 0x802e52c4
+0,         73,         73,        1,    67680, 0xa2582b4a
+0,         74,         74,        1,    67680, 0x9ca567d7
+0,         75,         75,        1,    67680, 0x2ec69fac
+0,         76,         76,        1,    67680, 0x3a6d35ea
+0,         77,         77,        1,    67680, 0x9df7b7f6
+0,         78,         78,        1,    67680, 0x2d9dc502
+0,         79,         79,        1,    67680, 0x0ee16604
+0,         80,         80,        1,    67680, 0xb25d31a0
+0,         81,         81,        1,    67680, 0x52c04cb4
+0,         82,         82,        1,    67680, 0xd9ddec28
+0,         83,         83,        1,    67680, 0x1732f444
+0,         84,         84,        1,    67680, 0x19e01da5
+0,         85,         85,        1,    67680, 0x9af109df
+0,         86,         86,        1,    67680, 0xc59ba581
+0,         87,         87,        1,    67680, 0x8daaa58f
+0,         88,         88,        1,    67680, 0xd560a9ae
+0,         89,         89,        1,    67680, 0xe3fe77b4
+0,         90,         90,        1,    67680, 0x2a0e6c20
+0,         91,         91,        1,    67680, 0x9741f744
+0,         92,         92,        1,    67680, 0x8ec827dd
+0,         93,         93,        1,    67680, 0x7d90551f
+0,         94,         94,        1,    67680, 0x4d8f2665
+0,         95,         95,        1,    67680, 0x21e5a86e
+0,         96,         96,        1,    67680, 0x9ba3fe8f
+0,         97,         97,        1,    67680, 0xc84b7e41
+0,         98,         98,        1,    67680, 0x8da743e2
+0,         99,         99,        1,    67680, 0x49c4e00e
+0,        100,        100,        1,    67680, 0x90fc5dab
+0,        101,        101,        1,    67680, 0x9973a011
+0,        102,        102,        1,    67680, 0xfdd58648
+0,        103,        103,        1,    67680, 0xe181e329
+0,        104,        104,        1,    67680, 0xf60065c3
+0,        105,        105,        1,    67680, 0xde9bfc23
+0,        106,        106,        1,    67680, 0x37b9f867
+0,        107,        107,        1,    67680, 0x232ce0e9
+0,        108,        108,        1,    67680, 0x3fde091d
+0,        109,        109,        1,    67680, 0x3f00a465
+0,        110,        110,        1,    67680, 0x882b0042
+0,        111,        111,        1,    67680, 0x1bc3d626
+0,        112,        112,        1,    67680, 0xd15861a7
+0,        113,        113,        1,    67680, 0x056cd815
+0,        114,        114,        1,    67680, 0xe3fc887f
+0,        115,        115,        1,    67680, 0xdbddd03a
+0,        116,        116,        1,    67680, 0xfe6d865f
+0,        117,        117,        1,    67680, 0xbea7f202
+0,        118,        118,        1,    67680, 0x6d4114b9
+0,        119,        119,        1,    67680, 0x47bc93be
+0,        120,        120,        1,    67680, 0xb6136a41
+0,        121,        121,        1,    67680, 0xf0e63ecb
+0,        122,        122,        1,    67680, 0xb014b2a0
+0,        123,        123,        1,    67680, 0xf85a4be5
+0,        124,        124,        1,    67680, 0x21457c25
+0,        125,        125,        1,    67680, 0x75ae6bfb
+0,        126,        126,        1,    67680, 0x7ced988c
+0,        127,        127,        1,    67680, 0x3bf67347
+0,        128,        128,        1,    67680, 0x43e1ace5
+0,        129,        129,        1,    67680, 0xa23f8f45
+0,        130,        130,        1,    67680, 0x29d6cd9e
+0,        131,        131,        1,    67680, 0xad41bd94
+0,        132,        132,        1,    67680, 0x58e131c8
+0,        133,        133,        1,    67680, 0x617debea
+0,        134,        134,        1,    67680, 0x8a9db524
+0,        135,        135,        1,    67680, 0x17264d55
diff --git a/tests/ref/fate/lagarith-red b/tests/ref/fate/lagarith-red
new file mode 100644
index 0000000..b5fb96b
--- /dev/null
+++ b/tests/ref/fate/lagarith-red
@@ -0,0 +1,26 @@
+#tb 0: 1/25
+0,          0,          0,        1,   230400, 0x67dfe576
+0,          1,          1,        1,   230400, 0x67dfe576
+0,          2,          2,        1,   230400, 0x67dfe576
+0,          3,          3,        1,   230400, 0x67dfe576
+0,          4,          4,        1,   230400, 0x67dfe576
+0,          5,          5,        1,   230400, 0x67dfe576
+0,          6,          6,        1,   230400, 0x67dfe576
+0,          7,          7,        1,   230400, 0x67dfe576
+0,          8,          8,        1,   230400, 0x67dfe576
+0,          9,          9,        1,   230400, 0x67dfe576
+0,         10,         10,        1,   230400, 0x67dfe576
+0,         11,         11,        1,   230400, 0x67dfe576
+0,         12,         12,        1,   230400, 0x67dfe576
+0,         13,         13,        1,   230400, 0x67dfe576
+0,         14,         14,        1,   230400, 0x67dfe576
+0,         15,         15,        1,   230400, 0x67dfe576
+0,         16,         16,        1,   230400, 0x67dfe576
+0,         17,         17,        1,   230400, 0x67dfe576
+0,         18,         18,        1,   230400, 0x67dfe576
+0,         19,         19,        1,   230400, 0x67dfe576
+0,         20,         20,        1,   230400, 0x67dfe576
+0,         21,         21,        1,   230400, 0x67dfe576
+0,         22,         22,        1,   230400, 0x67dfe576
+0,         23,         23,        1,   230400, 0x67dfe576
+0,         24,         24,        1,   230400, 0x67dfe576
diff --git a/tests/ref/fate/lossless-monkeysaudio b/tests/ref/fate/lossless-monkeysaudio-399
similarity index 100%
rename from tests/ref/fate/lossless-monkeysaudio
rename to tests/ref/fate/lossless-monkeysaudio-399
diff --git a/tests/ref/fate/mkv b/tests/ref/fate/mkv
new file mode 100644
index 0000000..78440b2
--- /dev/null
+++ b/tests/ref/fate/mkv
@@ -0,0 +1,217 @@
+#tb 0: 1/1000
+#tb 1: 1/1000
+0,        -42,          0,        0,    63501, 0x139d4c99
+0,          0,         84,        0,     5368, 0xd964b678, F=0x0
+1,          8,          8,       21,      528, 0x3c990ddf
+1,         29,         29,       21,      510, 0xc16e0719
+0,         42,         42,        0,     1840, 0x097b6726, F=0x0
+1,         50,         50,       21,      500, 0x6248f603
+1,         71,         71,       22,      491, 0xe767f705
+0,         84,        167,        0,     7168, 0xaa5913ed, F=0x0
+1,         93,         93,       21,      506, 0x4340f3f3
+1,        114,        114,       21,      492, 0xf11c0210
+0,        125,        125,        0,     2129, 0x6ab0db3e, F=0x0
+1,        135,        135,       21,      502, 0x314b007e
+1,        156,        156,       22,      507, 0x76de0162
+0,        167,        250,        0,     7230, 0x3fd63940, F=0x0
+1,        179,        179,       21,      501, 0x0538fa45
+1,        200,        200,       21,      521, 0xc89f06d2
+0,        209,        209,        0,     2114, 0xfceafb26, F=0x0
+1,        221,        221,       21,      646, 0x8d8d3599
+1,        242,        242,       22,      661, 0x222242de
+0,        250,        334,        0,    63420, 0x5ca6250f, F=0x0
+1,        264,        264,       21,      609, 0xc0dc255c
+1,        285,        285,       21,      619, 0x9ac52dd1
+0,        292,        292,        0,    16751, 0xf293ab46, F=0x0
+0,        292,        417,        0,    22029, 0x3696462b, F=0x0
+1,        306,        306,       21,      574, 0xf6410d4d
+1,        327,        327,       22,      565, 0xfd561191
+1,        350,        350,       21,      713, 0x48425147
+1,        371,        371,       21,      537, 0x09bbf515
+0,        375,        375,        0,     5044, 0xa0344ae6, F=0x0
+1,        392,        392,       21,      486, 0x7946e28c
+1,        413,        413,       22,      499, 0xa770f22a
+0,        417,        500,        0,    25289, 0x46f9a219, F=0x0
+1,        435,        435,       21,      506, 0x355ef81d
+1,        456,        456,       21,      474, 0x6d24e2c5
+0,        459,        459,        0,    12871, 0x23e570c4, F=0x0
+1,        477,        477,       21,      494, 0x7d77e90f
+1,        498,        498,       22,      524, 0x6c82fdd2
+0,        500,        584,        0,    29580, 0xd051ad0c, F=0x0
+1,        520,        520,       21,      482, 0xe625f255
+1,        541,        541,       21,      533, 0xed00fd16
+0,        542,        542,        0,     9221, 0xfa1bdf6c, F=0x0
+1,        562,        562,       21,      524, 0x65cdf879
+1,        583,        583,       22,      533, 0xee26f570
+0,        584,        667,        0,    22238, 0x4e0daf3e, F=0x0
+1,        605,        605,       21,      621, 0xed9f23cc
+0,        625,        625,        0,     7627, 0xc566337e, F=0x0
+1,        626,        626,       21,      400, 0xe4fdb43a
+1,        647,        647,       21,      428, 0xd7eacd61
+0,        667,        750,        0,    23124, 0x3bad1f16, F=0x0
+1,        668,        668,       22,      442, 0xef1fda0b
+1,        691,        691,       21,      450, 0x1c58e44b
+0,        709,        709,        0,     7093, 0x3ab77cce, F=0x0
+1,        712,        712,       21,      487, 0x0e5feab7
+1,        733,        733,       21,      465, 0x984adca9
+0,        750,        834,        0,    23210, 0xa7851bbf, F=0x0
+1,        754,        754,       22,      479, 0x0960e535
+1,        776,        776,       21,      489, 0x2f3ffc02
+0,        792,        792,        0,    16045, 0x33039eb5, F=0x0
+1,        797,        797,       21,      505, 0x541aff95
+1,        818,        818,       21,      485, 0xb7a5e7f8
+0,        834,        917,        0,    24859, 0x317ea0f2, F=0x0
+1,        839,        839,       22,      537, 0xb0dd1072
+1,        862,        862,       21,      485, 0x6e9eee58
+0,        875,        875,        0,     7589, 0x02a8e5d5, F=0x0
+1,        883,        883,       21,      480, 0x0a6fec0b
+1,        904,        904,       21,      496, 0x6ff8ee65
+0,        917,        959,        0,    19208, 0xdfb1a109, F=0x0
+1,        925,        925,       21,      505, 0x75a308b8
+1,        946,        946,       21,      512, 0x9628f3da
+0,        959,       2000,        0,    60241, 0x43fcc627
+1,        967,        967,       22,      506, 0xefc901cf
+1,        990,        990,       21,      487, 0x1fd3edc8
+1,       1011,       1011,       21,      485, 0x8ccde513
+1,       1993,       1993,       21,      459, 0x725ede33
+0,       2000,       2084,        0,    23528, 0xc1dd888a, F=0x0
+1,       2014,       2014,       21,      481, 0x2cd7e611
+1,       2035,       2035,       21,      473, 0x14f2d777
+0,       2042,       2042,        0,     9206, 0x8f8cb89b, F=0x0
+1,       2056,       2056,       21,      543, 0x0f6dfccf
+1,       2077,       2077,       22,      489, 0x8049f5df
+0,       2084,       2167,        0,    34864, 0x3a343fe0, F=0x0
+1,       2099,       2099,       21,      480, 0xaa82edfc
+1,       2120,       2120,       21,      505, 0xea87f3e9
+0,       2125,       2125,        0,    12516, 0x885c8e4d, F=0x0
+1,       2141,       2141,       21,      474, 0x0760e6a1
+1,       2162,       2162,       22,      547, 0xcde40a72
+0,       2167,       2250,        0,    21215, 0x4428040b, F=0x0
+1,       2184,       2184,       21,      606, 0x4e401ec6
+1,       2205,       2205,       21,      611, 0xd13e18b6
+0,       2209,       2209,        0,    11811, 0xfe46f6c7, F=0x0
+1,       2226,       2226,       21,      492, 0xe2a3ea95
+1,       2247,       2247,       22,      582, 0x15fe1df5
+0,       2250,       2334,        0,    18643, 0xdcd87177, F=0x0
+1,       2269,       2269,       21,      455, 0x3753cfd3
+1,       2290,       2290,       21,      467, 0x9342cfed
+0,       2292,       2292,        0,     4578, 0x0bacbdaf, F=0x0
+1,       2311,       2311,       21,      422, 0x080ec43e
+1,       2332,       2332,       22,      466, 0xefb8e9aa
+0,       2334,       2417,        0,    25403, 0x49348e8b, F=0x0
+1,       2355,       2355,       21,      482, 0x2455e264
+0,       2375,       2375,        0,     7254, 0xe5c672b9, F=0x0
+1,       2376,       2376,       21,      471, 0xb370df1e
+1,       2397,       2397,       21,      461, 0x01addfe6
+0,       2417,       2500,        0,    25215, 0x1149c259, F=0x0
+1,       2418,       2418,       22,      566, 0x93760a5d
+1,       2440,       2440,       21,      618, 0x4e8e2f95
+0,       2459,       2459,        0,    14257, 0x38956a4d, F=0x0
+1,       2461,       2461,       21,      612, 0xc79128bc
+1,       2482,       2482,       21,      594, 0x169d1975
+0,       2500,       2584,        0,    36619, 0xca6497c5, F=0x0
+1,       2503,       2503,       22,      488, 0xb218e907
+1,       2526,       2526,       21,      437, 0xb180c83f
+0,       2542,       2542,        0,    13152, 0x4ea52247, F=0x0
+1,       2547,       2547,       21,      432, 0x85f8cf2b
+1,       2568,       2568,       21,      469, 0x65d0e38e
+0,       2584,       2667,        0,    31751, 0xb0140e79, F=0x0
+1,       2589,       2589,       22,      473, 0xb4dee328
+1,       2611,       2611,       21,      462, 0xd95cd547
+0,       2625,       2625,        0,    13619, 0x97308292, F=0x0
+1,       2632,       2632,       21,      470, 0x3638f48d
+1,       2653,       2653,       21,      558, 0x93c3121b
+0,       2667,       2750,        0,    32851, 0x014d2abc, F=0x0
+1,       2674,       2674,       22,      486, 0x5983ed52
+1,       2696,       2696,       21,      507, 0x572af3c3
+0,       2709,       2709,        0,    16915, 0x3597bc67, F=0x0
+1,       2717,       2717,       21,      480, 0xe3b3e16c
+1,       2738,       2738,       21,      492, 0x9443f00e
+0,       2750,       2834,        0,    35380, 0x728cd77a, F=0x0
+1,       2759,       2759,       22,      480, 0x7845ea30
+1,       2781,       2781,       21,      480, 0x7d01e1a2
+0,       2792,       2792,        0,    12780, 0x84c38c29, F=0x0
+1,       2802,       2802,       21,      505, 0x17d6f18b
+1,       2823,       2823,       21,      506, 0xca09ee14
+0,       2834,       2917,        0,    26049, 0x3788982a, F=0x0
+1,       2844,       2844,       22,      479, 0x0383f05a
+1,       2867,       2867,       21,      499, 0xa3b5e804
+0,       2875,       2875,        0,    11796, 0x0cbff503, F=0x0
+1,       2888,       2888,       21,      494, 0x0970e72e
+1,       2909,       2909,       21,      484, 0x6f34da96
+0,       2917,       2959,        0,    16638, 0x097c9345, F=0x0
+1,       2930,       2930,       21,      492, 0x5282e9aa
+1,       2951,       2951,       21,      487, 0x6f19e15e
+0,       2959,       3000,        0,    64129, 0xc13b91ac
+1,       2972,       2972,       22,      500, 0x17aef81a
+1,       2995,       2995,       21,      510, 0xa323f6e6
+0,       3000,       3084,        0,    19338, 0xfe901382, F=0x0
+1,       3016,       3016,       21,      492, 0x49d7e74f
+1,       3038,       3038,       21,      483, 0xa78deadb
+0,       3042,       3042,        0,     4643, 0x5a05768b, F=0x0
+1,       3059,       3059,       21,      639, 0xf2c237e9
+1,       3080,       3080,       21,      661, 0xcd604711
+0,       3084,       3167,        0,    25932, 0x395e1d01, F=0x0
+1,       3101,       3101,       22,      647, 0xb8ee3acf
+1,       3123,       3123,       21,      575, 0x3303118e
+0,       3125,       3125,        0,     5301, 0x2aacb15c, F=0x0
+1,       3144,       3144,       21,      506, 0x2063eef7
+1,       3165,       3165,       21,      518, 0x7661f08e
+0,       3167,       3250,        0,    24089, 0x5cf78354, F=0x0
+1,       3186,       3186,       22,      534, 0x2858f90e
+1,       3208,       3208,       21,      520, 0xd596f460
+0,       3209,       3209,        0,     5837, 0x1c16cfad, F=0x0
+1,       3229,       3229,       21,      496, 0xc2a6efed
+0,       3250,       3334,        0,    26754, 0x4cf1ad04, F=0x0
+1,       3250,       3250,       21,      470, 0xcff5e778
+1,       3271,       3271,       22,      476, 0xcb63e48a
+0,       3292,       3292,        0,    11067, 0x8b0b776f, F=0x0
+1,       3293,       3293,       21,      516, 0xaea8f74b
+1,       3314,       3314,       21,      503, 0x5998f00d
+0,       3334,       3417,        0,    28780, 0xc610f024, F=0x0
+1,       3335,       3335,       21,      488, 0xd818dd28
+1,       3356,       3356,       22,      495, 0x2662f5b5
+0,       3375,       3375,        0,    14863, 0xd58ed8f0, F=0x0
+1,       3379,       3379,       21,      499, 0x6884ec30
+1,       3400,       3400,       21,      496, 0x556bdc0e
+0,       3417,       3500,        0,    24790, 0x71e32bae, F=0x0
+1,       3421,       3421,       21,      524, 0xa756f115
+1,       3442,       3442,       22,      505, 0xd332f37b
+0,       3459,       3459,        0,     9123, 0x6c72b7a3, F=0x0
+1,       3464,       3464,       21,      494, 0xa380e41e
+1,       3485,       3485,       21,      513, 0xf26bf0a9
+0,       3500,       3584,        0,    24706, 0x9bdd9247, F=0x0
+1,       3506,       3506,       21,      515, 0x28fffe2a
+1,       3527,       3527,       22,      506, 0xc5a2f83c
+0,       3542,       3542,        0,     8105, 0x85b8ff64, F=0x0
+1,       3550,       3550,       21,      510, 0xa10bf9c7
+1,       3571,       3571,       21,      507, 0x93d1e650
+0,       3584,       3667,        0,    25402, 0xe4622ee0, F=0x0
+1,       3592,       3592,       21,      506, 0x1a36f285
+1,       3613,       3613,       22,      522, 0xd7a1f5e4
+0,       3625,       3625,        0,     9693, 0x910910bc, F=0x0
+1,       3635,       3635,       21,      511, 0x2e79fa62
+1,       3656,       3656,       21,      516, 0xfda2ef86
+0,       3667,       3750,        0,    31403, 0xff9934ee, F=0x0
+1,       3677,       3677,       21,      497, 0xd65cf156
+1,       3698,       3698,       22,      480, 0xde3be560
+0,       3709,       3709,        0,    13936, 0x9b6aec9e, F=0x0
+1,       3720,       3720,       21,      514, 0x7d8cf49f
+1,       3741,       3741,       21,      667, 0x7a483dec
+0,       3750,       3834,        0,    28639, 0x620b80de, F=0x0
+1,       3762,       3762,       21,      640, 0x7cd92998
+1,       3783,       3783,       22,      504, 0xe3bbf106
+0,       3792,       3792,        0,    18769, 0xf51353c4, F=0x0
+1,       3805,       3805,       21,      498, 0xe8c6f489
+1,       3826,       3826,       21,      489, 0x620df125
+0,       3834,       3917,        0,    30240, 0x48151fb3, F=0x0
+1,       3847,       3847,       21,      505, 0x7d73e570
+1,       3868,       3868,       22,      496, 0xc211f6c6
+0,       3875,       3875,        0,    13391, 0x4f3f112d, F=0x0
+1,       3891,       3891,       21,      483, 0x126fe774
+1,       3912,       3912,       21,      479, 0xac88db91
+0,       3917,       3959,        0,    19896, 0x0e667f6e, F=0x0
+1,       3933,       3933,       21,      480, 0x545df57b
+1,       3954,       3954,       21,      473, 0x9a37e7ef
+1,       3975,       3975,       22,      472, 0x4c8ee70d
+1,       3998,       3998,       21,      508, 0x5c6bf8f3
diff --git a/tests/ref/fate/msvideo1-8bit b/tests/ref/fate/msvideo1-8bit
index 6e6bc0b..74d54e8 100644
--- a/tests/ref/fate/msvideo1-8bit
+++ b/tests/ref/fate/msvideo1-8bit
@@ -29,4 +29,3 @@
 0,         27,         27,        1,    57600, 0x4ec4a868
 0,         28,         28,        1,    57600, 0x7db370a1
 0,         29,         29,        1,    57600, 0x2b1e52f6
-0,         30,         30,        1,    57600, 0x2141467c
diff --git a/tests/ref/fate/murmur3 b/tests/ref/fate/murmur3
new file mode 100644
index 0000000..cd5c0e8
--- /dev/null
+++ b/tests/ref/fate/murmur3
@@ -0,0 +1 @@
+result: 0x63f3de036384ba69 0x7192878ce684ed2d
diff --git a/tests/ref/fate/nuv-rtjpeg b/tests/ref/fate/nuv-rtjpeg
index 8838fbb..96ead33 100644
--- a/tests/ref/fate/nuv-rtjpeg
+++ b/tests/ref/fate/nuv-rtjpeg
@@ -7,4 +7,3 @@
 0,          9,          9,        1,   460800, 0x4e091ee2
 0,         10,         10,        1,   460800, 0x2ea88828
 0,         11,         11,        1,   460800, 0x4b7f4df0
-0,         12,         12,        1,   460800, 0xa57f20d0
diff --git a/tests/ref/fate/parseutils b/tests/ref/fate/parseutils
index 5fa3bf4e..1482452 100644
--- a/tests/ref/fate/parseutils
+++ b/tests/ref/fate/parseutils
@@ -21,7 +21,7 @@
 '.23' -> 23/100 OK
 '-.23' -> -23/100 ERROR
 '-0.234' -> -117/500 ERROR
-'-0.0000001' -> 0/1 ERROR
+'-0.0000001' -> -1/10000000 ERROR
 '  21332.2324   ' -> 917286/43 OK
 ' -21332.2324   ' -> -917286/43 ERROR
 
diff --git a/tests/ref/fate/prores-alpha b/tests/ref/fate/prores-alpha
index bdb5c6e..9a8b9ee 100644
--- a/tests/ref/fate/prores-alpha
+++ b/tests/ref/fate/prores-alpha
@@ -1,3 +1,3 @@
 #tb 0: 100/2997
-0,          0,          0,        1, 12441600, 0x254d8f95
-0,          1,          1,        1, 12441600, 0x254d8f95
+0,          0,          0,        1, 16588800, 0x8dcdb600
+0,          1,          1,        1, 16588800, 0x8dcdb600
diff --git a/tests/ref/fate/prores-transparency b/tests/ref/fate/prores-transparency
new file mode 100644
index 0000000..9c71d33
--- /dev/null
+++ b/tests/ref/fate/prores-transparency
@@ -0,0 +1,5 @@
+#tb 0: 1/25
+#tb 1: 1/48000
+0,          0,          0,        1, 16588800, 0x20778f5e
+1,          0,          0,     1024,     4096, 0x00000000
+1,       1024,       1024,      896,     3584, 0x00000000
diff --git a/tests/ref/fate/redspark-demux b/tests/ref/fate/redspark-demux
new file mode 100644
index 0000000..fadfe93
--- /dev/null
+++ b/tests/ref/fate/redspark-demux
@@ -0,0 +1 @@
+CRC=0xc0fd1aa2
diff --git a/tests/ref/fate/ripemd b/tests/ref/fate/ripemd
new file mode 100644
index 0000000..947412d
--- /dev/null
+++ b/tests/ref/fate/ripemd
@@ -0,0 +1,28 @@
+Testing RIPEMD-128
+C14A12199C66E4BA84636B0F69144C77
+A1AA0689D0FAFA2DDC22E88B49133A06
+4A7F5723F954EBA1216C9D8F6320431F
+c14a1219 9c66e4ba 84636b0f 69144c77
+a1aa0689 d0fafa2d dc22e88b 49133a06
+4a7f5723 f954eba1 216c9d8f 6320431f
+Testing RIPEMD-160
+8EB208F7E05D987A9B044A8E98C6B087F15A0BFC
+12A053384A9C0C88E405A06C27DCF49ADA62EB2B
+52783243C1697BDBE16D37F97F68F08325DC1528
+8eb208f7 e05d987a 9b044a8e 98c6b087 f15a0bfc
+12a05338 4a9c0c88 e405a06c 27dcf49a da62eb2b
+52783243 c1697bdb e16d37f9 7f68f083 25dc1528
+Testing RIPEMD-256
+AFBD6E228B9D8CBBCEF5CA2D03E6DBA10AC0BC7DCBE4680E1E42D2E975459B65
+3843045583AAC6C8C8D9128573E7A9809AFB2A0F34CCC36EA9E72F16F6368E3F
+AC953744E10E31514C150D4D8D7B677342E33399788296E43AE4850CE4F97978
+afbd6e22 8b9d8cbb cef5ca2d 03e6dba1 0ac0bc7d cbe4680e 1e42d2e9 75459b65
+38430455 83aac6c8 c8d91285 73e7a980 9afb2a0f 34ccc36e a9e72f16 f6368e3f
+ac953744 e10e3151 4c150d4d 8d7b6773 42e33399 788296e4 3ae4850c e4f97978
+Testing RIPEMD-320
+DE4C01B3054F8930A79D09AE738E92301E5A17085BEFFDC1B8D116713E74F82FA942D64CDBC4682D
+D034A7950CF722021BA4B84DF769A5DE2060E259DF4C9BB4A4268C0E935BBC7470A969C9D072A1AC
+BDEE37F4371E20646B8B0D862DDA16292AE36F40965E8C8509E63D1DBDDECC503E2B63EB9245BB66
+de4c01b3 054f8930 a79d09ae 738e9230 1e5a1708 5beffdc1 b8d11671 3e74f82f a942d64c dbc4682d
+d034a795 0cf72202 1ba4b84d f769a5de 2060e259 df4c9bb4 a4268c0e 935bbc74 70a969c9 d072a1ac
+bdee37f4 371e2064 6b8b0d86 2dda1629 2ae36f40 965e8c85 09e63d1d bddecc50 3e2b63eb 9245bb66
diff --git a/tests/ref/fate/rsd-demux b/tests/ref/fate/rsd-demux
new file mode 100644
index 0000000..3aa2573
--- /dev/null
+++ b/tests/ref/fate/rsd-demux
@@ -0,0 +1 @@
+CRC=0x7b7807d8
diff --git a/tests/ref/fate/sha512 b/tests/ref/fate/sha512
new file mode 100644
index 0000000..6009115
--- /dev/null
+++ b/tests/ref/fate/sha512
@@ -0,0 +1,28 @@
+Testing SHA-512/224
+4634270F707B6A54DAAE7530460842E20E37ED265CEEE9A43E8924AA
+23FEC5BB94D60B23308192640B0C453335D664734FE40E7268674AF9
+37AB331D76F0D36DE422BD0EDEB22A28ACCD487B7A8453AE965DD287
+4634270f 707b6a54 daae7530 460842e2 0e37ed26 5ceee9a4 3e8924aa
+23fec5bb 94d60b23 30819264 0b0c4533 35d66473 4fe40e72 68674af9
+37ab331d 76f0d36d e422bd0e deb22a28 accd487b 7a8453ae 965dd287
+Testing SHA-512/256
+53048E2681941EF99B2E29B76B4C7DABE4C2D0C634FC6D46E0E2F13107E7AF23
+3928E184FB8690F840DA3988121D31BE65CB9D3EF83EE6146FEAC861E19B563A
+9A59A052930187A97038CAE692F30708AA6491923EF5194394DC68D56C74FB21
+53048e26 81941ef9 9b2e29b7 6b4c7dab e4c2d0c6 34fc6d46 e0e2f131 07e7af23
+3928e184 fb8690f8 40da3988 121d31be 65cb9d3e f83ee614 6feac861 e19b563a
+9a59a052 930187a9 7038cae6 92f30708 aa649192 3ef51943 94dc68d5 6c74fb21
+Testing SHA-384
+CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED1631A8B605A43FF5BED8086072BA1E7CC2358BAECA134C825A7
+09330C33F71147E83D192FC782CD1B4753111B173B3B05D22FA08086E3B0F712FCC7C71A557E2DB966C3E9FA91746039
+9D0E1809716474CB086E834E310A4A1CED149E9C00F248527972CEC5704C2A5B07B8B3DC38ECC4EBAE97DDD87F3D8985
+cb00753f 45a35e8b b5a03d69 9ac65007 272c32ab 0eded163 1a8b605a 43ff5bed 8086072b a1e7cc23 58baeca1 34c825a7
+09330c33 f71147e8 3d192fc7 82cd1b47 53111b17 3b3b05d2 2fa08086 e3b0f712 fcc7c71a 557e2db9 66c3e9fa 91746039
+9d0e1809 716474cb 086e834e 310a4a1c ed149e9c 00f24852 7972cec5 704c2a5b 07b8b3dc 38ecc4eb ae97ddd8 7f3d8985
+Testing SHA-512
+DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA20A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F
+8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA17299AEADB6889018501D289E4900F7E4331B99DEC4B5433AC7D329EEB6DD26545E96E55B874BE909
+E718483D0CE769644E2E42C7BC15B4638E1F98B13B2044285632A803AFA973EBDE0FF244877EA60A4CB0432CE577C31BEB009C5C2C49AA2E4EADB217AD8CC09B
+ddaf35a1 93617aba cc417349 ae204131 12e6fa4e 89a97ea2 0a9eeee6 4b55d39a 2192992a 274fc1a8 36ba3c23 a3feebbd 454d4423 643ce80e 2a9ac94f a54ca49f
+8e959b75 dae313da 8cf4f728 14fc143f 8f7779c6 eb9f7fa1 7299aead b6889018 501d289e 4900f7e4 331b99de c4b5433a c7d329ee b6dd2654 5e96e55b 874be909
+e718483d 0ce76964 4e2e42c7 bc15b463 8e1f98b1 3b204428 5632a803 afa973eb de0ff244 877ea60a 4cb0432c e577c31b eb009c5c 2c49aa2e 4eadb217 ad8cc09b
diff --git a/tests/ref/fate/sierra-vmd-video b/tests/ref/fate/sierra-vmd-video
index 5b9dde1..668faee 100644
--- a/tests/ref/fate/sierra-vmd-video
+++ b/tests/ref/fate/sierra-vmd-video
@@ -1,118 +1,118 @@
 #tb 0: 1/10
-0,          0,          0,        1,   230400, 0x0224ab01
-0,          1,          1,        1,   230400, 0x449e4d81
-0,          2,          2,        1,   230400, 0x3e15e07a
-0,          3,          3,        1,   230400, 0xdabe4172
-0,          4,          4,        1,   230400, 0x0947b7db
-0,          5,          5,        1,   230400, 0x934e243b
-0,          6,          6,        1,   230400, 0x6b5c5b6c
-0,          7,          7,        1,   230400, 0x4bf7bbb5
-0,          8,          8,        1,   230400, 0x423eec8e
-0,          9,          9,        1,   230400, 0x63663b5e
-0,         10,         10,        1,   230400, 0x9c258a67
-0,         11,         11,        1,   230400, 0x1c92b6e0
-0,         12,         12,        1,   230400, 0xdd0a0e28
-0,         13,         13,        1,   230400, 0x51d64af1
-0,         14,         14,        1,   230400, 0x5776ac12
-0,         15,         15,        1,   230400, 0x49070132
-0,         16,         16,        1,   230400, 0xa59635ab
-0,         17,         17,        1,   230400, 0xb1f99504
-0,         18,         18,        1,   230400, 0x61fac725
-0,         19,         19,        1,   230400, 0xc32c28d5
-0,         20,         20,        1,   230400, 0x2b7a91d6
-0,         21,         21,        1,   230400, 0x917be717
-0,         22,         22,        1,   230400, 0xd3c5a2ff
-0,         23,         23,        1,   230400, 0x0678a707
-0,         24,         24,        1,   230400, 0x122504e6
-0,         25,         25,        1,   230400, 0x76aebdae
-0,         26,         26,        1,   230400, 0x81357545
-0,         27,         27,        1,   230400, 0x38baeebd
-0,         28,         28,        1,   230400, 0x1c5c44d4
-0,         29,         29,        1,   230400, 0x60e189cc
-0,         30,         30,        1,   230400, 0xb1f4381c
-0,         31,         31,        1,   230400, 0xb5048fed
-0,         32,         32,        1,   230400, 0xc947c30e
-0,         33,         33,        1,   230400, 0xe8e31c07
-0,         34,         34,        1,   230400, 0x6d49dd02
-0,         35,         35,        1,   230400, 0x293e15d3
-0,         36,         36,        1,   230400, 0x354d792e
-0,         37,         37,        1,   230400, 0x35468780
-0,         38,         38,        1,   230400, 0x365d3991
-0,         39,         39,        1,   230400, 0xc9debef2
-0,         40,         40,        1,   230400, 0x4c4634c2
-0,         41,         41,        1,   230400, 0x347c2dca
-0,         42,         42,        1,   230400, 0x1efa0aaa
-0,         43,         43,        1,   230400, 0xa79a0b5a
-0,         44,         44,        1,   230400, 0xfdb2dcdb
-0,         45,         45,        1,   230400, 0x42dbea33
-0,         46,         46,        1,   230400, 0x2a207e43
-0,         47,         47,        1,   230400, 0x86573783
-0,         48,         48,        1,   230400, 0xc3968473
-0,         49,         49,        1,   230400, 0x8f62a7b4
-0,         50,         50,        1,   230400, 0x5a2e3073
-0,         51,         51,        1,   230400, 0xd24f5e2c
-0,         52,         52,        1,   230400, 0x1df3c67d
-0,         53,         53,        1,   230400, 0xe4fd884d
-0,         57,         57,        1,   230400, 0x9a228555
-0,         58,         58,        1,   230400, 0x9eba8ed5
-0,         59,         59,        1,   230400, 0x3d808a3d
-0,         60,         60,        1,   230400, 0xf57e866d
-0,         61,         61,        1,   230400, 0x85f594f5
-0,         62,         62,        1,   230400, 0xb09f99dd
-0,         63,         63,        1,   230400, 0x2b368475
-0,         64,         64,        1,   230400, 0xa2417afd
-0,         65,         65,        1,   230400, 0x590b709d
-0,         66,         66,        1,   230400, 0x5d617705
-0,         67,         67,        1,   230400, 0xabf981ad
-0,         68,         68,        1,   230400, 0x5a8590cd
-0,         69,         69,        1,   230400, 0x1bff853d
-0,         70,         70,        1,   230400, 0x71d08055
-0,         71,         71,        1,   230400, 0x2ebd817d
-0,         72,         72,        1,   230400, 0x6e838255
-0,         73,         73,        1,   230400, 0x043984cd
-0,         74,         74,        1,   230400, 0x7ff18495
-0,         75,         75,        1,   230400, 0xa43b8385
-0,         76,         76,        1,   230400, 0x72b5825d
-0,         77,         77,        1,   230400, 0x3a178085
-0,         78,         78,        1,   230400, 0x67748245
-0,         79,         79,        1,   230400, 0xeddf81d5
-0,         80,         80,        1,   230400, 0x8b088665
-0,         81,         81,        1,   230400, 0x6c408e15
-0,         82,         82,        1,   230400, 0x81f196dd
-0,         83,         83,        1,   230400, 0xab9f953d
-0,         84,         84,        1,   230400, 0xa5f69795
-0,         85,         85,        1,   230400, 0xa772950d
-0,         86,         86,        1,   230400, 0x6a5596d5
-0,         87,         87,        1,   230400, 0x1355958d
-0,         88,         88,        1,   230400, 0x4134981d
-0,         89,         89,        1,   230400, 0x8b929515
-0,         90,         90,        1,   230400, 0x482f95c5
-0,         91,         91,        1,   230400, 0x7a9795d5
-0,         92,         92,        1,   230400, 0x21c29abd
-0,         93,         93,        1,   230400, 0x9ae6a475
-0,         94,         94,        1,   230400, 0x3734aee5
-0,         95,         95,        1,   230400, 0xa0a1b365
-0,         96,         96,        1,   230400, 0x2dcab1c5
-0,         97,         97,        1,   230400, 0x9c8b6c44
-0,         98,         98,        1,   230400, 0x5da75feb
-0,         99,         99,        1,   230400, 0x4d02f8e3
-0,        100,        100,        1,   230400, 0x66824f3a
-0,        101,        101,        1,   230400, 0x0c9257e2
-0,        102,        102,        1,   230400, 0xb2927092
-0,        103,        103,        1,   230400, 0xb5dc6e9a
-0,        104,        104,        1,   230400, 0x6e567bc6
-0,        105,        105,        1,   230400, 0xbf9e0f7a
-0,        106,        106,        1,   230400, 0xb16f684a
-0,        107,        107,        1,   230400, 0xf9e55e81
-0,        108,        108,        1,   230400, 0xd8d0bcba
-0,        109,        109,        1,   230400, 0x44720ac0
-0,        110,        110,        1,   230400, 0x7d4c2058
-0,        113,        113,        1,   230400, 0xb0973eb9
-0,        114,        114,        1,   230400, 0x405a13ce
-0,        115,        115,        1,   230400, 0x6422f00a
-0,        116,        116,        1,   230400, 0x924b6c1e
-0,        145,        145,        1,   230400, 0xcf7809c0
-0,        146,        146,        1,   230400, 0x883a3863
-0,        147,        147,        1,   230400, 0x6adc9e03
-0,        148,        148,        1,   230400, 0x4f5ab7a8
-0,        214,        214,        1,   230400, 0xdc0aab94
+0,          0,          0,        1,   230400, 0x54b4bfe2
+0,          1,          1,        1,   230400, 0x9e1460e3
+0,          2,          2,        1,   230400, 0x8136f21c
+0,          3,          3,        1,   230400, 0xadfc5089
+0,          4,          4,        1,   230400, 0x76f2c4bc
+0,          5,          5,        1,   230400, 0x73862ec8
+0,          6,          6,        1,   230400, 0xba2562e3
+0,          7,          7,        1,   230400, 0xf908c0b6
+0,          8,          8,        1,   230400, 0x3596ee56
+0,          9,          9,        1,   230400, 0x97cc3a1e
+0,         10,         10,        1,   230400, 0xe2c585f9
+0,         11,         11,        1,   230400, 0x1732aedb
+0,         12,         12,        1,   230400, 0xa6d20354
+0,         13,         13,        1,   230400, 0x0e1e3d11
+0,         14,         14,        1,   230400, 0xe4f09bbd
+0,         15,         15,        1,   230400, 0x5c15ee1a
+0,         16,         16,        1,   230400, 0x33f51f69
+0,         17,         17,        1,   230400, 0xb6067c26
+0,         18,         18,        1,   230400, 0x985faab2
+0,         19,         19,        1,   230400, 0x3f0a09ae
+0,         20,         20,        1,   230400, 0x4052702f
+0,         21,         21,        1,   230400, 0xcd7fc29c
+0,         22,         22,        1,   230400, 0x73c97d9f
+0,         23,         23,        1,   230400, 0xf0fb8235
+0,         24,         24,        1,   230400, 0x7651e231
+0,         25,         25,        1,   230400, 0x3e749ecf
+0,         26,         26,        1,   230400, 0x20515985
+0,         27,         27,        1,   230400, 0xd086d4b0
+0,         28,         28,        1,   230400, 0x343c2c77
+0,         29,         29,        1,   230400, 0xb9a47309
+0,         30,         30,        1,   230400, 0x39de2037
+0,         31,         31,        1,   230400, 0x9fc2745a
+0,         32,         32,        1,   230400, 0x0868a2f3
+0,         33,         33,        1,   230400, 0xfe53f34d
+0,         34,         34,        1,   230400, 0xf2abaa57
+0,         35,         35,        1,   230400, 0x2dafdc4b
+0,         36,         36,        1,   230400, 0xf7d6353a
+0,         37,         37,        1,   230400, 0x8aa63c0a
+0,         38,         38,        1,   230400, 0xd1afe885
+0,         39,         39,        1,   230400, 0x64626c50
+0,         40,         40,        1,   230400, 0x2654dfca
+0,         41,         41,        1,   230400, 0x6183d8c7
+0,         42,         42,        1,   230400, 0xededb578
+0,         43,         43,        1,   230400, 0xadeeb629
+0,         44,         44,        1,   230400, 0x0009873a
+0,         45,         45,        1,   230400, 0xe2ec94eb
+0,         46,         46,        1,   230400, 0x62132788
+0,         47,         47,        1,   230400, 0x8cc5e014
+0,         48,         48,        1,   230400, 0x2ded2ecd
+0,         49,         49,        1,   230400, 0x81204eec
+0,         50,         50,        1,   230400, 0x4f9fda58
+0,         51,         51,        1,   230400, 0x9d7f073b
+0,         52,         52,        1,   230400, 0x607a6ee6
+0,         53,         53,        1,   230400, 0xed1c305c
+0,         57,         57,        1,   230400, 0x52b52d62
+0,         58,         58,        1,   230400, 0x4ae0370a
+0,         59,         59,        1,   230400, 0xe437326a
+0,         60,         60,        1,   230400, 0xefb82e8c
+0,         61,         61,        1,   230400, 0xa0f13d4b
+0,         62,         62,        1,   230400, 0x473a424a
+0,         63,         63,        1,   230400, 0x205a2c84
+0,         64,         64,        1,   230400, 0xe83022e5
+0,         65,         65,        1,   230400, 0x5db21854
+0,         66,         66,        1,   230400, 0x11991ed7
+0,         67,         67,        1,   230400, 0x649429b1
+0,         68,         68,        1,   230400, 0x840a3912
+0,         69,         69,        1,   230400, 0x8bb72d49
+0,         70,         70,        1,   230400, 0xedfc2850
+0,         71,         71,        1,   230400, 0x1b9b2977
+0,         72,         72,        1,   230400, 0x63912a4f
+0,         73,         73,        1,   230400, 0x971c2ccc
+0,         74,         74,        1,   230400, 0x1f022c98
+0,         75,         75,        1,   230400, 0x5dc42b8c
+0,         76,         76,        1,   230400, 0x25172a53
+0,         77,         77,        1,   230400, 0x31fd287f
+0,         78,         78,        1,   230400, 0x95182a44
+0,         79,         79,        1,   230400, 0xbf7d29ea
+0,         80,         80,        1,   230400, 0xdeb82e84
+0,         81,         81,        1,   230400, 0xc3ad3659
+0,         82,         82,        1,   230400, 0xfef23f36
+0,         83,         83,        1,   230400, 0xf4a23d8c
+0,         84,         84,        1,   230400, 0x90713fef
+0,         85,         85,        1,   230400, 0x5fad3d58
+0,         86,         86,        1,   230400, 0x69283f2e
+0,         87,         87,        1,   230400, 0x8f3d3dde
+0,         88,         88,        1,   230400, 0x3129407a
+0,         89,         89,        1,   230400, 0x266e3d64
+0,         90,         90,        1,   230400, 0xc41b3e19
+0,         91,         91,        1,   230400, 0x64203e29
+0,         92,         92,        1,   230400, 0x3f7e4328
+0,         93,         93,        1,   230400, 0xacef4d0e
+0,         94,         94,        1,   230400, 0xf0ca57a7
+0,         95,         95,        1,   230400, 0x87c75c41
+0,         96,         96,        1,   230400, 0x9db75a9c
+0,         97,         97,        1,   230400, 0x4152164c
+0,         98,         98,        1,   230400, 0x8a330ac8
+0,         99,         99,        1,   230400, 0x5113a45d
+0,        100,        100,        1,   230400, 0x60effb12
+0,        101,        101,        1,   230400, 0x01dc03c5
+0,        102,        102,        1,   230400, 0x7ae81caf
+0,        103,        103,        1,   230400, 0x35c31ab0
+0,        104,        104,        1,   230400, 0xd59e171e
+0,        105,        105,        1,   230400, 0x35c3989e
+0,        106,        106,        1,   230400, 0xf93656a5
+0,        107,        107,        1,   230400, 0x0962745c
+0,        108,        108,        1,   230400, 0x6a90cdb2
+0,        109,        109,        1,   230400, 0x4bc2216d
+0,        110,        110,        1,   230400, 0x7a6d3744
+0,        113,        113,        1,   230400, 0xf16a5742
+0,        114,        114,        1,   230400, 0x1495ce79
+0,        115,        115,        1,   230400, 0x3b4397b0
+0,        116,        116,        1,   230400, 0x33ed8506
+0,        145,        145,        1,   230400, 0xf953256d
+0,        146,        146,        1,   230400, 0xd7faaef9
+0,        147,        147,        1,   230400, 0xb37e6161
+0,        148,        148,        1,   230400, 0x526b6797
+0,        214,        214,        1,   230400, 0x8ec35bc5
diff --git a/tests/ref/fate/smvjpeg b/tests/ref/fate/smvjpeg
new file mode 100644
index 0000000..1a012cd
--- /dev/null
+++ b/tests/ref/fate/smvjpeg
@@ -0,0 +1,13 @@
+#tb 0: 1/1
+0,          0,          0,        1,    30720, 0x3a821807
+0,          1,          1,        1,    30720, 0x95168e5d
+0,          2,          2,        1,    30720, 0xd4d98e45
+0,          3,          3,        1,    30720, 0xe340a7ea
+0,          4,          4,        1,    30720, 0xb832a22d
+0,          5,          5,        1,    30720, 0x1f3eb488
+0,          6,          6,        1,    30720, 0x6429ce43
+0,          7,          7,        1,    30720, 0x3a3da232
+0,          8,          8,        1,    30720, 0x5c02aeff
+0,          9,          9,        1,    30720, 0x4c7b1c9a
+0,         10,         10,        1,    30720, 0x6f7a8313
+0,         11,         11,        1,    30720, 0xaa32fd72
diff --git a/tests/ref/fate/sub-aqtitle b/tests/ref/fate/sub-aqtitle
index f6900e7..c477b0a 100644
--- a/tests/ref/fate/sub-aqtitle
+++ b/tests/ref/fate/sub-aqtitle
@@ -1 +1 @@
-e888e1354cd0968895ab89cb169fec31
+1c68def68db6536c235819cbe0638e00
diff --git a/tests/ref/fate/sub-subviewer1 b/tests/ref/fate/sub-subviewer1
index 116fce7..052431a 100644
--- a/tests/ref/fate/sub-subviewer1
+++ b/tests/ref/fate/sub-subviewer1
@@ -1 +1 @@
-0c2096fedf7c971742b2e879bb303ce9
+cbeb015b1125757eed814f212cfc6c9c
diff --git a/tests/ref/fate/timefilter b/tests/ref/fate/timefilter
new file mode 100644
index 0000000..2fa88c9
--- /dev/null
+++ b/tests/ref/fate/timefilter
@@ -0,0 +1,6 @@
+ [80000.000000    0.800000  0.000000] [80000.000000    0.800000  0.000000] [80000.000000    0.800000  0.000000] [80000.000000    0.800000  0.000000]
+ [ 1688.672234    0.000000  0.018551] [   21.026792    0.000401  0.068856] [    1.162481    0.008576  0.121287] [    0.803356    0.016078  0.153518]
+ [ 1218.378235    0.000000  0.167011] [   12.908626    0.000281  0.296858] [   21.026792    0.000401  0.619608] [    2.064064    0.004760  1.020336]
+ [ 1218.378235    0.000000  0.909282] [   10.047626    0.000191  0.873495] [   14.909464    0.000297  1.935407] [   21.026792    0.000401  3.373312]
+ [  177.634056    0.000002  4.988477] [    5.363801    0.000176  2.102302] [   12.879355    0.000195  5.029066] [   15.615799    0.000298  9.292377]
+ [   43.713191    0.000007 63.605530] [    1.345385    0.000213 13.918138] [    6.800629    0.000142 13.284614] [   14.909464    0.000142 21.761697]
diff --git a/tests/ref/lavf-fate/mp3 b/tests/ref/lavf-fate/mp3
index 361314b..6f201e0 100644
--- a/tests/ref/lavf-fate/mp3
+++ b/tests/ref/lavf-fate/mp3
@@ -1,3 +1,3 @@
-7fcf80c2059b5c058a6cdd2e2f798b6c *./tests/data/lavf-fate/lavf.mp3
-96366 ./tests/data/lavf-fate/lavf.mp3
+6bdea919dc6856d76ef2553698e2b0d3 *./tests/data/lavf-fate/lavf.mp3
+96376 ./tests/data/lavf-fate/lavf.mp3
 ./tests/data/lavf-fate/lavf.mp3 CRC=0x6c9850fe
diff --git a/tests/ref/lavf/aiff b/tests/ref/lavf/aiff
index 2a5cd81..c504c18 100644
--- a/tests/ref/lavf/aiff
+++ b/tests/ref/lavf/aiff
@@ -1,3 +1,3 @@
-b0d42747a6fc99a5cd1ab0e861671f3a *./tests/data/lavf/lavf.aif
-90182 ./tests/data/lavf/lavf.aif
-./tests/data/lavf/lavf.aif CRC=0xf1ae5536
+2c129d88acef834e32869145fe792b9c *./tests/data/lavf/lavf.aif
+88270 ./tests/data/lavf/lavf.aif
+./tests/data/lavf/lavf.aif CRC=0x3a1da17e
diff --git a/tests/ref/lavf/alaw b/tests/ref/lavf/alaw
index 65bcf99..d93d6fc 100644
--- a/tests/ref/lavf/alaw
+++ b/tests/ref/lavf/alaw
@@ -1,3 +1,3 @@
-8bce9c3758b0d38da2e0718b6ab57fb4 *./tests/data/lavf/lavf.al
-45056 ./tests/data/lavf/lavf.al
-./tests/data/lavf/lavf.al CRC=0x5e6d372b
+652d96e474869ddb01403743deb35117 *./tests/data/lavf/lavf.al
+44100 ./tests/data/lavf/lavf.al
+./tests/data/lavf/lavf.al CRC=0xf9643112
diff --git a/tests/ref/lavf/asf b/tests/ref/lavf/asf
index cfa53dc..a90e547 100644
--- a/tests/ref/lavf/asf
+++ b/tests/ref/lavf/asf
@@ -1,3 +1,3 @@
-3937dfece4b48c0cdd8f44bcab3cdd2d *./tests/data/lavf/lavf.asf
+6bc7dc5698c3607fad8937d14560e50c *./tests/data/lavf/lavf.asf
 333581 ./tests/data/lavf/lavf.asf
-./tests/data/lavf/lavf.asf CRC=0x51485213
+./tests/data/lavf/lavf.asf CRC=0xf6340a10
diff --git a/tests/ref/lavf/ast b/tests/ref/lavf/ast
index 72a9824..513c612 100644
--- a/tests/ref/lavf/ast
+++ b/tests/ref/lavf/ast
@@ -1,3 +1,3 @@
-7fa8cd2dd7453428e71930a7c65f7b62 *./tests/data/lavf/lavf.ast
-181696 ./tests/data/lavf/lavf.ast
-./tests/data/lavf/lavf.ast CRC=0x7bd585ff
+07f5d23aa8bade984034f7005bd72947 *./tests/data/lavf/lavf.ast
+177872 ./tests/data/lavf/lavf.ast
+./tests/data/lavf/lavf.ast CRC=0xe61e3bd0
diff --git a/tests/ref/lavf/au b/tests/ref/lavf/au
index b9b70a1..ede4926 100644
--- a/tests/ref/lavf/au
+++ b/tests/ref/lavf/au
@@ -1,3 +1,3 @@
-dc54f834a23ddc0c086a86f0cef898d7 *./tests/data/lavf/lavf.au
-90144 ./tests/data/lavf/lavf.au
-./tests/data/lavf/lavf.au CRC=0xf1ae5536
+aa5ec1f82ac07c653ffc527b0f0dc10d *./tests/data/lavf/lavf.au
+88232 ./tests/data/lavf/lavf.au
+./tests/data/lavf/lavf.au CRC=0x3a1da17e
diff --git a/tests/ref/lavf/avi b/tests/ref/lavf/avi
index 056d0c7..3cbb44f 100644
--- a/tests/ref/lavf/avi
+++ b/tests/ref/lavf/avi
@@ -1,3 +1,3 @@
-feb26a85f820ede7e521a55be565f3b1 *./tests/data/lavf/lavf.avi
+8d3a3554cbe21bc232603ca26b0c4d3e *./tests/data/lavf/lavf.avi
 330806 ./tests/data/lavf/lavf.avi
-./tests/data/lavf/lavf.avi CRC=0x4780846b
+./tests/data/lavf/lavf.avi CRC=0xec6c3c68
diff --git a/tests/ref/lavf/caf b/tests/ref/lavf/caf
index f2ae9c3..7b2a67d 100644
--- a/tests/ref/lavf/caf
+++ b/tests/ref/lavf/caf
@@ -1,3 +1,3 @@
-6c97bfc8e455d5fb8b3b45806857a953 *./tests/data/lavf/lavf.caf
-90235 ./tests/data/lavf/lavf.caf
-./tests/data/lavf/lavf.caf CRC=0xf1ae5536
+c3c38cba600722c87c0e75bd0688b7fc *./tests/data/lavf/lavf.caf
+88323 ./tests/data/lavf/lavf.caf
+./tests/data/lavf/lavf.caf CRC=0x3a1da17e
diff --git a/tests/ref/lavf/dpx b/tests/ref/lavf/dpx
index 0206bd7..591ef1b 100644
--- a/tests/ref/lavf/dpx
+++ b/tests/ref/lavf/dpx
@@ -1,9 +1,18 @@
-d2f0b4e854fda2d3b3bee84cef80593c *./tests/data/images/dpx/02.dpx
+4c8880d5835ffb5fe37c1ed8c8d404de *./tests/data/images/dpx/02.dpx
 ./tests/data/images/dpx/%02d.dpx CRC=0x6da01946
 305792 ./tests/data/images/dpx/02.dpx
+16d65ceaa127806dc7ede9391fe80872 *./tests/data/images/dpx/02.dpx
+./tests/data/images/dpx/%02d.dpx CRC=0x22dcc7a8
+407168 ./tests/data/images/dpx/02.dpx
+02b4fd859d944075905e84e9f389bf23 *./tests/data/images/dpx/02.dpx
+./tests/data/images/dpx/%02d.dpx CRC=0x964b87ba
+609920 ./tests/data/images/dpx/02.dpx
 075963c3c08978b6a20555ba09161434 *./tests/data/images/dpx/02.dpx
 ./tests/data/images/dpx/%02d.dpx CRC=0xe5b9c023
 609920 ./tests/data/images/dpx/02.dpx
 b9f22728f8ff393bf30cf6cbd624fa95 *./tests/data/images/dpx/02.dpx
-./tests/data/images/dpx/%02d.dpx CRC=0xb6310a70
+./tests/data/images/dpx/%02d.dpx CRC=0xf38d5830
 407168 ./tests/data/images/dpx/02.dpx
+545603630f30dec2768c8ae8d12eb8ea *./tests/data/images/dpx/02.dpx
+./tests/data/images/dpx/%02d.dpx CRC=0xe72ce131
+812672 ./tests/data/images/dpx/02.dpx
diff --git a/tests/ref/lavf/dv_fmt b/tests/ref/lavf/dv_fmt
index ed8c5cc..3c8e5b1 100644
--- a/tests/ref/lavf/dv_fmt
+++ b/tests/ref/lavf/dv_fmt
@@ -1,9 +1,9 @@
 11be3e5caa2892236b3475c3f7807b76 *./tests/data/lavf/lavf.dv
 3600000 ./tests/data/lavf/lavf.dv
 ./tests/data/lavf/lavf.dv CRC=0x25bdd732
-78db8504eefb660ed205b417157d4f44 *./tests/data/lavf/lavf.dv
-3600000 ./tests/data/lavf/lavf.dv
-./tests/data/lavf/lavf.dv CRC=0x1cec8738
+e9949bc767924e1e7d28856029fee024 *./tests/data/lavf/lavf.dv
+3480000 ./tests/data/lavf/lavf.dv
+./tests/data/lavf/lavf.dv CRC=0xc4f27ca7
 87d3b20f656235671383a7eaa2f66330 *./tests/data/lavf/lavf.dv
 3600000 ./tests/data/lavf/lavf.dv
 ./tests/data/lavf/lavf.dv CRC=0x0e868a82
diff --git a/tests/ref/lavf/ffm b/tests/ref/lavf/ffm
index 6f67365..7071866 100644
--- a/tests/ref/lavf/ffm
+++ b/tests/ref/lavf/ffm
@@ -1,3 +1,3 @@
-d33fae310a7f6db1dc7fb74d1a9e0e6a *./tests/data/lavf/lavf.ffm
+6f1443b952819cff1dae875529675e88 *./tests/data/lavf/lavf.ffm
 376832 ./tests/data/lavf/lavf.ffm
-./tests/data/lavf/lavf.ffm CRC=0x5b136bb1
+./tests/data/lavf/lavf.ffm CRC=0x000e23ae
diff --git a/tests/ref/lavf/gxf b/tests/ref/lavf/gxf
index 9e7871d..14a2c87 100644
--- a/tests/ref/lavf/gxf
+++ b/tests/ref/lavf/gxf
@@ -1,9 +1,9 @@
-c8b3a8e3ba0185ce39122ac150c12bc3 *./tests/data/lavf/lavf.gxf
+9c96119322262ed2c43b34fd415233cc *./tests/data/lavf/lavf.gxf
 795876 ./tests/data/lavf/lavf.gxf
-./tests/data/lavf/lavf.gxf CRC=0x147ff044
-b26bd3cb439dff8b33cd74a27a3fc2d6 *./tests/data/lavf/lavf.gxf
+./tests/data/lavf/lavf.gxf CRC=0xda7cebbc
+260acc1c88a1706e5aaa74eff99ac389 *./tests/data/lavf/lavf.gxf
 794656 ./tests/data/lavf/lavf.gxf
-./tests/data/lavf/lavf.gxf CRC=0xe0199511
-e4721383461d7a9feae41435567c9257 *./tests/data/lavf/lavf.gxf
+./tests/data/lavf/lavf.gxf CRC=0x7f0c9089
+3cb8bab80b73a95f51e50989ccf06817 *./tests/data/lavf/lavf.gxf
 795876 ./tests/data/lavf/lavf.gxf
-./tests/data/lavf/lavf.gxf CRC=0xd9d58865
+./tests/data/lavf/lavf.gxf CRC=0x5ade0285
diff --git a/tests/ref/lavf/ircam b/tests/ref/lavf/ircam
index e29a7ad..47e0709 100644
--- a/tests/ref/lavf/ircam
+++ b/tests/ref/lavf/ircam
@@ -1,3 +1,3 @@
-2cfae025de1b13098ef84a5e7f9947aa *./tests/data/lavf/lavf.ircam
-91136 ./tests/data/lavf/lavf.ircam
-./tests/data/lavf/lavf.ircam CRC=0xf1ae5536
+45d9a4667030e95d1d8fb6ab012f1aa0 *./tests/data/lavf/lavf.ircam
+89224 ./tests/data/lavf/lavf.ircam
+./tests/data/lavf/lavf.ircam CRC=0x3a1da17e
diff --git a/tests/ref/lavf/ismv b/tests/ref/lavf/ismv
index 6f9f57b..05bb575 100644
--- a/tests/ref/lavf/ismv
+++ b/tests/ref/lavf/ismv
@@ -1,9 +1,9 @@
-a24a0426b5f8dc896daaf18502e38790 *./tests/data/lavf/lavf.ismv
-312263 ./tests/data/lavf/lavf.ismv
+3a2563358cc91017fc96f9e690f26b85 *./tests/data/lavf/lavf.ismv
+312255 ./tests/data/lavf/lavf.ismv
 ./tests/data/lavf/lavf.ismv CRC=0x9d9a638a
-1b98502911dd19a9792777de67922db2 *./tests/data/lavf/lavf.ismv
-321189 ./tests/data/lavf/lavf.ismv
+77dec1248e2c4d3b2b44dfe6bd27149a *./tests/data/lavf/lavf.ismv
+321181 ./tests/data/lavf/lavf.ismv
 ./tests/data/lavf/lavf.ismv CRC=0xe8130120
-a24a0426b5f8dc896daaf18502e38790 *./tests/data/lavf/lavf.ismv
-312263 ./tests/data/lavf/lavf.ismv
+3a2563358cc91017fc96f9e690f26b85 *./tests/data/lavf/lavf.ismv
+312255 ./tests/data/lavf/lavf.ismv
 ./tests/data/lavf/lavf.ismv CRC=0x9d9a638a
diff --git a/tests/ref/lavf/mkv b/tests/ref/lavf/mkv
index 64979b2..4bb97fd 100644
--- a/tests/ref/lavf/mkv
+++ b/tests/ref/lavf/mkv
@@ -1,6 +1,6 @@
-b53f31e572394f225aff0bc82b5d1cc9 *./tests/data/lavf/lavf.mkv
-472553 ./tests/data/lavf/lavf.mkv
-./tests/data/lavf/lavf.mkv CRC=0x4780846b
-84dcb326fe85aeeb5768beb44372f248 *./tests/data/lavf/lavf.mkv
-320297 ./tests/data/lavf/lavf.mkv
-./tests/data/lavf/lavf.mkv CRC=0x4780846b
+6273e6c20231e89e167f99706388b1b5 *./tests/data/lavf/lavf.mkv
+472542 ./tests/data/lavf/lavf.mkv
+./tests/data/lavf/lavf.mkv CRC=0xec6c3c68
+36633da729b88a171a0dfc969db23bcc *./tests/data/lavf/lavf.mkv
+320274 ./tests/data/lavf/lavf.mkv
+./tests/data/lavf/lavf.mkv CRC=0xec6c3c68
diff --git a/tests/ref/lavf/mmf b/tests/ref/lavf/mmf
index fea8015..fae95ca 100644
--- a/tests/ref/lavf/mmf
+++ b/tests/ref/lavf/mmf
@@ -1,3 +1,3 @@
-b165af6f2e5c6c1de733e9d3848bcebb *./tests/data/lavf/lavf.mmf
+643fadf7482f6d937ed75ec4f508e4f1 *./tests/data/lavf/lavf.mmf
 22611 ./tests/data/lavf/lavf.mmf
-./tests/data/lavf/lavf.mmf CRC=0x03633476
+./tests/data/lavf/lavf.mmf CRC=0x8dea1388
diff --git a/tests/ref/lavf/mov b/tests/ref/lavf/mov
index 2ed8ad0..3b484ec 100644
--- a/tests/ref/lavf/mov
+++ b/tests/ref/lavf/mov
@@ -1,12 +1,12 @@
-fcbe7806047914d9751fd9053009df69 *./tests/data/lavf/lavf.mov
-367365 ./tests/data/lavf/lavf.mov
-./tests/data/lavf/lavf.mov CRC=0xb2f59ab4
-72eac0051107a16e41d5263dab640f26 *./tests/data/lavf/lavf.mov
-358455 ./tests/data/lavf/lavf.mov
-./tests/data/lavf/lavf.mov CRC=0xb2f59ab4
-cf6ea2e8d4d16626d9dbd9e3fb802ce6 *./tests/data/lavf/lavf.mov
-367549 ./tests/data/lavf/lavf.mov
-./tests/data/lavf/lavf.mov CRC=0x6e82384a
-7c932d24837f46ef57d3e40a61331565 *./tests/data/lavf/lavf.mov
-357837 ./tests/data/lavf/lavf.mov
-./tests/data/lavf/lavf.mov CRC=0xb2f59ab4
+673de726034d2a44be176fa8166df376 *./tests/data/lavf/lavf.mov
+366421 ./tests/data/lavf/lavf.mov
+./tests/data/lavf/lavf.mov CRC=0xbb2b949b
+e833d2e258ee20ef7c13470be8ea293b *./tests/data/lavf/lavf.mov
+357511 ./tests/data/lavf/lavf.mov
+./tests/data/lavf/lavf.mov CRC=0xbb2b949b
+75fd61635a9707a8bed9a32958fe3275 *./tests/data/lavf/lavf.mov
+366593 ./tests/data/lavf/lavf.mov
+./tests/data/lavf/lavf.mov CRC=0xa9793231
+9bcbda2320a1434a3b9470389b45564e *./tests/data/lavf/lavf.mov
+356893 ./tests/data/lavf/lavf.mov
+./tests/data/lavf/lavf.mov CRC=0xbb2b949b
diff --git a/tests/ref/lavf/mpg b/tests/ref/lavf/mpg
index 798ee03..9feff66 100644
--- a/tests/ref/lavf/mpg
+++ b/tests/ref/lavf/mpg
@@ -1,9 +1,9 @@
-ddc5cd5469eb8a0500f8a725baead5e5 *./tests/data/lavf/lavf.mpg
+0a8c879bf813b6b758806088f29842dc *./tests/data/lavf/lavf.mpg
 372736 ./tests/data/lavf/lavf.mpg
-./tests/data/lavf/lavf.mpg CRC=0x5b136bb1
-7962eab004026dd7a8c0417470cdf574 *./tests/data/lavf/lavf.mpg
+./tests/data/lavf/lavf.mpg CRC=0x000e23ae
+d9446ae7b49de006a5a0f052ea9333ca *./tests/data/lavf/lavf.mpg
 389120 ./tests/data/lavf/lavf.mpg
-./tests/data/lavf/lavf.mpg CRC=0xbbbf92bc
-bb22933de60193bce9032f67ce6fcc23 *./tests/data/lavf/lavf.mpg
+./tests/data/lavf/lavf.mpg CRC=0x60ba4ab9
+edfef790122870cf4652e8a92ca558a0 *./tests/data/lavf/lavf.mpg
 372736 ./tests/data/lavf/lavf.mpg
-./tests/data/lavf/lavf.mpg CRC=0x5b136bb1
+./tests/data/lavf/lavf.mpg CRC=0x000e23ae
diff --git a/tests/ref/lavf/mulaw b/tests/ref/lavf/mulaw
index c6fa058..bd54084 100644
--- a/tests/ref/lavf/mulaw
+++ b/tests/ref/lavf/mulaw
@@ -1,3 +1,3 @@
-e64027a96ad5907ee281deff3286da0a *./tests/data/lavf/lavf.ul
-45056 ./tests/data/lavf/lavf.ul
-./tests/data/lavf/lavf.ul CRC=0xe028b50a
+ad492935e361f830f2f8302aa102701d *./tests/data/lavf/lavf.ul
+44100 ./tests/data/lavf/lavf.ul
+./tests/data/lavf/lavf.ul CRC=0x4515fa26
diff --git a/tests/ref/lavf/mxf b/tests/ref/lavf/mxf
index b1e46e9..b1918f5 100644
--- a/tests/ref/lavf/mxf
+++ b/tests/ref/lavf/mxf
@@ -1,9 +1,9 @@
 967f6ee9223c865328f4891465191108 *./tests/data/lavf/lavf.mxf
 525369 ./tests/data/lavf/lavf.mxf
 ./tests/data/lavf/lavf.mxf CRC=0xdbfff6f1
-7788939d349d09a7f9b546e59376a496 *./tests/data/lavf/lavf.mxf
+a085845074129d732fc6adb5601e3b5e *./tests/data/lavf/lavf.mxf
 560697 ./tests/data/lavf/lavf.mxf
-./tests/data/lavf/lavf.mxf CRC=0xb69f428b
+./tests/data/lavf/lavf.mxf CRC=0x3ff4178e
 ce535b606423d117675213b16275206a *./tests/data/lavf/lavf.mxf
 525369 ./tests/data/lavf/lavf.mxf
 ./tests/data/lavf/lavf.mxf CRC=0xdbfff6f1
diff --git a/tests/ref/lavf/nut b/tests/ref/lavf/nut
index 72e59e8..6c42a40 100644
--- a/tests/ref/lavf/nut
+++ b/tests/ref/lavf/nut
@@ -1,3 +1,3 @@
-56c403dd91ae1dd4569348381b2b43a4 *./tests/data/lavf/lavf.nut
+66386a488ee35e4592b605f63ef90a73 *./tests/data/lavf/lavf.nut
 319902 ./tests/data/lavf/lavf.nut
-./tests/data/lavf/lavf.nut CRC=0x4780846b
+./tests/data/lavf/lavf.nut CRC=0xec6c3c68
diff --git a/tests/ref/lavf/ogg b/tests/ref/lavf/ogg
index 584e09b..f8b58c4 100644
--- a/tests/ref/lavf/ogg
+++ b/tests/ref/lavf/ogg
@@ -1,3 +1,3 @@
-ce1734741fa50c6c85f9cc8f410a720c *./tests/data/lavf/lavf.ogg
-13985 ./tests/data/lavf/lavf.ogg
-./tests/data/lavf/lavf.ogg CRC=0x37a143ea
+304a201b4afa3583b206bdeef177ce6b *./tests/data/lavf/lavf.ogg
+13495 ./tests/data/lavf/lavf.ogg
+./tests/data/lavf/lavf.ogg CRC=0x3a1da17e
diff --git a/tests/ref/lavf/pam b/tests/ref/lavf/pam
index d21ccd7..50048ed 100644
--- a/tests/ref/lavf/pam
+++ b/tests/ref/lavf/pam
@@ -4,8 +4,8 @@
 2ed31ca8d8de560afb3e0fd7a873cde5 *./tests/data/images/pam/02.pam
 ./tests/data/images/pam/%02d.pam CRC=0xf07d29cd
 405573 ./tests/data/images/pam/02.pam
-587284e40b78accd54fa92fdb7ca29f4 *./tests/data/images/pam/02.pam
-./tests/data/images/pam/%02d.pam CRC=0x418d2963
+35cb9e42b2d3181be494f8693af1ddea *./tests/data/images/pam/02.pam
+./tests/data/images/pam/%02d.pam CRC=0x0ff205be
 101445 ./tests/data/images/pam/02.pam
 ebd43e97839b2538a79f35757e84ffb0 *./tests/data/images/pam/02.pam
 ./tests/data/images/pam/%02d.pam CRC=0x831a2963
diff --git a/tests/ref/lavf/pgm b/tests/ref/lavf/pgm
index 4043f7a..816579f 100644
--- a/tests/ref/lavf/pgm
+++ b/tests/ref/lavf/pgm
@@ -1,3 +1,3 @@
-388f5c51a678ca6a52cc006095c12f08 *./tests/data/images/pgm/02.pgm
-./tests/data/images/pgm/%02d.pgm CRC=0x418d2963
+cc777c5fc4d116d4c5a996eac8d3133e *./tests/data/images/pgm/02.pgm
+./tests/data/images/pgm/%02d.pgm CRC=0x0ff205be
 101391 ./tests/data/images/pgm/02.pgm
diff --git a/tests/ref/lavf/pgmpipe b/tests/ref/lavf/pgmpipe
index 28ad60e..da6f9a6 100644
--- a/tests/ref/lavf/pgmpipe
+++ b/tests/ref/lavf/pgmpipe
@@ -1,3 +1,3 @@
-04e66c8e9e064c8310bd657ee559bd70 *./tests/data/lavf/pgmpipe.pgm
+c34e37ea49237c2d1ea81a5944328e59 *./tests/data/lavf/pgmpipe.pgm
 2534775 ./tests/data/lavf/pgmpipe.pgm
-./tests/data/lavf/pgmpipe.pgm CRC=0xadf48ba9
+./tests/data/lavf/pgmpipe.pgm CRC=0x7aa0122f
diff --git a/tests/ref/lavf/pixfmt b/tests/ref/lavf/pixfmt
index bf62d90..8803087 100644
--- a/tests/ref/lavf/pixfmt
+++ b/tests/ref/lavf/pixfmt
@@ -26,7 +26,7 @@
 304128 ./tests/data/pixfmt/rgb565.yuv
 0df2a477af1415a1b8fbf2a3e552bc39 *./tests/data/pixfmt/rgb555.yuv
 304128 ./tests/data/pixfmt/rgb555.yuv
-6be306b0cce5f8e6c271ea17fef9745b *./tests/data/pixfmt/gray.yuv
+1e080c12bd9755c41ecb8e19b756f406 *./tests/data/pixfmt/gray.yuv
 304128 ./tests/data/pixfmt/gray.yuv
 6c719671e39f1bcf67b47eab98fa529b *./tests/data/pixfmt/monow.yuv
 304128 ./tests/data/pixfmt/monow.yuv
diff --git a/tests/ref/lavf/rm b/tests/ref/lavf/rm
index d396e00..62e0a31 100644
--- a/tests/ref/lavf/rm
+++ b/tests/ref/lavf/rm
@@ -1,2 +1,2 @@
-a3a875be9c528a2a4534a5a31230fdae *./tests/data/lavf/lavf.rm
+e30681d05d6f3d24108d3614600bf116 *./tests/data/lavf/lavf.rm
 346424 ./tests/data/lavf/lavf.rm
diff --git a/tests/ref/lavf/rso b/tests/ref/lavf/rso
index 648c248..5878f43 100644
--- a/tests/ref/lavf/rso
+++ b/tests/ref/lavf/rso
@@ -1,3 +1,3 @@
-f41fd78f7df981802e7caeb23648b8c0 *./tests/data/lavf/lavf.rso
-45064 ./tests/data/lavf/lavf.rso
-./tests/data/lavf/lavf.rso CRC=0x74b2b546
+443b72346065d6318ca18c8395aa1d87 *./tests/data/lavf/lavf.rso
+44108 ./tests/data/lavf/lavf.rso
+./tests/data/lavf/lavf.rso CRC=0x298fd284
diff --git a/tests/ref/lavf/smjpeg b/tests/ref/lavf/smjpeg
index 3e7e8ed..a2eeb97 100644
--- a/tests/ref/lavf/smjpeg
+++ b/tests/ref/lavf/smjpeg
@@ -1,3 +1,3 @@
-2f6e613e9e257545e1048d57de92ba92 *./tests/data/lavf/lavf.smjpeg
-791463 ./tests/data/lavf/lavf.smjpeg
-./tests/data/lavf/lavf.smjpeg CRC=0x557714ff
+a95982a2d390f4dcdc72a41d8920abb9 *./tests/data/lavf/lavf.smjpeg
+789551 ./tests/data/lavf/lavf.smjpeg
+./tests/data/lavf/lavf.smjpeg CRC=0x54bf6147
diff --git a/tests/ref/lavf/sox b/tests/ref/lavf/sox
index 0026480..fc368b1 100644
--- a/tests/ref/lavf/sox
+++ b/tests/ref/lavf/sox
@@ -1,3 +1,3 @@
-e6f278256f145b69ed06f35b8d3585c1 *./tests/data/lavf/lavf.sox
-180256 ./tests/data/lavf/lavf.sox
-./tests/data/lavf/lavf.sox CRC=0xf1ae5536
+683635d5cb1344e44fa96df90c3a993c *./tests/data/lavf/lavf.sox
+176432 ./tests/data/lavf/lavf.sox
+./tests/data/lavf/lavf.sox CRC=0x3a1da17e
diff --git a/tests/ref/lavf/ts b/tests/ref/lavf/ts
index 0cab3dd..02921ed 100644
--- a/tests/ref/lavf/ts
+++ b/tests/ref/lavf/ts
@@ -1,3 +1,3 @@
-4531d0f4a80d5a2ee2b08a8d4ba3b442 *./tests/data/lavf/lavf.ts
+a876e6bde8a2e8c7eca878869433ad3b *./tests/data/lavf/lavf.ts
 407020 ./tests/data/lavf/lavf.ts
-./tests/data/lavf/lavf.ts CRC=0xcc2dc628
+./tests/data/lavf/lavf.ts CRC=0x71287e25
diff --git a/tests/ref/lavf/voc b/tests/ref/lavf/voc
index 062da63..ded8af7 100644
--- a/tests/ref/lavf/voc
+++ b/tests/ref/lavf/voc
@@ -1,3 +1,3 @@
-e4cefbeb4c20f5735de1877fbcfd8d1d *./tests/data/lavf/lavf.voc
-45261 ./tests/data/lavf/lavf.voc
-./tests/data/lavf/lavf.voc CRC=0x74b2b546
+bb5ad96a5e1b35683d50bf18115db821 *./tests/data/lavf/lavf.voc
+44305 ./tests/data/lavf/lavf.voc
+./tests/data/lavf/lavf.voc CRC=0x298fd284
diff --git a/tests/ref/lavf/voc_s16 b/tests/ref/lavf/voc_s16
index 23e5aab..d026090 100644
--- a/tests/ref/lavf/voc_s16
+++ b/tests/ref/lavf/voc_s16
@@ -1,3 +1,3 @@
-a8225786fdbf5a2a19d1eeaf15f28632 *./tests/data/lavf/lavf.s16.voc
-180439 ./tests/data/lavf/lavf.s16.voc
-./tests/data/lavf/lavf.s16.voc CRC=0x7bd585ff
+db9fa22ff71992bd8b6cc80047223c92 *./tests/data/lavf/lavf.s16.voc
+176615 ./tests/data/lavf/lavf.s16.voc
+./tests/data/lavf/lavf.s16.voc CRC=0xe61e3bd0
diff --git a/tests/ref/lavf/w64 b/tests/ref/lavf/w64
index 9acda83..7da4f09 100644
--- a/tests/ref/lavf/w64
+++ b/tests/ref/lavf/w64
@@ -1,3 +1,3 @@
-420bf38762386ae2ba8bf2e85b6cc7f2 *./tests/data/lavf/lavf.w64
-90224 ./tests/data/lavf/lavf.w64
-./tests/data/lavf/lavf.w64 CRC=0xf1ae5536
+062b91c34d570a90af8d55427804878e *./tests/data/lavf/lavf.w64
+88312 ./tests/data/lavf/lavf.w64
+./tests/data/lavf/lavf.w64 CRC=0x3a1da17e
diff --git a/tests/ref/lavf/wav b/tests/ref/lavf/wav
index cc8ec1d..600c26a 100644
--- a/tests/ref/lavf/wav
+++ b/tests/ref/lavf/wav
@@ -1,3 +1,3 @@
-c4afa6eafac5243aa1c202397789ccb8 *./tests/data/lavf/lavf.wav
-90188 ./tests/data/lavf/lavf.wav
-./tests/data/lavf/lavf.wav CRC=0xf1ae5536
+eb5a869456d2e9107bb195c8c99be1a1 *./tests/data/lavf/lavf.wav
+88276 ./tests/data/lavf/lavf.wav
+./tests/data/lavf/lavf.wav CRC=0x3a1da17e
diff --git a/tests/ref/lavf/wtv b/tests/ref/lavf/wtv
index 8f2c2ac..fe1b83c 100644
--- a/tests/ref/lavf/wtv
+++ b/tests/ref/lavf/wtv
@@ -1,3 +1,3 @@
-345516d3a03fd239c62e5e7257c9f4a2 *./tests/data/lavf/lavf.wtv
+98dd5205889313542da71351fbaf4172 *./tests/data/lavf/lavf.wtv
 413696 ./tests/data/lavf/lavf.wtv
-./tests/data/lavf/lavf.wtv CRC=0xcc2dc628
+./tests/data/lavf/lavf.wtv CRC=0x71287e25
diff --git a/tests/ref/lavf/xwd b/tests/ref/lavf/xwd
index 73f859d..5e593b5 100644
--- a/tests/ref/lavf/xwd
+++ b/tests/ref/lavf/xwd
@@ -16,8 +16,8 @@
 fe1af954966a40c2cd35fc27094ff823 *./tests/data/images/xwd/02.xwd
 ./tests/data/images/xwd/%02d.xwd CRC=0xd69c3a09
 104559 ./tests/data/images/xwd/02.xwd
-9e2f3d455566897692cdfda88ff10112 *./tests/data/images/xwd/02.xwd
-./tests/data/images/xwd/%02d.xwd CRC=0x418d2963
+85e9b8b814a1dea71d143aac2e487037 *./tests/data/images/xwd/02.xwd
+./tests/data/images/xwd/%02d.xwd CRC=0x0ff205be
 101487 ./tests/data/images/xwd/02.xwd
 2131b4c41fe35178b0c7d121223af549 *./tests/data/images/xwd/02.xwd
 ./tests/data/images/xwd/%02d.xwd CRC=0x0f5aa5cb
diff --git a/tests/ref/lavfi/alphaextract_rgb b/tests/ref/lavfi/alphaextract_rgb
deleted file mode 100644
index d46b563..0000000
--- a/tests/ref/lavfi/alphaextract_rgb
+++ /dev/null
@@ -1 +0,0 @@
-alphaextract_rgb    4a46df014912056534fcab2f45a02279
diff --git a/tests/ref/lavfi/alphaextract_yuv b/tests/ref/lavfi/alphaextract_yuv
deleted file mode 100644
index 32b9ab9..0000000
--- a/tests/ref/lavfi/alphaextract_yuv
+++ /dev/null
@@ -1 +0,0 @@
-alphaextract_yuv    591e2d45f96ecfa8cc326eb741456a79
diff --git a/tests/ref/lavfi/alphamerge_rgb b/tests/ref/lavfi/alphamerge_rgb
deleted file mode 100644
index d890fae..0000000
--- a/tests/ref/lavfi/alphamerge_rgb
+++ /dev/null
@@ -1 +0,0 @@
-alphamerge_rgb      4a46df014912056534fcab2f45a02279
diff --git a/tests/ref/lavfi/alphamerge_yuv b/tests/ref/lavfi/alphamerge_yuv
deleted file mode 100644
index 2e58301..0000000
--- a/tests/ref/lavfi/alphamerge_yuv
+++ /dev/null
@@ -1 +0,0 @@
-alphamerge_yuv      591e2d45f96ecfa8cc326eb741456a79
diff --git a/tests/ref/lavfi/drawbox b/tests/ref/lavfi/drawbox
deleted file mode 100644
index 6d2f632..0000000
--- a/tests/ref/lavfi/drawbox
+++ /dev/null
@@ -1 +0,0 @@
-drawbox             b6ff6ecda5611de46ed26db05b49dc72
diff --git a/tests/ref/lavfi/edgedetect b/tests/ref/lavfi/edgedetect
deleted file mode 100644
index 6db0e72..0000000
--- a/tests/ref/lavfi/edgedetect
+++ /dev/null
@@ -1 +0,0 @@
-edgedetect          9d396de52d56b63a77ea6933a323f61f
diff --git a/tests/ref/lavfi/fade b/tests/ref/lavfi/fade
deleted file mode 100644
index 852abb9..0000000
--- a/tests/ref/lavfi/fade
+++ /dev/null
@@ -1 +0,0 @@
-fade                129fb9b266524b0adf102689c366cac8
diff --git a/tests/ref/lavfi/life b/tests/ref/lavfi/life
deleted file mode 100644
index 05713f3..0000000
--- a/tests/ref/lavfi/life
+++ /dev/null
@@ -1 +0,0 @@
-life                bc4822aa5d473a8b5efb31fef7aeac86
diff --git a/tests/ref/lavfi/overlay_rgb b/tests/ref/lavfi/overlay_rgb
deleted file mode 100644
index ce4e30b..0000000
--- a/tests/ref/lavfi/overlay_rgb
+++ /dev/null
@@ -1 +0,0 @@
-overlay_rgb         abea47d9e61d7eab40c4734294519524
diff --git a/tests/ref/lavfi/overlay_yuv420 b/tests/ref/lavfi/overlay_yuv420
deleted file mode 100644
index 3d12251..0000000
--- a/tests/ref/lavfi/overlay_yuv420
+++ /dev/null
@@ -1 +0,0 @@
-overlay_yuv420      4e85d551db9e56e8faddc1fc70fd6a00
diff --git a/tests/ref/lavfi/overlay_yuv444 b/tests/ref/lavfi/overlay_yuv444
deleted file mode 100644
index b83e605..0000000
--- a/tests/ref/lavfi/overlay_yuv444
+++ /dev/null
@@ -1 +0,0 @@
-overlay_yuv444      16215d0b4054a44bbe7f6c46bd97d235
diff --git a/tests/ref/lavfi/pixfmts_crop b/tests/ref/lavfi/pixfmts_crop
deleted file mode 100644
index 797aedc..0000000
--- a/tests/ref/lavfi/pixfmts_crop
+++ /dev/null
@@ -1,43 +0,0 @@
-abgr                ef31d9057f6e65a7c3308a1b1daa98fa
-argb                5e5e261c4870e0de05d56ff640b9550a
-bgr24               44bec15f35513de7e957b3d59b53cb7b
-bgr48be             0b5ebce3c48eb8614d79e204b5268603
-bgr48le             c4ab61a8b9d502132730c6abb6ffd84c
-bgr4_byte           cab930dbe1fe77d58b41837ecdcb8460
-bgr555be            67162782fdb86813f446d8e1c21c73e9
-bgr555le            85913cfa8dab465f7dcfcfe7f9001a01
-bgr565be            ee9a1debb896d41c53a026f9e6ce006b
-bgr565le            ab7b6055bc3b6b7edc9a5e4de43ec90d
-bgr8                f85ff16e21d922ad6d32648ef3acfbfb
-bgra                9f2e37d73ad3b759fc9d6b12ee668c38
-gray                3266b99065a17cbd647f2339addc5303
-gray16be            02ac848ad4e28c06938599563ba81ff7
-gray16le            672aebfeb8a0f4067b3c6064340056e4
-pal8                e1fd50b8a8a67fb5abd8b44abc778bbb
-rgb24               d044123f1fe50f656f2101dd3f091ead
-rgb48be             ef5507f88948b54218911d12e1dbef36
-rgb48le             6d045d5990d6ada64a112e3b581a7b38
-rgb4_byte           0f0f9ee31c65dc60da49bf98a1b06dcf
-rgb555be            48fa619bfd04f6dee05416b02605c031
-rgb555le            292cff1f824e49076bad50a07ab1c749
-rgb565be            0dd6f6a5a8713bd1c3d9826bb7a88eab
-rgb565le            6afd85faa8c6f0f330969539178eb9a2
-rgb8                87cf541b110e35a6f9a983e9cde85e15
-rgba                7abe1af7b97f5b9a7aa5ad3e4bf32f76
-yuv410p             126e0da1da4fd89be28087b8367bbb36
-yuv411p             b94f0af107fc4796aca70c0a36d374c5
-yuv420p             74c6b331bd30f005e6c75a192423ad90
-yuv420p16be         2d3c84ebff77479e8c5b6e3e59ec4e45
-yuv420p16le         e2c906f2751609bf8cbcbeb2f629319a
-yuv422p             124bc8d668072de1bb3b894cc4bae859
-yuv422p16be         3ec47e2709107fcc388b5e0abebf7eaf
-yuv422p16le         a4183a62917bf8568fe11ff446dd18f9
-yuv440p             15c81c685fa5b9db95150caff14ff83f
-yuv444p             12b752f78af72666627cea2d0c274cdb
-yuv444p16be         f2bf0e22a1d184e37eaa199a76cf22ba
-yuv444p16le         c11b151dced5c8854d385373fa4dcc8f
-yuva420p            920c5d1b965eeb72e3a0e343696face3
-yuvj420p            f9183e49f42bae31d7d85b92161fa82f
-yuvj422p            aabeed60a6e1b2cf88665ac627bf531f
-yuvj440p            5ae4f404b42f3167f978473d9a3737fc
-yuvj444p            6728997f65b879fd5a3175cb449a8f0c
diff --git a/tests/ref/lavfi/pixfmts_null b/tests/ref/lavfi/pixfmts_null
deleted file mode 100644
index 68ec828..0000000
--- a/tests/ref/lavfi/pixfmts_null
+++ /dev/null
@@ -1,110 +0,0 @@
-0bgr                a06d3a7652e4885c65895e0e168aab28
-0rgb                b6b5653d2228cdf2ba3c55a72f2e713f
-abgr                1a147fa04ed70b9a7e67a4c89052f630
-argb                997df0b5c268a0d8f9c611cae4e01e05
-bgr0                218df6dc3eb5094a0c16a8bd18bc3999
-bgr24               d6370f6dc34df2ea66e1718baf74137b
-bgr444be            aba6dfea008ae12c2120a95f54293904
-bgr444le            cfb5401e8f076cc8675e17ed1114a3df
-bgr48be             ab65229b64606f6408cd732b967c0b01
-bgr48le             f1b4e718cadee9bd2978289153ce43de
-bgr4_byte           de96505ef9ad7078f87b4dfdf6fe4b61
-bgr555be            8d5de9e9200d622f27dc73958a85045c
-bgr555le            74eb9837706143a40e26305a16a79369
-bgr565be            13a36d6502be88fc0c2aec05b8d2d501
-bgr565le            ed027571692aecd522aa65a90cc7e09b
-bgr8                71ef789609c746c2e7e4be9dec29062c
-bgra                0364b074268682ea46168742a8239f7d
-gbrp                89d6e4b116e3bd542fa09a19a977ad16
-gbrp10be            5dc62e2d01fa7c19a57abe48246f2232
-gbrp10le            0cac205a304b59811ce30fcad49b3527
-gbrp12be            de1d2a6b1d189bce9b9a2cf322c31c24
-gbrp12le            e3267ef00bb48778df21a386416d2e14
-gbrp14be            7979d158b30c0b45db97aba2228d15fc
-gbrp14le            d32b6c73a820f9d03a779a996924893d
-gbrp9be             2478d1c27ae4ec94ec4b5e439128af0c
-gbrp9le             640240ca2663e48f0bacd8edb5242c7d
-gray                1e5e2b8548843a6898eedd9c974c422c
-gray16be            389f4e5a8ab413b3af32767b59ed7f9e
-gray16le            a1f912941247e45b394b9cf4f0e81130
-monob               309b5785a36bd988d17e15d88f4ffad1
-monow               8809a02bc69b58d1114b09ca79ebffad
-nv12                75e90c54d858b993e99f4ee6d2a2a38f
-nv21                8831a3f411015d45fbc5dd191245ba9c
-pal8                13de2a1c3c80cb64d14e2bc4f6f461d0
-rgb0                992f5ad24802cc255edab45c3084db4a
-rgb24               c71ba90f69f15c8275232bb3f62d0ced
-rgb444be            26eaec65d7efd2b0c9c13b47dfd9b241
-rgb444le            5f29863553107110ea817f52151d77b7
-rgb48be             a3bc81c46c21818a989f23104a599ab0
-rgb48le             e87c661ac49aea1f1e93939802883d92
-rgb4_byte           293b1b84f01efd90bde40cb3faffc127
-rgb555be            5229183fa64d4e5c7e3703d8263ee6ae
-rgb555le            c3e9978cb2a4129a5575935e8cbc433a
-rgb565be            bc123b962629ead1a06af0c18cbb6e5f
-rgb565le            20757fafe4756e62d845b2ab4c0b8f93
-rgb8                e01614f5416dcc8ad365ad7a57afc9fb
-rgba                53796fa4c392a1b2659595b6a284f8c4
-uyvy422             3f411f947e3ac8f842c88e717d68bd9a
-yuv410p             7dcf3f4770c8b494290ceacd2c2ce6db
-yuv411p             9461b188dab6f8b90d9a27e353a89f58
-yuv420p             61fffd2d8425759a33ae07e718d0242d
-yuv420p10be         2abf90242cb021cb6fcf9f2c3c92f6a7
-yuv420p10le         180b7e4de684c7225d2fb37614f842cb
-yuv420p12be         256c9e6cfc878a8abf681b30777c0620
-yuv420p12le         8dc8b86c4790da3769d4a62e87608623
-yuv420p14be         8d22756c5d2b9e501924c082bfb22a6c
-yuv420p14le         c9da19d4818bcb119ad6481b75778f7e
-yuv420p16be         4ccdcca6dd6a960f9a3333f0aee095bd
-yuv420p16le         9c5847d9b0de258a10ee906dc47e24ea
-yuv420p9be          fa7ad4f73232aac0e35def62af1e2c39
-yuv420p9le          3720ba1786b56c8f4913e67dddebbb07
-yuv422p             eee223e92f1f2e5ad4186b411ebf5816
-yuv422p10be         80fa87750491dcc3e93d175b64835654
-yuv422p10le         e1640cd315bd96c6b59f7753825a7306
-yuv422p12be         5c6d86e919515d1af71f8004a6252f9e
-yuv422p12le         7f331cadb0ab75d07656d29f47bd8bd9
-yuv422p14be         4f4e186ba683b90fe990cccc4db7e521
-yuv422p14le         d78016c9119b1f1d1c922bd5aaf47732
-yuv422p16be         1f3c216927d17966a009a42def124bba
-yuv422p16le         90adbdffaeea9b09398339c8a1322b02
-yuv422p9be          e46446534dd0821029d3b831c9c1d1b0
-yuv422p9le          520e418a2429f7efee511b7fcbf45ab6
-yuv440p             456d83524b299f2fa1bb988e421554d9
-yuv444p             068bc09d282d18c9fa35c2787943fc2a
-yuv444p10be         9f6e1490080a454243daee9229425e1e
-yuv444p10le         cc183e51041351d9ac06c4df6e8ad5f7
-yuv444p12be         34f63ac6a47ac681016105d3bfb3e118
-yuv444p12le         7964701bfe8d718edf97f6e0002935bd
-yuv444p14be         4ad3a9d52fe9c050150c0f7d2f3cf63d
-yuv444p14le         69575e5a94b978f159c4fdb1a61587b0
-yuv444p16be         4000b12fa88ed0feef182da31c7e6b96
-yuv444p16le         96a857dba8dc6792c58daec872825b32
-yuv444p9be          07727e5c9040b7f0a17d591288ac330d
-yuv444p9le          4d12d20a68dc28618594c96c2ade4ff4
-yuva420p            3a8c5c142e051367c196f95696e0e2c3
-yuva420p10be        1b7c5ec6691498e24676ce6ed97f62f8
-yuva420p10le        4c13322bca914df2727da91cca85ca1a
-yuva420p16be        6afcf758f4b66c0b4173c942d42212d7
-yuva420p16le        13e195aa96329eb49921b6f9f07b875c
-yuva420p9be         05a78390de312dfd21ac666a9da05fbd
-yuva420p9le         78f5593bf51a31841ef83df41d0316eb
-yuva422p            45ae66d6f69fd5b77e6831e98d228bf4
-yuva422p10be        18284c58b926fe2389605c692a703145
-yuva422p10le        b934d28b615729a24bebf0381c465e37
-yuva422p16be        c3f7354b6013b43439e02aa02be5fe69
-yuva422p16le        a7ccc43820683ab15061d14cf8efce6c
-yuva422p9be         14c55a16d19499b54b4341f135d3e558
-yuva422p9le         a8bf168e5d2709222192d0aff46b1373
-yuva444p            86b05da54db8c7e8cf5b6638e19c6fc5
-yuva444p10be        8c417158165c00fbd42def60cbc27d69
-yuva444p10le        5f303ef3fb56faed69b4cc1c760ac6ae
-yuva444p16be        52a9591ec0d5059e49b1b2803f8582aa
-yuva444p16le        a9272ac197e4a4195662ce90f533976c
-yuva444p9be         f72f646ef07cdab613420585aba041ac
-yuva444p9le         6d431b0a27bf4f86ea44ef5f14247a01
-yuvj420p            73661456012f20cda81207b14bb0c0a5
-yuvj422p            aa97862b57f47c5a6506156e9aaf129a
-yuvj440p            ff8b9884a49d546b035f5d2ac1e673df
-yuvj444p            b8142888d80b8065c54045839e79b331
-yuyv422             f06a4fbbdb32807d05de825daa2c3a1b
diff --git a/tests/ref/lavfi/scalenorm b/tests/ref/lavfi/scalenorm
deleted file mode 100644
index 6df4bb8..0000000
--- a/tests/ref/lavfi/scalenorm
+++ /dev/null
@@ -1 +0,0 @@
-scalenorm           cad5d7b40b213deecc1d156cf45fc70d
diff --git a/tests/ref/lavfi/testsrc b/tests/ref/lavfi/testsrc
deleted file mode 100644
index 8e2363b..0000000
--- a/tests/ref/lavfi/testsrc
+++ /dev/null
@@ -1 +0,0 @@
-testsrc             cdac8817054b30e086d6ecabdcec5444
diff --git a/tests/ref/lavfi/transpose b/tests/ref/lavfi/transpose
deleted file mode 100644
index 1785e3a..0000000
--- a/tests/ref/lavfi/transpose
+++ /dev/null
@@ -1 +0,0 @@
-transpose           75d71957db820f657ccc46c14da6c8e9
diff --git a/tests/ref/lavfi/unsharp b/tests/ref/lavfi/unsharp
deleted file mode 100644
index ad064ae..0000000
--- a/tests/ref/lavfi/unsharp
+++ /dev/null
@@ -1 +0,0 @@
-unsharp             7d72d2ab7b7f60159c822a097e01068b
diff --git a/tests/ref/seek/lavf-alaw b/tests/ref/seek/lavf-alaw
index 84661ec..4b1f8fb 100644
--- a/tests/ref/seek/lavf-alaw
+++ b/tests/ref/seek/lavf-alaw
@@ -38,7 +38,7 @@
 ret: 0         st: 0 flags:0  ts:-0.904989
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:  1024
 ret: 0         st: 0 flags:1  ts: 1.989161
-ret: 0         st: 0 flags:1 dts: 1.989161 pts: 1.989161 pos:  43861 size:  1024
+ret: 0         st: 0 flags:1 dts: 1.989161 pts: 1.989161 pos:  43861 size:   239
 ret: 0         st:-1 flags:0  ts: 0.883340
 ret: 0         st: 0 flags:1 dts: 0.883356 pts: 0.883356 pos:  19478 size:  1024
 ret: 0         st:-1 flags:1  ts:-0.222493
diff --git a/tests/ref/seek/lavf-mkv b/tests/ref/seek/lavf-mkv
index 681462c..f03bcf8 100644
--- a/tests/ref/seek/lavf-mkv
+++ b/tests/ref/seek/lavf-mkv
@@ -1,48 +1,48 @@
-ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    555 size:   208
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    523 size:   208
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    771 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    739 size: 27837
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292185 size: 27834
+ret: 0         st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292153 size: 27834
 ret: 0         st: 0 flags:0  ts: 0.788000
-ret: 0         st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292185 size: 27834
+ret: 0         st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292153 size: 27834
 ret: 0         st: 0 flags:1  ts:-0.317000
-ret: 0         st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    771 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    739 size: 27837
 ret:-1         st: 1 flags:0  ts: 2.577000
 ret: 0         st: 1 flags:1  ts: 1.471000
-ret: 0         st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320026 size:   209
+ret: 0         st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 319994 size:   209
 ret: 0         st:-1 flags:0  ts: 0.365002
-ret: 0         st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146738 size: 27925
+ret: 0         st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146706 size: 27925
 ret: 0         st:-1 flags:1  ts:-0.740831
-ret: 0         st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    771 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    739 size: 27837
 ret:-1         st: 0 flags:0  ts: 2.153000
 ret: 0         st: 0 flags:1  ts: 1.048000
-ret: 0         st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292185 size: 27834
+ret: 0         st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292153 size: 27834
 ret: 0         st: 1 flags:0  ts:-0.058000
-ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    555 size:   208
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    523 size:   208
 ret: 0         st: 1 flags:1  ts: 2.836000
-ret: 0         st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320026 size:   209
+ret: 0         st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 319994 size:   209
 ret:-1         st:-1 flags:0  ts: 1.730004
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146738 size: 27925
+ret: 0         st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146706 size: 27925
 ret: 0         st: 0 flags:0  ts:-0.482000
-ret: 0         st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    771 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    739 size: 27837
 ret: 0         st: 0 flags:1  ts: 2.413000
-ret: 0         st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292185 size: 27834
+ret: 0         st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292153 size: 27834
 ret:-1         st: 1 flags:0  ts: 1.307000
 ret: 0         st: 1 flags:1  ts: 0.201000
-ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    555 size:   208
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    523 size:   208
 ret: 0         st:-1 flags:0  ts:-0.904994
-ret: 0         st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    771 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    739 size: 27837
 ret: 0         st:-1 flags:1  ts: 1.989173
-ret: 0         st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292185 size: 27834
+ret: 0         st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292153 size: 27834
 ret: 0         st: 0 flags:0  ts: 0.883000
-ret: 0         st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292185 size: 27834
+ret: 0         st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292153 size: 27834
 ret: 0         st: 0 flags:1  ts:-0.222000
-ret: 0         st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    771 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    739 size: 27837
 ret:-1         st: 1 flags:0  ts: 2.672000
 ret: 0         st: 1 flags:1  ts: 1.566000
-ret: 0         st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320026 size:   209
+ret: 0         st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 319994 size:   209
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146738 size: 27925
+ret: 0         st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146706 size: 27925
 ret: 0         st:-1 flags:1  ts:-0.645825
-ret: 0         st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    771 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    739 size: 27837
diff --git a/tests/ref/seek/lavf-mov b/tests/ref/seek/lavf-mov
index 9563a0d..93a9a23 100644
--- a/tests/ref/seek/lavf-mov
+++ b/tests/ref/seek/lavf-mov
@@ -1,48 +1,48 @@
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1739 size: 27837
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1739 size: 27837
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 1 flags:1 dts: 0.952018 pts: 0.952018 pos: 326931 size:  1024
+ret: 0         st: 1 flags:1 dts: 0.952018 pts: 0.952018 pos: 326943 size:  1024
 ret: 0         st: 0 flags:0  ts: 0.788359
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 327955 size: 27834
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 327967 size: 27834
 ret: 0         st: 0 flags:1  ts:-0.317500
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1739 size: 27837
 ret:-1         st: 1 flags:0  ts: 2.576667
 ret: 0         st: 1 flags:1  ts: 1.470839
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 327955 size: 27834
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 327967 size: 27834
 ret: 0         st:-1 flags:0  ts: 0.365002
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 165209 size: 27925
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 165221 size: 27925
 ret: 0         st:-1 flags:1  ts:-0.740831
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1739 size: 27837
 ret:-1         st: 0 flags:0  ts: 2.153359
 ret: 0         st: 0 flags:1  ts: 1.047500
-ret: 0         st: 1 flags:1 dts: 0.952018 pts: 0.952018 pos: 326931 size:  1024
+ret: 0         st: 1 flags:1 dts: 0.952018 pts: 0.952018 pos: 326943 size:  1024
 ret: 0         st: 1 flags:0  ts:-0.058322
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1739 size: 27837
 ret: 0         st: 1 flags:1  ts: 2.835828
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 327955 size: 27834
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 327967 size: 27834
 ret:-1         st:-1 flags:0  ts: 1.730004
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 1 flags:1 dts: 0.464399 pts: 0.464399 pos: 164185 size:  1024
+ret: 0         st: 1 flags:1 dts: 0.464399 pts: 0.464399 pos: 164197 size:  1024
 ret: 0         st: 0 flags:0  ts:-0.481641
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1739 size: 27837
 ret: 0         st: 0 flags:1  ts: 2.412500
-ret: 0         st: 1 flags:1 dts: 0.952018 pts: 0.952018 pos: 326931 size:  1024
+ret: 0         st: 1 flags:1 dts: 0.952018 pts: 0.952018 pos: 326943 size:  1024
 ret:-1         st: 1 flags:0  ts: 1.306667
 ret: 0         st: 1 flags:1  ts: 0.200839
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1739 size: 27837
 ret: 0         st:-1 flags:0  ts:-0.904994
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1739 size: 27837
 ret: 0         st:-1 flags:1  ts: 1.989173
-ret: 0         st: 1 flags:1 dts: 0.952018 pts: 0.952018 pos: 326931 size:  1024
+ret: 0         st: 1 flags:1 dts: 0.952018 pts: 0.952018 pos: 326943 size:  1024
 ret: 0         st: 0 flags:0  ts: 0.883359
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 327955 size: 27834
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 327967 size: 27834
 ret: 0         st: 0 flags:1  ts:-0.222500
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1739 size: 27837
 ret:-1         st: 1 flags:0  ts: 2.671678
 ret: 0         st: 1 flags:1  ts: 1.565850
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 327955 size: 27834
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 327967 size: 27834
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 165209 size: 27925
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 165221 size: 27925
 ret: 0         st:-1 flags:1  ts:-0.645825
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1739 size: 27837
diff --git a/tests/ref/seek/lavf-mulaw b/tests/ref/seek/lavf-mulaw
index 84661ec..4b1f8fb 100644
--- a/tests/ref/seek/lavf-mulaw
+++ b/tests/ref/seek/lavf-mulaw
@@ -38,7 +38,7 @@
 ret: 0         st: 0 flags:0  ts:-0.904989
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:  1024
 ret: 0         st: 0 flags:1  ts: 1.989161
-ret: 0         st: 0 flags:1 dts: 1.989161 pts: 1.989161 pos:  43861 size:  1024
+ret: 0         st: 0 flags:1 dts: 1.989161 pts: 1.989161 pos:  43861 size:   239
 ret: 0         st:-1 flags:0  ts: 0.883340
 ret: 0         st: 0 flags:1 dts: 0.883356 pts: 0.883356 pos:  19478 size:  1024
 ret: 0         st:-1 flags:1  ts:-0.222493
diff --git a/tests/ref/seek/lavf-ts b/tests/ref/seek/lavf-ts
index 407ba59..e57651e 100644
--- a/tests/ref/seek/lavf-ts
+++ b/tests/ref/seek/lavf-ts
@@ -1,53 +1,53 @@
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:0 dts: 1.880000 pts: 1.920000 pos: 216388 size: 17440
+ret: 0         st: 0 flags:1 dts: 1.880000 pts: 1.920000 pos: 189692 size: 24786
 ret: 0         st: 0 flags:0  ts: 0.788333
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
 ret: 0         st: 0 flags:1  ts:-0.317500
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
 ret: 0         st: 1 flags:0  ts: 2.576667
-ret: 0         st: 1 flags:1 dts: 2.120522 pts: 2.120522 pos: 404576 size:   209
+ret: 0         st: 1 flags:1 dts: 2.160522 pts: 2.160522 pos: 404576 size:   209
 ret: 0         st: 1 flags:1  ts: 1.470833
-ret: 0         st: 1 flags:1 dts: 1.389089 pts: 1.389089 pos: 159988 size:   208
+ret: 0         st: 1 flags:1 dts: 1.429089 pts: 1.429089 pos: 159988 size:   208
 ret: 0         st:-1 flags:0  ts: 0.365002
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
 ret: 0         st:-1 flags:1  ts:-0.740831
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
 ret: 0         st: 0 flags:0  ts: 2.153333
-ret: 0         st: 0 flags:0 dts: 2.160000 pts: 2.200000 pos: 325992 size: 12692
+ret: 0         st: 1 flags:1 dts: 1.794811 pts: 1.794811 pos: 322608 size:   209
 ret: 0         st: 0 flags:1  ts: 1.047500
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
 ret: 0         st: 1 flags:0  ts:-0.058333
-ret: 0         st: 1 flags:1 dts: 1.389089 pts: 1.389089 pos: 159988 size:   208
+ret: 0         st: 1 flags:1 dts: 1.429089 pts: 1.429089 pos: 159988 size:   208
 ret: 0         st: 1 flags:1  ts: 2.835833
-ret: 0         st: 1 flags:1 dts: 2.120522 pts: 2.120522 pos: 404576 size:   209
+ret: 0         st: 1 flags:1 dts: 2.160522 pts: 2.160522 pos: 404576 size:   209
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:0 dts: 1.760000 pts: 1.800000 pos: 162996 size: 12135
+ret: 0         st: 1 flags:1 dts: 1.429089 pts: 1.429089 pos: 159988 size:   208
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
 ret: 0         st: 0 flags:0  ts:-0.481667
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
 ret: 0         st: 0 flags:1  ts: 2.412500
-ret: 0         st: 1 flags:1 dts: 2.120522 pts: 2.120522 pos: 404576 size:   209
+ret: 0         st: 1 flags:1 dts: 2.160522 pts: 2.160522 pos: 404576 size:   209
 ret: 0         st: 1 flags:0  ts: 1.306667
-ret: 0         st: 1 flags:1 dts: 1.389089 pts: 1.389089 pos: 159988 size:   208
+ret: 0         st: 1 flags:1 dts: 1.429089 pts: 1.429089 pos: 159988 size:   208
 ret: 0         st: 1 flags:1  ts: 0.200844
-ret: 0         st: 1 flags:1 dts: 1.389089 pts: 1.389089 pos: 159988 size:   208
+ret: 0         st: 1 flags:1 dts: 1.429089 pts: 1.429089 pos: 159988 size:   208
 ret: 0         st:-1 flags:0  ts:-0.904994
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
 ret: 0         st:-1 flags:1  ts: 1.989173
-ret: 0         st: 0 flags:0 dts: 1.960000 pts: 2.000000 pos: 251356 size: 13449
+ret: 0         st: 0 flags:0 dts: 1.960000 pts: 2.000000 pos: 235000 size: 15019
 ret: 0         st: 0 flags:0  ts: 0.883344
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
 ret: 0         st: 0 flags:1  ts:-0.222489
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
 ret: 0         st: 1 flags:0  ts: 2.671678
-ret: 0         st: 1 flags:1 dts: 2.120522 pts: 2.120522 pos: 404576 size:   209
+ret: 0         st: 1 flags:1 dts: 2.160522 pts: 2.160522 pos: 404576 size:   209
 ret: 0         st: 1 flags:1  ts: 1.565844
-ret: 0         st: 1 flags:1 dts: 1.389089 pts: 1.389089 pos: 159988 size:   208
+ret: 0         st: 1 flags:1 dts: 1.429089 pts: 1.429089 pos: 159988 size:   208
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
 ret: 0         st:-1 flags:1  ts:-0.645825
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
diff --git a/tests/ref/seek/lavf-wtv b/tests/ref/seek/lavf-wtv
index 67def8a..71703c5 100644
--- a/tests/ref/seek/lavf-wtv
+++ b/tests/ref/seek/lavf-wtv
@@ -1,48 +1,48 @@
-ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
+ret: 0         st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos:  26344 size:   208
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
+ret: 0         st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos:  26344 size:   208
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 1 flags:1 dts: 0.694399 pts: 0.694399 pos: 294744 size:   209
+ret: 0         st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294744 size:   209
 ret: 0         st: 0 flags:0  ts: 0.788334
-ret: 0         st: 1 flags:1 dts: 0.694399 pts: 0.694399 pos: 294744 size:   209
+ret: 0         st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294744 size:   209
 ret: 0         st: 0 flags:1  ts:-0.317499
-ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
+ret: 0         st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos:  26344 size:   208
 ret:-1         st: 1 flags:0  ts: 2.576668
 ret: 0         st: 1 flags:1  ts: 1.470835
-ret: 0         st: 1 flags:1 dts: 0.694399 pts: 0.694399 pos: 294744 size:   209
+ret: 0         st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294744 size:   209
 ret: 0         st:-1 flags:0  ts: 0.365002
-ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
+ret: 0         st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos:  26344 size:   208
 ret: 0         st:-1 flags:1  ts:-0.740831
-ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
+ret: 0         st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos:  26344 size:   208
 ret:-1         st: 0 flags:0  ts: 2.153336
 ret: 0         st: 0 flags:1  ts: 1.047503
-ret: 0         st: 1 flags:1 dts: 0.694399 pts: 0.694399 pos: 294744 size:   209
+ret: 0         st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos:  26344 size:   208
 ret: 0         st: 1 flags:0  ts:-0.058330
-ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
+ret: 0         st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos:  26344 size:   208
 ret: 0         st: 1 flags:1  ts: 2.835837
-ret: 0         st: 1 flags:1 dts: 0.694399 pts: 0.694399 pos: 294744 size:   209
+ret: 0         st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294744 size:   209
 ret:-1         st:-1 flags:0  ts: 1.730004
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
+ret: 0         st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos:  26344 size:   208
 ret: 0         st: 0 flags:0  ts:-0.481662
-ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
+ret: 0         st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos:  26344 size:   208
 ret: 0         st: 0 flags:1  ts: 2.412505
-ret: 0         st: 1 flags:1 dts: 0.694399 pts: 0.694399 pos: 294744 size:   209
+ret: 0         st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294744 size:   209
 ret:-1         st: 1 flags:0  ts: 1.306672
 ret: 0         st: 1 flags:1  ts: 0.200839
-ret: 0         st: 1 flags:1 dts: 0.224195 pts: 0.224195 pos: 112904 size:   209
+ret: 0         st: 1 flags:1 dts: 0.211950 pts: 0.211950 pos:  99352 size:   209
 ret: 0         st:-1 flags:0  ts:-0.904994
-ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
+ret: 0         st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos:  26344 size:   208
 ret: 0         st:-1 flags:1  ts: 1.989173
-ret: 0         st: 1 flags:1 dts: 0.694399 pts: 0.694399 pos: 294744 size:   209
+ret: 0         st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294744 size:   209
 ret: 0         st: 0 flags:0  ts: 0.883340
-ret: 0         st: 1 flags:1 dts: 0.694399 pts: 0.694399 pos: 294744 size:   209
+ret: 0         st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294744 size:   209
 ret: 0         st: 0 flags:1  ts:-0.222493
-ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
+ret: 0         st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos:  26344 size:   208
 ret:-1         st: 1 flags:0  ts: 2.671674
 ret: 0         st: 1 flags:1  ts: 1.565841
-ret: 0         st: 1 flags:1 dts: 0.694399 pts: 0.694399 pos: 294744 size:   209
+ret: 0         st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294744 size:   209
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
+ret: 0         st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos:  26344 size:   208
 ret: 0         st:-1 flags:1  ts:-0.645825
-ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
+ret: 0         st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos:  26344 size:   208
diff --git a/tests/ref/vsynth/vsynth1-ffv1.0 b/tests/ref/vsynth/vsynth1-ffv1.0
new file mode 100644
index 0000000..2a4f41c
--- /dev/null
+++ b/tests/ref/vsynth/vsynth1-ffv1.0
@@ -0,0 +1,4 @@
+91c237f18bc19975077c85175daed734 *tests/data/fate/vsynth1-ffv1.0.avi
+2655364 tests/data/fate/vsynth1-ffv1.0.avi
+c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-ffv1.0.out.rawvideo
+stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth1-j2k b/tests/ref/vsynth/vsynth1-j2k
deleted file mode 100644
index 1e2f3f2..0000000
--- a/tests/ref/vsynth/vsynth1-j2k
+++ /dev/null
@@ -1,4 +0,0 @@
-e6e3d338eeb394d6fadc7bbb55fa9e6e *tests/data/fate/vsynth1-j2k.avi
-2306902 tests/data/fate/vsynth1-j2k.avi
-ee9b245b3b07eed90bc6f2147bbd916c *tests/data/fate/vsynth1-j2k.out.rawvideo
-stddev:    5.47 PSNR: 33.37 MAXDIFF:   64 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth1-jpeg2000 b/tests/ref/vsynth/vsynth1-jpeg2000
new file mode 100644
index 0000000..cf53feb
--- /dev/null
+++ b/tests/ref/vsynth/vsynth1-jpeg2000
@@ -0,0 +1,4 @@
+e6e3d338eeb394d6fadc7bbb55fa9e6e *tests/data/fate/vsynth1-jpeg2000.avi
+2306902 tests/data/fate/vsynth1-jpeg2000.avi
+1774b621bd92a53a24712cb77e9f0b28 *tests/data/fate/vsynth1-jpeg2000.out.rawvideo
+stddev:    5.37 PSNR: 33.52 MAXDIFF:   63 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth1-jpeg2000-97 b/tests/ref/vsynth/vsynth1-jpeg2000-97
new file mode 100644
index 0000000..f8399f2
--- /dev/null
+++ b/tests/ref/vsynth/vsynth1-jpeg2000-97
@@ -0,0 +1,4 @@
+c135eb14e9f219242180270c2a242634 *tests/data/fate/vsynth1-jpeg2000-97.avi
+2243132 tests/data/fate/vsynth1-jpeg2000-97.avi
+e1a095b40d7f6440f6c46f2995c4759c *tests/data/fate/vsynth1-jpeg2000-97.out.rawvideo
+stddev:    6.23 PSNR: 32.23 MAXDIFF:   75 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth1-qtrlegray b/tests/ref/vsynth/vsynth1-qtrlegray
index 425c11f..5e635f1 100644
--- a/tests/ref/vsynth/vsynth1-qtrlegray
+++ b/tests/ref/vsynth/vsynth1-qtrlegray
@@ -1,4 +1,4 @@
-d010ff7be190f4cd053d79ee7f601ce2 *tests/data/fate/vsynth1-qtrlegray.mov
-5113294 tests/data/fate/vsynth1-qtrlegray.mov
-29def4aed035ed65d3a89f7d382fccbe *tests/data/fate/vsynth1-qtrlegray.out.rawvideo
-stddev:   25.95 PSNR: 19.85 MAXDIFF:  122 bytes:  7603200/  7603200
+052b0956e54dbcaf58984199e8c2e240 *tests/data/fate/vsynth1-qtrlegray.mov
+5113293 tests/data/fate/vsynth1-qtrlegray.mov
+cb20af0e5a65aad7cf47002fcb52288e *tests/data/fate/vsynth1-qtrlegray.out.rawvideo
+stddev:   25.34 PSNR: 20.05 MAXDIFF:  122 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-ffv1.0 b/tests/ref/vsynth/vsynth2-ffv1.0
new file mode 100644
index 0000000..962c17c
--- /dev/null
+++ b/tests/ref/vsynth/vsynth2-ffv1.0
@@ -0,0 +1,4 @@
+3a757276e299bf88c30e06dfb53f1c99 *tests/data/fate/vsynth2-ffv1.0.avi
+3525792 tests/data/fate/vsynth2-ffv1.0.avi
+dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-ffv1.0.out.rawvideo
+stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-j2k b/tests/ref/vsynth/vsynth2-j2k
deleted file mode 100644
index 4f038fe..0000000
--- a/tests/ref/vsynth/vsynth2-j2k
+++ /dev/null
@@ -1,4 +0,0 @@
-fc49816ba28731689872f5c87ca91c10 *tests/data/fate/vsynth2-j2k.avi
-1151144 tests/data/fate/vsynth2-j2k.avi
-ec5218eec33a021945c28c72093382a5 *tests/data/fate/vsynth2-j2k.out.rawvideo
-stddev:    4.54 PSNR: 34.99 MAXDIFF:   61 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-jpeg2000 b/tests/ref/vsynth/vsynth2-jpeg2000
new file mode 100644
index 0000000..cacd467
--- /dev/null
+++ b/tests/ref/vsynth/vsynth2-jpeg2000
@@ -0,0 +1,4 @@
+fc49816ba28731689872f5c87ca91c10 *tests/data/fate/vsynth2-jpeg2000.avi
+1151144 tests/data/fate/vsynth2-jpeg2000.avi
+e7d79c9e11d0fe97f03e38be66c34e4f *tests/data/fate/vsynth2-jpeg2000.out.rawvideo
+stddev:    4.41 PSNR: 35.23 MAXDIFF:   63 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-jpeg2000-97 b/tests/ref/vsynth/vsynth2-jpeg2000-97
new file mode 100644
index 0000000..e7fce13
--- /dev/null
+++ b/tests/ref/vsynth/vsynth2-jpeg2000-97
@@ -0,0 +1,4 @@
+3ac3e49a89136bddde9e44bac3e5b4ed *tests/data/fate/vsynth2-jpeg2000-97.avi
+1118952 tests/data/fate/vsynth2-jpeg2000-97.avi
+8ac8b9ee81fa73c873668e9f6b78764d *tests/data/fate/vsynth2-jpeg2000-97.out.rawvideo
+stddev:    4.95 PSNR: 34.23 MAXDIFF:   60 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-qtrlegray b/tests/ref/vsynth/vsynth2-qtrlegray
index 4568391..c2aa4a6 100644
--- a/tests/ref/vsynth/vsynth2-qtrlegray
+++ b/tests/ref/vsynth/vsynth2-qtrlegray
@@ -1,4 +1,4 @@
-fa10a87e9cf648d635340b90e41d2d38 *tests/data/fate/vsynth2-qtrlegray.mov
+ce8a132e4a58748b487c18df2ed83fc1 *tests/data/fate/vsynth2-qtrlegray.mov
 5111283 tests/data/fate/vsynth2-qtrlegray.mov
-f63b5ebdfdba750e547c25131b0a3fd1 *tests/data/fate/vsynth2-qtrlegray.out.rawvideo
-stddev:   19.42 PSNR: 22.36 MAXDIFF:   72 bytes:  7603200/  7603200
+d7bfbe259af9ae323bb94b09c33570a5 *tests/data/fate/vsynth2-qtrlegray.out.rawvideo
+stddev:   18.65 PSNR: 22.72 MAXDIFF:   72 bytes:  7603200/  7603200
diff --git a/tests/tiny_psnr.c b/tests/tiny_psnr.c
index 264aa4d..5d01065 100644
--- a/tests/tiny_psnr.c
+++ b/tests/tiny_psnr.c
@@ -22,7 +22,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <inttypes.h>
-#include <assert.h>
 
 #include "libavutil/intfloat.h"
 
diff --git a/tools/ffeval.c b/tools/ffeval.c
index 0fab877..66b1032 100644
--- a/tools/ffeval.c
+++ b/tools/ffeval.c
@@ -24,6 +24,7 @@
 #endif
 
 #include "libavutil/eval.h"
+#include "libavutil/mem.h"
 
 #if !HAVE_GETOPT
 #include "compat/getopt.c"
@@ -47,20 +48,26 @@
            "-p PROMPT         set output prompt\n");
 }
 
-#define MAX_BLOCK_SIZE SIZE_MAX
-
 int main(int argc, char **argv)
 {
-    size_t buf_size = 256;
-    char *buf = av_malloc(buf_size);
+    int buf_size = 0;
+    char *buf = NULL;
     const char *outfilename = NULL, *infilename = NULL;
     FILE *outfile = NULL, *infile = NULL;
     const char *prompt = "=> ";
     int count = 0, echo = 0;
     int c;
 
-    av_max_alloc(MAX_BLOCK_SIZE);
+#define GROW_ARRAY()                                                    \
+    do {                                                                \
+        if (!av_dynarray2_add((void **)&buf, &buf_size, 1, NULL)) {     \
+            av_log(NULL, AV_LOG_ERROR,                                  \
+                   "Memory allocation problem occurred\n");             \
+            return 1;                                                   \
+        }                                                               \
+    } while (0)
 
+    GROW_ARRAY();
     while ((c = getopt(argc, argv, "ehi:o:p:")) != -1) {
         switch (c) {
         case 'e':
@@ -111,28 +118,18 @@
 
             buf[count] = 0;
             if (buf[0] != '#') {
-                av_expr_parse_and_eval(&d, buf,
-                                       NULL, NULL,
-                                       NULL, NULL, NULL, NULL, NULL, 0, NULL);
+                int ret = av_expr_parse_and_eval(&d, buf,
+                                                 NULL, NULL,
+                                                 NULL, NULL, NULL, NULL, NULL, 0, NULL);
                 if (echo)
                     fprintf(outfile, "%s ", buf);
-                fprintf(outfile, "%s%f\n", prompt, d);
+                if (ret >= 0) fprintf(outfile, "%s%f\n", prompt, d);
+                else          fprintf(outfile, "%s%s\n", prompt, av_err2str(ret));
             }
             count = 0;
         } else {
-            if (count >= buf_size-1) {
-                if (buf_size == MAX_BLOCK_SIZE) {
-                    av_log(NULL, AV_LOG_ERROR, "Memory allocation problem, "
-                           "max block size '%zd' reached\n", MAX_BLOCK_SIZE);
-                    return 1;
-                }
-                buf_size = FFMIN(buf_size, MAX_BLOCK_SIZE / 2) * 2;
-                buf = av_realloc_f((void *)buf, buf_size, 1);
-                if (!buf) {
-                    av_log(NULL, AV_LOG_ERROR, "Memory allocation problem occurred\n");
-                    return 1;
-                }
-            }
+            if (count >= buf_size-1)
+                GROW_ARRAY();
             buf[count++] = c;
         }
     }
diff --git a/tools/ffhash.c b/tools/ffhash.c
new file mode 100644
index 0000000..00a2872
--- /dev/null
+++ b/tools/ffhash.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2002 Fabrice Bellard
+ * Copyright (c) 2013 Michael Niedermayer
+ * Copyright (c) 2013 James Almer
+ *
+ * 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
+ */
+
+#include "config.h"
+#include "libavutil/error.h"
+#include "libavutil/hash.h"
+#include "libavutil/mem.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/stat.h>
+
+#if HAVE_IO_H
+#include <io.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#define SIZE 65536
+
+static struct AVHashContext *hash;
+static uint8_t *res;
+
+static void usage(void)
+{
+    int i = 0;
+    const char *name;
+
+    printf("usage: ffhash [algorithm] [input]...\n");
+    printf("Supported hash algorithms:");
+    do {
+        name = av_hash_names(i);
+        if (name)
+            printf(" %s", name);
+        i++;
+    } while(name);
+    printf("\n");
+}
+
+static void finish(void)
+{
+    int i, len = av_hash_get_size(hash);
+
+    printf("%s=0x", av_hash_get_name(hash));
+    av_hash_final(hash, res);
+    for (i = 0; i < len; i++)
+        printf("%02x", res[i]);
+}
+
+static int check(char *file)
+{
+    uint8_t buffer[SIZE];
+    int fd, flags = O_RDONLY;
+    int ret = 0;
+
+#ifdef O_BINARY
+    flags |= O_BINARY;
+#endif
+    if (file) fd = open(file, flags);
+    else      fd = 0;
+    if (fd == -1) {
+        printf("%s=OPEN-FAILED: %s:", av_hash_get_name(hash), strerror(errno));
+        ret = 1;
+        goto end;
+    }
+
+    av_hash_init(hash);
+    for (;;) {
+        ssize_t size = read(fd, buffer, SIZE);
+        if (size < 0) {
+            close(fd);
+            finish();
+            printf("+READ-FAILED: %s", strerror(errno));
+            ret = 2;
+            goto end;
+        } else if(!size)
+            break;
+        av_hash_update(hash, buffer, size);
+    }
+    close(fd);
+
+    finish();
+end:
+    if (file)
+        printf(" *%s", file);
+    printf("\n");
+
+    return ret;
+}
+
+int main(int argc, char **argv)
+{
+    int i;
+    int ret = 0;
+
+    if (argc == 1) {
+        usage();
+        return 0;
+    }
+
+    if ((ret = av_hash_alloc(&hash, argv[1])) < 0) {
+        switch(ret) {
+        case AVERROR(EINVAL):
+            printf("Invalid hash type: %s\n", argv[1]);
+            break;
+        case AVERROR(ENOMEM):
+            printf("%s\n", strerror(errno));
+            break;
+        }
+        return 1;
+    }
+    res = av_malloc(av_hash_get_size(hash));
+    if (!res) {
+        printf("%s\n", strerror(errno));
+        return 1;
+    }
+
+    for (i = 2; i < argc; i++)
+        ret |= check(argv[i]);
+
+    if (argc < 3)
+        ret |= check(NULL);
+
+    av_hash_freep(&hash);
+    av_freep(&res);
+
+    return ret;
+}
diff --git a/tools/fourcc2pixfmt.c b/tools/fourcc2pixfmt.c
index 77cb0b6..1a653ed 100644
--- a/tools/fourcc2pixfmt.c
+++ b/tools/fourcc2pixfmt.c
@@ -102,7 +102,7 @@
     if (list_pix_fmt_fourccs) {
         for (i = 0; i < AV_PIX_FMT_NB; i++) {
             const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(i);
-            if (!pix_desc->name || pix_desc->flags & PIX_FMT_HWACCEL)
+            if (!pix_desc->name || pix_desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
                 continue;
             printf("%s: ", pix_desc->name);
             print_pix_fmt_fourccs(i, ' ');
diff --git a/tools/graph2dot.c b/tools/graph2dot.c
index 167c49b..2daceb6 100644
--- a/tools/graph2dot.c
+++ b/tools/graph2dot.c
@@ -36,7 +36,7 @@
 
 static void usage(void)
 {
-    printf("Convert a libavfilter graph to a dot file\n");
+    printf("Convert a libavfilter graph to a dot file.\n");
     printf("Usage: graph2dot [OPTIONS]\n");
     printf("\n"
            "Options:\n"
@@ -137,7 +137,7 @@
         infilename = "/dev/stdin";
     infile = fopen(infilename, "r");
     if (!infile) {
-        fprintf(stderr, "Impossible to open input file '%s': %s\n",
+        fprintf(stderr, "Failed to open input file '%s': %s\n",
                 infilename, strerror(errno));
         return 1;
     }
@@ -146,7 +146,7 @@
         outfilename = "/dev/stdout";
     outfile = fopen(outfilename, "w");
     if (!outfile) {
-        fprintf(stderr, "Impossible to open output file '%s': %s\n",
+        fprintf(stderr, "Failed to open output file '%s': %s\n",
                 outfilename, strerror(errno));
         return 1;
     }
@@ -179,7 +179,7 @@
     avfilter_register_all();
 
     if (avfilter_graph_parse(graph, graph_string, NULL, NULL, NULL) < 0) {
-        fprintf(stderr, "Impossible to parse the graph description\n");
+        fprintf(stderr, "Failed to parse the graph description\n");
         return 1;
     }
 
diff --git a/tools/ismindex.c b/tools/ismindex.c
index 67a1927..7aaa235 100644
--- a/tools/ismindex.c
+++ b/tools/ismindex.c
@@ -34,15 +34,11 @@
 
 #include <stdio.h>
 #include <string.h>
-#include <sys/stat.h>
-#ifdef _WIN32
-#include <direct.h>
-#define mkdir(a, b) _mkdir(a)
-#endif
 
 #include "cmdutils.h"
 
 #include "libavformat/avformat.h"
+#include "libavformat/os_support.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mathematics.h"
 
diff --git a/tools/patcheck b/tools/patcheck
index 83db4c0..59a16ef 100755
--- a/tools/patcheck
+++ b/tools/patcheck
@@ -50,7 +50,7 @@
 hiegrep '//[-/<\* ]*$'    'empty comment' $*
 hiegrep '/\*[-<\* ]*\*/'  'empty comment' $*
 hiegrep 'for *\( *'"$ERE_PRITYP"' '  'not gcc 2.95 compatible' $*
-hiegrep '(static|inline|const) *\1'  'duplicate word' $*
+hiegrep '(static|inline|const) *\1[^_a-zA-Z]'  'duplicate word' $*
 hiegrep 'INIT_VLC_USE_STATIC' 'forbidden ancient vlc type' $*
 hiegrep '=[-+\*\&] ' 'looks like compound assignment' $*
 hiegrep2 '/\*\* *[a-zA-Z0-9].*' '\*/' 'Inconsistently formatted doxygen comment' $*
@@ -67,7 +67,7 @@
 cat $TMP
 hiegrep '# *ifdef * (HAVE|CONFIG)_' 'ifdefs that should be #if' $*
 
-hiegrep '\b(awnser|cant|dont|wont|usefull|successfull|occured|teh|alot|wether|skiped|skiping|heigth|informations|colums|loosy|loosing|ouput|seperate|preceed|upto|paket|posible|unkown|inpossible|dimention|acheive|funtions|overriden|outputing|seperation|initalize|compatibilty|bistream|knwon|unknwon)\b' 'common typos' $*
+hiegrep '\b(awnser|cant|dont|wont|doesnt|usefull|successfull|occured|teh|alot|wether|skiped|skiping|heigth|informations|colums|loosy|loosing|ouput|seperate|preceed|upto|paket|posible|unkown|inpossible|dimention|acheive|funtions|overriden|outputing|seperation|initalize|compatibilty|bistream|knwon|unknwon)\b' 'common typos' $*
 
 hiegrep 'av_log\( *NULL' 'Missing context in av_log' $*
 hiegrep '[^sn]printf' 'Please use av_log' $*
diff --git a/tools/pktdumper.c b/tools/pktdumper.c
index 920397b..61cb5cc 100644
--- a/tools/pktdumper.c
+++ b/tools/pktdumper.c
@@ -31,18 +31,18 @@
 #include <io.h>
 #endif
 
-#define FILENAME_BUF_SIZE 4096
-
 #include "libavutil/avstring.h"
 #include "libavutil/time.h"
 #include "libavformat/avformat.h"
 
+#define FILENAME_BUF_SIZE 4096
 #define PKTFILESUFF "_%08" PRId64 "_%02d_%010" PRId64 "_%06d_%c.bin"
 
 static int usage(int ret)
 {
-    fprintf(stderr, "dump (up to maxpkts) AVPackets as they are demuxed by libavformat.\n");
-    fprintf(stderr, "each packet is dumped in its own file named like `basename file.ext`_$PKTNUM_$STREAMINDEX_$STAMP_$SIZE_$FLAGS.bin\n");
+    fprintf(stderr, "Dump (up to maxpkts) AVPackets as they are demuxed by libavformat.\n");
+    fprintf(stderr, "Each packet is dumped in its own file named like\n");
+    fprintf(stderr, "$(basename file.ext)_$PKTNUM_$STREAMINDEX_$STAMP_$SIZE_$FLAGS.bin\n");
     fprintf(stderr, "pktdumper [-nw] file [maxpkts]\n");
     fprintf(stderr, "-n\twrite No file at all, only demux.\n");
     fprintf(stderr, "-w\tWait at end of processing instead of quitting.\n");
@@ -79,7 +79,7 @@
     if (strrchr(fntemplate, '.'))
         *strrchr(fntemplate, '.') = '\0';
     if (strchr(fntemplate, '%')) {
-        fprintf(stderr, "can't use filenames containing '%%'\n");
+        fprintf(stderr, "cannot use filenames containing '%%'\n");
         return usage(1);
     }
     if (strlen(fntemplate) + sizeof(PKTFILESUFF) >= sizeof(fntemplate) - 1) {
diff --git a/tools/qt-faststart.c b/tools/qt-faststart.c
index c9aa6e8..cb36c43 100644
--- a/tools/qt-faststart.c
+++ b/tools/qt-faststart.c
@@ -229,7 +229,7 @@
         atom_type = BE_32(&moov_atom[i]);
         if (atom_type == STCO_ATOM) {
             printf(" patching stco atom...\n");
-            atom_size = BE_32(&moov_atom[i - 4]);
+            atom_size = (uint32_t)BE_32(&moov_atom[i - 4]);
             if (i + atom_size - 4 > moov_atom_size) {
                 printf(" bad atom size\n");
                 goto error_out;
@@ -240,7 +240,7 @@
                 goto error_out;
             }
             for (j = 0; j < offset_count; j++) {
-                current_offset  = BE_32(&moov_atom[i + 12 + j * 4]);
+                current_offset  = (uint32_t)BE_32(&moov_atom[i + 12 + j * 4]);
                 current_offset += moov_atom_size;
                 moov_atom[i + 12 + j * 4 + 0] = (current_offset >> 24) & 0xFF;
                 moov_atom[i + 12 + j * 4 + 1] = (current_offset >> 16) & 0xFF;
@@ -250,7 +250,7 @@
             i += atom_size - 4;
         } else if (atom_type == CO64_ATOM) {
             printf(" patching co64 atom...\n");
-            atom_size = BE_32(&moov_atom[i - 4]);
+            atom_size = (uint32_t)BE_32(&moov_atom[i - 4]);
             if (i + atom_size - 4 > moov_atom_size) {
                 printf(" bad atom size\n");
                 goto error_out;
diff --git a/tools/zmqsend.c b/tools/zmqsend.c
new file mode 100644
index 0000000..ae3c8d7
--- /dev/null
+++ b/tools/zmqsend.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2013 Stefano Sabatini
+ *
+ * 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
+ */
+
+#include "config.h"
+
+#include <zmq.h>
+
+#include "libavutil/mem.h"
+#include "libavutil/bprint.h"
+
+#if HAVE_UNISTD_H
+#include <unistd.h>             /* getopt */
+#endif
+
+#if !HAVE_GETOPT
+#include "compat/getopt.c"
+#endif
+
+/**
+ * @file
+ * zmq message sender example, meant to be used with the zmq filters
+ */
+
+static void usage(void)
+{
+    printf("send message to ZMQ recipient, to use with the zmq filters\n");
+    printf("usage: zmqsend [OPTIONS]\n");
+    printf("\n"
+           "Options:\n"
+           "-b ADDRESS        set bind address\n"
+           "-h                print this help\n"
+           "-i INFILE         set INFILE as input file, stdin if omitted\n");
+}
+
+int main(int argc, char **argv)
+{
+    AVBPrint src;
+    char c, *src_buf, *recv_buf;
+    int recv_buf_size, ret;
+    void *ctx, *socket;
+    const char *bind_address = "tcp://localhost:5555";
+    const char *infilename = NULL;
+    FILE *infile = NULL;
+    zmq_msg_t msg;
+
+    while ((c = getopt(argc, argv, "b:hi:")) != -1) {
+        switch (c) {
+        case 'b':
+            bind_address = optarg;
+            break;
+        case 'h':
+            usage();
+            return 0;
+        case 'i':
+            infilename = optarg;
+            break;
+        case '?':
+            return 1;
+        }
+    }
+
+    if (!infilename || !strcmp(infilename, "-")) {
+        infilename = "stdin";
+        infile = stdin;
+    } else {
+        infile = fopen(infilename, "r");
+    }
+    if (!infile) {
+        av_log(NULL, AV_LOG_ERROR,
+               "Impossible to open input file '%s': %s\n", infilename, strerror(errno));
+        return 1;
+    }
+
+    ctx = zmq_ctx_new();
+    if (!ctx) {
+        av_log(NULL, AV_LOG_ERROR,
+               "Could not create ZMQ context: %s\n", zmq_strerror(errno));
+        return 1;
+    }
+
+    socket = zmq_socket(ctx, ZMQ_REQ);
+    if (!socket) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Could not create ZMQ socket: %s\n", zmq_strerror(errno));
+        ret = 1;
+        goto end;
+    }
+
+    if (zmq_connect(socket, bind_address) == -1) {
+        av_log(ctx, AV_LOG_ERROR, "Could not bind ZMQ responder to address '%s': %s\n",
+               bind_address, zmq_strerror(errno));
+        ret = 1;
+        goto end;
+    }
+
+    /* grab the input and store it in src */
+    av_bprint_init(&src, 1, AV_BPRINT_SIZE_UNLIMITED);
+    while ((c = fgetc(infile)) != EOF)
+        av_bprint_chars(&src, c, 1);
+    av_bprint_chars(&src, 0, 1);
+
+    if (!av_bprint_is_complete(&src)) {
+        av_log(NULL, AV_LOG_ERROR, "Could not allocate a buffer for the source string\n");
+        av_bprint_finalize(&src, NULL);
+        ret = 1;
+        goto end;
+    }
+    av_bprint_finalize(&src, &src_buf);
+
+    if (zmq_send(socket, src_buf, strlen(src_buf), 0) == -1) {
+        av_log(NULL, AV_LOG_ERROR, "Could not send message: %s\n", zmq_strerror(errno));
+        ret = 1;
+        goto end;
+    }
+
+    if (zmq_msg_init(&msg) == -1) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Could not initialize receiving message: %s\n", zmq_strerror(errno));
+        ret = 1;
+        goto end;
+    }
+
+    if (zmq_msg_recv(&msg, socket, 0) == -1) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Could not receive message: %s\n", zmq_strerror(errno));
+        zmq_msg_close(&msg);
+        ret = 1;
+        goto end;
+    }
+
+    recv_buf_size = zmq_msg_size(&msg) + 1;
+    recv_buf = av_malloc(recv_buf_size);
+    if (!recv_buf) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Could not allocate receiving message buffer\n");
+        zmq_msg_close(&msg);
+        ret = 1;
+        goto end;
+    }
+    memcpy(recv_buf, zmq_msg_data(&msg), recv_buf_size);
+    recv_buf[recv_buf_size-1] = 0;
+    printf("%s\n", recv_buf);
+    zmq_msg_close(&msg);
+    av_free(recv_buf);
+
+end:
+    zmq_close(socket);
+    zmq_ctx_destroy(ctx);
+    return ret;
+}
diff --git a/tools/zmqshell.py b/tools/zmqshell.py
new file mode 100755
index 0000000..a7d1126
--- /dev/null
+++ b/tools/zmqshell.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python2
+
+import sys, zmq, cmd
+
+class LavfiCmd(cmd.Cmd):
+    prompt = 'lavfi> '
+
+    def __init__(self, bind_address):
+        context = zmq.Context()
+        self.requester = context.socket(zmq.REQ)
+        self.requester.connect(bind_address)
+        cmd.Cmd.__init__(self)
+
+    def onecmd(self, cmd):
+        if cmd == 'EOF':
+            sys.exit(0)
+        print 'Sending command:[%s]' % cmd
+        self.requester.send(cmd)
+        message = self.requester.recv()
+        print 'Received reply:[%s]' % message
+
+try:
+    bind_address = sys.argv[1] if len(sys.argv) > 1 else "tcp://localhost:5555"
+    LavfiCmd(bind_address).cmdloop('FFmpeg libavfilter interactive shell')
+except KeyboardInterrupt:
+    pass